Allow opening monoforums.

This commit is contained in:
John Preston 2025-05-06 21:22:36 +04:00
parent d3f9a84a0a
commit 51878ab38e
14 changed files with 317 additions and 20 deletions

View file

@ -199,12 +199,18 @@ void ChannelData::setFlags(ChannelDataFlags which) {
// Let Data::Forum live till the end of _flags.set. // Let Data::Forum live till the end of _flags.set.
// That way the data can be used in changes handler. // That way the data can be used in changes handler.
// Example: render frame for forum auto-closing animation. // Example: render frame for forum auto-closing animation.
const auto taken = ((diff & Flag::Forum) && !(which & Flag::Forum)) const auto takenForum = ((diff & Flag::Forum) && !(which & Flag::Forum))
? mgInfo->takeForumData() ? mgInfo->takeForumData()
: nullptr; : nullptr;
const auto takenMonoforum = ((diff & Flag::Monoforum)
&& !(which & Flag::Monoforum))
? mgInfo->takeMonoforumData()
: nullptr;
const auto wasIn = amIn(); const auto wasIn = amIn();
if ((diff & Flag::Forum) && (which & Flag::Forum)) { if ((diff & Flag::Forum) && (which & Flag::Forum)) {
mgInfo->ensureForum(this); mgInfo->ensureForum(this);
} else if ((diff & Flag::Monoforum) && (which & Flag::Monoforum)) {
mgInfo->ensureMonoforum(this);
} }
_flags.set(which); _flags.set(which);
if (diff & (Flag::Left | Flag::Forbidden)) { if (diff & (Flag::Left | Flag::Forbidden)) {
@ -252,7 +258,7 @@ void ChannelData::setFlags(ChannelDataFlags which) {
} }
} }
} }
if (const auto raw = taken.get()) { if (const auto raw = takenForum.get()) {
owner().forumIcons().clearUserpicsReset(raw); owner().forumIcons().clearUserpicsReset(raw);
} }
} }

View file

