From abc4e368e41649fa6d400f5dd04f323fa8aadf9a Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 3 Aug 2026 08:31:16 +0300 Subject: [PATCH] Fixed restoring pinned community dialogs on launch. --- Telegram/SourceFiles/apiwrap.cpp | 24 +++++++++++++++++----- Telegram/SourceFiles/apiwrap.h | 5 +++++ Telegram/SourceFiles/data/data_session.cpp | 20 ++++++++++++++++++ Telegram/SourceFiles/data/data_session.h | 3 +++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 4d61b5ab7d..ca6e01670a 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -1101,17 +1101,31 @@ void ApiWrap::requestPinnedDialogs(Data::Folder *folder) { return; } - const auto finalize = [=] { + state->pinnedRequestId = sendPinnedDialogsRequest(folder, [=] { if (const auto state = dialogsLoadState(folder)) { state->pinnedRequestId = 0; state->pinnedReceived = true; dialogsLoadFinish(folder); } - }; - state->pinnedRequestId = request(MTPmessages_GetPinnedDialogs( + }); +} + +void ApiWrap::reloadPinnedDialogs(Data::Folder *folder) { + if (!_pinnedDialogsReloads.emplace(folder).second) { + return; + } + sendPinnedDialogsRequest(folder, [=] { + _pinnedDialogsReloads.remove(folder); + }); +} + +mtpRequestId ApiWrap::sendPinnedDialogsRequest( + Data::Folder *folder, + Fn finish) { + return request(MTPmessages_GetPinnedDialogs( MTP_int(folder ? folder->id() : 0) )).done([=](const MTPmessages_PeerDialogs &result) { - finalize(); + finish(); result.match([&](const MTPDmessages_peerDialogs &data) { _session->data().processUsers(data.vusers()); _session->data().processChats(data.vchats()); @@ -1124,7 +1138,7 @@ void ApiWrap::requestPinnedDialogs(Data::Folder *folder) { _session->data().notifyPinnedDialogsOrderUpdated(); }); }).fail([=] { - finalize(); + finish(); }).send(); } diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 568841fde9..7f6e2c958f 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -191,6 +191,7 @@ public: void requestContacts(); void requestDialogs(Data::Folder *folder = nullptr); void requestPinnedDialogs(Data::Folder *folder = nullptr); + void reloadPinnedDialogs(Data::Folder *folder = nullptr); void requestMoreBlockedByDateDialogs(); void requestMoreDialogsIfNeeded(); rpl::producer dialogsLoadMayBlockByDate() const; @@ -509,6 +510,9 @@ private: const QVector &dialogs, const QVector &messages); void requestMoreDialogs(Data::Folder *folder); + mtpRequestId sendPinnedDialogsRequest( + Data::Folder *folder, + Fn finish); DialogsLoadState *dialogsLoadState(Data::Folder *folder); void dialogsLoadFinish(Data::Folder *folder); @@ -765,6 +769,7 @@ private: base::flat_map< not_null, DialogsLoadState> _foldersLoadState; + base::flat_set _pinnedDialogsReloads; rpl::event_stream _sendActions; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 43e35365bf..d8b6d22f07 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -1269,6 +1269,12 @@ not_null Session::processChat(const MTPChat &data) { } else if (!result->isLoaded()) { result->setLoadedStatus(PeerData::LoadedStatus::Normal); } + if (!_pinnedCommunitiesNotLoaded.empty()) { + if (const auto channel = result->asChannel() + ; channel && channel->isCommunity()) { + checkPinnedCommunityLoaded(channel); + } + } if (flags) { session().changes().peerUpdated(result, flags); } @@ -2694,8 +2700,12 @@ void Session::applyDialog( const auto channelId = ChannelId(data.vcommunity_id().v); const auto channel = channelLoaded(channelId); if (!channel || !channel->isCommunity()) { + if (data.is_pinned()) { + _pinnedCommunitiesNotLoaded.emplace(channelId); + } return; } + _pinnedCommunitiesNotLoaded.remove(channelId); const auto history = this->history(channel); notifySettings().apply( peerFromChannel(channelId), @@ -2704,6 +2714,13 @@ void Session::applyDialog( setPinnedFromEntryList(history, data.is_pinned()); } +void Session::checkPinnedCommunityLoaded(not_null channel) { + if (!_pinnedCommunitiesNotLoaded.remove(peerToChannel(channel->id))) { + return; + } + session().api().reloadPinnedDialogs(); +} + bool Session::pinnedCanPin(not_null entry) const { if ([[maybe_unused]] const auto sublist = entry->asSublist()) { if (sublist->parentChat()) { @@ -2831,6 +2848,9 @@ const std::vector &Session::pinnedChatsOrder( } void Session::clearPinnedChats(Data::Folder *folder) { + if (!folder) { + _pinnedCommunitiesNotLoaded.clear(); + } chatsList(folder)->pinned()->clear(); } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 3aef257a1f..1effe2cf46 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -1049,6 +1049,7 @@ private: void applyDialog( Folder *requestFolder, const MTPDdialogCommunity &data); + void checkPinnedCommunityLoaded(not_null channel); const Messages *messagesList(PeerId peerId) const; not_null messagesListForInsert(PeerId peerId); @@ -1355,6 +1356,8 @@ private: not_null, ChannelId>> _postponedMonoforumLinkedIds; + base::flat_set _pinnedCommunitiesNotLoaded; + // This one from `channel`, not `channelFull`. base::flat_map, int> _commonStarsPerMessage;