From 3bc20c35509deeae2c4e9f924fade85b5be8ee75 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 5 Jun 2025 12:47:16 +0400 Subject: [PATCH] Save last opened subsection within a launch. --- Telegram/SourceFiles/data/data_channel.cpp | 4 ++-- Telegram/SourceFiles/data/data_forum.cpp | 17 +++++++++++++ Telegram/SourceFiles/data/data_forum.h | 5 ++++ .../SourceFiles/data/data_saved_messages.cpp | 14 +++++++++++ .../SourceFiles/data/data_saved_messages.h | 5 ++++ Telegram/SourceFiles/data/data_thread.cpp | 15 ++++++++++++ Telegram/SourceFiles/data/data_thread.h | 2 ++ .../SourceFiles/dialogs/dialogs_widget.cpp | 24 ++++++++++++++++++- .../SourceFiles/history/history_widget.cpp | 4 ++++ .../view/history_view_chat_section.cpp | 6 +++++ .../window/window_session_controller.cpp | 15 ++++++++---- 11 files changed, 103 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index bb41dd4b4e..7a0f6a502a 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -409,8 +409,8 @@ void ChannelData::setPendingRequestsCount( } bool ChannelData::useSubsectionTabs() const { - return isForum() - && (flags() & ChannelDataFlag::ForumTabs); + return amMonoforumAdmin() + || (isForum() && (flags() & ChannelDataFlag::ForumTabs)); } ChatRestrictionsInfo ChannelData::KickedRestrictedRights( diff --git a/Telegram/SourceFiles/data/data_forum.cpp b/Telegram/SourceFiles/data/data_forum.cpp index ffc92a9847..3890b4c0ed 100644 --- a/Telegram/SourceFiles/data/data_forum.cpp +++ b/Telegram/SourceFiles/data/data_forum.cpp @@ -189,6 +189,9 @@ void Forum::applyTopicDeleted(MsgId rootId) { reorderLastTopics(); } + if (_activeSubsectionTopic == raw) { + _activeSubsectionTopic = nullptr; + } _topicDestroyed.fire(raw); session().changes().topicUpdated( raw, @@ -259,6 +262,20 @@ const std::vector> &Forum::recentTopics() const { return _lastTopics; } +void Forum::saveActiveSubsectionThread(not_null thread) { + if (const auto topic = thread->asTopic()) { + Assert(topic->forum() == this); + _activeSubsectionTopic = topic->creating() ? nullptr : topic; + } else { + Assert(thread == history()); + _activeSubsectionTopic = nullptr; + } +} + +Thread *Forum::activeSubsectionThread() const { + return _activeSubsectionTopic; +} + void Forum::listMessageChanged(HistoryItem *from, HistoryItem *to) { if (from || to) { reorderLastTopics(); diff --git a/Telegram/SourceFiles/data/data_forum.h b/Telegram/SourceFiles/data/data_forum.h index 732ef80097..ae0cc2d1a5 100644 --- a/Telegram/SourceFiles/data/data_forum.h +++ b/Telegram/SourceFiles/data/data_forum.h @@ -96,6 +96,9 @@ public: [[nodiscard]] auto recentTopics() const -> const std::vector> &; + void saveActiveSubsectionThread(not_null thread); + [[nodiscard]] Thread *activeSubsectionThread() const; + [[nodiscard]] rpl::lifetime &lifetime() { return _lifetime; } @@ -129,6 +132,8 @@ private: std::vector> _lastTopics; int _lastTopicsVersion = 0; + ForumTopic *_activeSubsectionTopic = nullptr; + rpl::event_stream<> _chatsListChanges; rpl::event_stream<> _chatsListLoadedEvents; diff --git a/Telegram/SourceFiles/data/data_saved_messages.cpp b/Telegram/SourceFiles/data/data_saved_messages.cpp index 8108530c3b..12f3e870b9 100644 --- a/Telegram/SourceFiles/data/data_saved_messages.cpp +++ b/Telegram/SourceFiles/data/data_saved_messages.cpp @@ -82,6 +82,20 @@ void SavedMessages::clear() { _owningHistory = nullptr; } +void SavedMessages::saveActiveSubsectionThread(not_null thread) { + if (const auto sublist = thread->asSublist()) { + Assert(sublist->parent() == this); + _activeSubsectionSublist = sublist; + } else { + Assert(thread == _owningHistory); + _activeSubsectionSublist = nullptr; + } +} + +Thread *SavedMessages::activeSubsectionThread() const { + return _activeSubsectionSublist; +} + SavedMessages::~SavedMessages() { clear(); } diff --git a/Telegram/SourceFiles/data/data_saved_messages.h b/Telegram/SourceFiles/data/data_saved_messages.h index 34800518b5..193dfc25d5 100644 --- a/Telegram/SourceFiles/data/data_saved_messages.h +++ b/Telegram/SourceFiles/data/data_saved_messages.h @@ -77,6 +77,9 @@ public: void clear(); + void saveActiveSubsectionThread(not_null thread); + Thread *activeSubsectionThread() const; + [[nodiscard]] rpl::lifetime &lifetime(); private: @@ -132,6 +135,8 @@ private: rpl::event_stream<> _chatsListChanges; rpl::event_stream<> _chatsListLoadedEvents; + SavedSublist *_activeSubsectionSublist = nullptr; + bool _pinnedLoaded = false; bool _unsupported = false; diff --git a/Telegram/SourceFiles/data/data_thread.cpp b/Telegram/SourceFiles/data/data_thread.cpp index 702aed3639..47a8f22232 100644 --- a/Telegram/SourceFiles/data/data_thread.cpp +++ b/Telegram/SourceFiles/data/data_thread.cpp @@ -7,9 +7,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/data_thread.h" +#include "data/data_forum.h" #include "data/data_forum_topic.h" #include "data/data_changes.h" +#include "data/data_channel.h" #include "data/data_peer.h" +#include "data/data_saved_messages.h" #include "data/data_saved_sublist.h" #include "history/history.h" #include "history/history_item.h" @@ -202,4 +205,16 @@ void Thread::setHasPinnedMessages(bool has) { EntryUpdate::Flag::HasPinnedMessages); } +void Thread::saveMeAsActiveSubsectionThread() { + if (const auto channel = owningHistory()->peer->asChannel()) { + if (channel->useSubsectionTabs()) { + if (const auto forum = channel->forum()) { + forum->saveActiveSubsectionThread(this); + } else if (const auto monoforum = channel->monoforum()) { + monoforum->saveActiveSubsectionThread(this); + } + } + } +} + } // namespace Data diff --git a/Telegram/SourceFiles/data/data_thread.h b/Telegram/SourceFiles/data/data_thread.h index 09a33f27da..42fd2dca06 100644 --- a/Telegram/SourceFiles/data/data_thread.h +++ b/Telegram/SourceFiles/data/data_thread.h @@ -120,6 +120,8 @@ public: [[nodiscard]] bool hasPinnedMessages() const; void setHasPinnedMessages(bool has); + void saveMeAsActiveSubsectionThread(); + protected: void setUnreadMarkFlag(bool unread); diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 1d578857d8..48f82bbd2e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -79,6 +79,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_changes.h" #include "data/data_download_manager.h" #include "data/data_chat_filters.h" +#include "data/data_saved_messages.h" #include "data/data_saved_sublist.h" #include "data/data_stories.h" #include "info/downloads/info_downloads_widget.h" @@ -920,7 +921,8 @@ void Widget::chosenRow(const ChosenRow &row) { && history->isForum() && !row.message.fullId && (!controller()->adaptive().isOneColumn() - || !history->peer->forum()->channel()->viewForumAsMessages())) { + || !history->peer->forum()->channel()->viewForumAsMessages() + || history->peer->forum()->channel()->useSubsectionTabs())) { const auto forum = history->peer->forum(); if (controller()->shownForum().current() == forum) { controller()->closeForum(); @@ -943,6 +945,26 @@ void Widget::chosenRow(const ChosenRow &row) { } } return; + } else if (history + && history->amMonoforumAdmin() + && !row.message.fullId) { + const auto monoforum = history->peer->monoforum(); + if (row.newWindow) { + controller()->showInNewWindow( + Window::SeparateId(Window::SeparateType::Chat, history)); + } else { + if (const auto active = monoforum->activeSubsectionThread()) { + controller()->showThread( + active, + ShowAtUnreadMsgId, + Window::SectionShow::Way::ClearStack); + } else { + controller()->showPeerHistory( + history, + Window::SectionShow::Way::ClearStack); + } + } + return; } else if (history) { const auto peer = history->peer; const auto showAtMsgId = controller()->uniqueChatsInSearchResults() diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 397b8bdc88..b468697738 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -4834,6 +4834,10 @@ void HistoryWidget::doneShow() { controller()->widget()->setInnerFocus(); _preserveScrollTop = false; checkSuggestToGigagroup(); + + if (_history) { + _history->saveMeAsActiveSubsectionThread(); + } } void HistoryWidget::cornerButtonsShowAtPosition( diff --git a/Telegram/SourceFiles/history/view/history_view_chat_section.cpp b/Telegram/SourceFiles/history/view/history_view_chat_section.cpp index c9421d8b25..6bbe275c07 100644 --- a/Telegram/SourceFiles/history/view/history_view_chat_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_chat_section.cpp @@ -2880,6 +2880,12 @@ void ChatWidget::showFinishedHook() { // because after that the method showChildren() is called. setupDragArea(); updatePinnedVisibility(); + + if (_topic) { + _topic->saveMeAsActiveSubsectionThread(); + } else if (_sublist) { + _sublist->saveMeAsActiveSubsectionThread(); + } } bool ChatWidget::floatPlayerHandleWheelEvent(QEvent *e) { diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 5a49bab04d..3e3a77260f 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -586,7 +586,8 @@ void SessionNavigation::showPeerByLinkResolved( if (const auto forum = peer->forum()) { if (controller->windowId().hasChatsList() && !controller->adaptive().isOneColumn() - && controller->shownForum().current() != forum) { + && controller->shownForum().current() != forum + && !forum->channel()->useSubsectionTabs()) { controller->showForum(forum); } } @@ -1878,7 +1879,11 @@ void SessionController::showForum( if (showForumInDifferentWindow(forum, params)) { return; } else if (forum->channel()->useSubsectionTabs()) { - showPeerHistory(forum->channel(), params); + if (const auto active = forum->activeSubsectionThread()) { + showThread(active, ShowAtUnreadMsgId, params); + } else { + showPeerHistory(forum->channel(), params); + } return; } _shownForumLifetime.destroy(); @@ -1992,9 +1997,9 @@ void SessionController::setActiveChatEntry(Dialogs::RowDescriptor row) { Data::PeerFlagValue( channel, ChannelData::Flag::Forum - ) | rpl::filter( - rpl::mappers::_1 - ) | rpl::start_with_next([=] { + ) | rpl::filter([=](bool forum) { + return forum && !channel->useSubsectionTabs(); + }) | rpl::start_with_next([=] { clearSectionStack( { anim::type::normal, anim::activation::background }); showForum(channel->forum(),