diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index bcb2062e33..8843d4dbbd 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -995,7 +995,12 @@ void Widget::chosenRow(const ChosenRow &row) { && !row.message.fullId && history->peer->asChannel() && history->peer->asChannel()->isCommunity()) { - if (const auto info = history->peer->asChannel()->communityInfo()) { + if (row.newWindow) { + controller()->showInNewWindow(Window::SeparateId( + Window::SeparateType::Community, + history)); + } else if (const auto info + = history->peer->asChannel()->communityInfo()) { if (controller()->openedCommunity().current() == info) { controller()->closeCommunity(); } else { diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 356d215c21..25206572d4 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -723,6 +723,24 @@ void Filler::addNewWindow(bool addSeparator) { } return; } + if (const auto channel = _peer ? _peer->asChannel() : nullptr) { + if (channel->isCommunity()) { + const auto history = channel->owner().history(channel); + const auto weak = base::make_weak(history); + _addAction(tr::lng_context_new_window(tr::now), [=] { + Ui::PreventDelayedActivation(); + if (const auto strong = weak.get()) { + controller->showInNewWindow(SeparateId( + SeparateType::Community, + strong)); + } + }, &st::menuIconNewWindow); + if (addSeparator) { + AddSeparatorAndShiftUp(_addAction); + } + return; + } + } const auto history = _request.key.history(); if (!_peer || (history diff --git a/Telegram/SourceFiles/window/window_separate_id.cpp b/Telegram/SourceFiles/window/window_separate_id.cpp index f6ed9155fd..5a4080108a 100644 --- a/Telegram/SourceFiles/window/window_separate_id.cpp +++ b/Telegram/SourceFiles/window/window_separate_id.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_separate_id.h" #include "data/data_channel.h" +#include "data/data_community.h" #include "data/data_folder.h" #include "data/data_peer.h" #include "data/data_saved_messages.h" @@ -78,10 +79,19 @@ Data::SavedSublist *SeparateId::sublist() const { : thread->asSublist(); } +Data::CommunityInfo *SeparateId::community() const { + if (type != SeparateType::Community || !thread) { + return nullptr; + } + const auto channel = thread->peer()->asChannel(); + return channel ? channel->communityInfo() : nullptr; +} + bool SeparateId::hasChatsList() const { return (type == SeparateType::Primary) || (type == SeparateType::Archive) - || (type == SeparateType::Forum); + || (type == SeparateType::Forum) + || (type == SeparateType::Community); } } // namespace Window diff --git a/Telegram/SourceFiles/window/window_separate_id.h b/Telegram/SourceFiles/window/window_separate_id.h index dbc79397a5..c5e8b67700 100644 --- a/Telegram/SourceFiles/window/window_separate_id.h +++ b/Telegram/SourceFiles/window/window_separate_id.h @@ -15,6 +15,7 @@ class Thread; class Folder; class Forum; class SavedSublist; +class CommunityInfo; } // namespace Data namespace Main { @@ -33,6 +34,7 @@ enum class SeparateType { Archive, Chat, Forum, + Community, SavedSublist, SharedMedia, }; @@ -69,6 +71,7 @@ struct SeparateId { [[nodiscard]] Data::Forum *forum() const; [[nodiscard]] Data::Folder *folder() const; [[nodiscard]] Data::SavedSublist *sublist() const; + [[nodiscard]] Data::CommunityInfo *community() const; [[nodiscard]] bool hasChatsList() const; diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 1cdc9bb42e..66f4db93a9 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -1431,6 +1431,12 @@ void SessionNavigation::showByInitialId( clearSectionStack(instant); parent->showForum(id.forum(), instant); break; + case SeparateType::Community: + clearSectionStack(instant); + if (const auto info = id.community()) { + parent->openCommunity(info); + } + break; case SeparateType::Primary: clearSectionStack(instant); break; @@ -1559,6 +1565,7 @@ SessionController::SessionController( , _invitePeekTimer([=] { checkInvitePeek(); }) , _activeChatsFilter(session->data().chatsFilters().defaultId()) , _openedFolder(window->id().folder()) +, _openedCommunity(window->id().community()) , _defaultChatTheme(std::make_shared()) , _chatStyle(std::make_unique(session->colorIndicesValue())) { init(); @@ -2096,26 +2103,33 @@ void SessionController::openCommunity(not_null info) { } _openedCommunityLifetime.destroy(); - using FlagChange = Data::Flags::Change; - info->channel()->flagsValue( - ) | rpl::on_next([=](FlagChange change) { - if (change.diff & ChannelDataFlag::CommunityCollapsed) { - if (!info->collapsedInDialogs()) { - closeCommunity(); + if (windowId().type != SeparateType::Community) { + using FlagChange = Data::Flags::Change; + info->channel()->flagsValue( + ) | rpl::on_next([=](FlagChange change) { + if (change.diff & ChannelDataFlag::CommunityCollapsed) { + if (!info->collapsedInDialogs()) { + closeCommunity(); + } } - } - }, _openedCommunityLifetime); - info->chatsList()->fullSize().value( - ) | rpl::skip( - 1 - ) | rpl::filter( - rpl::mappers::_1 == 0 - ) | rpl::on_next([=] { - closeCommunity(); - }, _openedCommunityLifetime); + }, _openedCommunityLifetime); + info->chatsList()->fullSize().value( + ) | rpl::skip( + 1 + ) | rpl::filter( + rpl::mappers::_1 == 0 + ) | rpl::on_next([=] { + closeCommunity(); + }, _openedCommunityLifetime); + } } void SessionController::closeCommunity() { + if (_openedCommunity.current() + && windowId().type == SeparateType::Community) { + Core::App().closeWindow(_window); + return; + } _openedCommunityLifetime.destroy(); _openedCommunity = nullptr; }