diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 789f2fa409..846ac5d828 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -5044,7 +5044,7 @@ bool InnerWidget::archiveSearchActive() const { } bool InnerWidget::communitySearchActive() const { - return _openedCommunity + return (_openedCommunity || _searchState.community) && ((_searchState.tab == ChatSearchTab::ThisCommunity) || !QStringView(_searchState.query).trimmed().isEmpty()); } @@ -5115,8 +5115,13 @@ void InnerWidget::updateSearchIn() { const auto archiveIcon = (_openedFolder && !_searchState.inChat) ? Ui::MakeIconThumbnail(st::menuIconArchive) : nullptr; - const auto communityIcon = (_openedCommunity && !_searchState.inChat) - ? Ui::MakeUserpicThumbnail(_openedCommunity->channel()) + const auto communityChannel = _searchState.community + ? _searchState.community + : _openedCommunity + ? _openedCommunity->channel().get() + : nullptr; + const auto communityIcon = (communityChannel && !_searchState.inChat) + ? Ui::MakeUserpicThumbnail(communityChannel) : nullptr; const auto publicIcon = (_searchHashOrCashtag != HashOrCashtag::None) ? Ui::MakeIconThumbnail(st::menuIconChannel) diff --git a/Telegram/SourceFiles/dialogs/dialogs_key.h b/Telegram/SourceFiles/dialogs/dialogs_key.h index f74fba9815..31ec96f925 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_key.h +++ b/Telegram/SourceFiles/dialogs/dialogs_key.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class History; class PeerData; +class ChannelData; namespace Data { class Thread; @@ -141,6 +142,7 @@ enum class ChatTypeFilter : uchar { struct SearchState { Key inChat; PeerData *fromPeer = nullptr; + ChannelData *community = nullptr; std::vector tags; ChatSearchTab tab = {}; ChatTypeFilter filter = ChatTypeFilter::All; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index c797633161..e0e2c7b386 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -2935,6 +2935,11 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) { const auto fromPeer = searchFromPeer(); const auto &inTags = searchInTags(); const auto tab = _searchState.tab; + const auto community = _searchState.community + ? _searchState.community + : _openedCommunity + ? _openedCommunity->channel().get() + : nullptr; const auto filter = _searchState.filter; const auto fromStartType = SearchRequestType{ .start = true, @@ -2978,9 +2983,7 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) { _searchQueryFrom = fromPeer; _searchQueryTags = inTags; _searchQueryTab = tab; - _searchQueryCommunity = _openedCommunity - ? _openedCommunity->channel().get() - : nullptr; + _searchQueryCommunity = community; _searchQueryFilter = filter; process->nextRate = 0; process->full = false; @@ -2993,15 +2996,14 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) { || _searchQueryFrom != fromPeer || _searchQueryTags != inTags || _searchQueryTab != tab + || _searchQueryCommunity != community || _searchQueryFilter != filter) { const auto process = currentSearchProcess(); _searchQuery = query; _searchQueryFrom = fromPeer; _searchQueryTags = inTags; _searchQueryTab = tab; - _searchQueryCommunity = _openedCommunity - ? _openedCommunity->channel().get() - : nullptr; + _searchQueryCommunity = community; _searchQueryFilter = filter; process->nextRate = 0; process->full = false; @@ -3135,6 +3137,15 @@ void Widget::searchMessages(SearchState state) { if (_openedForum && peer->forum() != _openedForum) { controller()->closeForum(); } + const auto channel = peer->asChannel(); + if (_openedCommunity + && channel + && channel->isCommunity() + && channel != _openedCommunity->channel() + && controller()->windowId().type + != Window::SeparateType::Community) { + controller()->closeCommunity(); + } } else if (state.query.isEmpty()) { if (_childList) { hideChildList(); @@ -3908,10 +3919,15 @@ bool Widget::applySearchState(SearchState state) { const auto topic = state.inChat.topic(); const auto forum = peer ? peer->forum() : nullptr; const auto folder = state.inChat.folder(); - const auto community = (_openedCommunity - && peer == _openedCommunity->channel()) - ? _openedCommunity + const auto channel = peer ? peer->asChannel() : nullptr; + const auto community = (channel && channel->isCommunity()) + ? channel : nullptr; + if (community) { + state.community = community; + } else if (peer) { + state.community = nullptr; + } if (folder || (forum && !topic) || community) { state.inChat = {}; } @@ -3924,7 +3940,7 @@ bool Widget::applySearchState(SearchState state) { ? ChatSearchTab::ThisPeer : _openedFolder ? ChatSearchTab::Archive - : _openedCommunity + : (state.community || _openedCommunity) ? ChatSearchTab::ThisCommunity : ChatSearchTab::MyMessages; } else if (!state.inChat @@ -3932,7 +3948,7 @@ bool Widget::applySearchState(SearchState state) { const auto archive = _openedFolder && ((folder == _openedFolder) || (state.tab == ChatSearchTab::Archive)); - const auto communityScope = _openedCommunity + const auto communityScope = (state.community || _openedCommunity) && (community || (state.tab == ChatSearchTab::ThisCommunity)); state.tab = (forum || _openedForum) @@ -3954,6 +3970,7 @@ bool Widget::applySearchState(SearchState state) { } const auto inChatChanged = (_searchState.inChat != state.inChat); + const auto communityChanged = (_searchState.community != state.community); const auto fromPeerChanged = (_searchState.fromPeer != state.fromPeer); const auto tagsChanged = (_searchState.tags != state.tags); const auto queryChanged = (_searchState.query != state.query); @@ -3978,7 +3995,10 @@ bool Widget::applySearchState(SearchState state) { } else { return false; } - } else if ((folder && folder == _openedFolder) || community) { + } else if ((folder && folder == _openedFolder) + || (community + && _openedCommunity + && community == _openedCommunity->channel())) { showSearchInTopBar(anim::type::normal); } else if (peer && (_layout != Layout::Main)) { return false; @@ -3992,7 +4012,7 @@ bool Widget::applySearchState(SearchState state) { || (state.tab == ChatSearchTab::Archive && (!_openedFolder || state.inChat)) || (state.tab == ChatSearchTab::ThisCommunity - && (!_openedCommunity || state.inChat)) + && ((!state.community && !_openedCommunity) || state.inChat)) || (state.tab == ChatSearchTab::PublicPosts && _searchHashOrCashtag == HashOrCashtag::None)) { state.tab = state.inChat.topic() @@ -4000,6 +4020,7 @@ bool Widget::applySearchState(SearchState state) { : (state.inChat.owningHistory() || state.inChat.sublist()) ? ChatSearchTab::ThisPeer : ChatSearchTab::MyMessages; + state.community = nullptr; } const auto migrateFrom = (peer @@ -4014,10 +4035,12 @@ bool Widget::applySearchState(SearchState state) { if (inChatChanged && _searchState.inChat && _stories) { storiesExplicitCollapse(); } - if (_chatFilters && (queryEmptyChanged || inChatChanged)) { + if (_chatFilters + && (queryEmptyChanged || inChatChanged || communityChanged)) { _chatFilters->setVisible(_searchState.query.isEmpty() && !_openedForum && !_openedCommunity + && !_searchState.community && !searchInPeer()); updateControlsGeometry(); } @@ -4045,6 +4068,7 @@ bool Widget::applySearchState(SearchState state) { && state.tags.empty(); if (searchCleared || inChatChanged + || communityChanged || fromPeerChanged || filterChanged || tagsChanged @@ -4811,6 +4835,9 @@ bool Widget::cancelSearch(CancelSearchOptions options) { && (forceFullCancel || !clearingQuery)) { updatedState.tab = ChatSearchTab::MyMessages; } + if (forceFullCancel || !clearingQuery) { + updatedState.community = nullptr; + } const auto clearSearchFocus = (forceFullCancel || !updatedState.inChat) && (_searchHasFocus || _searchSuggestionsLocked); if (!updatedState.inChat && _suggestions) { diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index d3b3988926..95a43b450c 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -454,6 +454,7 @@ infoProfileTopBarActionReport: icon{{ "profile/report-23x23", windowBoldFg }}; infoProfileTopBarActionLeave: icon{{ "profile/leave-23x23", windowBoldFg }}; infoProfileTopBarActionMore: icon{{ "profile/profile_more", windowBoldFg }}; infoProfileTopBarActionManage: icon{{ "profile/profile_manage", windowBoldFg }}; +infoProfileTopBarActionSearch: icon{{ "menu/search", windowBoldFg }}; infoProfileTopBarActionLiveStream: icon{{ "profile/live_stream-23x23", windowBoldFg }}; infoProfileTopBarTopicStatusButton: RoundButton(defaultTableSmallButton) { diff --git a/Telegram/SourceFiles/info/profile/info_profile_top_bar.cpp b/Telegram/SourceFiles/info/profile/info_profile_top_bar.cpp index ce78da9aac..ad83e050ea 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_top_bar.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_top_bar.cpp @@ -256,11 +256,6 @@ struct PatternColors { return points; } -[[nodiscard]] bool CommunityCanManage(PeerData *peer) { - const auto channel = peer ? peer->asChannel() : nullptr; - return channel && channel->canEditInformation(); -} - } // namespace TopBar::TopBar( @@ -307,8 +302,6 @@ TopBar::TopBar( _gifPausedChecker)) , _hasActions(descriptor.source != Source::Stories && descriptor.source != Source::Preview - && (descriptor.source != Source::Community - || CommunityCanManage(_peer)) && (_wrap.current() != Wrap::Side || !_peer->isNotificationsUser())) , _minForProgress([&] { QWidget::setMinimumHeight(st::infoLayerTopBarHeight); @@ -458,6 +451,18 @@ TopBar::TopBar( setupActions(controller); }, lifetime()); } + if (_source == Source::Community) { + Shortcuts::Requests( + ) | rpl::filter([=] { + return Core::App().activeWindow() == &controller->window(); + }) | rpl::on_next([=](not_null request) { + using Command = Shortcuts::Command; + request->check(Command::Search, 1) && request->handle([=] { + searchInCommunity(controller); + return true; + }); + }, lifetime()); + } setupStoryOutline(); if (_topic) { _topicIconView = std::make_unique( @@ -808,6 +813,18 @@ void TopBar::finalizeActions( shadowRaw->stackUnder(_actions.get()); } +void TopBar::searchInCommunity( + not_null controller) { + const auto channel = _peer->asChannel(); + if (!channel) { + return; + } + const auto history = channel->owner().history(channel); + controller->hideLayer(); + controller->hideSpecialLayer(); + controller->searchInChat(history); +} + void TopBar::setupActions(not_null controller) { const auto peer = _peer; const auto user = peer->asUser(); @@ -835,6 +852,18 @@ void TopBar::setupActions(not_null controller) { buttons.push_back(manage); _actions->add(manage); } + if (channel) { + const auto search = Ui::CreateChild( + this, + tr::lng_dlg_filter(tr::now), + st::infoProfileTopBarActionSearch); + search->setClickedCallback([=] { + searchInCommunity(controller); + }); + search->setAccessibleName(tr::lng_dlg_filter(tr::now)); + buttons.push_back(search); + _actions->add(search); + } finalizeActions(buttons); return; } diff --git a/Telegram/SourceFiles/info/profile/info_profile_top_bar.h b/Telegram/SourceFiles/info/profile/info_profile_top_bar.h index 82f673f7bb..56914a9c80 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_top_bar.h +++ b/Telegram/SourceFiles/info/profile/info_profile_top_bar.h @@ -157,6 +157,7 @@ private: void setupBirthdayEffect(); void startUploadOverlay(); void setupActions(not_null controller); + void searchInCommunity(not_null controller); void finalizeActions( const std::vector> &buttons); void setupButtons(