@ -74,6 +74,10 @@ rpl::producer<> SavedMessages::chatsListChanges() const {
return _chatsListChanges.events(); return _chatsListChanges.events();
} }
rpl::producer<> SavedMessages::chatsListLoadedEvents() const {
return _chatsListLoadedEvents.events();
}
void SavedMessages::loadMore() { void SavedMessages::loadMore() {
_loadMoreScheduled = true; _loadMoreScheduled = true;
_loadMore.call(); _loadMore.call();
@ -104,6 +108,9 @@ void SavedMessages::sendLoadMore() {
).done([=](const MTPmessages_SavedDialogs &result) { ).done([=](const MTPmessages_SavedDialogs &result) {
apply(result, false); apply(result, false);
_chatsListChanges.fire({}); _chatsListChanges.fire({});
if (_chatsList.loaded()) {
_chatsListLoadedEvents.fire({});
}
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
if (error.type() == u"SAVED_DIALOGS_UNSUPPORTED"_q) { if (error.type() == u"SAVED_DIALOGS_UNSUPPORTED"_q) {
_unsupported = true; _unsupported = true;
@ -321,6 +328,23 @@ void SavedMessages::apply(const MTPDupdateSavedDialogPinned &update) {
}); });
} }
rpl::producer<> SavedMessages::destroyed() const {
if (!_parentChat) {
return rpl::never<>();
}
return _parentChat->flagsValue(
) | rpl::filter([=](const ChannelData::Flags::Change &update) {
using Flag = ChannelData::Flag;
return (update.diff & Flag::Monoforum)
&& !(update.value & Flag::Monoforum);
}) | rpl::take(1) | rpl::to_empty;
}
auto SavedMessages::sublistDestroyed() const
-> rpl::producer<not_null<SavedSublist*>> {
return _sublistDestroyed.events();
}
rpl::lifetime &SavedMessages::lifetime() { rpl::lifetime &SavedMessages::lifetime() {
return _lifetime; return _lifetime;
} }

View file

@ -35,6 +35,11 @@ public:
[[nodiscard]] not_null<SavedSublist*> sublist(not_null<PeerData*> peer); [[nodiscard]] not_null<SavedSublist*> sublist(not_null<PeerData*> peer);
[[nodiscard]] rpl::producer<> chatsListChanges() const; [[nodiscard]] rpl::producer<> chatsListChanges() const;
[[nodiscard]] rpl::producer<> chatsListLoadedEvents() const;
[[nodiscard]] rpl::producer<> destroyed() const;
[[nodiscard]] auto sublistDestroyed() const
-> rpl::producer<not_null<SavedSublist*>>;
void loadMore(); void loadMore();
void loadMore(not_null<SavedSublist*> sublist); void loadMore(not_null<SavedSublist*> sublist);
@ -55,6 +60,8 @@ private:
const not_null<Session*> _owner; const not_null<Session*> _owner;
ChannelData *_parentChat = nullptr; ChannelData *_parentChat = nullptr;
rpl::event_stream<not_null<SavedSublist*>> _sublistDestroyed;
Dialogs::MainList _chatsList; Dialogs::MainList _chatsList;
base::flat_map< base::flat_map<
not_null<PeerData*>, not_null<PeerData*>,
@ -73,6 +80,7 @@ private:
bool _loadMoreScheduled = false; bool _loadMoreScheduled = false;
rpl::event_stream<> _chatsListChanges; rpl::event_stream<> _chatsListChanges;
rpl::event_stream<> _chatsListLoadedEvents;
bool _pinnedLoaded = false; bool _pinnedLoaded = false;
bool _unsupported = false; bool _unsupported = false;

View file

@ -781,6 +781,47 @@ void InnerWidget::changeOpenedForum(Data::Forum *forum) {
} }
} }
void InnerWidget::changeOpenedMonoforum(Data::SavedMessages *monoforum) {
if (_savedSublists == monoforum) {
return;
}
stopReorderPinned();
clearSelection();
if (monoforum) {
saveChatsFilterScrollState(_filterId);
}
_filterId = monoforum
? 0
: _controller->activeChatsFilterCurrent();
if (_openedForum) {
// If we close it inside forum destruction we should not schedule.
session().data().forumIcons().scheduleUserpicsReset(_openedForum);
}
_savedSublists = monoforum;
_st = &st::defaultDialogRow;
refreshShownList();
_openedForumLifetime.destroy();
if (monoforum) {
rpl::merge(
monoforum->chatsListChanges(),
monoforum->chatsListLoadedEvents()
) | rpl::start_with_next([=] {
refresh();
}, _openedForumLifetime);
}
refreshWithCollapsedRows(true);
if (_loadMoreCallback) {
_loadMoreCallback();
}
if (!monoforum) {
restoreChatsFilterScrollState(_filterId);
}
}
void InnerWidget::showSavedSublists(ChannelData *parentChat) { void InnerWidget::showSavedSublists(ChannelData *parentChat) {
Expects(!parentChat || parentChat->monoforum()); Expects(!parentChat || parentChat->monoforum());
Expects(!_geometryInited); Expects(!_geometryInited);

View file

@ -141,6 +141,7 @@ public:
void changeOpenedFolder(Data::Folder *folder); void changeOpenedFolder(Data::Folder *folder);
void changeOpenedForum(Data::Forum *forum); void changeOpenedForum(Data::Forum *forum);
void changeOpenedMonoforum(Data::SavedMessages *monoforum);
void showSavedSublists(ChannelData *parentChat); void showSavedSublists(ChannelData *parentChat);
void selectSkip(int32 direction); void selectSkip(int32 direction);
void selectSkipPage(int32 pixels, int32 direction); void selectSkipPage(int32 pixels, int32 direction);

View file

@ -28,7 +28,7 @@ MainList::MainList(
std::move( std::move(
pinnedLimit pinnedLimit
) | rpl::start_with_next([=](int limit) { ) | rpl::start_with_next([=](int limit) {
_pinned.setLimit(limit); _pinned.setLimit(std::max(limit, 1));
}, _lifetime); }, _lifetime);
session->changes().realtimeNameUpdates( session->changes().realtimeNameUpdates(

View file

@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_contact_status.h" #include "history/view/history_view_contact_status.h"
#include "history/view/history_view_requests_bar.h" #include "history/view/history_view_requests_bar.h"
#include "history/view/history_view_group_call_bar.h" #include "history/view/history_view_group_call_bar.h"
#include "history/view/history_view_sublist_section.h"
#include "boxes/peers/edit_peer_requests_box.h" #include "boxes/peers/edit_peer_requests_box.h"
#include "ui/text/text_utilities.h" #include "ui/text/text_utilities.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
@ -78,6 +79,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h" #include "data/data_changes.h"
#include "data/data_download_manager.h" #include "data/data_download_manager.h"
#include "data/data_chat_filters.h" #include "data/data_chat_filters.h"
#include "data/data_saved_messages.h"
#include "data/data_saved_sublist.h" #include "data/data_saved_sublist.h"
#include "data/data_stories.h" #include "data/data_stories.h"
#include "info/downloads/info_downloads_widget.h" #include "info/downloads/info_downloads_widget.h"
@ -418,6 +420,8 @@ Widget::Widget(
) | rpl::filter([=](const Data::HistoryUpdate &update) { ) | rpl::filter([=](const Data::HistoryUpdate &update) {
if (_openedForum) { if (_openedForum) {
return (update.history == _openedForum->history()); return (update.history == _openedForum->history());
} else if (_openedMonoforum) {
return (update.history->peer == _openedMonoforum->parentChat());
} else if (_openedFolder) { } else if (_openedFolder) {
return (update.history->folder() == _openedFolder) return (update.history->folder() == _openedFolder)
&& !update.history->isPinnedDialog(FilterId()); && !update.history->isPinnedDialog(FilterId());
@ -596,6 +600,7 @@ Widget::Widget(
_search->setFocusFast(); _search->setFocusFast();
if (_childList) { if (_childList) {
controller->closeForum(); controller->closeForum();
controller->closeMonoforum();
} }
}); });
@ -618,6 +623,8 @@ Widget::Widget(
searchMore(); searchMore();
} else if (_openedForum && state == WidgetState::Default) { } else if (_openedForum && state == WidgetState::Default) {
_openedForum->requestTopics(); _openedForum->requestTopics();
} else if (_openedMonoforum && state == WidgetState::Default) {
_openedMonoforum->loadMore();
} else { } else {
const auto folder = _inner->shownFolder(); const auto folder = _inner->shownFolder();
if (!folder || !folder->chatsList()->loaded()) { if (!folder || !folder->chatsList()->loaded()) {
@ -666,7 +673,16 @@ Widget::Widget(
) | rpl::filter(!rpl::mappers::_1) | rpl::start_with_next([=] { ) | rpl::filter(!rpl::mappers::_1) | rpl::start_with_next([=] {
if (_openedForum) { if (_openedForum) {
changeOpenedForum(nullptr, anim::type::normal); changeOpenedForum(nullptr, anim::type::normal);
} else if (_childList) { } else if (_childList && !_childList->openedMonoforum()) {
closeChildList(anim::type::normal);
}
}, lifetime());
controller->shownMonoforum().changes(
) | rpl::filter(!rpl::mappers::_1) | rpl::start_with_next([=] {
if (_openedMonoforum) {
changeOpenedMonoforum(nullptr, anim::type::normal);
} else if (_childList && !_childList->openedForum()) {
closeChildList(anim::type::normal); closeChildList(anim::type::normal);
} }
}, lifetime()); }, lifetime());
@ -795,7 +811,7 @@ void Widget::setupSwipeBack() {
} }
}); });
} }
if (controller()->shownForum().current()) { if (controller()->shownForum().current()) { // #TODO monoforum
if (!isRightToLeft) { if (!isRightToLeft) {
return Ui::Controls::SwipeHandlerFinishData(); return Ui::Controls::SwipeHandlerFinishData();
} }
@ -924,6 +940,26 @@ void Widget::chosenRow(const ChosenRow &row) {
} }
} }
return; return;
} else if (history
&& history->isMonoforum()
&& !row.message.fullId
&& !controller()->adaptive().isOneColumn()) {
const auto monoforum = history->peer->monoforum();
if (controller()->shownMonoforum().current() == monoforum) {
controller()->closeMonoforum();
//} else if (row.newWindow) { // #TODO monoforum
// controller()->showInNewWindow(
// Window::SeparateId(Window::SeparateType::Forum, history));
} else {
controller()->showMonoforum(
monoforum,
Window::SectionShow().withChildColumn());
controller()->showThread(
history,
ShowAtUnreadMsgId,
Window::SectionShow::Way::ClearStack);
}
return;
} else if (history) { } else if (history) {
const auto peer = history->peer; const auto peer = history->peer;
const auto showAtMsgId = controller()->uniqueChatsInSearchResults() const auto showAtMsgId = controller()->uniqueChatsInSearchResults()
@ -958,6 +994,13 @@ void Widget::chosenRow(const ChosenRow &row) {
} }
controller()->openFolder(folder); controller()->openFolder(folder);
hideChildList(); hideChildList();
} else if (const auto sublist = row.key.sublist()) {
using namespace Window;
auto params = SectionShow(SectionShow::Way::Forward);
params.dropSameFromStack = true;
controller()->showSection(
std::make_shared<HistoryView::SublistMemento>(sublist),
params);
} }
if (row.filteredRow && !session().supportMode()) { if (row.filteredRow && !session().supportMode()) {
if (_subsectionTopBar) { if (_subsectionTopBar) {
@ -1032,7 +1075,8 @@ void Widget::setupTopBarSuggestions(not_null<Ui::VerticalLayout*> dialogs) {
) | rpl::filter(_1 == nullptr) | rpl::map([=] { ) | rpl::filter(_1 == nullptr) | rpl::map([=] {
auto on = rpl::combine( auto on = rpl::combine(
controller()->activeChatsFilter(), controller()->activeChatsFilter(),
_openedFolderOrForumChanges.events_starting_with(false), _openedFolderOrForumOrMonoforumChanges.events_starting_with(
false),
widthValue() | rpl::map( widthValue() | rpl::map(
_1 >= st::columnMinimalWidthLeft _1 >= st::columnMinimalWidthLeft
) | rpl::distinct_until_changed(), ) | rpl::distinct_until_changed(),
@ -1041,11 +1085,11 @@ void Widget::setupTopBarSuggestions(not_null<Ui::VerticalLayout*> dialogs) {
_jumpToDate->toggledValue() _jumpToDate->toggledValue()
) | rpl::map([=]( ) | rpl::map([=](
FilterId id, FilterId id,
bool folderOrForum, bool folderOrForumOrMonoforum,
bool wide, bool wide,
bool search, bool search,
bool searchInPeer) { bool searchInPeer) {
return !folderOrForum return !folderOrForumOrMonoforum
&& wide && wide
&& !search && !search
&& !searchInPeer && !searchInPeer
@ -1102,7 +1146,8 @@ void Widget::updateFrozenAccountBar() {
void Widget::updateTopBarSuggestions() { void Widget::updateTopBarSuggestions() {
if (_topBarSuggestion) { if (_topBarSuggestion) {
_openedFolderOrForumChanges.fire(_openedForum || _openedFolder); _openedFolderOrForumOrMonoforumChanges.fire(
_openedFolder || _openedForum || _openedMonoforum);
} }
} }
@ -1540,7 +1585,7 @@ void Widget::updateControlsVisibility(bool fast) {
if (_chatFilters) { if (_chatFilters) {
_chatFilters->setVisible(!_openedForum); _chatFilters->setVisible(!_openedForum);
} }
if (_openedFolder || _openedForum) { if (_openedFolder || _openedForum || _openedMonoforum) {
_subsectionTopBar->show(); _subsectionTopBar->show();
if (_forumTopShadow) { if (_forumTopShadow) {
_forumTopShadow->show(); _forumTopShadow->show();
@ -1919,6 +1964,29 @@ void Widget::changeOpenedForum(Data::Forum *forum, anim::type animated) {
}, (forum != nullptr), animated); }, (forum != nullptr), animated);
} }
void Widget::changeOpenedMonoforum(
Data::SavedMessages *monoforum,
anim::type animated) {
if (_openedMonoforum == monoforum) {
return;
}
changeOpenedSubsection([&] {
cancelSearch({ .forceFullCancel = true });
closeChildList(anim::type::instant);
_openedMonoforum = monoforum;
_searchState.tab = monoforum
? ChatSearchTab::ThisPeer
: ChatSearchTab::MyMessages;
_searchWithPostsPreview = computeSearchWithPostsPreview();
_api.request(base::take(_topicSearchRequest)).cancel();
_inner->changeOpenedMonoforum(monoforum);
storiesToggleExplicitExpand(false);
updateFrozenAccountBar();
updateTopBarSuggestions();
updateStoriesVisibility();
}, (monoforum != nullptr), animated);
}
void Widget::hideChildList() { void Widget::hideChildList() {
if (_childList) { if (_childList) {
controller()->closeForum(); controller()->closeForum();
@ -1926,7 +1994,7 @@ void Widget::hideChildList() {
} }
void Widget::refreshTopBars() { void Widget::refreshTopBars() {
if (_openedFolder || _openedForum) { if (_openedFolder || _openedForum || _openedMonoforum) {
if (!_subsectionTopBar) { if (!_subsectionTopBar) {
_subsectionTopBar.create(this, controller()); _subsectionTopBar.create(this, controller());
if (_stories) { if (_stories) {
@ -1956,10 +2024,12 @@ void Widget::refreshTopBars() {
} }
const auto history = _openedForum const auto history = _openedForum
? _openedForum->history().get() ? _openedForum->history().get()
: _openedMonoforum
? session().data().history(_openedMonoforum->parentChat()).get()
: nullptr; : nullptr;
_subsectionTopBar->setActiveChat( _subsectionTopBar->setActiveChat(
HistoryView::TopBarWidget::ActiveChat{ HistoryView::TopBarWidget::ActiveChat{
.key = (_openedForum .key = ((_openedForum || _openedMonoforum)
? Dialogs::Key(history) ? Dialogs::Key(history)
: Dialogs::Key(_openedFolder)), : Dialogs::Key(_openedFolder)),
.section = Dialogs::EntryState::Section::ChatsList, .section = Dialogs::EntryState::Section::ChatsList,
@ -2121,6 +2191,14 @@ bool Widget::searchHasFocus() const {
return _searchHasFocus; return _searchHasFocus;
} }
Data::Forum *Widget::openedForum() const {
return _openedForum;
}
Data::SavedMessages *Widget::openedMonoforum() const {
return _openedMonoforum;
}
void Widget::jumpToTop(bool belowPinned) { void Widget::jumpToTop(bool belowPinned) {
if (session().supportMode()) { if (session().supportMode()) {
return; return;
@ -3283,12 +3361,33 @@ void Widget::showForum(
return; return;
} }
cancelSearch({ .forceFullCancel = true }); cancelSearch({ .forceFullCancel = true });
openChildList(forum, params); openChildList(forum, nullptr, params);
}
void Widget::showMonoforum(
not_null<Data::SavedMessages*> monoforum,
const Window::SectionShow &params) {
if (_openedMonoforum == monoforum) {
return;
}
const auto nochat = !controller()->mainSectionShown();
if (!params.childColumn
|| (Core::App().settings().dialogsWidthRatio(nochat) == 0.)
|| (_layout != Layout::Main)
|| OptionForumHideChatsList.value()) {
changeOpenedMonoforum(monoforum, params.animated);
return;
}
cancelSearch({ .forceFullCancel = true });
openChildList(nullptr, monoforum, params);
} }
void Widget::openChildList( void Widget::openChildList(
not_null<Data::Forum*> forum, Data::Forum *forum,
Data::SavedMessages *monoforum,
const Window::SectionShow &params) { const Window::SectionShow &params) {
Expects(forum || monoforum);
auto slide = Window::SectionSlideParams(); auto slide = Window::SectionSlideParams();
const auto animated = !_childList const auto animated = !_childList
&& (params.animated == anim::type::normal); && (params.animated == anim::type::normal);
@ -3309,8 +3408,13 @@ void Widget::openChildList(
this, this,
controller(), controller(),
Layout::Child); Layout::Child);
_childList->showForum(forum, copy); if (forum) {
_childListPeerId = forum->channel()->id; _childList->showForum(forum, copy);
_childListPeerId = forum->channel()->id;
} else {
_childList->showMonoforum(monoforum, copy);
_childListPeerId = monoforum->parentChat()->id;
}
} }
_childListShadow = std::make_unique<Ui::RpWidget>(this); _childListShadow = std::make_unique<Ui::RpWidget>(this);

View file

@ -23,6 +23,7 @@ class Error;
namespace Data { namespace Data {
class Forum; class Forum;
class SavedMessages;
enum class StorySourcesList : uchar; enum class StorySourcesList : uchar;
struct ReactionId; struct ReactionId;
} // namespace Data } // namespace Data
@ -108,9 +109,15 @@ public:
void showForum( void showForum(
not_null<Data::Forum*> forum, not_null<Data::Forum*> forum,
const Window::SectionShow &params); const Window::SectionShow &params);
void showMonoforum(
not_null<Data::SavedMessages*> monoforum,
const Window::SectionShow &params);
void setInnerFocus(bool unfocusSearch = false); void setInnerFocus(bool unfocusSearch = false);
[[nodiscard]] bool searchHasFocus() const; [[nodiscard]] bool searchHasFocus() const;
[[nodiscard]] Data::Forum *openedForum() const;
[[nodiscard]] Data::SavedMessages *openedMonoforum() const;
void jumpToTop(bool belowPinned = false); void jumpToTop(bool belowPinned = false);
void raiseWithTooltip(); void raiseWithTooltip();
@ -247,6 +254,9 @@ private:
anim::type animated); anim::type animated);
void changeOpenedFolder(Data::Folder *folder, anim::type animated); void changeOpenedFolder(Data::Folder *folder, anim::type animated);
void changeOpenedForum(Data::Forum *forum, anim::type animated); void changeOpenedForum(Data::Forum *forum, anim::type animated);
void changeOpenedMonoforum(
Data::SavedMessages *monoforum,
anim::type animated);
void hideChildList(); void hideChildList();
void destroyChildListCanvas(); void destroyChildListCanvas();
[[nodiscard]] QPixmap grabForFolderSlideAnimation(); [[nodiscard]] QPixmap grabForFolderSlideAnimation();
@ -256,7 +266,8 @@ private:
Window::SlideDirection direction); Window::SlideDirection direction);
void openChildList( void openChildList(
not_null<Data::Forum*> forum, Data::Forum *forum,
Data::SavedMessages *monoforum,
const Window::SectionShow &params); const Window::SectionShow &params);
void closeChildList(anim::type animated); void closeChildList(anim::type animated);
@ -332,7 +343,7 @@ private:
Ui::SlideWrap<Ui::RpWidget> *_topBarSuggestion = nullptr; Ui::SlideWrap<Ui::RpWidget> *_topBarSuggestion = nullptr;
rpl::event_stream<int> _topBarSuggestionHeightChanged; rpl::event_stream<int> _topBarSuggestionHeightChanged;
rpl::event_stream<bool> _searchStateForTopBarSuggestion; rpl::event_stream<bool> _searchStateForTopBarSuggestion;
rpl::event_stream<bool> _openedFolderOrForumChanges; rpl::event_stream<bool> _openedFolderOrForumOrMonoforumChanges;
object_ptr<Ui::ElasticScroll> _scroll; object_ptr<Ui::ElasticScroll> _scroll;
QPointer<InnerWidget> _inner; QPointer<InnerWidget> _inner;
@ -358,6 +369,7 @@ private:
Data::Folder *_openedFolder = nullptr; Data::Folder *_openedFolder = nullptr;
Data::Forum *_openedForum = nullptr; Data::Forum *_openedForum = nullptr;
Data::SavedMessages *_openedMonoforum = nullptr;
SearchState _searchState; SearchState _searchState;
History *_searchInMigrated = nullptr; History *_searchInMigrated = nullptr;
rpl::lifetime _searchTagsLifetime; rpl::lifetime _searchTagsLifetime;

View file

@ -762,6 +762,10 @@ void TopBarWidget::backClicked() {
&& _activeChat.key.history() && _activeChat.key.history()
&& _activeChat.key.history()->isForum()) { && _activeChat.key.history()->isForum()) {
_controller->closeForum(); _controller->closeForum();
} else if (_activeChat.section == Section::ChatsList
&& _activeChat.key.history()
&& _activeChat.key.history()->isMonoforum()) {
_controller->closeMonoforum();
} else { } else {
_controller->showBackFromStack(); _controller->showBackFromStack();
} }

View file

@ -2183,6 +2183,23 @@ Ui::MultiSlideTracker DetailsFiller::fillChannelButtons(
std::move(viewChannel), std::move(viewChannel),
tracker); tracker);
auto viewDirectVisible = channel->flagsValue() | rpl::map([=] {
return channel->monoforumLink() != nullptr;
}) | rpl::distinct_until_changed();
auto viewDirect = [=] {
if (const auto linked = channel->monoforumLink()) {
if (const auto monoforum = linked->monoforum()) {
window->showMonoforum(monoforum);
}
}
};
AddMainButton( // #TODO monoforum
_wrap,
rpl::single(u"View Direct Messages"_q),
std::move(viewDirectVisible),
std::move(viewDirect),
tracker);
return tracker; return tracker;
} }

View file

@ -1565,6 +1565,18 @@ void MainWidget::showForum(
} }
} }
void MainWidget::showMonoforum(
not_null<Data::SavedMessages*> monoforum,
const SectionShow &params) {
Expects(_dialogs != nullptr);
_dialogs->showMonoforum(monoforum, params);
if (params.activation != anim::activation::background) {
_controller->window().hideSettingsAndLayer();
}
}
PeerData *MainWidget::peer() const { PeerData *MainWidget::peer() const {
return _history->peer(); return _history->peer();
} }

View file

@ -32,6 +32,7 @@ class Thread;
class WallPaper; class WallPaper;
struct ForwardDraft; struct ForwardDraft;
class Forum; class Forum;
class SavedMessages;
struct ReportInput; struct ReportInput;
} // namespace Data } // namespace Data
@ -198,6 +199,9 @@ public:
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
const SectionShow &params); const SectionShow &params);
void showForum(not_null<Data::Forum*> forum, const SectionShow &params); void showForum(not_null<Data::Forum*> forum, const SectionShow &params);
void showMonoforum(
not_null<Data::SavedMessages*> monoforum,
const SectionShow &params);
bool notify_switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot, MsgId samePeerReplyTo); bool notify_switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot, MsgId samePeerReplyTo);

View file

@ -603,10 +603,15 @@ void SessionNavigation::showPeerByLinkResolved(
showPeerInfo(peer, params); showPeerInfo(peer, params);
} else if (resolveType == ResolveType::HashtagSearch) { } else if (resolveType == ResolveType::HashtagSearch) {
searchMessages(info.text, peer->owner().history(peer)); searchMessages(info.text, peer->owner().history(peer));
} else if (peer->isForum() && resolveType != ResolveType::Boost) { } else if ((peer->isForum() || peer->isMonoforum())
&& resolveType != ResolveType::Boost) {
const auto itemId = info.messageId; const auto itemId = info.messageId;
if (!itemId) { if (!itemId) {
parentController()->showForum(peer->forum(), params); if (peer->isForum()) {
parentController()->showForum(peer->forum(), params);
} else {
parentController()->showMonoforum(peer->monoforum(), params);
}
} else if (const auto item = peer->owner().message(peer, itemId)) { } else if (const auto item = peer->owner().message(peer, itemId)) {
showMessageByLinkResolved(item, info); showMessageByLinkResolved(item, info);
} else { } else {
@ -1924,6 +1929,56 @@ const rpl::variable<Data::Forum*> &SessionController::shownForum() const {
return _shownForum; return _shownForum;
} }
void SessionController::showMonoforum(
not_null<Data::SavedMessages*> monoforum,
const SectionShow &params) {
// if (showForumInDifferentWindow(forum, params)) {
// return;
// }
_shownMonoforumLifetime.destroy();
if (_shownMonoforum.current() != monoforum) {
resetFakeUnreadWhileOpened();
}
if (monoforum
&& _activeChatEntry.current().key.peer()
&& adaptive().isOneColumn()) {
clearSectionStack(params);
}
_shownMonoforum = monoforum.get();
if (_shownMonoforum.current() != monoforum) {
return;
}
monoforum->destroyed(
) | rpl::start_with_next([=] {
closeMonoforum();
}, _shownMonoforumLifetime);
content()->showMonoforum(monoforum, params);
}
void SessionController::closeMonoforum() {
if (const auto monoforum = _shownMonoforum.current()) {
const auto id = windowId();
if (id.type == SeparateType::SavedSublist) {
const auto initial = id.parentChat;
if (!initial
|| !initial->monoforum()
|| initial == monoforum->parentChat()) {
Core::App().closeWindow(_window);
} else {
showMonoforum(initial->monoforum());
}
return;
}
}
_shownMonoforumLifetime.destroy();
_shownMonoforum = nullptr;
}
auto SessionController::shownMonoforum() const
-> const rpl::variable<Data::SavedMessages*> & {
return _shownMonoforum;
}
void SessionController::setActiveChatEntry(Dialogs::RowDescriptor row) { void SessionController::setActiveChatEntry(Dialogs::RowDescriptor row) {
if (windowId().type == SeparateType::SharedMedia) { if (windowId().type == SeparateType::SharedMedia) {
return; return;

View file

@ -26,6 +26,7 @@ enum class WindowLayout;
namespace Data { namespace Data {
struct StoriesContext; struct StoriesContext;
class SavedMessages;
enum class StorySourcesList : uchar; enum class StorySourcesList : uchar;
} // namespace Data } // namespace Data
@ -405,6 +406,12 @@ public:
void closeForum(); void closeForum();
const rpl::variable<Data::Forum*> &shownForum() const; const rpl::variable<Data::Forum*> &shownForum() const;
void showMonoforum(
not_null<Data::SavedMessages*> monoforum,
const SectionShow &params = SectionShow::Way::ClearStack);
void closeMonoforum();
const rpl::variable<Data::SavedMessages*> &shownMonoforum() const;
void setActiveChatEntry(Dialogs::RowDescriptor row); void setActiveChatEntry(Dialogs::RowDescriptor row);
void setActiveChatEntry(Dialogs::Key key); void setActiveChatEntry(Dialogs::Key key);
Dialogs::RowDescriptor activeChatEntryCurrent() const; Dialogs::RowDescriptor activeChatEntryCurrent() const;
@ -746,6 +753,8 @@ private:
rpl::variable<Data::Folder*> _openedFolder; rpl::variable<Data::Folder*> _openedFolder;
rpl::variable<Data::Forum*> _shownForum; rpl::variable<Data::Forum*> _shownForum;
rpl::lifetime _shownForumLifetime; rpl::lifetime _shownForumLifetime;
rpl::variable<Data::SavedMessages*> _shownMonoforum;
rpl::lifetime _shownMonoforumLifetime;
rpl::event_stream<> _filtersMenuChanged; rpl::event_stream<> _filtersMenuChanged;