From ee8f997c147e6a82968ebea307136d2f001a1f56 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 26 Oct 2022 18:49:07 +0400 Subject: [PATCH] Implement search inside a single topic. --- .../dialogs/dialogs_inner_widget.cpp | 40 +++++++++++++++---- .../dialogs/dialogs_inner_widget.h | 11 ++++- .../SourceFiles/dialogs/dialogs_widget.cpp | 17 +++++--- .../SourceFiles/dialogs/ui/dialogs_layout.cpp | 5 ++- .../SourceFiles/history/history_widget.cpp | 26 ++++++------ .../view/history_view_replies_section.cpp | 35 ++++++++++++++++ .../view/history_view_replies_section.h | 2 + Telegram/SourceFiles/mainwidget.cpp | 4 -- 8 files changed, 107 insertions(+), 33 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 13e816fea..098a8ee74 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -675,7 +675,12 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } if (_searchInChat) { - paintSearchInChat(p); + paintSearchInChat(p, { + .st = &st::forumTopicRow, + .now = ms, + .width = fullWidth, + .paused = videoPaused, + }); p.translate(0, searchInChatSkip()); if (_waitingForSearch && _searchResults.empty()) { p.fillRect( @@ -926,7 +931,9 @@ void InnerWidget::paintPeerSearchResult( result->name.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } -void InnerWidget::paintSearchInChat(Painter &p) const { +void InnerWidget::paintSearchInChat( + Painter &p, + const Ui::PaintContext &context) const { auto height = searchInChatSkip(); auto top = st::searchedBarHeight; @@ -942,7 +949,9 @@ void InnerWidget::paintSearchInChat(Painter &p) const { } p.setPen(st::dialogsNameFg); - if (const auto peer = _searchInChat.peer()) { + if (const auto topic = _searchInChat.topic()) { + paintSearchInTopic(p, context, topic, _searchInChatUserpic, top, _searchInChatText); + } else if (const auto peer = _searchInChat.peer()) { if (peer->isSelf()) { paintSearchInSaved(p, top, _searchInChatText); } else if (peer->isRepliesChat()) { @@ -1035,6 +1044,21 @@ void InnerWidget::paintSearchInReplies( paintSearchInFilter(p, paintUserpic, top, nullptr, text); } +void InnerWidget::paintSearchInTopic( + Painter &p, + const Ui::PaintContext &context, + not_null topic, + std::shared_ptr &userpic, + int top, + const Ui::Text::String &text) const { + const auto paintUserpic = [&](Painter &p, int x, int y, int size) { + p.translate(x, y); + topic->paintUserpic(p, userpic, context); + p.translate(-x, -y); + }; + paintSearchInFilter(p, paintUserpic, top, nullptr, text); +} + void InnerWidget::mouseMoveEvent(QMouseEvent *e) { const auto globalPosition = e->globalPos(); if (!_lastMousePosition) { @@ -2313,9 +2337,9 @@ void InnerWidget::searchReceived( const auto isMigratedSearch = (type == SearchRequestType::MigratedFromStart) || (type == SearchRequestType::MigratedFromOffset); - const auto key = _openedForum - ? Key(_openedForum->history()) - : _searchInChat; + const auto key = (!_openedForum || _searchInChat.topic()) + ? _searchInChat + : Key(_openedForum->history()); if (inject && (!_searchInChat || inject->history() == _searchInChat.history())) { @@ -2600,7 +2624,9 @@ void InnerWidget::searchInChat(Key key, PeerData *from) { void InnerWidget::refreshSearchInChatLabel() { const auto dialog = [&] { - if (const auto peer = _searchInChat.peer()) { + if (const auto topic = _searchInChat.topic()) { + return topic->title(); + } else if (const auto peer = _searchInChat.peer()) { if (peer->isSelf()) { return tr::lng_saved_messages(tr::now); } else if (peer->isRepliesChat()) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 15e00bd4e..a06afcc4e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -301,7 +301,9 @@ private: Painter &p, not_null result, const Ui::PaintContext &context); - void paintSearchInChat(Painter &p) const; + void paintSearchInChat( + Painter &p, + const Ui::PaintContext &context) const; void paintSearchInPeer( Painter &p, not_null peer, @@ -316,6 +318,13 @@ private: Painter &p, int top, const Ui::Text::String &text) const; + void paintSearchInTopic( + Painter &p, + const Ui::PaintContext &context, + not_null topic, + std::shared_ptr &userpic, + int top, + const Ui::Text::String &text) const; template void paintSearchInFilter( Painter &p, diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 80cacac02..826cfd7c9 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -1848,6 +1848,12 @@ void Widget::applyFilterUpdate(bool force) { } void Widget::searchInChat(Key chat) { + if (_openedFolder) { + controller()->closeFolder(); + } + if (const auto topic = chat.topic()) { + controller()->openForum(topic->channel()); + } cancelSearch(); setSearchInChat(chat); applyFilterUpdate(true); @@ -1855,24 +1861,25 @@ void Widget::searchInChat(Key chat) { void Widget::setSearchInChat(Key chat, PeerData *from) { const auto peer = chat.peer(); - if (const auto forum = peer ? peer->forum() : nullptr) { + const auto topic = chat.topic(); + const auto forum = peer ? peer->forum() : nullptr; + if (forum) { if (controller()->openedForum().current() == peer) { _subsectionTopBar->toggleSearch(true, anim::type::normal); } else { _forumSearchRequested = true; controller()->openForum(forum->channel()); } - return; } - if (chat.folder()) { + if (chat.folder() || (forum && !topic)) { chat = Key(); } _searchInMigrated = nullptr; - if (const auto peer = chat.peer()) { + if (peer) { if (const auto migrateTo = peer->migrateTo()) { return setSearchInChat(peer->owner().history(migrateTo), from); } else if (const auto migrateFrom = peer->migrateFrom()) { - if (!chat.topic()) { + if (!topic) { _searchInMigrated = peer->owner().history(migrateFrom); } } diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index ab331a49a..574d6bde2 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -955,9 +955,10 @@ void RowPainter::Paint( const auto entry = topic ? (Entry*)topic : (Entry*)history; auto cloudDraft = nullptr; const auto from = [&] { - return topic + const auto in = row->searchInChat(); + return (topic && (in.topic() != topic)) ? nullptr - : row->searchInChat() + : in ? item->displayFrom() : history->peer->migrateTo() ? history->peer->migrateTo() diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 084178ad7..1bcd8be9f 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -1825,25 +1825,24 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, U void HistoryWidget::setupShortcuts() { Shortcuts::Requests( ) | rpl::filter([=] { - return Ui::AppInFocus() + return _history + && Ui::AppInFocus() && Ui::InFocusChain(this) && !Ui::isLayerShown() && (Core::App().activeWindow() == &controller()->window()); }) | rpl::start_with_next([=](not_null request) { using Command = Shortcuts::Command; - if (_history) { - request->check(Command::Search, 1) && request->handle([=] { - searchInChat(); + request->check(Command::Search, 1) && request->handle([=] { + searchInChat(); + return true; + }); + if (session().supportMode()) { + request->check( + Command::SupportToggleMuted + ) && request->handle([=] { + toggleMuteUnmute(); return true; }); - if (session().supportMode()) { - request->check( - Command::SupportToggleMuted - ) && request->handle([=] { - toggleMuteUnmute(); - return true; - }); - } } }, lifetime()); } @@ -4450,8 +4449,7 @@ bool HistoryWidget::updateCmdStartShown() { void HistoryWidget::searchInChat() { if (!_history) { return; - } - if (controller()->isPrimary()) { + } else if (controller()->isPrimary()) { controller()->content()->searchInChat(_history); } else if (!_composeSearch) { const auto search = [=] { diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index da6336e7c..30264b91e 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -55,7 +55,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/call_delayed.h" #include "base/qt/qt_key_modifiers.h" #include "core/file_utilities.h" +#include "core/application.h" +#include "core/shortcuts.h" #include "main/main_session.h" +#include "mainwidget.h" #include "data/data_session.h" #include "data/data_user.h" #include "data/data_chat.h" @@ -233,6 +236,7 @@ RepliesWidget::RepliesWidget( setupRoot(); setupRootView(); + setupShortcuts(); session().api().requestFullPeer(_history->peer); @@ -258,6 +262,10 @@ RepliesWidget::RepliesWidget( ) | rpl::start_with_next([=] { clearSelected(); }, _topBar->lifetime()); + _topBar->searchRequest( + ) | rpl::start_with_next([=] { + searchInTopic(); + }, _topBar->lifetime()); if (_rootView) { _rootView->raise(); @@ -2133,4 +2141,31 @@ void RepliesWidget::setupDragArea() { areas.photo->setDroppedCallback(droppedCallback(true)); } +void RepliesWidget::setupShortcuts() { + Shortcuts::Requests( + ) | rpl::filter([=] { + return _topic + && Ui::AppInFocus() + && Ui::InFocusChain(this) + && !Ui::isLayerShown() + && (Core::App().activeWindow() == &controller()->window()); + }) | rpl::start_with_next([=](not_null request) { + using Command = Shortcuts::Command; + request->check(Command::Search, 1) && request->handle([=] { + searchInTopic(); + return true; + }); + }, lifetime()); +} + +void RepliesWidget::searchInTopic() { + if (!_topic) { + return; + } else if (controller()->isPrimary()) { + controller()->content()->searchInChat(_topic); + } else { + // #TODO forum window + } +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index 4ab5b651c..e3c37d523 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -206,7 +206,9 @@ private: void subscribeToTopic(); void setTopic(Data::ForumTopic *topic); void setupDragArea(); + void setupShortcuts(); + void searchInTopic(); void scrollDownAnimationFinish(); void updatePinnedVisibility(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index f99070d25..2ba25fcb6 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -2678,10 +2678,6 @@ void MainWidget::searchInChat(Dialogs::Key chat) { if (!_dialogs) { return; } - - if (_controller->openedFolder().current()) { - _controller->closeFolder(); - } _dialogs->searchInChat(chat); if (isOneColumn()) { Ui::showChatsList(&session());