From ffe6786ad1a309fbd650edc54ff7d78961391496 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 30 May 2025 21:10:18 +0400 Subject: [PATCH] Support unread reactions in monoforums. --- Telegram/SourceFiles/api/api_unread_things.cpp | 13 +++++++++---- .../SourceFiles/data/data_saved_messages.cpp | 6 ++++++ Telegram/SourceFiles/data/data_saved_messages.h | 1 + .../SourceFiles/data/data_saved_sublist.cpp | 1 + Telegram/SourceFiles/history/history.cpp | 17 ++++++++++++++--- Telegram/SourceFiles/history/history.h | 4 +++- Telegram/SourceFiles/history/history_item.cpp | 5 +++++ .../history/view/history_view_chat_section.cpp | 6 ++++-- Telegram/SourceFiles/menu/menu_send.cpp | 11 ++++++++--- .../window/notifications_manager.cpp | 13 ++++++------- .../SourceFiles/window/window_peer_menu.cpp | 6 ++++-- 11 files changed, 61 insertions(+), 22 deletions(-) diff --git a/Telegram/SourceFiles/api/api_unread_things.cpp b/Telegram/SourceFiles/api/api_unread_things.cpp index be597c954d..32deab3c88 100644 --- a/Telegram/SourceFiles/api/api_unread_things.cpp +++ b/Telegram/SourceFiles/api/api_unread_things.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_peer.h" #include "data/data_channel.h" #include "data/data_forum_topic.h" +#include "data/data_saved_sublist.h" #include "data/data_session.h" #include "main/main_session.h" #include "history/history.h" @@ -31,7 +32,9 @@ UnreadThings::UnreadThings(not_null api) : _api(api) { bool UnreadThings::trackMentions(Data::Thread *thread) const { const auto peer = thread ? thread->peer().get() : nullptr; - return peer && (peer->isChat() || peer->isMegagroup()); + return peer + && (peer->isChat() || peer->isMegagroup()) + && !peer->isMonoforum(); } bool UnreadThings::trackReactions(Data::Thread *thread) const { @@ -93,7 +96,7 @@ void UnreadThings::cancelRequests(not_null thread) { void UnreadThings::requestMentions( not_null thread, int loaded) { - if (_mentionsRequests.contains(thread)) { + if (_mentionsRequests.contains(thread) || thread->asSublist()) { return; } const auto offsetId = std::max( @@ -138,13 +141,15 @@ void UnreadThings::requestReactions( const auto maxId = 0; const auto minId = 0; const auto history = thread->owningHistory(); + const auto sublist = thread->asSublist(); const auto topic = thread->asTopic(); using Flag = MTPmessages_GetUnreadReactions::Flag; const auto requestId = _api->request(MTPmessages_GetUnreadReactions( - MTP_flags(topic ? Flag::f_top_msg_id : Flag()), + MTP_flags((topic ? Flag::f_top_msg_id : Flag()) + | (sublist ? Flag::f_saved_peer_id : Flag())), history->peer->input, MTP_int(topic ? topic->rootId() : 0), - MTPInputPeer(), // saved_peer_id + (sublist ? sublist->sublistPeer()->input : MTPInputPeer()), MTP_int(offsetId), MTP_int(addOffset), MTP_int(limit), diff --git a/Telegram/SourceFiles/data/data_saved_messages.cpp b/Telegram/SourceFiles/data/data_saved_messages.cpp index 94d02148c4..ae5d4e3218 100644 --- a/Telegram/SourceFiles/data/data_saved_messages.cpp +++ b/Telegram/SourceFiles/data/data_saved_messages.cpp @@ -128,6 +128,12 @@ void SavedMessages::loadMore() { _loadMore.call(); } +void SavedMessages::clearAllUnreadReactions() { + for (const auto &[peer, sublist] : _sublists) { + sublist->unreadReactions().clear(); + } +} + void SavedMessages::sendLoadMore() { if (_loadMoreRequestId || _chatsList.loaded()) { return; diff --git a/Telegram/SourceFiles/data/data_saved_messages.h b/Telegram/SourceFiles/data/data_saved_messages.h index 8b5530db79..9b20b8920a 100644 --- a/Telegram/SourceFiles/data/data_saved_messages.h +++ b/Telegram/SourceFiles/data/data_saved_messages.h @@ -47,6 +47,7 @@ public: void preloadSublists(); void loadMore(); + void clearAllUnreadReactions(); void apply(const MTPDupdatePinnedSavedDialogs &update); void apply(const MTPDupdateSavedDialogPinned &update); diff --git a/Telegram/SourceFiles/data/data_saved_sublist.cpp b/Telegram/SourceFiles/data/data_saved_sublist.cpp index 29bf6d5a13..50f75e051b 100644 --- a/Telegram/SourceFiles/data/data_saved_sublist.cpp +++ b/Telegram/SourceFiles/data/data_saved_sublist.cpp @@ -725,6 +725,7 @@ void SavedSublist::applyMonoforumDialog( data.vread_inbox_max_id().v, data.vunread_count().v); setOutboxReadTill(data.vread_outbox_max_id().v); + unreadReactions().setCount(data.vunread_reactions_count().v); setUnreadMark(data.is_unread_mark()); applyMaybeLast(topItem); } diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index fc99f35daf..bee130f501 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -836,11 +836,19 @@ void History::clearUnreadMentionsFor(MsgId topicRootId) { } } -void History::clearUnreadReactionsFor(MsgId topicRootId) { +void History::clearUnreadReactionsFor( + MsgId topicRootId, + Data::SavedSublist *sublist) { const auto forum = peer->forum(); - if (!topicRootId) { + const auto monoforum = peer->monoforum(); + const auto sublistPeerId = sublist ? sublist->sublistPeer()->id : 0; + if ((!topicRootId && !sublist) + || (!topicRootId && forum) + || (!sublist && monoforum)) { if (forum) { forum->clearAllUnreadReactions(); + } else if (monoforum) { + monoforum->clearAllUnreadReactions(); } unreadReactions().clear(); return; @@ -848,6 +856,8 @@ void History::clearUnreadReactionsFor(MsgId topicRootId) { if (const auto topic = forum->topicFor(topicRootId)) { topic->unreadReactions().clear(); } + } else if (monoforum) { + sublist->unreadReactions().clear(); } const auto &ids = unreadReactionsIds(); if (ids.empty()) { @@ -859,7 +869,8 @@ void History::clearUnreadReactionsFor(MsgId topicRootId) { items.reserve(ids.size()); for (const auto &id : ids) { if (const auto item = owner->message(peerId, id)) { - if (item->topicRootId() == topicRootId) { + if ((topicRootId && item->topicRootId() == topicRootId) + || (sublist && item->sublistPeerId() == sublistPeerId)) { items.emplace(id); } } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index e58ed77a1a..2bddc0eef0 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -284,7 +284,9 @@ public: void clearLastKeyboard(); void clearUnreadMentionsFor(MsgId topicRootId); - void clearUnreadReactionsFor(MsgId topicRootId); + void clearUnreadReactionsFor( + MsgId topicRootId, + Data::SavedSublist *sublist); Data::Draft *draft(Data::DraftKey key) const; void setDraft(Data::DraftKey key, std::unique_ptr &&draft); diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index cc6e4e8bb1..231a8d7a09 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -1476,6 +1476,9 @@ void HistoryItem::markReactionsRead() { if (const auto topic = this->topic()) { topic->updateChatListEntry(); topic->unreadReactions().erase(id); + } else if (const auto sublist = this->savedSublist()) { + sublist->updateChatListEntry(); + sublist->unreadReactions().erase(id); } } @@ -2195,6 +2198,8 @@ void HistoryItem::destroyHistoryEntry() { history()->unreadReactions().erase(id); if (const auto topic = this->topic()) { topic->unreadReactions().erase(id); + } else if (const auto sublist = this->savedSublist()) { + sublist->unreadReactions().erase(id); } } if (isRegular() && _history->peer->isMegagroup()) { diff --git a/Telegram/SourceFiles/history/view/history_view_chat_section.cpp b/Telegram/SourceFiles/history/view/history_view_chat_section.cpp index 32ef2bf028..3d164d2946 100644 --- a/Telegram/SourceFiles/history/view/history_view_chat_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_chat_section.cpp @@ -2198,7 +2198,7 @@ void ChatWidget::cornerButtonsShowAtPosition( Data::Thread *ChatWidget::cornerButtonsThread() { return _sublist - ? nullptr + ? static_cast(_sublist) : _topic ? static_cast(_topic) : _history; @@ -2233,7 +2233,9 @@ bool ChatWidget::cornerButtonsUnreadMayBeShown() { } bool ChatWidget::cornerButtonsHas(CornerButtonType type) { - return _topic || (type == CornerButtonType::Down); + return _topic + || (_sublist && type == CornerButtonType::Reactions) + || (type == CornerButtonType::Down); } void ChatWidget::showAtStart() { diff --git a/Telegram/SourceFiles/menu/menu_send.cpp b/Telegram/SourceFiles/menu/menu_send.cpp index 5d7ca9d396..4125ac0891 100644 --- a/Telegram/SourceFiles/menu/menu_send.cpp +++ b/Telegram/SourceFiles/menu/menu_send.cpp @@ -45,6 +45,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_forum.h" #include "data/data_forum_topic.h" #include "data/data_message_reactions.h" +#include "data/data_saved_sublist.h" #include "data/data_session.h" #include "main/main_session.h" #include "apiwrap.h" @@ -924,14 +925,16 @@ void SetupUnreadReactionsMenu( return; } const auto topic = thread->asTopic(); + const auto sublist = thread->asSublist(); const auto peer = thread->peer(); const auto rootId = topic ? topic->rootId() : 0; using Flag = MTPmessages_ReadReactions::Flag; peer->session().api().request(MTPmessages_ReadReactions( - MTP_flags(rootId ? Flag::f_top_msg_id : Flag(0)), + MTP_flags((rootId ? Flag::f_top_msg_id : Flag(0)) + | (sublist ? Flag::f_saved_peer_id : Flag(0))), peer->input, MTP_int(rootId), - MTPInputPeer() // saved_peer_id + sublist ? sublist->sublistPeer()->input : MTPInputPeer() )).done([=](const MTPmessages_AffectedHistory &result) { const auto offset = peer->session().api().applyAffectedHistory( peer, @@ -940,7 +943,9 @@ void SetupUnreadReactionsMenu( resend(weakThread, done, resend); } else { done(); - peer->owner().history(peer)->clearUnreadReactionsFor(rootId); + peer->owner().history(peer)->clearUnreadReactionsFor( + rootId, + sublist); } }).fail(done).send(); }; diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index 0038a41783..36f27e4dc0 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -1167,6 +1167,9 @@ Window::SessionController *Manager::openNotificationMessage( && item->isRegular() && (item->out() || (item->mentionsMe() && !history->peer->isUser())); const auto topic = item ? item->topic() : nullptr; + const auto sublist = (item && item->history()->amMonoforumAdmin()) + ? item->savedSublist() + : nullptr; const auto guard = gsl::finally([&] { if (topic) { @@ -1223,13 +1226,9 @@ Window::SessionController *Manager::openNotificationMessage( if (window) { window->widget()->showFromTray(); if (topic) { - using namespace HistoryView; - window->showSection( - std::make_shared(ChatViewId{ - .history = history, - .repliesRootId = topic->rootId(), - }, itemId), - SectionShow::Way::Forward); + window->showTopic(topic, itemId, SectionShow::Way::Forward); + } else if (sublist) { + window->showSublist(sublist, itemId, SectionShow::Way::Forward); } else { window->showPeerHistory( history->peer->id, diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 477b1b6707..183526a0a7 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -3090,12 +3090,14 @@ void UnpinAllMessages( const auto sendRequest = [=](auto self) -> void { const auto history = strong->owningHistory(); const auto topicRootId = strong->topicRootId(); + const auto sublist = strong->asSublist(); using Flag = MTPmessages_UnpinAllMessages::Flag; api->request(MTPmessages_UnpinAllMessages( - MTP_flags(topicRootId ? Flag::f_top_msg_id : Flag()), + MTP_flags((topicRootId ? Flag::f_top_msg_id : Flag()) + | (sublist ? Flag::f_saved_peer_id : Flag())), history->peer->input, MTP_int(topicRootId.bare), - MTPInputPeer() // saved_peer_id + sublist ? sublist->sublistPeer()->input : MTPInputPeer() )).done([=](const MTPmessages_AffectedHistory &result) { const auto peer = history->peer; const auto offset = api->applyAffectedHistory(peer, result);