merged overview, merged search and searchGlobal done (supergroups)

This commit is contained in:
John Preston 2015-11-18 16:11:56 +03:00
parent ca34a09f20
commit 37de0904af
13 changed files with 937 additions and 676 deletions

View File

@ -236,17 +236,17 @@ namespace App {
case -2: {
QDate yesterday(date(now).date());
return int32(QDateTime(yesterday.addDays(-3)).toTime_t());
return int32(QDateTime(yesterday.addDays(-3)).toTime_t()) + (unixtime() - myunixtime());
} break;
case -3: {
QDate weekago(date(now).date());
return int32(QDateTime(weekago.addDays(-7)).toTime_t());
return int32(QDateTime(weekago.addDays(-7)).toTime_t()) + (unixtime() - myunixtime());
} break;
case -4: {
QDate monthago(date(now).date());
return int32(QDateTime(monthago.addDays(-30)).toTime_t());
return int32(QDateTime(monthago.addDays(-30)).toTime_t()) + (unixtime() - myunixtime());
} break;
}
return -online;

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,15 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
class MainWidget;
enum DialogsSearchRequestType {
DialogsSearchFromStart,
DialogsSearchFromOffset,
DialogsSearchPeerFromStart,
DialogsSearchPeerFromOffset,
DialogsSearchMigratedFromStart,
DialogsSearchMigratedFromOffset,
};
class DialogsInner : public SplittedWidget {
Q_OBJECT
@ -32,7 +41,7 @@ public:
void dialogsReceived(const QVector<MTPDialog> &dialogs);
void addSavedPeersAfter(const QDateTime &date);
void addAllSavedPeers();
void searchReceived(const QVector<MTPMessage> &messages, bool fromStart, int32 fullCount);
bool searchReceived(const QVector<MTPMessage> &messages, DialogsSearchRequestType type, int32 fullCount);
void peopleReceived(const QString &query, const QVector<MTPPeer> &people);
void showMore(int32 pixels);
@ -86,7 +95,10 @@ public:
FilteredDialogs &filteredList();
PeopleResults &peopleList();
SearchResults &searchList();
int32 lastSearchDate() const;
PeerData *lastSearchPeer() const;
MsgId lastSearchId() const;
MsgId lastSearchMigratedId() const;
void setMouseSel(bool msel, bool toTop = false);
@ -144,22 +156,24 @@ private:
bool contactSel;
bool selByMouse;
QString filter, _hashtagFilter;
QString _filter, _hashtagFilter;
QStringList hashtagResults;
int32 hashtagSel;
QStringList _hashtagResults;
int32 _hashtagSel;
FilteredDialogs filterResults;
int32 filteredSel;
FilteredDialogs _filterResults;
int32 _filteredSel;
SearchResults searchResults;
int32 searchedCount, searchedSel;
SearchResults _searchResults;
int32 _searchedCount, _searchedMigratedCount, _searchedSel;
QString peopleQuery;
PeopleResults peopleResults;
int32 peopleSel;
QString _peopleQuery;
PeopleResults _peopleResults;
int32 _peopleSel;
MsgId _lastSearchId;
int32 _lastSearchDate;
PeerData *_lastSearchPeer;
MsgId _lastSearchId, _lastSearchMigratedId;
State _state;
@ -172,7 +186,7 @@ private:
bool _overDelete;
PeerData *_searchInPeer;
PeerData *_searchInPeer, *_searchInMigrated;
};
@ -184,7 +198,7 @@ public:
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req);
void contactsReceived(const MTPcontacts_Contacts &contacts);
void searchReceived(bool fromStart, const MTPmessages_Messages &result, mtpRequestId req);
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req);
bool addNewContact(int32 uid, bool show = true);
@ -223,7 +237,7 @@ public:
DialogsIndexed &dialogsList();
void searchMessages(const QString &query, PeerData *inPeer = 0);
void onSearchMore(MsgId minMsgId);
void onSearchMore();
void itemRemoved(HistoryItem *item);
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
@ -260,7 +274,7 @@ private:
void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
bool dialogsFailed(const RPCError &error, mtpRequestId req);
bool contactsFailed(const RPCError &error);
bool searchFailed(const RPCError &error, mtpRequestId req);
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
bool peopleFailed(const RPCError &error, mtpRequestId req);
int32 _dialogsOffset, _dialogsCount;
@ -276,11 +290,11 @@ private:
anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_shadow;
PeerData *_searchInPeer;
PeerData *_searchInPeer, *_searchInMigrated;
QTimer _searchTimer;
QString _searchQuery, _peopleQuery;
bool _searchFull, _peopleFull;
bool _searchFull, _searchFullMigrated, _peopleFull;
mtpRequestId _searchRequest, _peopleRequest;
typedef QMap<QString, MTPmessages_Messages> SearchCache;

View File

