Implement search inside a single topic.

This commit is contained in:
John Preston 2022-10-26 18:49:07 +04:00
parent 60aef7871a
commit ee8f997c14
8 changed files with 107 additions and 33 deletions

View file

@ -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<Data::ForumTopic*> topic,
std::shared_ptr<Data::CloudImageView> &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()) {

View file

@ -301,7 +301,9 @@ private:
Painter &p,
not_null<const PeerSearchResult*> 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<PeerData*> 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<Data::ForumTopic*> topic,
std::shared_ptr<Data::CloudImageView> &userpic,
int top,
const Ui::Text::String &text) const;
template <typename PaintUserpic>
void paintSearchInFilter(
Painter &p,

View file

@ -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);
}
}

View file

@ -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()

View file

@ -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<Shortcuts::Request*> 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 = [=] {

View file

@ -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<Shortcuts::Request*> 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

View file

@ -206,7 +206,9 @@ private:
void subscribeToTopic();
void setTopic(Data::ForumTopic *topic);
void setupDragArea();
void setupShortcuts();
void searchInTopic();
void scrollDownAnimationFinish();
void updatePinnedVisibility();

View file

@ -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());