diff --git a/Telegram/SourceFiles/data/data_folder.cpp b/Telegram/SourceFiles/data/data_folder.cpp index 2fa038f8ac..ea651cea9f 100644 --- a/Telegram/SourceFiles/data/data_folder.cpp +++ b/Telegram/SourceFiles/data/data_folder.cpp @@ -90,12 +90,55 @@ void Folder::registerOne(not_null history) { if (_chatsList.indexed()->size() == 1) { updateChatListSortPosition(); } + applyChatListMessage(history->chatListMessage()); } void Folder::unregisterOne(not_null history) { if (_chatsList.empty()) { updateChatListExistence(); } + if (_chatListMessage && _chatListMessage->history() == history) { + computeChatListMessage(); + } +} + +void Folder::oneListMessageChanged(HistoryItem *from, HistoryItem *to) { + if (!applyChatListMessage(to) && _chatListMessage == from) { + computeChatListMessage(); + } +} + +bool Folder::applyChatListMessage(HistoryItem *item) { + if (!item) { + return false; + } else if (_chatListMessage + && _chatListMessage->date() >= item->date()) { + return false; + } + _chatListMessage = item; + updateChatListEntry(); + return true; +} + +void Folder::computeChatListMessage() { + auto &&items = ranges::view::all( + *_chatsList.indexed() + ) | ranges::view::filter([](not_null row) { + return row->entry()->chatListMessage() != nullptr; + }); + const auto chatListDate = [](not_null row) { + return row->entry()->chatListMessage()->date(); + }; + const auto top = ranges::max_element( + items, + ranges::less(), + chatListDate); + if (top == items.end()) { + _chatListMessage = nullptr; + } else { + _chatListMessage = (*top)->entry()->chatListMessage(); + } + updateChatListEntry(); } not_null Folder::chatsList() { @@ -158,10 +201,7 @@ void Folder::requestChatListMessage() { } TimeId Folder::adjustedChatListTimeId() const { - const auto list = _chatsList.indexed(); - return list->empty() - ? TimeId(0) - : (*list->begin())->entry()->adjustedChatListTimeId(); + return _chatListMessage ? _chatListMessage->date() : chatListTimeId(); } void Folder::applyDialog(const MTPDdialogFolder &data) { @@ -291,16 +331,11 @@ bool Folder::chatListMutedBadge() const { } HistoryItem *Folder::chatListMessage() const { - const auto list = _chatsList.indexed(); - return list->empty() - ? nullptr - : (*list->begin())->key().entry()->chatListMessage(); + return _chatListMessage; } bool Folder::chatListMessageKnown() const { - const auto list = _chatsList.indexed(); - return list->empty() - || (*list->begin())->key().entry()->chatListMessageKnown(); + return true; } const QString &Folder::chatListName() const { diff --git a/Telegram/SourceFiles/data/data_folder.h b/Telegram/SourceFiles/data/data_folder.h index 01f146d448..c1f7ccf80d 100644 --- a/Telegram/SourceFiles/data/data_folder.h +++ b/Telegram/SourceFiles/data/data_folder.h @@ -32,6 +32,7 @@ public: FolderId id() const; void registerOne(not_null history); void unregisterOne(not_null history); + void oneListMessageChanged(HistoryItem *from, HistoryItem *to); not_null chatsList(); @@ -75,6 +76,8 @@ public: private: void indexNameParts(); + bool applyChatListMessage(HistoryItem *item); + void computeChatListMessage(); FolderId _id = 0; Dialogs::MainList _chatsList; @@ -84,6 +87,7 @@ private: base::flat_set _nameFirstLetters; Dialogs::UnreadState _cloudUnread; + HistoryItem *_chatListMessage = nullptr; //rpl::variable _unreadPosition; }; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index aa56cc0279..c124bd9512 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -154,7 +154,7 @@ void History::checkChatListMessageRemoved(not_null item) { if (chatListMessage() != item) { return; } - _chatListMessage = std::nullopt; + setChatListMessageUnknown(); refreshChatListMessage(); //if (const auto channel = peer->asChannel()) { // #feed // if (const auto feed = channel->feed()) { @@ -2201,12 +2201,16 @@ void History::setLastMessage(HistoryItem *item) { } } _lastMessage = item; - _chatListMessage = std::nullopt; - if (!peer->migrateTo()) { + if (peer->migrateTo()) { // We don't want to request last message for all deactivated chats. // This is a heavy request for them, because we need to get last // two items by messages.getHistory to skip the migration message. - requestChatListMessage(); + setChatListMessageUnknown(); + } else { + setChatListMessageFromLast(); + if (!chatListMessageKnown()) { + setFakeChatListMessage(); + } } } @@ -2222,6 +2226,7 @@ void History::setChatListMessage(HistoryItem *item) { if (_chatListMessage && *_chatListMessage == item) { return; } + const auto was = _chatListMessage.value_or(nullptr); if (item) { if (!_chatListMessage || !*_chatListMessage) { Local::removeSavedPeer(peer); @@ -2235,6 +2240,9 @@ void History::setChatListMessage(HistoryItem *item) { _chatListMessage = nullptr; updateChatListEntry(); } + if (const auto folder = this->folder()) { + folder->oneListMessageChanged(was, item); + } if (const auto to = peer->migrateTo()) { if (const auto history = owner().historyLoaded(to)) { if (!history->chatListMessageKnown()) { @@ -2297,7 +2305,18 @@ void History::setChatListMessageFromLast() { if (const auto good = computeChatListMessageFromLast()) { setChatListMessage(*good); } else { - _chatListMessage = std::nullopt; + setChatListMessageUnknown(); + } +} + +void History::setChatListMessageUnknown() { + if (!_chatListMessage.has_value()) { + return; + } + const auto was = *_chatListMessage; + _chatListMessage = std::nullopt; + if (const auto folder = this->folder()) { + folder->oneListMessageChanged(was, nullptr); } } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 5697d3da20..fdef7d5b8a 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -439,6 +439,7 @@ private: void setChatListMessage(HistoryItem *item); std::optional computeChatListMessageFromLast() const; void setChatListMessageFromLast(); + void setChatListMessageUnknown(); void setFakeChatListMessage(); // Add all items to the unread mentions if we were not loaded at bottom and now are.