@ -179,7 +179,11 @@ void DialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackgrou
p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b);
if (onlyBackground) return;
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));
if (history->peer->migrateTo()) {
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->migrateTo()->photo->pix(st::dlgPhotoSize));
} else {
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));
}
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor;
@ -277,8 +281,11 @@ void FakeDialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBack
if (onlyBackground) return;
History *history = _item->history();
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));
if (history->peer->migrateTo()) {
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->migrateTo()->photo->pix(st::dlgPhotoSize));
} else {
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));
}
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor;
@ -363,7 +370,7 @@ History::History(const PeerId &peerId) : width(0), height(0)
outboxReadBefore = INT_MAX;
}
for (int32 i = 0; i < OverviewCount; ++i) {
overviewCount[i] = -1; // not loaded yet
overviewCountData[i] = -1; // not loaded yet
}
}
@ -444,11 +451,8 @@ void History::eraseFromOverview(MediaOverviewType type, MsgId msgId) {
for (History::MediaOverview::iterator i = overview[type].begin(), e = overview[type].end(); i != e; ++i) {
if ((*i) == msgId) {
overview[type].erase(i);
if (overviewCount[type] > 0) {
--overviewCount[type];
if (!overviewCount[type]) {
overviewCount[type] = -1;
}
if (overviewCountData[type] > 0) {
--overviewCountData[type];
}
break;
}
@ -1655,7 +1659,9 @@ void History::addToOverview(HistoryItem *item, MediaOverviewType type) {
if (overviewIds[type].constFind(item->id) == overviewIds[type].cend()) {
overview[type].push_back(item->id);
overviewIds[type].insert(item->id, NullType());
if (overviewCount[type] > 0) ++overviewCount[type];
if (overviewCountData[type] > 0) {
++overviewCountData[type];
}
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
}
}
@ -2105,7 +2111,7 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
if (!wasLoadedAtBottom && loadedAtBottom()) { // add all loaded photos to overview
int32 mask = 0;
for (int32 i = 0; i < OverviewCount; ++i) {
if (overviewCount[i] == 0) continue; // all loaded
if (overviewCountData[i] == 0) continue; // all loaded
if (!overview[i].isEmpty() || !overviewIds[i].isEmpty()) {
overview[i].clear();
overviewIds[i].clear();
@ -2126,13 +2132,13 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
if (t != OverviewCount) {
if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) {
t = OverviewAudioDocuments;
if (overviewCount[t] != 0) {
if (overviewCountData[t] != 0) {
overview[t].push_back(item->id);
overviewIds[t].insert(item->id, NullType());
mask |= (1 << t);
}
} else {
if (overviewCount[t] != 0) {
if (overviewCountData[t] != 0) {
overview[t].push_back(item->id);
overviewIds[t].insert(item->id, NullType());
mask |= (1 << t);
@ -2142,7 +2148,7 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
}
if (item->hasTextLinks()) {
MediaOverviewType t = OverviewLinks;
if (overviewCount[t] != 0) {
if (overviewCountData[t] != 0) {
overview[t].push_back(item->id);
overviewIds[t].insert(item->id, NullType());
mask |= (1 << t);
@ -2564,9 +2570,11 @@ void History::clear(bool leaveItems) {
for (int32 i = 0; i < OverviewCount; ++i) {
if (!overview[i].isEmpty() || !overviewIds[i].isEmpty()) {
if (leaveItems) {
if (overviewCount[i] == 0) overviewCount[i] = overview[i].size();
if (overviewCountData[i] == 0) {
overviewCountData[i] = overview[i].size();
}
} else {
overviewCount[i] = -1; // not loaded yet
overviewCountData[i] = -1; // not loaded yet
}
overview[i].clear();
overviewIds[i].clear();
@ -2599,6 +2607,86 @@ void History::clear(bool leaveItems) {
if (leaveItems && App::main()) App::main()->historyCleared(this);
}
void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages &result, bool onlyCounts) {
const QVector<MTPMessage> *v = 0;
switch (result.type()) {
case mtpc_messages_messages: {
const MTPDmessages_messages &d(result.c_messages_messages());
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
v = &d.vmessages.c_vector().v;
overviewCountData[overviewIndex] = 0;
} break;
case mtpc_messages_messagesSlice: {
const MTPDmessages_messagesSlice &d(result.c_messages_messagesSlice());
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
overviewCountData[overviewIndex] = d.vcount.v;
v = &d.vmessages.c_vector().v;
} break;
case mtpc_messages_channelMessages: {
const MTPDmessages_channelMessages &d(result.c_messages_channelMessages());
if (peer->isChannel()) {
peer->asChannel()->ptsReceived(d.vpts.v);
} else {
LOG(("API Error: received messages.channelMessages when no channel was passed! (History::overviewSliceDone, onlyCounts %1)").arg(logBool(onlyCounts)));
}
if (d.has_collapsed()) { // should not be returned
LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (History::overviewSliceDone, onlyCounts %1)").arg(logBool(onlyCounts)));
}
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
overviewCountData[overviewIndex] = d.vcount.v;
v = &d.vmessages.c_vector().v;
} break;
default: return;
}
if (!onlyCounts && v->isEmpty()) {
overviewCountData[overviewIndex] = 0;
} else if (overviewCountData[overviewIndex] > 0) {
for (History::MediaOverviewIds::const_iterator i = overviewIds[overviewIndex].cbegin(), e = overviewIds[overviewIndex].cend(); i != e; ++i) {
if (i.key() < 0) {
++overviewCountData[overviewIndex];
} else {
break;
}
}
}
for (QVector<MTPMessage>::const_iterator i = v->cbegin(), e = v->cend(); i != e; ++i) {
HistoryItem *item = App::histories().addNewMessage(*i, NewMessageExisting);
if (item && overviewIds[overviewIndex].constFind(item->id) == overviewIds[overviewIndex].cend()) {
overviewIds[overviewIndex].insert(item->id, NullType());
overview[overviewIndex].push_front(item->id);
}
}
}
void History::changeMsgId(MsgId oldId, MsgId newId) {
for (int32 i = 0; i < OverviewCount; ++i) {
History::MediaOverviewIds::iterator j = overviewIds[i].find(oldId);
if (j != overviewIds[i].cend()) {
overviewIds[i].erase(j);
int32 index = overview[i].indexOf(oldId);
if (overviewIds[i].constFind(newId) == overviewIds[i].cend()) {
overviewIds[i].insert(newId, NullType());
if (index >= 0) {
overview[i][index] = newId;
} else {
overview[i].push_back(newId);
}
} else if (index >= 0) {
overview[i].removeAt(index);
}
}
}
}
void History::blockResized(HistoryBlock *block, int32 dh) {
int32 i = blocks.indexOf(block), l = blocks.size();
if (i >= 0) {
@ -2910,6 +2998,11 @@ void HistoryItem::detachFast() {
_block = 0;
}
void HistoryItem::setId(MsgId newId) {
history()->changeMsgId(id, newId);
id = newId;
}
HistoryItem::~HistoryItem() {
itemAnimations().remove(this);
App::historyUnregItem(this);
@ -6555,7 +6648,7 @@ void HistoryMessage::setViewsCount(int32 count) {
void HistoryMessage::setId(MsgId newId) {
bool wasPositive = (id > 0), positive = (newId > 0);
id = newId;
HistoryItem::setId(newId);
if (wasPositive == positive) {
if (App::main()) App::main()->msgUpdated(this);
} else {

View File

@ -342,20 +342,46 @@ public:
QMap<SendActionType, uint64> mySendActions;
typedef QList<MsgId> MediaOverview;
typedef QMap<MsgId, NullType> MediaOverviewIds;
MediaOverview overview[OverviewCount];
MediaOverviewIds overviewIds[OverviewCount];
int32 overviewCount[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded
bool overviewCountKnown(int32 overviewIndex) const {
return overviewCount[overviewIndex] >= 0;
bool overviewCountLoaded(int32 overviewIndex) const {
return overviewCountData[overviewIndex] >= 0;
}
int32 overviewCountValue(int32 overviewIndex) const {
return (overviewCount[overviewIndex] == 0) ? overview[overviewIndex].size() : overviewCount[overviewIndex];
bool overviewLoaded(int32 overviewIndex) const {
return overviewCount(overviewIndex) == overview[overviewIndex].size();
}
int32 overviewCount(int32 overviewIndex, int32 defaultValue = -1) const {
int32 result = overviewCountData[overviewIndex], loaded = overview[overviewIndex].size();
if (result < 0) return defaultValue;
if (result < loaded) {
if (result > 0) {
const_cast<History*>(this)->overviewCountData[overviewIndex] = 0;
}
return loaded;
}
return result;
}
MsgId overviewMinId(int32 overviewIndex) const {
for (MediaOverviewIds::const_iterator i = overviewIds[overviewIndex].cbegin(), e = overviewIds[overviewIndex].cend(); i != e; ++i) {
if (i.key() > 0) {
return i.key();
}
}
return 0;
}
void overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages &result, bool onlyCounts = false);
bool overviewHasMsgId(int32 overviewIndex, MsgId msgId) const {
return overviewIds[overviewIndex].constFind(msgId) != overviewIds[overviewIndex].cend();
}
void changeMsgId(MsgId oldId, MsgId newId);
private:
typedef QMap<MsgId, NullType> MediaOverviewIds;
MediaOverviewIds overviewIds[OverviewCount];
int32 overviewCountData[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded
friend class HistoryBlock;
friend class ChannelHistory;
@ -469,7 +495,9 @@ struct DialogsList {
DialogRow *drawFrom = current;
p.translate(0, drawFrom->pos * st::dlgHeight);
while (drawFrom != end && drawFrom->pos * st::dlgHeight < hTo) {
drawFrom->paint(p, w, (drawFrom->history->peer == act), (drawFrom->history->peer == sel), onlyBackground);
bool active = (drawFrom->history->peer == act) || (drawFrom->history->peer->migrateTo() && drawFrom->history->peer->migrateTo() == act);
bool selected = (drawFrom->history->peer == sel);
drawFrom->paint(p, w, active, selected, onlyBackground);
drawFrom = drawFrom->next;
p.translate(0, st::dlgHeight);
}
@ -923,9 +951,7 @@ public:
}
virtual void setViewsCount(int32 count) {
}
virtual void setId(MsgId newId) {
id = newId;
}
virtual void setId(MsgId newId);
virtual void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const = 0;
virtual QString notificationHeader() const {
return QString();

View File

@ -1296,7 +1296,7 @@ bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
if (type == OverviewCount) return false;
History *h = App::history(peer->id);
if (h->overviewCount[type] >= 0 || _overviewPreload[type].constFind(peer) != _overviewPreload[type].cend()) {
if (h->overviewCountLoaded(type) || _overviewPreload[type].constFind(peer) != _overviewPreload[type].cend()) {
return false;
}
@ -1331,50 +1331,7 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r
if (type == OverviewCount) return;
History *h = App::history(peer->id);
switch (result.type()) {
case mtpc_messages_messages: {
const MTPDmessages_messages &d(result.c_messages_messages());
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
h->overviewCount[type] = d.vmessages.c_vector().v.size();
} break;
case mtpc_messages_messagesSlice: {
const MTPDmessages_messagesSlice &d(result.c_messages_messagesSlice());
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
h->overviewCount[type] = d.vcount.v;
} break;
case mtpc_messages_channelMessages: {
const MTPDmessages_channelMessages &d(result.c_messages_channelMessages());
if (peer && peer->isChannel()) {
peer->asChannel()->ptsReceived(d.vpts.v);
} else {
LOG(("API Error: received messages.channelMessages when no channel was passed! (MainWidget::overviewPreloaded)"));
}
if (d.has_collapsed()) { // should not be returned
LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (MainWidget::overviewPreloaded)"));
}
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
h->overviewCount[type] = d.vcount.v;
} break;
default: return;
}
if (h->overviewCount[type] > 0) {
for (History::MediaOverviewIds::const_iterator i = h->overviewIds[type].cbegin(), e = h->overviewIds[type].cend(); i != e; ++i) {
if (i.key() < 0) {
++h->overviewCount[type];
} else {
break;
}
}
}
App::history(peer->id)->overviewSliceDone(type, result, true);
mediaOverviewUpdated(peer, type);
}
@ -1390,9 +1347,9 @@ void MainWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
History *m = (peer && peer->migrateFrom()) ? App::historyLoaded(peer->migrateFrom()->id) : 0;
if (h) {
for (int32 i = 0; i < OverviewCount; ++i) {
if (!h->overview[i].isEmpty() || h->overviewCount[i] > 0 || i == overview->type()) {
if (!h->overview[i].isEmpty() || h->overviewCount(i) > 0 || i == overview->type()) {
mask |= (1 << i);
} else if (m && (!m->overview[i].isEmpty() || m->overviewCount[i] > 0)) {
} else if (m && (!m->overview[i].isEmpty() || m->overviewCount(i) > 0)) {
mask |= (1 << i);
}
}
@ -1499,22 +1456,16 @@ bool MainWidget::overviewFailed(PeerData *peer, const RPCError &error, mtpReques
void MainWidget::loadMediaBack(PeerData *peer, MediaOverviewType type, bool many) {
if (_overviewLoad[type].constFind(peer) != _overviewLoad[type].cend()) return;
MsgId minId = 0;
History *hist = App::history(peer->id);
if (hist->overviewCount[type] == 0) return; // all loaded
History *history = App::history(peer->id);
if (history->overviewLoaded(type)) return;
for (History::MediaOverviewIds::const_iterator i = hist->overviewIds[type].cbegin(), e = hist->overviewIds[type].cend(); i != e; ++i) {
if (i.key() > 0) {
minId = i.key();
break;
}
}
int32 limit = many ? SearchManyPerPage : (hist->overview[type].size() > MediaOverviewStartPerPage) ? SearchPerPage : MediaOverviewStartPerPage;
MsgId minId = history->overviewMinId(type);
int32 limit = many ? SearchManyPerPage : (history->overview[type].size() > MediaOverviewStartPerPage) ? SearchPerPage : MediaOverviewStartPerPage;
MTPMessagesFilter filter = typeToMediaFilter(type);
if (type == OverviewCount) return;
int32 flags = (peer->isChannel() && !peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0;
_overviewLoad[type].insert(peer, MTP::send(MTPmessages_Search(MTP_int(flags), peer->input, MTPstring(), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(minId), MTP_int(limit)), rpcDone(&MainWidget::overviewLoaded, hist)));
_overviewLoad[type].insert(peer, MTP::send(MTPmessages_Search(MTP_int(flags), peer->input, MTPstring(), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(minId), MTP_int(limit)), rpcDone(&MainWidget::overviewLoaded, history)));
}
void MainWidget::peerUsernameChanged(PeerData *peer) {
@ -1542,11 +1493,11 @@ void MainWidget::showNewGroup() {
dialogs.onNewGroup();
}
void MainWidget::overviewLoaded(History *h, const MTPmessages_Messages &msgs, mtpRequestId req) {
void MainWidget::overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req) {
OverviewsPreload::iterator it;
MediaOverviewType type = OverviewCount;
for (int32 i = 0; i < OverviewCount; ++i) {
it = _overviewLoad[i].find(h->peer);
it = _overviewLoad[i].find(history->peer);
if (it != _overviewLoad[i].cend()) {
type = MediaOverviewType(i);
_overviewLoad[i].erase(it);
@ -1555,65 +1506,9 @@ void MainWidget::overviewLoaded(History *h, const MTPmessages_Messages &msgs, mt
}
if (type == OverviewCount) return;
const QVector<MTPMessage> *v = 0;
switch (msgs.type()) {
case mtpc_messages_messages: {
const MTPDmessages_messages &d(msgs.c_messages_messages());
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
v = &d.vmessages.c_vector().v;
h->overviewCount[type] = 0;
} break;
history->overviewSliceDone(type, result);
case mtpc_messages_messagesSlice: {
const MTPDmessages_messagesSlice &d(msgs.c_messages_messagesSlice());
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
h->overviewCount[type] = d.vcount.v;
v = &d.vmessages.c_vector().v;
} break;
case mtpc_messages_channelMessages: {
const MTPDmessages_channelMessages &d(msgs.c_messages_channelMessages());
if (h && h->peer->isChannel()) {
h->peer->asChannel()->ptsReceived(d.vpts.v);
} else {
LOG(("API Error: received messages.channelMessages when no channel was passed! (MainWidget::overviewLoaded)"));
}
if (d.has_collapsed()) { // should not be returned
LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (MainWidget::overviewLoaded)"));
}
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
h->overviewCount[type] = d.vcount.v;
v = &d.vmessages.c_vector().v;
} break;
default: return;
}
if (h->overviewCount[type] > 0) {
for (History::MediaOverviewIds::const_iterator i = h->overviewIds[type].cbegin(), e = h->overviewIds[type].cend(); i != e; ++i) {
if (i.key() < 0) {
++h->overviewCount[type];
} else {
break;
}
}
}
if (v->isEmpty()) {
h->overviewCount[type] = 0;
}
for (QVector<MTPMessage>::const_iterator i = v->cbegin(), e = v->cend(); i != e; ++i) {
HistoryItem *item = App::histories().addNewMessage(*i, NewMessageExisting);
if (item && h->overviewIds[type].constFind(item->id) == h->overviewIds[type].cend()) {
h->overviewIds[type].insert(item->id, NullType());
h->overview[type].push_front(item->id);
}
}
if (App::wnd()) App::wnd()->mediaOverviewUpdated(h->peer, type);
if (App::wnd()) App::wnd()->mediaOverviewUpdated(history->peer, type);
}
void MainWidget::sendReadRequest(PeerData *peer, MsgId upTo) {
@ -4263,22 +4158,6 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
HistoryItem *msgRow = App::histItemById(msg);
if (msgRow) {
App::historyUnregItem(msgRow);
History *h = msgRow->history();
for (int32 i = 0; i < OverviewCount; ++i) {
History::MediaOverviewIds::iterator j = h->overviewIds[i].find(msgRow->id);
if (j != h->overviewIds[i].cend()) {
h->overviewIds[i].erase(j);
if (h->overviewIds[i].constFind(d.vid.v) == h->overviewIds[i].cend()) {
h->overviewIds[i].insert(d.vid.v, NullType());
for (int32 k = 0, l = h->overview[i].size(); k != l; ++k) {
if (h->overview[i].at(k) == msgRow->id) {
h->overview[i][k] = d.vid.v;
break;
}
}
}
}
}
if (App::wnd()) App::wnd()->changingMsgId(msgRow, d.vid.v);
msgRow->setId(d.vid.v);
if (msgRow->history()->peer->isSelf()) {
@ -4287,6 +4166,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
if (!App::historyRegItem(msgRow)) {
msgUpdated(msgRow);
} else {
History *h = msgRow->history();
bool wasLast = (h->lastMsg == msgRow);
msgRow->destroy();
if (wasLast && !h->lastMsg) {

View File

@ -490,7 +490,7 @@ private:
void readRequestDone(PeerData *peer);
void messagesAffected(PeerData *peer, const MTPmessages_AffectedMessages &result);
void overviewLoaded(History *h, const MTPmessages_Messages &msgs, mtpRequestId req);
void overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req);
bool _started;

View File

@ -345,7 +345,7 @@ void MediaView::updateControls() {
_dateText = lng_mediaview_date_time(lt_date, d.date().toString(qsl("dd.MM.yy")), lt_time, d.time().toString(cTimeFormat()));
}
if (_from) {
_fromName.setText(st::mvFont, _from->name);
_fromName.setText(st::mvFont, (_from->migrateTo() ? _from->migrateTo() : _from)->name);
_nameNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mvFont->height);
_dateNav = myrtlrect(st::mvTextLeft + _nameNav.width() + st::mvTextSkip, height() - st::mvTextTop, st::mvFont->width(_dateText), st::mvFont->height);
} else {
@ -355,15 +355,15 @@ void MediaView::updateControls() {
updateHeader();
if (_photo || (_history && (_overview == OverviewPhotos || _overview == OverviewDocuments))) {
_leftNavVisible = (_index > 0) || (_index == 0 && (
(!_msgmigrated && _history && _history->overview[_overview].size() < _history->overviewCount[_overview]) ||
(_msgmigrated && _migrated && _migrated->overview[_overview].size() < _migrated->overviewCount[_overview]) ||
(!_msgmigrated && _history && _migrated && (!_migrated->overview[_overview].isEmpty() || _migrated->overviewCount[_overview] > 0))));
(!_msgmigrated && _history && _history->overview[_overview].size() < _history->overviewCount(_overview)) ||
(_msgmigrated && _migrated && _migrated->overview[_overview].size() < _migrated->overviewCount(_overview)) ||
(!_msgmigrated && _history && _migrated && (!_migrated->overview[_overview].isEmpty() || _migrated->overviewCount(_overview) > 0))));
_rightNavVisible = (_index >= 0) && (
(!_msgmigrated && _history && _index + 1 < _history->overview[_overview].size()) ||
(_msgmigrated && _migrated && _index + 1 < _migrated->overview[_overview].size()) ||
(_msgmigrated && _migrated && _history && (!_history->overview[_overview].isEmpty() || _history->overviewCount[_overview] > 0)) ||
(_msgmigrated && _migrated && _history && (!_history->overview[_overview].isEmpty() || _history->overviewCount(_overview) > 0)) ||
(!_history && _user && (_index + 1 < _user->photos.size() || _index + 1 < _user->photosCount)));
if (_msgmigrated && _history->overview[_overview].size() < _history->overviewCountValue(_overview)) {
if (_msgmigrated && !_history->overviewLoaded(_overview)) {
_leftNavVisible = _rightNavVisible = false;
}
} else {
@ -1480,7 +1480,7 @@ void MediaView::moveToNext(int32 delta) {
if (_index < 0 || (_history && _overview != OverviewPhotos && _overview != OverviewDocuments) || (_overview == OverviewCount && !_user)) {
return;
}
if (_msgmigrated && _history->overview[_overview].size() < _history->overviewCountValue(_overview)) {
if (_msgmigrated && !_history->overviewLoaded(_overview)) {
return;
}
@ -1491,7 +1491,7 @@ void MediaView::moveToNext(int32 delta) {
newIndex += _migrated->overview[_overview].size();
newMigrated = true;
} else if (newMigrated && newIndex >= _migrated->overview[_overview].size()) {
newIndex -= _migrated->overview[_overview].size() + (_history->overviewCountValue(_overview) - _history->overview[_overview].size());
newIndex -= _migrated->overview[_overview].size() + (_history->overviewCount(_overview) - _history->overview[_overview].size());
newMigrated = false;
}
if (newIndex >= 0 && newIndex < (newMigrated ? _migrated : _history)->overview[_overview].size()) {
@ -1540,7 +1540,7 @@ void MediaView::preloadData(int32 delta) {
int32 previewIndex = i;
if (_msgmigrated && previewIndex >= _migrated->overview[_overview].size()) {
previewHistory = _history;
previewIndex -= _migrated->overview[_overview].size() + (_history->overviewCountValue(_overview) - _history->overview[_overview].size());
previewIndex -= _migrated->overview[_overview].size() + (_history->overviewCount(_overview) - _history->overview[_overview].size());
} else if (!_msgmigrated && previewIndex < 0) {
previewHistory = _migrated;
previewIndex += _migrated->overview[_overview].size();
@ -1561,7 +1561,7 @@ void MediaView::preloadData(int32 delta) {
History *forgetHistory = _msgmigrated ? _migrated : _history;
if (_msgmigrated && forgetIndex >= _migrated->overview[_overview].size()) {
forgetHistory = _history;
forgetIndex -= _migrated->overview[_overview].size() + (_history->overviewCountValue(_overview) - _history->overview[_overview].size());
forgetIndex -= _migrated->overview[_overview].size() + (_history->overviewCount(_overview) - _history->overview[_overview].size());
} else if (!_msgmigrated && forgetIndex < 0) {
forgetHistory = _migrated;
forgetIndex += _migrated->overview[_overview].size();
@ -1985,10 +1985,10 @@ void MediaView::findCurrent() {
break;
}
}
if (_history->overviewCount[_overview] < 0) {
if (!_history->overviewCountLoaded(_overview)) {
loadBack();
} else if (_history->overviewCountValue(_overview) <= _history->overview[_overview].size()) { // all loaded
if (_migrated->overviewCount[_overview] < 0 || (_index < 2 && _migrated->overviewCount[_overview] > 0)) {
} else if (_history->overviewLoaded(_overview) && !_migrated->overviewLoaded(_overview)) { // all loaded
if (!_migrated->overviewCountLoaded(_overview) || (_index < 2 && _migrated->overviewCount(_overview) > 0)) {
loadBack();
}
}
@ -1999,10 +1999,14 @@ void MediaView::findCurrent() {
break;
}
}
if (_history->overviewCount[_overview] < 0 || (_index < 2 && _history->overviewCount[_overview] > 0) || (_index < 1 && _migrated && _migrated->overviewCount[_overview] != 0)) {
if (!_history->overviewLoaded(_overview)) {
if (!_history->overviewCountLoaded(_overview) || (_index < 2 && _history->overviewCount(_overview) > 0) || (_index < 1 && _migrated && !_migrated->overviewLoaded(_overview))) {
loadBack();
}
} else if (_index < 1 && _migrated && !_migrated->overviewLoaded(_overview)) {
loadBack();
}
if (_migrated && _migrated->overviewCount[_overview] < 0) {
if (_migrated && !_migrated->overviewCountLoaded(_overview)) {
App::main()->preloadOverview(_migrated->peer, _overview);
}
}
@ -2011,17 +2015,17 @@ void MediaView::findCurrent() {
void MediaView::loadBack() {
if (_loadRequest || _index < 0 || (_overview == OverviewCount && !_user)) return;
if (_history && _overview != OverviewCount && (_history->overviewCount[_overview] != 0 || (_migrated && _migrated->overviewCount[_overview] != 0))) {
if (_history && _overview != OverviewCount && (!_history->overviewLoaded(_overview) || (_migrated && !_migrated->overviewLoaded(_overview)))) {
if (App::main()) {
if (_msgmigrated || (_migrated && _index == 0 && _history->overviewCount[_overview] >= 0 && _history->overviewCountValue(_overview) <= _history->overview[_overview].size())) {
if (_msgmigrated || (_migrated && _index == 0 && _history->overviewLoaded(_overview))) {
App::main()->loadMediaBack(_migrated->peer, _overview);
} else {
App::main()->loadMediaBack(_history->peer, _overview);
if (_migrated && _index == 0 && _migrated->overviewCount[_overview] != 0 && _migrated->overview[_overview].isEmpty()) {
if (_migrated && _index == 0 && _migrated->overview[_overview].isEmpty() && !_migrated->overviewLoaded(_overview)) {
App::main()->loadMediaBack(_migrated->peer, _overview);
}
}
if (_msgmigrated && _history->overviewCount[_overview] < 0) {
if (_msgmigrated && !_history->overviewCountLoaded(_overview)) {
App::main()->preloadOverview(_history->peer, _overview);
}
}
@ -2068,14 +2072,14 @@ void MediaView::userPhotosLoaded(UserData *u, const MTPphotos_Photos &photos, mt
}
void MediaView::updateHeader() {
int32 index = _index, count = 0, addcount = (_migrated && _overview != OverviewCount) ? _migrated->overviewCountValue(_overview) : 0;
int32 index = _index, count = 0, addcount = (_migrated && _overview != OverviewCount) ? _migrated->overviewCount(_overview) : 0;
if (_history) {
if (_overview != OverviewCount) {
count = _history->overviewCountValue(_overview);
count = _history->overviewCount(_overview);
if (addcount >= 0 && count >= 0) {
count += addcount;
}
if (index >= 0 && (_msgmigrated ? (count >= 0 && addcount >= 0 && _history->overviewCountValue(_overview) <= _history->overview[_overview].size()) : (count >= 0))) {
if (index >= 0 && (_msgmigrated ? (count >= 0 && addcount >= 0 && _history->overviewLoaded(_overview)) : (count >= 0))) {
if (_msgmigrated) {
index += addcount - _migrated->overview[_overview].size();
} else {

View File

@ -136,16 +136,16 @@ int32 OverviewInner::CachedLink::countHeight(int32 w) {
// flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html
OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const PeerData *peer, MediaOverviewType type) : QWidget(0)
OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerData *peer, MediaOverviewType type) : QWidget(0)
, _overview(overview)
, _scroll(scroll)
, _resizeIndex(-1)
, _resizeSkip(0)
, _peer(App::peer(peer->id))
, _peer(peer->migrateTo() ? peer->migrateTo() : peer)
, _type(type)
, _migrated(0)
, _history(App::history(peer->id))
, _channel(peerToChannel(peer->id))
, _migrated(_peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0)
, _history(App::history(_peer->id))
, _channel(peerToChannel(_peer->id))
, _photosInRow(1)
, _photosToAdd(0)
, _selMode(false)
@ -159,8 +159,10 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const
, _itemsToBeLoaded(LinksOverviewPerPage * 2)
, _inSearch(false)
, _searchFull(false)
, _searchFullMigrated(false)
, _searchRequest(0)
, _lastSearchId(0)
, _lastSearchMigratedId(0)
, _searchedCount(0)
, _width(st::wndMinWidth)
, _height(0)
@ -169,7 +171,8 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const
, _cursor(style::cur_default)
, _cursorState(HistoryDefaultCursorState)
, _dragAction(NoDrag)
, _dragItem(0), _selectedMsgId(0)
, _dragItem(0)
, _selectedMsgId(0)
, _dragItemIndex(-1)
, _mousedItem(0)
, _mousedItemIndex(-1)
@ -272,16 +275,35 @@ void OverviewInner::touchUpdateSpeed() {
_touchPrevPos = _touchPos;
}
bool OverviewInner::itemMigrated(MsgId msgId) const {
return _migrated && (msgId < 0) && (-msgId < ServerMaxMsgId);
}
ChannelId OverviewInner::itemChannel(MsgId msgId) const {
return itemMigrated(msgId) ? _migrated->channelId() : _channel;
}
MsgId OverviewInner::itemMsgId(MsgId msgId) const {
return itemMigrated(msgId) ? -msgId : msgId;
}
int32 OverviewInner::migratedIndexSkip() const {
return (_migrated && _history->overviewLoaded(_type)) ? _migrated->overview[_type].size() : 0;
}
void OverviewInner::fixItemIndex(int32 &current, MsgId msgId) const {
if (!msgId) {
current = -1;
} else if (_type == OverviewPhotos || _type == OverviewAudioDocuments) {
int32 l = _history->overview[_type].size();
if (current < 0 || current >= l || _history->overview[_type][current] != msgId) {
History *history = itemMigrated(msgId) ? _migrated : _history;
int32 l = history->overview[_type].size(), indexskip = migratedIndexSkip();
int32 index = (current >= 0 && history == _history) ? (current - indexskip) : current;
MsgId findMsgId = (history == _history ? 1 : -1) * msgId;
if (current < 0 || current >= l || history->overview[_type][current] != findMsgId) {
current = -1;
for (int32 i = 0; i < l; ++i) {
if (_history->overview[_type][i] == msgId) {
current = i;
if (history->overview[_type][i] == findMsgId) {
current = i + (history == _history ? indexskip : 0);
break;
}
}
@ -300,12 +322,14 @@ void OverviewInner::fixItemIndex(int32 &current, MsgId msgId) const {
}
}
void OverviewInner::searchReceived(bool fromStart, const MTPmessages_Messages &result, mtpRequestId req) {
if (fromStart && !_search.text().isEmpty()) {
SearchQueries::iterator i = _searchQueries.find(req);
if (i != _searchQueries.cend()) {
_searchCache[i.value()] = result;
_searchQueries.erase(i);
void OverviewInner::searchReceived(SearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req) {
if (!_search.text().isEmpty()) {
if (_type == SearchFromStart) {
SearchQueries::iterator i = _searchQueries.find(req);
if (i != _searchQueries.cend()) {
_searchCache[i.value()] = result;
_searchQueries.erase(i);
}
}
}
@ -346,20 +370,36 @@ void OverviewInner::searchReceived(bool fromStart, const MTPmessages_Messages &r
} break;
}
if (messages) {
bool migratedSearch = (type == SearchMigratedFromStart || type == SearchMigratedFromOffset);
if (messages->isEmpty()) {
_searchFull = true;
if (migratedSearch) {
_searchFullMigrated = true;
} else {
_searchFull = true;
}
}
if (fromStart) {
if (type == SearchFromStart) {
_searchResults.clear();
_lastSearchId = 0;
_lastSearchId = _lastSearchMigratedId = 0;
_itemsToBeLoaded = LinksOverviewPerPage * 2;
}
if (type == SearchMigratedFromStart) {
_lastSearchMigratedId = 0;
}
for (QVector<MTPMessage>::const_iterator i = messages->cbegin(), e = messages->cend(); i != e; ++i) {
HistoryItem *item = App::histories().addNewMessage(*i, NewMessageExisting);
_searchResults.push_front(item->id);
_lastSearchId = item->id;
if (migratedSearch) {
_searchResults.push_front(-item->id);
_lastSearchMigratedId = item->id;
} else {
_searchResults.push_front(item->id);
_lastSearchId = item->id;
}
}
mediaOverviewUpdated();
if (messages->isEmpty()) {
update();
}
}
_searchRequest = 0;
@ -367,19 +407,24 @@ void OverviewInner::searchReceived(bool fromStart, const MTPmessages_Messages &r
}
}
bool OverviewInner::searchFailed(const RPCError &error, mtpRequestId req) {
bool OverviewInner::searchFailed(SearchRequestType type, const RPCError &error, mtpRequestId req) {
if (mtpIsFlood(error)) return false;
if (_searchRequest == req) {
_searchRequest = 0;
_searchFull = true;
if (type == SearchFromStart || type == SearchFromOffset) {
_searchFull = true;
} else if (type == SearchMigratedFromStart || type == SearchMigratedFromOffset) {
_searchFullMigrated = true;
}
}
return true;
}
OverviewInner::CachedLink *OverviewInner::cachedLink(HistoryItem *item) {
CachedLinks::const_iterator i = _links.constFind(item->id);
if (i == _links.cend()) i = _links.insert(item->id, new CachedLink(item));
MsgId msgId = (item->history() == _migrated) ? -item->id : item->id;
CachedLinks::const_iterator i = _links.constFind(msgId);
if (i == _links.cend()) i = _links.insert(msgId, new CachedLink(item));
return i.value();
}
@ -423,7 +468,7 @@ bool OverviewInner::itemHasPoint(MsgId msgId, int32 index, int32 x, int32 y) con
return true;
}
} else {
HistoryItem *item = App::histItemById(_channel, msgId);
HistoryItem *item = App::histItemById(itemChannel(msgId), itemMsgId(msgId));
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (media) {
int32 w = _width - st::msgMargin.left() - st::msgMargin.right();
@ -462,11 +507,12 @@ void OverviewInner::moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32
index += delta;
if (_type == OverviewPhotos || _type == OverviewAudioDocuments) {
if (index < 0 || index >= _history->overview[_type].size()) {
int32 indexskip = migratedIndexSkip();
if (index < 0 || index >= indexskip + _history->overview[_type].size()) {
msgId = 0;
index = -1;
} else {
msgId = _history->overview[_type][index];
msgId = (index >= indexskip) ? _history->overview[_type][index - indexskip] : (-_migrated->overview[_type][index]);
}
} else {
while (index >= 0 && index < _items.size() && !_items[index].msgid) {
@ -739,7 +785,7 @@ void OverviewInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton bu
}
if (_dragAction == PrepareSelect && !needClick && !_dragWasInactive && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
SelectedItems::iterator i = _selected.find(_dragItem);
if (i == _selected.cend() && _dragItem > 0) {
if (i == _selected.cend() && itemMsgId(_dragItem) > 0) {
if (_selected.size() < MaxSelectedItems) {
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
_selected.clear();
@ -755,7 +801,7 @@ void OverviewInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton bu
if (i != _selected.cend() && i.value() == FullItemSel) {
_selected.erase(i);
updateMsg(_dragItem, _dragItemIndex);
} else if (i == _selected.cend() && _dragItem > 0 && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
} else if (i == _selected.cend() && itemMsgId(_dragItem) > 0 && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
if (_selected.size() < MaxSelectedItems) {
_selected.insert(_dragItem, FullItemSel);
updateMsg(_dragItem, _dragItemIndex);
@ -797,7 +843,7 @@ void OverviewInner::onDragExec() {
QList<QUrl> urls;
bool forwardSelected = false;
if (uponSelected) {
forwardSelected = !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel && cWideMode() && !_history->peer->isChannel();
forwardSelected = !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel && cWideMode();
} else if (textlnkDown()) {
sel = textlnkDown()->encoded();
if (!sel.isEmpty() && sel.at(0) != '/' && sel.at(0) != '@' && sel.at(0) != '#') {
@ -841,9 +887,7 @@ void OverviewInner::onDragExec() {
QDrag *drag = new QDrag(App::wnd());
QMimeData *mimeData = new QMimeData;
if (!_history->peer->isChannel()) {
mimeData->setData(qsl("application/x-td-forward-pressed-link"), "1");
}
mimeData->setData(qsl("application/x-td-forward-pressed-link"), "1");
if (lnkDocument) {
QString already = static_cast<DocumentOpenLink*>(textlnkDown().data())->document()->already(true);
if (!already.isEmpty()) {
@ -867,42 +911,60 @@ void OverviewInner::touchScrollUpdated(const QPoint &screenPos) {
touchUpdateSpeed();
}
void OverviewInner::addSelectionRange(int32 selFrom, int32 selTo, History *history) {
if (selFrom < 0 || selTo < 0) return;
for (int32 i = selFrom; i <= selTo; ++i) {
MsgId msgid = 0;
if (_type == OverviewPhotos || _type == OverviewAudioDocuments) {
msgid = ((history == _history) ? 1 : -1) * history->overview[_type][i];
} else {
msgid = _items[i].msgid;
}
if (!msgid) continue;
SelectedItems::iterator j = _selected.find(msgid);
if (_dragSelecting && itemMsgId(msgid) > 0) {
if (j == _selected.cend()) {
if (_selected.size() >= MaxSelectedItems) break;
_selected.insert(msgid, FullItemSel);
} else if (j.value() != FullItemSel) {
*j = FullItemSel;
}
} else {
if (j != _selected.cend()) {
_selected.erase(j);
}
}
}
}
void OverviewInner::applyDragSelection() {
if (_dragSelFromIndex < 0 || _dragSelToIndex < 0) return;
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
_selected.clear();
}
if (_dragSelecting) {
for (int32 i = _dragSelToIndex; i <= _dragSelFromIndex; ++i) {
MsgId msgid = (_type == OverviewPhotos || _type == OverviewAudioDocuments) ? _history->overview[_type][i] : _items[i].msgid;
if (!msgid) continue;
SelectedItems::iterator j = _selected.find(msgid);
if (msgid > 0) {
if (j == _selected.cend()) {
if (_selected.size() >= MaxSelectedItems) break;
_selected.insert(msgid, FullItemSel);
} else if (j.value() != FullItemSel) {
*j = FullItemSel;
}
int32 selfrom = _dragSelToIndex, selto = _dragSelFromIndex;
if (_migrated && (_type == OverviewPhotos || _type == OverviewAudioDocuments)) {
int32 indexskip = migratedIndexSkip();
if (selfrom < indexskip) {
if (selto < indexskip) {
addSelectionRange(selfrom, selto, _migrated);
selto = -1;
} else {
if (j != _selected.cend()) {
_selected.erase(j);
}
}
}
} else {
for (int32 i = _dragSelToIndex; i <= _dragSelFromIndex; ++i) {
MsgId msgid = (_type == OverviewPhotos || _type == OverviewAudioDocuments) ? _history->overview[_type][i] : _items[i].msgid;
if (!msgid) continue;
SelectedItems::iterator j = _selected.find(msgid);
if (j != _selected.cend()) {
_selected.erase(j);
addSelectionRange(selfrom, _migrated->overview[_type].size() - 1, _migrated);
selto -= indexskip;
}
selfrom = 0;
} else if (selto < indexskip) { // wtf
selfrom = selto = -1;
} else {
selfrom -= indexskip;
selto -= indexskip;
}
}
addSelectionRange(selfrom, selto, _history);
_dragSelFrom = _dragSelTo = 0;
_dragSelFromIndex = _dragSelToIndex = -1;
_overview->updateTopBarSelection();
@ -940,9 +1002,14 @@ void OverviewInner::clear() {
}
int32 OverviewInner::itemTop(const FullMsgId &msgId) const {
if (_type == OverviewAudioDocuments && msgId.channel == _channel) {
int32 index = _history->overview[_type].indexOf(msgId.msg);
if (index >= 0) {
if (_type == OverviewAudioDocuments) {
if (msgId.channel == _channel) {
int32 index = _history->overview[_type].indexOf(msgId.msg);
if (index >= 0) {
return _addToY + int32((index + migratedIndexSkip()) * _audioHeight);
}
} else if (_migrated && msgId.channel == _migrated->channelId()) {
int32 index = _migrated->overview[_type].indexOf(msgId.msg);
return _addToY + int32(index * _audioHeight);
}
}
@ -951,21 +1018,30 @@ int32 OverviewInner::itemTop(const FullMsgId &msgId) const {
void OverviewInner::preloadMore() {
if (_inSearch) {
if (!_searchRequest && !_searchFull) {
int32 flags = (_history->peer->isChannel() && !_history->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterUrl(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, !_lastSearchId), rpcFail(&OverviewInner::searchFailed));
if (!_lastSearchId) {
_searchQueries.insert(_searchRequest, _searchQuery);
if (!_searchRequest) {
if (!_searchFull) {
int32 flags = (_history->peer->isChannel() && !_history->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterUrl(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchId ? SearchFromOffset : SearchFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchId ? SearchFromOffset : SearchFromStart));
if (!_lastSearchId) {
_searchQueries.insert(_searchRequest, _searchQuery);
}
} else if (_migrated && !_searchFullMigrated) {
int32 flags = (_migrated->peer->isChannel() && !_migrated->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _migrated->peer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterUrl(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchMigratedId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart));
}
}
} else if (App::main()) {
App::main()->loadMediaBack(_history->peer, _type, _type != OverviewLinks);
if (_migrated && _history->overviewLoaded(_type)) {
App::main()->loadMediaBack(_migrated->peer, _type, _type != OverviewLinks);
} else {
App::main()->loadMediaBack(_history->peer, _type, _type != OverviewLinks);
}
}
}
bool OverviewInner::preloadLocal() {
if (_type != OverviewLinks) return false;
if (_itemsToBeLoaded >= _history->overview[_type].size()) return false;
if (_itemsToBeLoaded >= migratedIndexSkip() + _history->overview[_type].size()) return false;
_itemsToBeLoaded += LinksOverviewPerPage;
mediaOverviewUpdated();
return true;
@ -1000,11 +1076,11 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
QRect r(e->rect());
p.setClipRect(r);
if (_history->overview[_type].isEmpty()) {
if (_history->overview[_type].isEmpty() && (!_migrated || !_history->overviewLoaded(_type) || _migrated->overview[_type].isEmpty())) {
QPoint dogPos((_width - st::msgDogImg.pxWidth()) / 2, ((height() - st::msgDogImg.pxHeight()) * 4) / 9);
p.drawPixmap(dogPos, *cChatDogImage());
return;
} else if (_inSearch && _searchResults.isEmpty() && _searchFull && !_searchTimer.isActive()) {
} else if (_inSearch && _searchResults.isEmpty() && _searchFull && (!_migrated || _searchFullMigrated) && !_searchTimer.isActive()) {
p.setFont(st::noContactsFont->f);
p.setPen(st::noContactsColor->p);
p.drawText(QRect(_linksLeft, _addToY, _linksWidth, _addToY), lng_search_found_results(lt_count, 0), style::al_center);
@ -1021,8 +1097,9 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
bool hasSel = !_selected.isEmpty();
if (_type == OverviewPhotos) {
History::MediaOverview &overview(_history->overview[_type]);
int32 count = overview.size();
History::MediaOverview &overview(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migratedCount = migratedIndexSkip();
int32 count = migratedCount + overview.size();
int32 rowFrom = floorclamp(r.y() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, count);
int32 rowTo = ceilclamp(r.y() + r.height() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, count);
float64 w = float64(_width - st::overviewPhotoSkip) / _photosInRow;
@ -1033,7 +1110,10 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
if (index < 0) continue;
if (index >= count) break;
HistoryItem *item = App::histItemById(_channel, overview[index]);
bool migratedindex = (index < migratedCount);
int32 bareindex = migratedindex ? index : (index - migratedCount);
HistoryItem *item = App::histItemById(migratedindex ? _migrated->channelId() : _channel, (migratedindex ? *migratedOverview : overview)[bareindex]);
HistoryMedia *m = item ? item->getMedia(true) : 0;
if (!m) continue;
@ -1088,7 +1168,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
if (index >= selfrom && index <= selto) {
sel = (_dragSelecting && item->id > 0) ? FullItemSel : 0;
} else if (hasSel) {
SelectedItems::const_iterator i = _selected.constFind(item->id);
SelectedItems::const_iterator i = _selected.constFind(migratedindex ? -item->id : item->id);
if (i != selEnd) {
sel = i.value();
}
@ -1104,15 +1184,19 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
}
}
} else if (_type == OverviewAudioDocuments) {
History::MediaOverview &overview(_history->overview[_type]);
int32 count = overview.size();
History::MediaOverview &overview(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migratedCount = migratedIndexSkip();
int32 count = migratedCount + overview.size();
int32 from = floorclamp(r.y() - _addToY, _audioHeight, 0, count);
int32 to = ceilclamp(r.y() + r.height() - _addToY, _audioHeight, 0, count);
p.translate(_audioLeft, _addToY + from * _audioHeight);
for (int32 index = from; index < to; ++index) {
if (index >= count) break;
HistoryItem *item = App::histItemById(_channel, overview[index]);
bool migratedindex = (index < migratedCount);
int32 bareindex = migratedindex ? index : (index - migratedCount);
HistoryItem *item = App::histItemById(migratedindex ? _migrated->channelId() : _channel, (migratedindex ? *migratedOverview : overview)[bareindex]);
HistoryMedia *m = item ? item->getMedia(true) : 0;
if (!m || m->type() != MediaTypeDocument) continue;
@ -1120,13 +1204,14 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
if (index >= selfrom && index <= selto) {
sel = (_dragSelecting && item->id > 0) ? FullItemSel : 0;
} else if (hasSel) {
SelectedItems::const_iterator i = _selected.constFind(item->id);
SelectedItems::const_iterator i = _selected.constFind(migratedindex ? -item->id : item->id);
if (i != selEnd) {
sel = i.value();
}
}
static_cast<HistoryDocument*>(m)->drawInPlaylist(p, item, (sel == FullItemSel), ((_menu ? (App::contextItem() ? App::contextItem()->id : 0) : _selectedMsgId) == item->id), _audioWidth);
bool drawOver = _menu ? (App::contextItem() ? (App::contextItem() == item) : false) : (itemMsgId(_selectedMsgId) == item->id && itemChannel(_selectedMsgId) == item->channelId());
static_cast<HistoryDocument*>(m)->drawInPlaylist(p, item, (sel == FullItemSel), drawOver, _audioWidth);
p.translate(0, _audioHeight);
}
} else if (_type == OverviewLinks) {
@ -1171,7 +1256,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
uint32 sel = 0;
if (i >= selfrom && i <= selto) {
sel = (_dragSelecting && _items[i].msgid > 0) ? FullItemSel : 0;
sel = (_dragSelecting && itemMsgId(_items[i].msgid) > 0) ? FullItemSel : 0;
} else if (hasSel) {
SelectedItems::const_iterator j = _selected.constFind(_items[i].msgid);
if (j != selEnd) {
@ -1231,7 +1316,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
p.translate(0, curY - y);
if (_items[i].msgid) { // draw item
HistoryItem *item = App::histItemById(_channel, _items[i].msgid);
HistoryItem *item = App::histItemById(itemChannel(_items[i].msgid), itemMsgId(_items[i].msgid));
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (media) {
bool out = item->out(), fromChannel = item->fromChannel(), outbg = out && !fromChannel;
@ -1245,9 +1330,9 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
if (i >= selfrom && i <= selto) {
sel = (_dragSelecting && item->id > 0) ? FullItemSel : 0;
} else if (hasSel) {
SelectedItems::const_iterator i = _selected.constFind(item->id);
if (i != selEnd) {
sel = i.value();
SelectedItems::const_iterator j = _selected.constFind(_items[i].msgid);
if (j != selEnd) {
sel = j.value();
}
}
@ -1309,7 +1394,9 @@ void OverviewInner::onUpdateSelected() {
if (row < 0) row = 0;
bool upon = true;
int32 i = row * _photosInRow + inRow - _photosToAdd, count = _history->overview[_type].size();
History::MediaOverview &overview(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migratedCount = migratedIndexSkip();
int32 i = row * _photosInRow + inRow - _photosToAdd, count = migratedCount + overview.size();
if (i < 0) {
i = 0;
upon = false;
@ -1319,8 +1406,8 @@ void OverviewInner::onUpdateSelected() {
upon = false;
}
if (i >= 0) {
MsgId msgid = _history->overview[_type][i];
HistoryItem *histItem = App::histItemById(_channel, msgid);
MsgId msgid = (i >= migratedCount) ? overview[i - migratedCount] : (*migratedOverview)[i];
HistoryItem *histItem = App::histItemById((i >= migratedCount) ? _channel : _migrated->channelId(), msgid);
if (histItem) {
item = histItem;
index = i;
@ -1335,7 +1422,9 @@ void OverviewInner::onUpdateSelected() {
}
}
} else if (_type == OverviewAudioDocuments) {
int32 i = int32((m.y() - _addToY) / _audioHeight), count = _history->overview[_type].size();
History::MediaOverview &overview(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migratedCount = migratedIndexSkip();
int32 i = int32((m.y() - _addToY) / _audioHeight), count = migratedCount + overview.size();
bool upon = true;
if (m.y() < _addToY) {
@ -1347,8 +1436,8 @@ void OverviewInner::onUpdateSelected() {
upon = false;
}
if (i >= 0) {
MsgId msgid = _history->overview[_type][i];
HistoryItem *histItem = App::histItemById(_channel, msgid);
MsgId msgid = (i >= migratedCount) ? overview[i - migratedCount] : (*migratedOverview)[i];
HistoryItem *histItem = App::histItemById((i >= migratedCount) ? _channel : _migrated->channelId(), msgid);
if (histItem) {
item = histItem;
index = i;
@ -1356,13 +1445,13 @@ void OverviewInner::onUpdateSelected() {
HistoryMedia *media = item->getMedia(true);
if (media && media->type() == MediaTypeDocument) {
lnk = static_cast<HistoryDocument*>(media)->linkInPlaylist();
newsel = item->id;
newsel = (item->history() == _migrated) ? (-item->id) : item->id;
}
}
}
}
if (newsel != _selectedMsgId) {
if (_selectedMsgId) updateMsg(App::histItemById(_channel, _selectedMsgId));
if (_selectedMsgId) updateMsg(_selectedMsgId, -1);
_selectedMsgId = newsel;
updateMsg(item);
}
@ -1386,7 +1475,7 @@ void OverviewInner::onUpdateSelected() {
}
}
HistoryItem *histItem = App::histItemById(_channel, _items[i].msgid);
HistoryItem *histItem = App::histItemById(itemChannel(_items[i].msgid), itemMsgId(_items[i].msgid));
if (histItem) {
item = histItem;
index = i;
@ -1435,7 +1524,7 @@ void OverviewInner::onUpdateSelected() {
}
}
HistoryItem *histItem = App::histItemById(_channel, _items[i].msgid);
HistoryItem *histItem = App::histItemById(itemChannel(_items[i].msgid), itemMsgId(_items[i].msgid));
if (histItem) {
item = histItem;
index = i;
@ -1461,7 +1550,7 @@ void OverviewInner::onUpdateSelected() {
MsgId oldMousedItem = _mousedItem;
int32 oldMousedItemIndex = _mousedItemIndex;
_mousedItem = item ? item->id : 0;
_mousedItem = item ? ((item->history() == _migrated) ? -item->id : item->id) : 0;
_mousedItemIndex = index;
m = mapMouseToItem(m, _mousedItem, _mousedItemIndex);
@ -1479,7 +1568,7 @@ void OverviewInner::onUpdateSelected() {
}
if (lnkIndex != _lnkOverIndex || _mousedItem != oldMousedItem) {
lnkChanged = true;
if (oldMousedItem) updateMsg(App::histItemById(_channel, oldMousedItem));
if (oldMousedItem) updateMsg(oldMousedItem, oldMousedItemIndex);
_lnkOverIndex = lnkIndex;
if (item) updateMsg(item);
QToolTip::hideText();
@ -1606,7 +1695,7 @@ void OverviewInner::onUpdateSelected() {
bool dragSelecting = false;
MsgId dragFirstAffected = dragSelFrom;
int32 dragFirstAffectedIndex = dragSelFromIndex;
while (dragFirstAffectedIndex >= 0 && dragFirstAffected <= 0) {
while (dragFirstAffectedIndex >= 0 && itemMsgId(dragFirstAffected) <= 0) {
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, ((selectingDown && (_type == OverviewPhotos || _type == OverviewAudioDocuments)) || (!selectingDown && (_type != OverviewPhotos && _type != OverviewAudioDocuments))) ? -1 : 1);
}
if (dragFirstAffectedIndex >= 0) {
@ -1653,7 +1742,7 @@ void OverviewInner::showLinkTip() {
QToolTip::showText(_dragPos, url, this, r);
}
} else if (_cursorState == HistoryInDateCursorState && _dragAction == NoDrag && _mousedItem) {
if (HistoryItem *item = App::histItemById(_channel, _mousedItem)) {
if (HistoryItem *item = App::histItemById(itemChannel(_mousedItem), itemMsgId(_mousedItem))) {
QToolTip::showText(_dragPos, item->date.toString(QLocale::system().dateTimeFormat(QLocale::LongFormat)), this, r);
}
}
@ -1704,8 +1793,8 @@ void OverviewInner::enterEvent(QEvent *e) {
}
void OverviewInner::leaveEvent(QEvent *e) {
if (_selectedMsgId > 0) {
updateMsg(App::histItemById(_channel, _selectedMsgId));
if (_selectedMsgId) {
updateMsg(_selectedMsgId, -1);
_selectedMsgId = 0;
}
if (textlnkOver()) {
@ -1738,14 +1827,14 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->deleteLater();
_menu = 0;
updateMsg(App::contextItem());
if (_selectedMsgId > 0) updateMsg(App::histItemById(_channel, _selectedMsgId));
if (_selectedMsgId) updateMsg(_selectedMsgId, -1);
}
if (e->reason() == QContextMenuEvent::Mouse) {
dragActionUpdate(e->globalPos());
}
bool ignoreMousedItem = false;
if (_mousedItem > 0) {
if (itemMsgId(_mousedItem) > 0) {
QPoint m = mapMouseToItem(mapFromGlobal(e->globalPos()), _mousedItem, _mousedItemIndex);
if (m.y() < 0 || m.y() >= itemHeight(_mousedItem, _mousedItemIndex)) {
ignoreMousedItem = true;
@ -1761,7 +1850,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
isUponSelected = -1;
if (_selected.cbegin().value() == FullItemSel) {
hasSelected = 2;
if (!ignoreMousedItem && App::mousedItem() && _selected.constFind(App::mousedItem()->id) != _selected.cend()) {
if (!ignoreMousedItem && App::mousedItem() && _selected.constFind(App::mousedItem()->history() == _migrated ? -App::mousedItem()->id : App::mousedItem()->id) != _selected.cend()) {
isUponSelected = 2;
} else {
isUponSelected = -2;
@ -1816,8 +1905,8 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}
App::contextItem(App::hoveredLinkItem());
updateMsg(App::contextItem());
if (_selectedMsgId > 0) updateMsg(App::histItemById(_channel, _selectedMsgId));
} else if (!ignoreMousedItem && App::mousedItem() && App::mousedItem()->id == _mousedItem) {
if (_selectedMsgId) updateMsg(_selectedMsgId, -1);
} else if (!ignoreMousedItem && App::mousedItem() && App::mousedItem()->channelId() == itemChannel(_mousedItem) && App::mousedItem()->id == itemMsgId(_mousedItem)) {
_contextMenuUrl = _lnkOverIndex ? urlByIndex(_mousedItem, _mousedItemIndex, _lnkOverIndex) : QString();
_menu = new PopupMenu();
if ((_contextMenuLnk && dynamic_cast<TextLink*>(_contextMenuLnk.data())) || (!_contextMenuUrl.isEmpty() && !urlIsEmail(_contextMenuUrl))) {
@ -1856,7 +1945,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}
App::contextItem(App::mousedItem());
updateMsg(App::contextItem());
if (_selectedMsgId > 0) updateMsg(App::histItemById(_channel, _selectedMsgId));
if (_selectedMsgId) updateMsg(_selectedMsgId, -1);
}
if (_menu) {
connect(_menu, SIGNAL(destroyed(QObject*)), this, SLOT(onMenuDestroy(QObject*)));
@ -1896,6 +1985,10 @@ PeerData *OverviewInner::peer() const {
return _peer;
}
PeerData *OverviewInner::migratePeer() const {
return _migrated ? _migrated->peer : 0;
}
MediaOverviewType OverviewInner::type() const {
return _type;
}
@ -1970,12 +2063,13 @@ void OverviewInner::selectMessage() {
HistoryItem *item = App::contextItem();
if (!item || item->type() != HistoryItemMsg || item->serviceMsg()) return;
MsgId msgid = item->history() == _migrated ? -item->id : item->id;
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
_selected.clear();
} else if (_selected.size() == MaxSelectedItems && _selected.constFind(item->id) == _selected.cend()) {
} else if (_selected.size() == MaxSelectedItems && _selected.constFind(msgid) == _selected.cend()) {
return;
}
_selected.insert(item->id, FullItemSel);
_selected.insert(msgid, FullItemSel);
_overview->updateTopBarSelection();
_overview->update();
}
@ -2015,6 +2109,7 @@ void OverviewInner::openContextFile() {
}
bool OverviewInner::onSearchMessages(bool searchCache) {
_searchTimer.stop();
QString q = _search.text().trimmed();
if (q.isEmpty()) {
if (_searchRequest) {
@ -2026,16 +2121,16 @@ bool OverviewInner::onSearchMessages(bool searchCache) {
SearchCache::const_iterator i = _searchCache.constFind(q);
if (i != _searchCache.cend()) {
_searchQuery = q;
_searchFull = false;
_searchFull = _searchFullMigrated = false;
_searchRequest = 0;
searchReceived(true, i.value(), 0);
searchReceived(SearchFromStart, i.value(), 0);
return true;
}
} else if (_searchQuery != q) {
_searchQuery = q;
_searchFull = false;
_searchFull = _searchFullMigrated = false;
int32 flags = (_history->peer->isChannel() && !_history->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterUrl(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, true), rpcFail(&OverviewInner::searchFailed));
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterUrl(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, SearchFromStart), rpcFail(&OverviewInner::searchFailed, SearchFromStart));
_searchQueries.insert(_searchRequest, _searchQuery);
}
return false;
@ -2044,7 +2139,7 @@ bool OverviewInner::onSearchMessages(bool searchCache) {
void OverviewInner::onNeedSearchMessages() {
if (!onSearchMessages(true)) {
_searchTimer.start(AutoSearchTimeout);
if (_inSearch && _searchFull && _searchResults.isEmpty()) {
if (_inSearch && _searchFull && (!_migrated || _searchFullMigrated) && _searchResults.isEmpty()) {
update();
}
}
@ -2098,7 +2193,7 @@ void OverviewInner::onMenuDestroy(QObject *obj) {
_menu = 0;
dragActionUpdate(QCursor::pos());
updateMsg(App::contextItem());
if (_selectedMsgId > 0) updateMsg(App::histItemById(_channel, _selectedMsgId));
if (_selectedMsgId) updateMsg(_selectedMsgId, -1);
}
}
@ -2106,7 +2201,7 @@ void OverviewInner::getSelectionState(int32 &selectedForForward, int32 &selected
selectedForForward = selectedForDelete = 0;
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) {
if (i.value() == FullItemSel) {
if (HistoryItem *item = App::histItemById(_channel, i.key())) {
if (HistoryItem *item = App::histItemById(itemChannel(i.key()), itemMsgId(i.key()))) {
if (item->canDelete()) {
++selectedForDelete;
}
@ -2131,7 +2226,7 @@ void OverviewInner::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
if (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel) return;
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) {
HistoryItem *item = App::histItemById(_channel, i.key());
HistoryItem *item = App::histItemById(itemChannel(i.key()), itemMsgId(i.key()));
if (item && item->toHistoryMessage() && item->id > 0) {
if (item->history() == _migrated) {
sel.insert(item->id - ServerMaxMsgId, item);
@ -2171,15 +2266,16 @@ void OverviewInner::onTouchScrollTimer() {
void OverviewInner::mediaOverviewUpdated(bool fromResize) {
int32 oldHeight = _height;
if (_type == OverviewLinks) {
History::MediaOverview &o(_inSearch ? _searchResults : _history->overview[_type]);
int32 l = o.size(), tocheck = qMin(l, _itemsToBeLoaded);
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migrateCount = migratedIndexSkip();
int32 l = _inSearch ? _searchResults.size() : (migrateCount + o.size()), tocheck = qMin(l, _itemsToBeLoaded);
_items.reserve(2 * l); // day items
int32 y = 0, in = 0;
bool allGood = true;
QDate prevDate;
for (int32 i = 0; i < tocheck; ++i) {
MsgId msgid = o.at(l - i - 1);
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -(*migratedOverview)[l - i - 1] : o.at(l - i - 1 - migrateCount));
if (allGood) {
if (_items.size() > in && _items.at(in).msgid == msgid) {
prevDate = _items.at(in).date;
@ -2210,7 +2306,8 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
}
allGood = false;
}
HistoryItem *item = App::histItemById(_channel, msgid);
HistoryItem *item = App::histItemById(itemChannel(msgid), itemMsgId(msgid));
if (!item) continue;
QDate date = item->date.date();
if (!in || (in > 0 && date != prevDate)) {
@ -2227,11 +2324,11 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
}
if (_items.size() > in) {
_items[in] = CachedItem(item->id, item->date.date(), y);
_items[in] = CachedItem(msgid, item->date.date(), y);
_items[in].link = cachedLink(item);
y += _items[in].link->countHeight(_linksWidth);
} else {
_items.push_back(CachedItem(item->id, item->date.date(), y));
_items.push_back(CachedItem(msgid, item->date.date(), y));
_items.back().link = cachedLink(item);
y += _items.back().link->countHeight(_linksWidth);
}
@ -2249,8 +2346,9 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
dragActionUpdate(QCursor::pos());
update();
} else if (_type != OverviewPhotos && _type != OverviewAudioDocuments) {
History::MediaOverview &o(_history->overview[_type]);
int32 l = o.size();
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migrateCount = migratedIndexSkip();
int32 l = migrateCount + o.size();
_items.reserve(2 * l); // day items
int32 y = 0, in = 0;
@ -2258,7 +2356,7 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
bool allGood = true;
QDate prevDate;
for (int32 i = 0; i < l; ++i) {
MsgId msgid = o.at(l - i - 1);
MsgId msgid = (l - i - 1 < migrateCount) ? -(*migratedOverview)[l - i - 1] : o.at(l - i - 1 - migrateCount);
if (allGood) {
if (_items.size() > in && _items.at(in).msgid == msgid) {
prevDate = _items.at(in).date;
@ -2297,7 +2395,7 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
}
allGood = false;
}
HistoryItem *item = App::histItemById(_channel, msgid);
HistoryItem *item = App::histItemById(itemChannel(msgid), itemMsgId(msgid));
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (!media) continue;
@ -2363,33 +2461,36 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
}
void OverviewInner::changingMsgId(HistoryItem *row, MsgId newId) {
if (_dragSelFrom == row->id) _dragSelFrom = newId;
if (_dragSelTo == row->id) _dragSelTo = newId;
if (_mousedItem == row->id) _mousedItem = newId;
if (_dragItem == row->id) _dragItem = newId;
MsgId oldId = (row->history() == _migrated) ? -row->id : row->id;
if (row->history() == _migrated) newId = -newId;
if (_dragSelFrom == oldId) _dragSelFrom = newId;
if (_dragSelTo == oldId) _dragSelTo = newId;
if (_mousedItem == oldId) _mousedItem = newId;
if (_dragItem == oldId) _dragItem = newId;
if (_selectedMsgId == oldId) _selectedMsgId = newId;
for (SelectedItems::iterator i = _selected.begin(), e = _selected.end(); i != e; ++i) {
if (i.key() == row->id) {
if (i.key() == oldId) {
uint32 sel = i.value();
_selected.erase(i);
_selected.insert(newId, sel);
break;
}
}
if (_links.contains(row->id) && row->id != newId) {
if (_links.contains(oldId) && oldId != newId) {
if (_links.contains(newId)) {
for (CachedItems::iterator i = _items.begin(), e = _items.end(); i != e; ++i) {
if (i->msgid == newId && i->link) {
i->link = _links[row->id];
i->link = _links[oldId];
break;
}
}
}
_links[newId] = _links[row->id];
delete _links[row->id];
_links.remove(row->id);
delete _links[newId];
_links[newId] = _links[oldId];
_links.remove(oldId);
}
for (CachedItems::iterator i = _items.begin(), e = _items.end(); i != e; ++i) {
if (i->msgid == row->id) {
if (i->msgid == oldId) {
i->msgid = newId;
break;
}
@ -2397,11 +2498,15 @@ void OverviewInner::changingMsgId(HistoryItem *row, MsgId newId) {
}
void OverviewInner::itemRemoved(HistoryItem *item) {
if (_dragItem == item->id) {
MsgId msgId = (item->history() == _migrated) ? -item->id : item->id;
if (_dragItem == msgId) {
dragActionCancel();
}
if (_selectedMsgId == msgId) {
_selectedMsgId = 0;
}
SelectedItems::iterator i = _selected.find(item->id);
SelectedItems::iterator i = _selected.find(msgId);
if (i != _selected.cend()) {
_selected.erase(i);
_overview->updateTopBarSelection();
@ -2409,11 +2514,11 @@ void OverviewInner::itemRemoved(HistoryItem *item) {
onUpdateSelected();
if (_dragSelFrom == item->id) {
if (_dragSelFrom == msgId) {
_dragSelFrom = 0;
_dragSelFromIndex = -1;
}
if (_dragSelTo == item->id) {
if (_dragSelTo == msgId) {
_dragSelTo = 0;
_dragSelToIndex = -1;
}
@ -2427,8 +2532,9 @@ void OverviewInner::itemResized(HistoryItem *item, bool scrollToIt) {
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (!media) return;
MsgId msgId = (item->history() == _migrated) ? -item->id : item->id;
for (int32 i = 0, l = _items.size(); i < l; ++i) {
if (_items[i].msgid == item->id) {
if (_items[i].msgid == msgId) {
int32 from = 0;
if (i > 0) from = _items[i - 1].y;
@ -2460,23 +2566,30 @@ void OverviewInner::itemResized(HistoryItem *item, bool scrollToIt) {
}
void OverviewInner::msgUpdated(const HistoryItem *msg) {
if (!msg || _history != msg->history()) return;
if (!msg) return;
History *history = (msg->history() == _history) ? _history : (msg->history() == _migrated ? _migrated : 0);
if (!history) return;
int32 migrateindex = migratedIndexSkip();
MsgId msgid = msg->id;
if (_history->overviewIds[_type].constFind(msgid) != _history->overviewIds[_type].cend()) {
if (history->overviewHasMsgId(_type, msgid) && (history == _history || migrateindex > 0)) {
if (_type == OverviewPhotos) {
int32 index = _history->overview[_type].indexOf(msgid);
int32 index = history->overview[_type].indexOf(msgid);
if (index >= 0) {
if (history == _history) index += migrateindex;
float64 w = (float64(width() - st::overviewPhotoSkip) / _photosInRow);
int32 vsize = (_vsize + st::overviewPhotoSkip);
int32 row = (_photosToAdd + index) / _photosInRow, col = (_photosToAdd + index) % _photosInRow;
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
}
} else if (_type == OverviewAudioDocuments) {
int32 index = _history->overview[_type].indexOf(msgid);
int32 index = history->overview[_type].indexOf(msgid);
if (index >= 0) {
if (history == _history) index += migrateindex;
update(_audioLeft, _addToY + int32(index * _audioHeight), _audioWidth, _audioHeight);
}
} else if (_type == OverviewLinks) {
if (history == _migrated) msgid = -msgid;
for (int32 i = 0, l = _items.size(); i != l; ++i) {
if (_items[i].msgid == msgid) {
update(_linksLeft, _addToY + _items[i].y, _linksWidth, itemHeight(msgid, i));
@ -2484,6 +2597,7 @@ void OverviewInner::msgUpdated(const HistoryItem *msg) {
}
}
} else {
if (history == _migrated) msgid = -msgid;
for (int32 i = 0, l = _items.size(); i != l; ++i) {
if (_items[i].msgid == msgid) {
update(0, _addToY + _height - _items[i].y, _width, itemHeight(msgid, i));
@ -2499,8 +2613,10 @@ void OverviewInner::showAll(bool recountHeights) {
if (_type == OverviewPhotos) {
_photosInRow = int32(width() - st::overviewPhotoSkip) / int32(st::overviewPhotoMinSize + st::overviewPhotoSkip);
_vsize = (int32(width() - st::overviewPhotoSkip) / _photosInRow) - st::overviewPhotoSkip;
int32 count = _history->overview[_type].size(), fullCount = _history->overviewCount[_type];
if (fullCount > 0) {
int32 migratedCount = migratedIndexSkip(), count = migratedCount + _history->overview[_type].size();
int32 migratedFullCount = _migrated ? _migrated->overviewCount(_type) : 0;
int32 fullCount = migratedFullCount + _history->overviewCount(_type);
if (fullCount > 0 && migratedFullCount >= 0) {
int32 cnt = count - (fullCount % _photosInRow);
if (cnt < 0) cnt += _photosInRow;
_photosToAdd = (_photosInRow - (cnt % _photosInRow)) % _photosInRow;
@ -2511,7 +2627,7 @@ void OverviewInner::showAll(bool recountHeights) {
newHeight = _height = (_vsize + st::overviewPhotoSkip) * rows + st::overviewPhotoSkip;
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
} else if (_type == OverviewAudioDocuments) {
int32 count = _history->overview[_type].size(), fullCount = _history->overviewCount[_type];
int32 migratedCount = migratedIndexSkip(), count = migratedCount + _history->overview[_type].size();
newHeight = _height = count * _audioHeight + 2 * st::playlistPadding;
_addToY = st::playlistPadding;
} else if (_type == OverviewLinks) {
@ -2544,7 +2660,7 @@ OverviewInner::~OverviewInner() {
_links.clear();
}
OverviewWidget::OverviewWidget(QWidget *parent, const PeerData *peer, MediaOverviewType type) : TWidget(parent)
OverviewWidget::OverviewWidget(QWidget *parent, PeerData *peer, MediaOverviewType type) : TWidget(parent)
, _scroll(this, st::historyScroll, false)
, _inner(this, &_scroll, peer, type)
, _noDropResizeIndex(false)
@ -2709,6 +2825,10 @@ PeerData *OverviewWidget::peer() const {
return _inner.peer();
}
PeerData *OverviewWidget::migratePeer() const {
return _inner.migratePeer();
}
MediaOverviewType OverviewWidget::type() const {
return _inner.type();
}
@ -2861,7 +2981,7 @@ void OverviewWidget::doneShow() {
}
void OverviewWidget::mediaOverviewUpdated(PeerData *p, MediaOverviewType t) {
if (peer() == p && t == type()) {
if ((peer() == p || migratePeer() == p) && t == type()) {
_inner.mediaOverviewUpdated();
onScroll();
updateTopBarSelection();
@ -2869,13 +2989,13 @@ void OverviewWidget::mediaOverviewUpdated(PeerData *p, MediaOverviewType t) {
}
void OverviewWidget::changingMsgId(HistoryItem *row, MsgId newId) {
if (peer() == row->history()->peer) {
if (peer() == row->history()->peer || migratePeer() == row->history()->peer) {
_inner.changingMsgId(row, newId);
}
}
void OverviewWidget::msgUpdated(const HistoryItem *msg) {
if (peer() == msg->history()->peer) {
if (peer() == msg->history()->peer || migratePeer() == msg->history()->peer) {
_inner.msgUpdated(msg);
}
}
@ -2885,7 +3005,7 @@ void OverviewWidget::itemRemoved(HistoryItem *row) {
}
void OverviewWidget::itemResized(HistoryItem *row, bool scrollToIt) {
if (!row || row->history()->peer == peer()) {
if (!row || row->history()->peer == peer() || row->history()->peer == migratePeer()) {
_inner.itemResized(row, scrollToIt);
}
}

View File

@ -26,7 +26,7 @@ class OverviewInner : public QWidget, public RPCSender {
public:
OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const PeerData *peer, MediaOverviewType type);
OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerData *peer, MediaOverviewType type);
void activate();
@ -61,6 +61,7 @@ public:
void dropResizeIndex();
PeerData *peer() const;
PeerData *migratePeer() const;
MediaOverviewType type() const;
void switchType(MediaOverviewType type);
@ -110,6 +111,11 @@ public slots:
private:
bool itemMigrated(MsgId msgId) const;
ChannelId itemChannel(MsgId msgId) const;
MsgId itemMsgId(MsgId msgId) const;
int32 migratedIndexSkip() const;
void fixItemIndex(int32 &current, MsgId msgId) const;
bool itemHasPoint(MsgId msgId, int32 index, int32 x, int32 y) const;
int32 itemHeight(MsgId msgId, int32 index) const;
@ -125,6 +131,7 @@ private:
void touchDeaccelerate(int32 elapsed);
void applyDragSelection();
void addSelectionRange(int32 selFrom, int32 selTo, History *history);
QPixmap genPix(PhotoData *photo, int32 size);
void showAll(bool recountHeights = false);
@ -184,13 +191,19 @@ private:
QTimer _searchTimer;
QString _searchQuery;
bool _inSearch, _searchFull;
bool _inSearch, _searchFull, _searchFullMigrated;
mtpRequestId _searchRequest;
History::MediaOverview _searchResults;
MsgId _lastSearchId;
MsgId _lastSearchId, _lastSearchMigratedId;
int32 _searchedCount;
void searchReceived(bool fromStart, const MTPmessages_Messages &result, mtpRequestId req);
bool searchFailed(const RPCError &error, mtpRequestId req);
enum SearchRequestType {
SearchFromStart,
SearchFromOffset,
SearchMigratedFromStart,
SearchMigratedFromOffset
};
void searchReceived(SearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
bool searchFailed(SearchRequestType type, const RPCError &error, mtpRequestId req);
typedef QMap<QString, MTPmessages_Messages> SearchCache;
SearchCache _searchCache;
@ -268,7 +281,7 @@ class OverviewWidget : public TWidget, public RPCSender {
public:
OverviewWidget(QWidget *parent, const PeerData *peer, MediaOverviewType type);
OverviewWidget(QWidget *parent, PeerData *peer, MediaOverviewType type);
void clear();
@ -283,6 +296,7 @@ public:
void topBarClick();
PeerData *peer() const;
PeerData *migratePeer() const;
MediaOverviewType type() const;
void switchType(MediaOverviewType type);
void updateTopBarSelection();

View File

@ -267,22 +267,24 @@ void PlayerWidget::updateOverRect(OverState state) {
void PlayerWidget::updateControls() {
_fullAvailable = (_index >= 0);
History *history = _msgmigrated ? _migrated : _history;
_prevAvailable = _fullAvailable && ((_index > 0) || (_index == 0 && _migrated && !_msgmigrated && !_migrated->overview[OverviewAudioDocuments].isEmpty()));
_nextAvailable = _fullAvailable && ((_index < (_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments].size() - 1) || (_msgmigrated && _index == _migrated->overview[OverviewAudioDocuments].size() - 1 && _history->overviewCount[OverviewAudioDocuments] >= 0 && _history->overviewCountValue(OverviewAudioDocuments) <= _history->overview[OverviewAudioDocuments].size()));
_nextAvailable = _fullAvailable && ((_index < history->overview[OverviewAudioDocuments].size() - 1) || (_msgmigrated && _index == _migrated->overview[OverviewAudioDocuments].size() - 1 && _history->overviewLoaded(OverviewAudioDocuments) && _history->overviewCount(OverviewAudioDocuments) > 0));
resizeEvent(0);
update();
if (_index >= 0 && _index < MediaOverviewStartPerPage) {
if (_history->overviewCount[OverviewAudioDocuments] != 0 || (_migrated && _migrated->overviewCount[OverviewAudioDocuments] != 0)) {
if (!_history->overviewLoaded(OverviewAudioDocuments) || (_migrated && !_migrated->overviewLoaded(OverviewAudioDocuments))) {
if (App::main()) {
if (_msgmigrated || (_migrated && _index == 0 && _history->overviewCount[OverviewAudioDocuments] >= 0 && _history->overviewCountValue(OverviewAudioDocuments) <= _history->overview[OverviewAudioDocuments].size())) {
if (_msgmigrated || (_migrated && _index == 0 && _history->overviewLoaded(OverviewAudioDocuments))) {
App::main()->loadMediaBack(_migrated->peer, OverviewAudioDocuments);
} else {
App::main()->loadMediaBack(_history->peer, OverviewAudioDocuments);
if (_migrated && _index == 0 && _migrated->overviewCount[OverviewAudioDocuments] != 0 && _migrated->overview[OverviewAudioDocuments].isEmpty()) {
if (_migrated && _index == 0 && _migrated->overview[OverviewAudioDocuments].isEmpty() && !_migrated->overviewLoaded(OverviewAudioDocuments)) {
App::main()->loadMediaBack(_migrated->peer, OverviewAudioDocuments);
}
}
if (_msgmigrated && _history->overviewCount[OverviewAudioDocuments] < 0) {
if (_msgmigrated && !_history->overviewCountLoaded(OverviewAudioDocuments)) {
App::main()->preloadOverview(_history->peer, OverviewAudioDocuments);
}
}
@ -305,10 +307,11 @@ void PlayerWidget::findCurrent() {
}
if (_index < 0) return;
History *history = _msgmigrated ? _migrated : _history;
HistoryItem *next = 0;
if (_index < o->size() - 1) {
next = App::histItemById((_msgmigrated ? _migrated : _history)->channelId(), o->at(_index + 1));
} else if (_msgmigrated && _index == o->size() - 1 && _history->overviewCount[OverviewAudioDocuments] >= 0 && _history->overviewCountValue(OverviewAudioDocuments) <= _history->overview[OverviewAudioDocuments].size()) {
next = App::histItemById(history->channelId(), o->at(_index + 1));
} else if (_msgmigrated && _index == o->size() - 1 && _history->overviewLoaded(OverviewAudioDocuments) && _history->overviewCount(OverviewAudioDocuments) > 0) {
next = App::histItemById(_history->channelId(), _history->overview[OverviewAudioDocuments].at(0));
}
if (next) {
@ -343,9 +346,10 @@ void PlayerWidget::clearSelection() {
void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
if (_history && (_history->peer == peer || (_migrated && _migrated->peer == peer)) && type == OverviewAudioDocuments) {
_index = -1;
if ((_msgmigrated ? _migrated : _history)->channelId() == _song.msgId.channel) {
for (int i = 0, l = (_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments].size(); i < l; ++i) {
if ((_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments].at(i) == _song.msgId.msg) {
History *history = _msgmigrated ? _migrated : _history;
if (history->channelId() == _song.msgId.channel) {
for (int i = 0, l = history->overview[OverviewAudioDocuments].size(); i < l; ++i) {
if (history->overview[OverviewAudioDocuments].at(i) == _song.msgId.msg) {
_index = i;
break;
}
@ -505,9 +509,10 @@ void PlayerWidget::playPausePressed() {
void PlayerWidget::prevPressed() {
if (isHidden()) return;
const History::MediaOverview *o = _history ? &(_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments] : 0;
History *history = _msgmigrated ? _migrated : _history;
const History::MediaOverview *o = history ? &history->overview[OverviewAudioDocuments] : 0;
if (audioPlayer() && o && _index > 0 && _index <= o->size() && !o->isEmpty()) {
startPlay(FullMsgId((_msgmigrated ? _migrated : _history)->channelId(), o->at(_index - 1)));
startPlay(FullMsgId(history->channelId(), o->at(_index - 1)));
} else if (!_index && _history && _migrated && !_msgmigrated) {
o = &_migrated->overview[OverviewAudioDocuments];
if (!o->isEmpty()) {
@ -519,12 +524,15 @@ void PlayerWidget::prevPressed() {
void PlayerWidget::nextPressed() {
if (isHidden()) return;
const History::MediaOverview *o = _history ? &(_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments] : 0;
History *history = _msgmigrated ? _migrated : _history;
const History::MediaOverview *o = history ? &history->overview[OverviewAudioDocuments] : 0;
if (audioPlayer() && o && _index >= 0 && _index < o->size() - 1) {
startPlay(FullMsgId((_msgmigrated ? _migrated : _history)->channelId(), o->at(_index + 1)));
} else if (o && (_index == o->size() - 1) && _msgmigrated && _history->overviewCount[OverviewAudioDocuments] >= 0 && _history->overviewCountValue(OverviewAudioDocuments) <= _history->overview[OverviewAudioDocuments].size()) {
startPlay(FullMsgId(history->channelId(), o->at(_index + 1)));
} else if (o && (_index == o->size() - 1) && _msgmigrated && _history->overviewLoaded(OverviewAudioDocuments)) {
o = &_history->overview[OverviewAudioDocuments];
if (!o->isEmpty()) startPlay(FullMsgId(_history->channelId(), o->at(0)));
if (!o->isEmpty()) {
startPlay(FullMsgId(_history->channelId(), o->at(0)));
}
}
}

View File

@ -1142,7 +1142,7 @@ bool ProfileInner::updateMediaLinks(int32 *addToScroll) {
for (int i = 0; i < OverviewCount; ++i) {
int32 addToY = _mediaButtons[i]->height() + st::setLittleSkip;
int32 count = _history->overviewCountValue(i), additional = _migrated ? _migrated->overviewCountValue(i) : 0;
int32 count = _history->overviewCount(i), additional = _migrated ? _migrated->overviewCount(i) : 0;
int32 sum = (count > 0 ? count : 0) + (additional > 0 ? additional : 0);
if (sum > 0) {
_mediaButtons[i]->setText(overviewLinkText(i, sum));

View File

@ -118,6 +118,13 @@ inline int32 idFromMessage(const MTPmessage &msg) {
}
return 0;
}
inline int32 dateFromMessage(const MTPmessage &msg) {
switch (msg.type()) {
case mtpc_message: return msg.c_message().vdate.v;
case mtpc_messageService: return msg.c_messageService().vdate.v;
}
return 0;
}
typedef uint64 PhotoId;
typedef uint64 VideoId;
@ -670,7 +677,7 @@ inline ChannelData *PeerData::migrateTo() const {
return (isChat() && asChat()->migrateToPtr && asChat()->migrateToPtr->amIn()) ? asChat()->migrateToPtr : 0;
}
inline const Text &PeerData::dialogName() const {
return (isUser() && !asUser()->phoneText.isEmpty()) ? asUser()->phoneText : nameText;
return migrateTo() ? migrateTo()->dialogName() : ((isUser() && !asUser()->phoneText.isEmpty()) ? asUser()->phoneText : nameText);
}
inline const QString &PeerData::shortName() const {
return isUser() ? asUser()->firstName : name;