From 798f800913b2932bb86fbd4eea238102056e7e8a Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 28 Feb 2016 14:58:30 +0300 Subject: [PATCH] History::dialogs and Histories::unread are private now, counting only chats from dialogs list to the badge --- Telegram/SourceFiles/apiwrap.cpp | 2 +- Telegram/SourceFiles/app.cpp | 2 +- Telegram/SourceFiles/dialogswidget.cpp | 32 ++++--- Telegram/SourceFiles/dialogswidget.h | 3 +- Telegram/SourceFiles/history.cpp | 110 ++++++++++++++++------- Telegram/SourceFiles/history.h | 91 +++++++++++++------ Telegram/SourceFiles/mainwidget.cpp | 8 +- Telegram/SourceFiles/pspecific_linux.cpp | 14 +-- Telegram/SourceFiles/pspecific_mac.cpp | 4 +- Telegram/SourceFiles/pspecific_wnd.cpp | 4 +- Telegram/SourceFiles/title.cpp | 4 +- Telegram/SourceFiles/types.h | 36 ++++++++ 12 files changed, 213 insertions(+), 97 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 295500225..78b74c727 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -273,7 +273,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt if (!h->isEmpty()) { h->clear(true); } - if (!hto->dialogs.isEmpty() && !h->dialogs.isEmpty()) { + if (hto->inChatList() && h->inChatList()) { App::removeDialog(h); } } diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 521f923ad..dc77d01e8 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -522,7 +522,7 @@ namespace App { if (!h->isEmpty()) { h->clear(true); } - if (!hto->dialogs.isEmpty() && !h->dialogs.isEmpty()) { + if (hto->inChatList() && h->inChatList()) { App::removeDialog(h); } } diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index f7bf3298f..29d3437f0 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -443,16 +443,12 @@ void DialogsInner::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow) { } void DialogsInner::createDialog(History *history) { - bool creating = history->dialogs.isEmpty(); + bool creating = !history->inChatList(); if (creating) { - history->dialogs = dialogs.addToEnd(history); - contactsNoDialogs.del(history->peer, history->dialogs[0]); + DialogRow *mainRow = history->addToChatList(dialogs); + contactsNoDialogs.del(history->peer, mainRow); } - - History::DialogLinks links = history->dialogs; - int32 movedFrom = links[0]->pos * st::dlgHeight; - dialogs.adjustByPos(links); - int32 movedTo = links[0]->pos * st::dlgHeight; + RefPair(int32, movedFrom, int32, movedTo) = history->adjustByPosInChatsList(dialogs); emit dialogMoved(movedFrom, movedTo); @@ -471,8 +467,7 @@ void DialogsInner::removeDialog(History *history) { if (sel && sel->history == history) { sel = 0; } - dialogs.del(history->peer); - history->dialogs = History::DialogLinks(); + history->removeFromChatList(dialogs); history->clearNotifications(); if (App::wnd()) App::wnd()->notifyClear(history); 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 (peer) { if (History *h = App::historyLoaded(peer->id)) { - if (h->dialogs.contains(0)) { - update(0, h->dialogs.value(0)->pos * st::dlgHeight, fullWidth(), st::dlgHeight); + if (h->inChatList()) { + update(0, h->posInChatList() * st::dlgHeight, fullWidth(), st::dlgHeight); } } } else if (sel) { @@ -1019,7 +1014,7 @@ void DialogsInner::addSavedPeersAfter(const QDateTime &date) { SavedPeersByTime &saved(cRefSavedPeersByTime()); while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) { History *history = App::history(saved.last()->id); - history->setPosInDialogsDate(saved.lastKey()); + history->setChatsListDate(saved.lastKey()); contactsNoDialogs.del(history->peer); saved.remove(saved.lastKey(), saved.last()); } @@ -1074,8 +1069,11 @@ void DialogsInner::peopleReceived(const QString &query, const QVector & _peopleResults.reserve(people.size()); for (QVector::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) { PeerId peerId = peerFromMTP(*i); - History *h = App::historyLoaded(peerId); - if (h && !h->dialogs.isEmpty()) continue; // skip dialogs + if (History *h = App::historyLoaded(peerId)) { + if (h->inChatList()) { + continue; // skip existing chats + } + } _peopleResults.push_back(App::peer(peerId)); } @@ -1786,11 +1784,11 @@ void DialogsWidget::activate() { } void DialogsWidget::createDialog(History *history) { - bool creating = history->dialogs.isEmpty(); + bool creating = !history->inChatList(); _inner.createDialog(history); if (creating && history->peer->migrateFrom()) { if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) { - if (!h->dialogs.isEmpty()) { + if (h->inChatList()) { removeDialog(h); } } diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index a535d2fa1..dfa643f5b 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -67,7 +67,6 @@ public: void selectSkipPage(int32 pixels, int32 direction); void createDialog(History *history); - void moveDialogToTop(const History::DialogLinks &links); void dlgUpdated(DialogRow *row); void dlgUpdated(History *row, MsgId msgId); void removeDialog(History *history); @@ -219,7 +218,7 @@ public: void contactsReceived(const MTPcontacts_Contacts &contacts); void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req); void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req); - + void dragEnterEvent(QDragEnterEvent *e); void dragMoveEvent(QDragMoveEvent *e); void dragLeaveEvent(QDragLeaveEvent *e); diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 4dd68f6bf..4a69bdd3d 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -294,7 +294,7 @@ History::History(const PeerId &peerId) : width(0), height(0) , sendRequestId(0) , textCachedFor(0) , lastItemTextCache(st::dlgRichMinWidth) -, posInDialogs(0) +, _sortKeyInChatList(0) , typingText(st::dlgRichMinWidth) { if (peer->isChannel() || (peer->isUser() && peer->asUser()->botInfo)) { outboxReadBefore = INT_MAX; @@ -367,7 +367,7 @@ bool History::updateTyping(uint64 ms, bool force) { } } if (changed && App::main()) { - if (!dialogs.isEmpty()) App::main()->dlgUpdated(dialogs[0]); + updateChatListEntry(); if (App::main()->historyPeer() == peer) { 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) { - if (sortMode == DialogsSortByDate) history->dialogs.remove(*i); + if (sortMode == DialogsSortByDate) history->removeChatListEntryByLetter(*i); DialogsIndex::iterator j = index.find(*i); if (j != index.cend()) { j.value()->del(peer->id, mainRow); @@ -1191,11 +1191,8 @@ void DialogsIndexed::peerNameChanged(PeerData *peer, const PeerData::Names &oldN if (j == index.cend()) { j = index.insert(*i, new DialogsList(sortMode)); } - if (sortMode == DialogsSortByDate) { - history->dialogs.insert(*i, j.value()->addToEnd(history)); - } else { - j.value()->addToEnd(history); - } + DialogRow *row = j.value()->addToEnd(history); + if (sortMode == DialogsSortByDate) history->addChatListEntryByLetter(*i, row); } } } @@ -2175,16 +2172,10 @@ MsgId History::inboxRead(MsgId upTo) { if (!upTo) upTo = msgIdForRead(); inboxReadBefore = qMax(inboxReadBefore, upTo + 1); - if (App::main()) { - if (!dialogs.isEmpty()) { - App::main()->dlgUpdated(dialogs[0]); - } - if (peer->migrateTo()) { - if (History *h = App::historyLoaded(peer->migrateTo()->id)) { - if (!h->dialogs.isEmpty()) { - App::main()->dlgUpdated(h->dialogs[0]); - } - } + updateChatListEntry(); + if (peer->migrateTo()) { + if (History *h = App::historyLoaded(peer->migrateTo()->id)) { + h->updateChatListEntry(); } } @@ -2235,10 +2226,13 @@ void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) { showFrom = 0; inboxReadBefore = qMax(inboxReadBefore, msgIdForRead() + 1); } - App::histories().unreadFull += newUnreadCount - unreadCount; - if (mute) App::histories().unreadMuted += newUnreadCount - unreadCount; + if (inChatList()) { + App::histories().unreadIncrement(newUnreadCount - unreadCount, mute); + if (psUpdate && (!mute || cIncludeMuted()) && App::wnd()) { + App::wnd()->updateCounter(); + } + } unreadCount = newUnreadCount; - if (psUpdate && (!mute || cIncludeMuted()) && App::wnd()) App::wnd()->updateCounter(); if (unreadBar) { int32 count = unreadCount; if (peer->migrateTo()) { @@ -2253,10 +2247,12 @@ void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) { void History::setMute(bool newMute) { if (mute != newMute) { - App::histories().unreadMuted += newMute ? unreadCount : (-unreadCount); mute = newMute; - if (App::wnd()) App::wnd()->updateCounter(); - if (!dialogs.isEmpty() && App::main()) App::main()->dlgUpdated(dialogs[0]); + if (inChatList() && unreadCount) { + App::histories().unreadMuteChanged(unreadCount, newMute); + if (App::wnd()) App::wnd()->updateCounter(); + } + updateChatListEntry(); } } @@ -2420,25 +2416,25 @@ void History::setLastMessage(HistoryItem *msg) { if (msg) { if (!lastMsg) Local::removeSavedPeer(peer); lastMsg = msg; - setPosInDialogsDate(msg->date); + setChatsListDate(msg->date); } else { lastMsg = 0; } - if (!dialogs.isEmpty() && App::main()) App::main()->dlgUpdated(dialogs[0]); + updateChatListEntry(); } -void History::setPosInDialogsDate(const QDateTime &date) { - bool updateDialog = (App::main() && (!peer->isChannel() || peer->asChannel()->amIn() || !dialogs.isEmpty())); - if (peer->migrateTo() && dialogs.isEmpty()) { +void History::setChatsListDate(const QDateTime &date) { + bool updateDialog = (App::main() && (!peer->isChannel() || peer->asChannel()->amIn() || !_chatListLinks.isEmpty())); + if (peer->migrateTo() && _chatListLinks.isEmpty()) { updateDialog = false; } if (!lastMsgDate.isNull() && lastMsgDate >= date) { - if (!updateDialog || !dialogs.isEmpty()) { + if (!updateDialog || !_chatListLinks.isEmpty()) { return; } } lastMsgDate = date; - posInDialogs = dialogPosFromDate(lastMsgDate); + _sortKeyInChatList = dialogPosFromDate(lastMsgDate); if (updateDialog) { App::main()->createDialog(this); } @@ -2560,6 +2556,58 @@ void History::clear(bool leaveItems) { if (leaveItems && App::main()) App::main()->historyCleared(this); } +QPair 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) { const QVector *v = 0; switch (result.type()) { diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 8d80eb393..237670ecf 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -40,7 +40,7 @@ public: typedef QHash 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); @@ -52,7 +52,7 @@ public: void clear(); void remove(const PeerId &peer); ~Histories() { - unreadFull = unreadMuted = 0; + _unreadFull = _unreadMuted = 0; } HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type); @@ -62,7 +62,29 @@ public: TypingHistories typing; 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; @@ -195,6 +217,7 @@ enum AddToOverviewMethod { AddToOverviewBack, // when new messages slice was received and it is the last one, we index all media }; +struct DialogsIndexed; class ChannelHistory; class History { public: @@ -264,9 +287,27 @@ public: void getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop); void setLastMessage(HistoryItem *msg); - void setPosInDialogsDate(const QDateTime &date); void fixLastMessage(bool wasAtBottom); + typedef QMap ChatListLinksMap; + void setChatsListDate(const QDateTime &date); + QPair 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 maxMsgId() const; MsgId msgIdForRead() const; @@ -345,10 +386,6 @@ public: mutable const HistoryItem *textCachedFor; // cache mutable Text lastItemTextCache; - typedef QMap DialogLinks; - DialogLinks dialogs; - uint64 posInDialogs; // like ((unixtime) << 32) | (incremented counter) - typedef QMap TypingUsers; TypingUsers typing; typedef QMap SendActionUsers; @@ -395,6 +432,9 @@ public: private: + ChatListLinksMap _chatListLinks; + uint64 _sortKeyInChatList; // like ((unixtime) << 32) | (incremented counter) + typedef QMap MediaOverviewIds; MediaOverviewIds overviewIds[OverviewCount]; 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; DialogRow *change = row; - if (change != begin && begin->history->posInDialogs < row->history->posInDialogs) { + if (change != begin && begin->history->sortKeyInChatList() < row->history->sortKeyInChatList()) { 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; } 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; - } 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; } insertAfter(row, change); @@ -688,22 +728,19 @@ struct DialogsIndexed { DialogsIndexed(DialogsSortMode sortMode) : sortMode(sortMode), list(sortMode) { } - History::DialogLinks addToEnd(History *history) { - History::DialogLinks result; + History::ChatListLinksMap addToEnd(History *history) { + History::ChatListLinksMap result; DialogsList::RowByPeer::const_iterator i = list.rowByPeer.find(history->peer->id); - 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); - if (j == index.cend()) { - j = index.insert(*i, new DialogsList(sortMode)); + if (i == list.rowByPeer.cend()) { + 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); + if (j == index.cend()) { + j = index.insert(*i, new DialogsList(sortMode)); + } + result.insert(*i, j.value()->addToEnd(history)); } - result.insert(*i, j.value()->addToEnd(history)); } - return result; } @@ -724,8 +761,8 @@ struct DialogsIndexed { return res; } - void adjustByPos(const History::DialogLinks &links) { - for (History::DialogLinks::const_iterator i = links.cbegin(), e = links.cend(); i != e; ++i) { + void adjustByPos(const History::ChatListLinksMap &links) { + for (History::ChatListLinksMap::const_iterator i = links.cbegin(), e = links.cend(); i != e; ++i) { if (i.key() == QChar(0)) { list.adjustByPos(i.value()); } else { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 6c588c619..735892f4d 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -785,8 +785,8 @@ void MainWidget::notify_clipStopperHidden(ClipStopperType type) { void MainWidget::ui_repaintHistoryItem(const HistoryItem *item) { history.ui_repaintHistoryItem(item); - if (!item->history()->dialogs.isEmpty() && item->history()->lastMsg == item) { - dialogs.dlgUpdated(item->history()->dialogs[0]); + if (item->history()->lastMsg == item) { + item->history()->updateChatListEntry(); } 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) { dlgUpdated(h, h->lastMsg->id); } - if (!h->dialogs.isEmpty()) { - dlgUpdated(h->dialogs[0]); - } + h->updateChatListEntry(); } ptsApplySkippedUpdates(); diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp index b734e9f0b..7221645bc 100644 --- a/Telegram/SourceFiles/pspecific_linux.cpp +++ b/Telegram/SourceFiles/pspecific_linux.cpp @@ -250,8 +250,8 @@ namespace { #define GTK_ALPHA 3 QImage _trayIconImageGen() { - int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; - bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; + int32 counter = App::histories().unreadBadge(), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; + bool muted = App::histories().unreadOnlyMuted(); if (_trayIconImage.isNull() || _trayIconImage.width() != _trayIconSize || muted != _trayIconMuted || counterSlice != _trayIconCount) { if (_trayIconImageBack.isNull() || _trayIconImageBack.width() != _trayIconSize) { _trayIconImageBack = App::wnd()->iconLarge().scaled(_trayIconSize, _trayIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); @@ -286,8 +286,8 @@ namespace { } QString _trayIconImageFile() { - int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; - bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; + int32 counter = App::histories().unreadBadge(), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter; + bool muted = App::histories().unreadOnlyMuted(); QString name = cWorkingDir() + qsl("tdata/ticons/ico%1_%2_%3.png").arg(muted ? "mute" : "").arg(_trayIconSize).arg(counterSlice); QFileInfo info(name); @@ -621,7 +621,7 @@ void PsMainWindow::psUpdateIndicator() { void PsMainWindow::psUpdateCounter() { 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")); if (_psUnityLauncherEntry) { @@ -645,8 +645,8 @@ void PsMainWindow::psUpdateCounter() { ps_gtk_status_icon_set_from_pixbuf(_trayIcon, _trayPixbuf); } } else if (trayIcon) { - int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted); - bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; + int32 counter = App::histories().unreadBadge(); + bool muted = App::histories().unreadOnlyMuted(); style::color bg = muted ? st::counterMuteBG : st::counterBG; QIcon iconSmall; diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 7f2cf9508..2f8971696 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -176,7 +176,7 @@ void _placeCounter(QImage &img, int size, int count, style::color bg, style::col } 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")); setWindowIcon(wndIcon); @@ -185,7 +185,7 @@ void PsMainWindow::psUpdateCounter() { _private.setWindowBadge(counter ? cnt : QString()); if (trayIcon) { - bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; + bool muted = App::histories().unreadOnlyMuted(); bool dm = objc_darkMode(); style::color bg = muted ? st::counterMuteBG : st::counterBG; diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index 02077ba67..6b91561eb 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -1133,8 +1133,8 @@ static HICON _qt_createHIcon(const QIcon &icon, int xSize, int ySize) { } void PsMainWindow::psUpdateCounter() { - int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted); - bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; + int32 counter = App::histories().unreadBadge(); + bool muted = App::histories().unreadOnlyMuted(); style::color bg = muted ? st::counterMuteBG : st::counterBG; QIcon iconSmall, iconBig; diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp index 2bc52abc6..28069d257 100644 --- a/Telegram/SourceFiles/title.cpp +++ b/Telegram/SourceFiles/title.cpp @@ -266,8 +266,8 @@ void TitleWidget::updateAdaptiveLayout() { void TitleWidget::updateCounter() { if (!Adaptive::OneColumn() || !MTP::authedId()) return; - int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted); - bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false; + int32 counter = App::histories().unreadBadge(); + bool muted = App::histories().unreadOnlyMuted(); style::color bg = muted ? st::counterMuteBG : st::counterBG; diff --git a/Telegram/SourceFiles/types.h b/Telegram/SourceFiles/types.h index 2814ce5cc..68d6864ce 100644 --- a/Telegram/SourceFiles/types.h +++ b/Telegram/SourceFiles/types.h @@ -554,6 +554,42 @@ static int32 QuarterArcLength = (FullArcLength / 4); static int32 MinArcLength = (FullArcLength / 360); static int32 AlmostFullArcLength = (FullArcLength - MinArcLength); +template +class RefPairImplementation { +public: + template + const RefPairImplementation &operator=(const RefPairImplementation &other) const { + _first = other._first; + _second = other._second; + return *this; + } + + template + const RefPairImplementation &operator=(const QPair &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 + friend RefPairImplementation RefPairCreator(T3 &first, T4 &second); + + T1 &_first; + T2 &_second; +}; + +template +inline RefPairImplementation RefPairCreator(T1 &first, T2 &second) { + return RefPairImplementation(first, second); +} + +#define RefPair(Type1, Name1, Type2, Name2) Type1 Name1; Type2 Name2; RefPairCreator(Name1, Name2) + template inline void destroyImplementation(I *&ptr) { if (ptr) {