History::dialogs and Histories::unread are private now, counting only chats from dialogs list to the badge

This commit is contained in:
John Preston 2016-02-28 14:58:30 +03:00
parent 7338c3e21e
commit 798f800913
12 changed files with 213 additions and 97 deletions

View File

@ -273,7 +273,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
if (!h->isEmpty()) { if (!h->isEmpty()) {
h->clear(true); h->clear(true);
} }
if (!hto->dialogs.isEmpty() && !h->dialogs.isEmpty()) { if (hto->inChatList() && h->inChatList()) {
App::removeDialog(h); App::removeDialog(h);
} }
} }

View File

@ -522,7 +522,7 @@ namespace App {
if (!h->isEmpty()) { if (!h->isEmpty()) {
h->clear(true); h->clear(true);
} }
if (!hto->dialogs.isEmpty() && !h->dialogs.isEmpty()) { if (hto->inChatList() && h->inChatList()) {
App::removeDialog(h); App::removeDialog(h);
} }
} }

View File

@ -443,16 +443,12 @@ void DialogsInner::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow) {
} }
void DialogsInner::createDialog(History *history) { void DialogsInner::createDialog(History *history) {
bool creating = history->dialogs.isEmpty(); bool creating = !history->inChatList();
if (creating) { if (creating) {
history->dialogs = dialogs.addToEnd(history); DialogRow *mainRow = history->addToChatList(dialogs);
contactsNoDialogs.del(history->peer, history->dialogs[0]); contactsNoDialogs.del(history->peer, mainRow);
} }
RefPair(int32, movedFrom, int32, movedTo) = history->adjustByPosInChatsList(dialogs);
History::DialogLinks links = history->dialogs;
int32 movedFrom = links[0]->pos * st::dlgHeight;
dialogs.adjustByPos(links);
int32 movedTo = links[0]->pos * st::dlgHeight;
emit dialogMoved(movedFrom, movedTo); emit dialogMoved(movedFrom, movedTo);
@ -471,8 +467,7 @@ void DialogsInner::removeDialog(History *history) {
if (sel && sel->history == history) { if (sel && sel->history == history) {
sel = 0; sel = 0;
} }
dialogs.del(history->peer); history->removeFromChatList(dialogs);
history->dialogs = History::DialogLinks();
history->clearNotifications(); history->clearNotifications();
if (App::wnd()) App::wnd()->notifyClear(history); if (App::wnd()) App::wnd()->notifyClear(history);
if (contacts.list.rowByPeer.constFind(history->peer->id) != contacts.list.rowByPeer.cend()) { if (contacts.list.rowByPeer.constFind(history->peer->id) != contacts.list.rowByPeer.cend()) {
@ -550,8 +545,8 @@ void DialogsInner::updateSelectedRow(PeerData *peer) {
if (_state == DefaultState) { if (_state == DefaultState) {
if (peer) { if (peer) {
if (History *h = App::historyLoaded(peer->id)) { if (History *h = App::historyLoaded(peer->id)) {
if (h->dialogs.contains(0)) { if (h->inChatList()) {
update(0, h->dialogs.value(0)->pos * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, h->posInChatList() * st::dlgHeight, fullWidth(), st::dlgHeight);
} }
} }
} else if (sel) { } else if (sel) {
@ -1019,7 +1014,7 @@ void DialogsInner::addSavedPeersAfter(const QDateTime &date) {
SavedPeersByTime &saved(cRefSavedPeersByTime()); SavedPeersByTime &saved(cRefSavedPeersByTime());
while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) { while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) {
History *history = App::history(saved.last()->id); History *history = App::history(saved.last()->id);
history->setPosInDialogsDate(saved.lastKey()); history->setChatsListDate(saved.lastKey());
contactsNoDialogs.del(history->peer); contactsNoDialogs.del(history->peer);
saved.remove(saved.lastKey(), saved.last()); saved.remove(saved.lastKey(), saved.last());
} }
@ -1074,8 +1069,11 @@ void DialogsInner::peopleReceived(const QString &query, const QVector<MTPPeer> &
_peopleResults.reserve(people.size()); _peopleResults.reserve(people.size());
for (QVector<MTPPeer>::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) { for (QVector<MTPPeer>::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) {
PeerId peerId = peerFromMTP(*i); PeerId peerId = peerFromMTP(*i);
History *h = App::historyLoaded(peerId); if (History *h = App::historyLoaded(peerId)) {
if (h && !h->dialogs.isEmpty()) continue; // skip dialogs if (h->inChatList()) {
continue; // skip existing chats
}
}
_peopleResults.push_back(App::peer(peerId)); _peopleResults.push_back(App::peer(peerId));
} }
@ -1786,11 +1784,11 @@ void DialogsWidget::activate() {
} }
void DialogsWidget::createDialog(History *history) { void DialogsWidget::createDialog(History *history) {
bool creating = history->dialogs.isEmpty(); bool creating = !history->inChatList();
_inner.createDialog(history); _inner.createDialog(history);
if (creating && history->peer->migrateFrom()) { if (creating && history->peer->migrateFrom()) {
if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) { if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) {
if (!h->dialogs.isEmpty()) { if (h->inChatList()) {
removeDialog(h); removeDialog(h);
} }
} }

View File

@ -67,7 +67,6 @@ public:
void selectSkipPage(int32 pixels, int32 direction); void selectSkipPage(int32 pixels, int32 direction);
void createDialog(History *history); void createDialog(History *history);
void moveDialogToTop(const History::DialogLinks &links);
void dlgUpdated(DialogRow *row); void dlgUpdated(DialogRow *row);
void dlgUpdated(History *row, MsgId msgId); void dlgUpdated(History *row, MsgId msgId);
void removeDialog(History *history); void removeDialog(History *history);
@ -219,7 +218,7 @@ public:
void contactsReceived(const MTPcontacts_Contacts &contacts); void contactsReceived(const MTPcontacts_Contacts &contacts);
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req); void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req); void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req);
void dragEnterEvent(QDragEnterEvent *e); void dragEnterEvent(QDragEnterEvent *e);
void dragMoveEvent(QDragMoveEvent *e); void dragMoveEvent(QDragMoveEvent *e);
void dragLeaveEvent(QDragLeaveEvent *e); void dragLeaveEvent(QDragLeaveEvent *e);

View File

@ -294,7 +294,7 @@ History::History(const PeerId &peerId) : width(0), height(0)
, sendRequestId(0) , sendRequestId(0)
, textCachedFor(0) , textCachedFor(0)
, lastItemTextCache(st::dlgRichMinWidth) , lastItemTextCache(st::dlgRichMinWidth)
, posInDialogs(0) , _sortKeyInChatList(0)
, typingText(st::dlgRichMinWidth) { , typingText(st::dlgRichMinWidth) {
if (peer->isChannel() || (peer->isUser() && peer->asUser()->botInfo)) { if (peer->isChannel() || (peer->isUser() && peer->asUser()->botInfo)) {
outboxReadBefore = INT_MAX; outboxReadBefore = INT_MAX;
@ -367,7 +367,7 @@ bool History::updateTyping(uint64 ms, bool force) {
} }
} }
if (changed && App::main()) { if (changed && App::main()) {
if (!dialogs.isEmpty()) App::main()->dlgUpdated(dialogs[0]); updateChatListEntry();
if (App::main()->historyPeer() == peer) { if (App::main()->historyPeer() == peer) {
App::main()->topBar()->update(); App::main()->topBar()->update();
} }
@ -1180,7 +1180,7 @@ void DialogsIndexed::peerNameChanged(PeerData *peer, const PeerData::Names &oldN
} }
} }
for (PeerData::NameFirstChars::const_iterator i = toRemove.cbegin(), e = toRemove.cend(); i != e; ++i) { for (PeerData::NameFirstChars::const_iterator i = toRemove.cbegin(), e = toRemove.cend(); i != e; ++i) {
if (sortMode == DialogsSortByDate) history->dialogs.remove(*i); if (sortMode == DialogsSortByDate) history->removeChatListEntryByLetter(*i);
DialogsIndex::iterator j = index.find(*i); DialogsIndex::iterator j = index.find(*i);
if (j != index.cend()) { if (j != index.cend()) {
j.value()->del(peer->id, mainRow); j.value()->del(peer->id, mainRow);
@ -1191,11 +1191,8 @@ void DialogsIndexed::peerNameChanged(PeerData *peer, const PeerData::Names &oldN
if (j == index.cend()) { if (j == index.cend()) {
j = index.insert(*i, new DialogsList(sortMode)); j = index.insert(*i, new DialogsList(sortMode));
} }
if (sortMode == DialogsSortByDate) { DialogRow *row = j.value()->addToEnd(history);
history->dialogs.insert(*i, j.value()->addToEnd(history)); if (sortMode == DialogsSortByDate) history->addChatListEntryByLetter(*i, row);
} else {
j.value()->addToEnd(history);
}
} }
} }
} }
@ -2175,16 +2172,10 @@ MsgId History::inboxRead(MsgId upTo) {
if (!upTo) upTo = msgIdForRead(); if (!upTo) upTo = msgIdForRead();
inboxReadBefore = qMax(inboxReadBefore, upTo + 1); inboxReadBefore = qMax(inboxReadBefore, upTo + 1);
if (App::main()) { updateChatListEntry();
if (!dialogs.isEmpty()) { if (peer->migrateTo()) {
App::main()->dlgUpdated(dialogs[0]); if (History *h = App::historyLoaded(peer->migrateTo()->id)) {
} h->updateChatListEntry();
if (peer->migrateTo()) {
if (History *h = App::historyLoaded(peer->migrateTo()->id)) {
if (!h->dialogs.isEmpty()) {
App::main()->dlgUpdated(h->dialogs[0]);
}
}
} }
} }
@ -2235,10 +2226,13 @@ void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) {
showFrom = 0; showFrom = 0;
inboxReadBefore = qMax(inboxReadBefore, msgIdForRead() + 1); inboxReadBefore = qMax(inboxReadBefore, msgIdForRead() + 1);
} }
App::histories().unreadFull += newUnreadCount - unreadCount; if (inChatList()) {
if (mute) App::histories().unreadMuted += newUnreadCount - unreadCount; App::histories().unreadIncrement(newUnreadCount - unreadCount, mute);
if (psUpdate && (!mute || cIncludeMuted()) && App::wnd()) {
App::wnd()->updateCounter();
}
}
unreadCount = newUnreadCount; unreadCount = newUnreadCount;
if (psUpdate && (!mute || cIncludeMuted()) && App::wnd()) App::wnd()->updateCounter();
if (unreadBar) { if (unreadBar) {
int32 count = unreadCount; int32 count = unreadCount;
if (peer->migrateTo()) { if (peer->migrateTo()) {
@ -2253,10 +2247,12 @@ void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) {
void History::setMute(bool newMute) { void History::setMute(bool newMute) {
if (mute != newMute) { if (mute != newMute) {
App::histories().unreadMuted += newMute ? unreadCount : (-unreadCount);
mute = newMute; mute = newMute;
if (App::wnd()) App::wnd()->updateCounter(); if (inChatList() && unreadCount) {
if (!dialogs.isEmpty() && App::main()) App::main()->dlgUpdated(dialogs[0]); App::histories().unreadMuteChanged(unreadCount, newMute);
if (App::wnd()) App::wnd()->updateCounter();
}
updateChatListEntry();
} }
} }
@ -2420,25 +2416,25 @@ void History::setLastMessage(HistoryItem *msg) {
if (msg) { if (msg) {
if (!lastMsg) Local::removeSavedPeer(peer); if (!lastMsg) Local::removeSavedPeer(peer);
lastMsg = msg; lastMsg = msg;
setPosInDialogsDate(msg->date); setChatsListDate(msg->date);
} else { } else {
lastMsg = 0; lastMsg = 0;
} }
if (!dialogs.isEmpty() && App::main()) App::main()->dlgUpdated(dialogs[0]); updateChatListEntry();
} }
void History::setPosInDialogsDate(const QDateTime &date) { void History::setChatsListDate(const QDateTime &date) {
bool updateDialog = (App::main() && (!peer->isChannel() || peer->asChannel()->amIn() || !dialogs.isEmpty())); bool updateDialog = (App::main() && (!peer->isChannel() || peer->asChannel()->amIn() || !_chatListLinks.isEmpty()));
if (peer->migrateTo() && dialogs.isEmpty()) { if (peer->migrateTo() && _chatListLinks.isEmpty()) {
updateDialog = false; updateDialog = false;
} }
if (!lastMsgDate.isNull() && lastMsgDate >= date) { if (!lastMsgDate.isNull() && lastMsgDate >= date) {
if (!updateDialog || !dialogs.isEmpty()) { if (!updateDialog || !_chatListLinks.isEmpty()) {
return; return;
} }
} }
lastMsgDate = date; lastMsgDate = date;
posInDialogs = dialogPosFromDate(lastMsgDate); _sortKeyInChatList = dialogPosFromDate(lastMsgDate);
if (updateDialog) { if (updateDialog) {
App::main()->createDialog(this); App::main()->createDialog(this);
} }
@ -2560,6 +2556,58 @@ void History::clear(bool leaveItems) {
if (leaveItems && App::main()) App::main()->historyCleared(this); if (leaveItems && App::main()) App::main()->historyCleared(this);
} }
QPair<int32, int32> History::adjustByPosInChatsList(DialogsIndexed &indexed) {
int32 movedFrom = _chatListLinks[0]->pos * st::dlgHeight;
indexed.adjustByPos(_chatListLinks);
int32 movedTo = _chatListLinks[0]->pos * st::dlgHeight;
return qMakePair(movedFrom, movedTo);
}
DialogRow *History::addToChatList(DialogsIndexed &indexed) {
if (!inChatList()) {
_chatListLinks = indexed.addToEnd(this);
if (unreadCount) {
App::histories().unreadIncrement(unreadCount, mute);
if (App::wnd()) App::wnd()->updateCounter();
}
}
t_assert(!_chatListLinks.isEmpty());
return _chatListLinks[0];
}
void History::removeFromChatList(DialogsIndexed &indexed) {
if (inChatList()) {
indexed.del(peer);
_chatListLinks.clear();
if (unreadCount) {
App::histories().unreadIncrement(-unreadCount, mute);
if (App::wnd()) App::wnd()->updateCounter();
}
}
}
void History::removeChatListEntryByLetter(QChar letter) {
t_assert(letter != 0);
if (inChatList()) {
_chatListLinks.remove(letter);
}
}
void History::addChatListEntryByLetter(QChar letter, DialogRow *row) {
t_assert(letter != 0);
if (inChatList()) {
_chatListLinks.insert(letter, row);
}
}
void History::updateChatListEntry() const {
if (MainWidget *m = App::main()) {
if (inChatList()) {
m->dlgUpdated(_chatListLinks[0]);
}
}
}
void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages &result, bool onlyCounts) { void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages &result, bool onlyCounts) {
const QVector<MTPMessage> *v = 0; const QVector<MTPMessage> *v = 0;
switch (result.type()) { switch (result.type()) {

View File

@ -40,7 +40,7 @@ public:
typedef QHash<PeerId, History*> Map; typedef QHash<PeerId, History*> Map;
Map map; Map map;
Histories() : _a_typings(animation(this, &Histories::step_typings)), unreadFull(0), unreadMuted(0) { Histories() : _a_typings(animation(this, &Histories::step_typings)), _unreadFull(0), _unreadMuted(0) {
} }
void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action); void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action);
@ -52,7 +52,7 @@ public:
void clear(); void clear();
void remove(const PeerId &peer); void remove(const PeerId &peer);
~Histories() { ~Histories() {
unreadFull = unreadMuted = 0; _unreadFull = _unreadMuted = 0;
} }
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type); HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
@ -62,7 +62,29 @@ public:
TypingHistories typing; TypingHistories typing;
Animation _a_typings; Animation _a_typings;
int32 unreadFull, unreadMuted; int32 unreadBadge() const {
return _unreadFull - (cIncludeMuted() ? 0 : _unreadMuted);
}
bool unreadOnlyMuted() const {
return cIncludeMuted() ? (_unreadMuted >= _unreadFull) : false;
}
void unreadIncrement(int32 count, bool muted) {
_unreadFull += count;
if (muted) {
_unreadMuted += count;
}
}
void unreadMuteChanged(int32 count, bool muted) {
if (muted) {
_unreadMuted += count;
} else {
_unreadMuted -= count;
}
}
private:
int32 _unreadFull, _unreadMuted;
}; };
class HistoryBlock; class HistoryBlock;
@ -195,6 +217,7 @@ enum AddToOverviewMethod {
AddToOverviewBack, // when new messages slice was received and it is the last one, we index all media AddToOverviewBack, // when new messages slice was received and it is the last one, we index all media
}; };
struct DialogsIndexed;
class ChannelHistory; class ChannelHistory;
class History { class History {
public: public:
@ -264,9 +287,27 @@ public:
void getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop); void getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop);
void setLastMessage(HistoryItem *msg); void setLastMessage(HistoryItem *msg);
void setPosInDialogsDate(const QDateTime &date);
void fixLastMessage(bool wasAtBottom); void fixLastMessage(bool wasAtBottom);
typedef QMap<QChar, DialogRow*> ChatListLinksMap;
void setChatsListDate(const QDateTime &date);
QPair<int32, int32> adjustByPosInChatsList(DialogsIndexed &indexed);
uint64 sortKeyInChatList() const {
return _sortKeyInChatList;
}
bool inChatList() const {
return !_chatListLinks.isEmpty();
}
int32 posInChatList() const {
t_assert(inChatList());
return _chatListLinks[0]->pos;
}
DialogRow *addToChatList(DialogsIndexed &indexed);
void removeFromChatList(DialogsIndexed &indexed);
void removeChatListEntryByLetter(QChar letter);
void addChatListEntryByLetter(QChar letter, DialogRow *row);
void updateChatListEntry() const;
MsgId minMsgId() const; MsgId minMsgId() const;
MsgId maxMsgId() const; MsgId maxMsgId() const;
MsgId msgIdForRead() const; MsgId msgIdForRead() const;
@ -345,10 +386,6 @@ public:
mutable const HistoryItem *textCachedFor; // cache mutable const HistoryItem *textCachedFor; // cache
mutable Text lastItemTextCache; mutable Text lastItemTextCache;
typedef QMap<QChar, DialogRow*> DialogLinks;
DialogLinks dialogs;
uint64 posInDialogs; // like ((unixtime) << 32) | (incremented counter)
typedef QMap<UserData*, uint64> TypingUsers; typedef QMap<UserData*, uint64> TypingUsers;
TypingUsers typing; TypingUsers typing;
typedef QMap<UserData*, SendAction> SendActionUsers; typedef QMap<UserData*, SendAction> SendActionUsers;
@ -395,6 +432,9 @@ public:
private: private:
ChatListLinksMap _chatListLinks;
uint64 _sortKeyInChatList; // like ((unixtime) << 32) | (incremented counter)
typedef QMap<MsgId, NullType> MediaOverviewIds; typedef QMap<MsgId, NullType> MediaOverviewIds;
MediaOverviewIds overviewIds[OverviewCount]; MediaOverviewIds overviewIds[OverviewCount];
int32 overviewCountData[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded int32 overviewCountData[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded
@ -632,15 +672,15 @@ struct DialogsList {
if (sortMode != DialogsSortByDate) return; if (sortMode != DialogsSortByDate) return;
DialogRow *change = row; DialogRow *change = row;
if (change != begin && begin->history->posInDialogs < row->history->posInDialogs) { if (change != begin && begin->history->sortKeyInChatList() < row->history->sortKeyInChatList()) {
change = begin; change = begin;
} else while (change->prev && change->prev->history->posInDialogs < row->history->posInDialogs) { } else while (change->prev && change->prev->history->sortKeyInChatList() < row->history->sortKeyInChatList()) {
change = change->prev; change = change->prev;
} }
if (!insertBefore(row, change)) { if (!insertBefore(row, change)) {
if (change->next != end && end->prev->history->posInDialogs > row->history->posInDialogs) { if (change->next != end && end->prev->history->sortKeyInChatList() > row->history->sortKeyInChatList()) {
change = end->prev; change = end->prev;
} else while (change->next != end && change->next->history->posInDialogs > row->history->posInDialogs) { } else while (change->next != end && change->next->history->sortKeyInChatList() > row->history->sortKeyInChatList()) {
change = change->next; change = change->next;
} }
insertAfter(row, change); insertAfter(row, change);
@ -688,22 +728,19 @@ struct DialogsIndexed {
DialogsIndexed(DialogsSortMode sortMode) : sortMode(sortMode), list(sortMode) { DialogsIndexed(DialogsSortMode sortMode) : sortMode(sortMode), list(sortMode) {
} }
History::DialogLinks addToEnd(History *history) { History::ChatListLinksMap addToEnd(History *history) {
History::DialogLinks result; History::ChatListLinksMap result;
DialogsList::RowByPeer::const_iterator i = list.rowByPeer.find(history->peer->id); DialogsList::RowByPeer::const_iterator i = list.rowByPeer.find(history->peer->id);
if (i != list.rowByPeer.cend()) { if (i == list.rowByPeer.cend()) {
return i.value()->history->dialogs; result.insert(0, list.addToEnd(history));
} for (PeerData::NameFirstChars::const_iterator i = history->peer->chars.cbegin(), e = history->peer->chars.cend(); i != e; ++i) {
DialogsIndex::iterator j = index.find(*i);
result.insert(0, list.addToEnd(history)); if (j == index.cend()) {
for (PeerData::NameFirstChars::const_iterator i = history->peer->chars.cbegin(), e = history->peer->chars.cend(); i != e; ++i) { j = index.insert(*i, new DialogsList(sortMode));
DialogsIndex::iterator j = index.find(*i); }
if (j == index.cend()) { result.insert(*i, j.value()->addToEnd(history));
j = index.insert(*i, new DialogsList(sortMode));
} }
result.insert(*i, j.value()->addToEnd(history));
} }
return result; return result;
} }
@ -724,8 +761,8 @@ struct DialogsIndexed {
return res; return res;
} }
void adjustByPos(const History::DialogLinks &links) { void adjustByPos(const History::ChatListLinksMap &links) {
for (History::DialogLinks::const_iterator i = links.cbegin(), e = links.cend(); i != e; ++i) { for (History::ChatListLinksMap::const_iterator i = links.cbegin(), e = links.cend(); i != e; ++i) {
if (i.key() == QChar(0)) { if (i.key() == QChar(0)) {
list.adjustByPos(i.value()); list.adjustByPos(i.value());
} else { } else {

View File

@ -785,8 +785,8 @@ void MainWidget::notify_clipStopperHidden(ClipStopperType type) {
void MainWidget::ui_repaintHistoryItem(const HistoryItem *item) { void MainWidget::ui_repaintHistoryItem(const HistoryItem *item) {
history.ui_repaintHistoryItem(item); history.ui_repaintHistoryItem(item);
if (!item->history()->dialogs.isEmpty() && item->history()->lastMsg == item) { if (item->history()->lastMsg == item) {
dialogs.dlgUpdated(item->history()->dialogs[0]); item->history()->updateChatListEntry();
} }
if (overview) overview->ui_repaintHistoryItem(item); if (overview) overview->ui_repaintHistoryItem(item);
} }
@ -4246,9 +4246,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
if (h->lastMsg && h->lastMsg->out() && h->lastMsg->id <= d.vmax_id.v) { if (h->lastMsg && h->lastMsg->out() && h->lastMsg->id <= d.vmax_id.v) {
dlgUpdated(h, h->lastMsg->id); dlgUpdated(h, h->lastMsg->id);
} }
if (!h->dialogs.isEmpty()) { h->updateChatListEntry();
dlgUpdated(h->dialogs[0]);
}
} }
ptsApplySkippedUpdates(); ptsApplySkippedUpdates();

View File

@ -250,8 +250,8 @@ namespace {
#define GTK_ALPHA 3 #define GTK_ALPHA 3
QImage _trayIconImageGen() { QImage _trayIconImageGen() {
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; int32 counter = App::histories().unreadBadge(), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; bool muted = App::histories().unreadOnlyMuted();
if (_trayIconImage.isNull() || _trayIconImage.width() != _trayIconSize || muted != _trayIconMuted || counterSlice != _trayIconCount) { if (_trayIconImage.isNull() || _trayIconImage.width() != _trayIconSize || muted != _trayIconMuted || counterSlice != _trayIconCount) {
if (_trayIconImageBack.isNull() || _trayIconImageBack.width() != _trayIconSize) { if (_trayIconImageBack.isNull() || _trayIconImageBack.width() != _trayIconSize) {
_trayIconImageBack = App::wnd()->iconLarge().scaled(_trayIconSize, _trayIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); _trayIconImageBack = App::wnd()->iconLarge().scaled(_trayIconSize, _trayIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
@ -286,8 +286,8 @@ namespace {
} }
QString _trayIconImageFile() { QString _trayIconImageFile() {
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; int32 counter = App::histories().unreadBadge(), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; bool muted = App::histories().unreadOnlyMuted();
QString name = cWorkingDir() + qsl("tdata/ticons/ico%1_%2_%3.png").arg(muted ? "mute" : "").arg(_trayIconSize).arg(counterSlice); QString name = cWorkingDir() + qsl("tdata/ticons/ico%1_%2_%3.png").arg(muted ? "mute" : "").arg(_trayIconSize).arg(counterSlice);
QFileInfo info(name); QFileInfo info(name);
@ -621,7 +621,7 @@ void PsMainWindow::psUpdateIndicator() {
void PsMainWindow::psUpdateCounter() { void PsMainWindow::psUpdateCounter() {
setWindowIcon(wndIcon); setWindowIcon(wndIcon);
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted); int32 counter = App::histories().unreadBadge();
setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram")); setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"));
if (_psUnityLauncherEntry) { if (_psUnityLauncherEntry) {
@ -645,8 +645,8 @@ void PsMainWindow::psUpdateCounter() {
ps_gtk_status_icon_set_from_pixbuf(_trayIcon, _trayPixbuf); ps_gtk_status_icon_set_from_pixbuf(_trayIcon, _trayPixbuf);
} }
} else if (trayIcon) { } else if (trayIcon) {
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted); int32 counter = App::histories().unreadBadge();
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; bool muted = App::histories().unreadOnlyMuted();
style::color bg = muted ? st::counterMuteBG : st::counterBG; style::color bg = muted ? st::counterMuteBG : st::counterBG;
QIcon iconSmall; QIcon iconSmall;

View File

@ -176,7 +176,7 @@ void _placeCounter(QImage &img, int size, int count, style::color bg, style::col
} }
void PsMainWindow::psUpdateCounter() { void PsMainWindow::psUpdateCounter() {
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted); int32 counter = App::histories().unreadBadge();
setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram")); setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"));
setWindowIcon(wndIcon); setWindowIcon(wndIcon);
@ -185,7 +185,7 @@ void PsMainWindow::psUpdateCounter() {
_private.setWindowBadge(counter ? cnt : QString()); _private.setWindowBadge(counter ? cnt : QString());
if (trayIcon) { if (trayIcon) {
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; bool muted = App::histories().unreadOnlyMuted();
bool dm = objc_darkMode(); bool dm = objc_darkMode();
style::color bg = muted ? st::counterMuteBG : st::counterBG; style::color bg = muted ? st::counterMuteBG : st::counterBG;

View File

@ -1133,8 +1133,8 @@ static HICON _qt_createHIcon(const QIcon &icon, int xSize, int ySize) {
} }
void PsMainWindow::psUpdateCounter() { void PsMainWindow::psUpdateCounter() {
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted); int32 counter = App::histories().unreadBadge();
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; bool muted = App::histories().unreadOnlyMuted();
style::color bg = muted ? st::counterMuteBG : st::counterBG; style::color bg = muted ? st::counterMuteBG : st::counterBG;
QIcon iconSmall, iconBig; QIcon iconSmall, iconBig;

View File

@ -266,8 +266,8 @@ void TitleWidget::updateAdaptiveLayout() {
void TitleWidget::updateCounter() { void TitleWidget::updateCounter() {
if (!Adaptive::OneColumn() || !MTP::authedId()) return; if (!Adaptive::OneColumn() || !MTP::authedId()) return;
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted); int32 counter = App::histories().unreadBadge();
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; bool muted = App::histories().unreadOnlyMuted();
style::color bg = muted ? st::counterMuteBG : st::counterBG; style::color bg = muted ? st::counterMuteBG : st::counterBG;

View File

@ -554,6 +554,42 @@ static int32 QuarterArcLength = (FullArcLength / 4);
static int32 MinArcLength = (FullArcLength / 360); static int32 MinArcLength = (FullArcLength / 360);
static int32 AlmostFullArcLength = (FullArcLength - MinArcLength); static int32 AlmostFullArcLength = (FullArcLength - MinArcLength);
template <typename T1, typename T2>
class RefPairImplementation {
public:
template <typename T3, typename T4>
const RefPairImplementation &operator=(const RefPairImplementation<T3, T4> &other) const {
_first = other._first;
_second = other._second;
return *this;
}
template <typename T3, typename T4>
const RefPairImplementation &operator=(const QPair<T3, T4> &other) const {
_first = other.first;
_second = other.second;
return *this;
}
private:
RefPairImplementation(T1 &first, T2 &second) : _first(first), _second(second) {
}
RefPairImplementation(const RefPairImplementation &other);
template <typename T3, typename T4>
friend RefPairImplementation<T3, T4> RefPairCreator(T3 &first, T4 &second);
T1 &_first;
T2 &_second;
};
template <typename T1, typename T2>
inline RefPairImplementation<T1, T2> RefPairCreator(T1 &first, T2 &second) {
return RefPairImplementation<T1, T2>(first, second);
}
#define RefPair(Type1, Name1, Type2, Name2) Type1 Name1; Type2 Name2; RefPairCreator(Name1, Name2)
template <typename I> template <typename I>
inline void destroyImplementation(I *&ptr) { inline void destroyImplementation(I *&ptr) {
if (ptr) { if (ptr) {