Fix saved tag click in separate window messages.

This commit is contained in:
John Preston 2024-01-30 13:04:46 +04:00
parent 39b80c98c7
commit 3421b656db
7 changed files with 61 additions and 33 deletions

View file

@ -3000,7 +3000,7 @@ void InnerWidget::searchInChat(
reactions->myTagsValue(sublist), reactions->myTagsValue(sublist),
tags); tags);
_searchTags->selectedValue( _searchTags->selectedChanges(
) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) { ) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) {
_searchTagsSelected = std::move(list); _searchTagsSelected = std::move(list);
}, _searchTags->lifetime()); }, _searchTags->lifetime());
@ -3055,11 +3055,11 @@ void InnerWidget::searchInChat(
_searchInChat || !_filter.isEmpty()); _searchInChat || !_filter.isEmpty());
} }
auto InnerWidget::searchTagsValue() const auto InnerWidget::searchTagsChanges() const
-> rpl::producer<std::vector<Data::ReactionId>> { -> rpl::producer<std::vector<Data::ReactionId>> {
return _searchTags return _searchTags
? _searchTags->selectedValue() ? _searchTags->selectedChanges()
: rpl::single(std::vector<Data::ReactionId>()); : rpl::never<std::vector<Data::ReactionId>>();
} }
void InnerWidget::refreshSearchInChatLabel() { void InnerWidget::refreshSearchInChatLabel() {

View file

@ -143,7 +143,7 @@ public:
Key key, Key key,
PeerData *from, PeerData *from,
std::vector<Data::ReactionId> tags); std::vector<Data::ReactionId> tags);
[[nodiscard]] auto searchTagsValue() const [[nodiscard]] auto searchTagsChanges() const
-> rpl::producer<std::vector<Data::ReactionId>>; -> rpl::producer<std::vector<Data::ReactionId>>;
void applyFilterUpdate(QString newFilter, bool force = false); void applyFilterUpdate(QString newFilter, bool force = false);

View file

@ -271,7 +271,7 @@ ClickHandlerPtr SearchTags::lookupHandler(QPoint point) const {
return nullptr; return nullptr;
} }
auto SearchTags::selectedValue() const auto SearchTags::selectedChanges() const
-> rpl::producer<std::vector<Data::ReactionId>> { -> rpl::producer<std::vector<Data::ReactionId>> {
return _selectedChanges.events() | rpl::map([=] { return _selectedChanges.events() | rpl::map([=] {
return collectSelected(); return collectSelected();

View file

@ -37,7 +37,7 @@ public:
[[nodiscard]] rpl::producer<> repaintRequests() const; [[nodiscard]] rpl::producer<> repaintRequests() const;
[[nodiscard]] ClickHandlerPtr lookupHandler(QPoint point) const; [[nodiscard]] ClickHandlerPtr lookupHandler(QPoint point) const;
[[nodiscard]] auto selectedValue() const [[nodiscard]] auto selectedChanges() const
-> rpl::producer<std::vector<Data::ReactionId>>; -> rpl::producer<std::vector<Data::ReactionId>>;
void paint( void paint(

View file

@ -2666,7 +2666,7 @@ bool Widget::setSearchInChat(
} }
_searchTags = std::move(tags); _searchTags = std::move(tags);
_inner->searchInChat(_searchInChat, _searchFromAuthor, _searchTags); _inner->searchInChat(_searchInChat, _searchFromAuthor, _searchTags);
_searchTagsLifetime = _inner->searchTagsValue( _searchTagsLifetime = _inner->searchTagsChanges(
) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) { ) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) {
if (_searchTags != list) { if (_searchTags != list) {
clearSearchCache(); clearSearchCache();

View file

@ -287,10 +287,8 @@ protected:
private: private:
void clearItems(); void clearItems();
void setupTags( void refreshTags();
not_null<Window::SessionController*> window, void updateSize();
not_null<History*> history,
PeerData *from);
void requestSearch(bool cache = true); void requestSearch(bool cache = true);
void requestSearchDelayed(); void requestSearchDelayed();
@ -299,6 +297,8 @@ private:
base::unique_qptr<Ui::MultiSelect> _select; base::unique_qptr<Ui::MultiSelect> _select;
std::unique_ptr<Dialogs::SearchTags> _searchTags; std::unique_ptr<Dialogs::SearchTags> _searchTags;
const not_null<Window::SessionController*> _window;
const not_null<History*> _history;
rpl::variable<PeerData*> _from = nullptr; rpl::variable<PeerData*> _from = nullptr;
base::Timer _searchTimer; base::Timer _searchTimer;
@ -325,15 +325,16 @@ TopBar::TopBar(
st::searchInChatMultiSelect, st::searchInChatMultiSelect,
tr::lng_dlg_filter(), tr::lng_dlg_filter(),
_searchTagsSelected.empty() ? query : QString())) _searchTagsSelected.empty() ? query : QString()))
, _window(window)
, _history(history)
, _searchTimer([=] { requestSearch(); }) { , _searchTimer([=] { requestSearch(); }) {
setupTags(window, history, from); refreshTags();
rpl::combine( moveToLeft(0, 0);
parent->geometryValue(),
_searchTags ? _searchTags->heightValue() : rpl::single(0) parent->geometryValue(
) | rpl::start_with_next([=](const QRect &r, int tagsHeight) { ) | rpl::start_with_next([=] {
moveToLeft(0, 0); updateSize();
resize(r.width(), st::topBarHeight + tagsHeight);
}, lifetime()); }, lifetime());
sizeValue( sizeValue(
@ -387,8 +388,22 @@ void TopBar::setInnerFocus() {
_select->setInnerFocus(); _select->setInnerFocus();
} }
void TopBar::updateSize() {
const auto height = st::topBarHeight
+ (_searchTags ? _searchTags->height() : 0);
resize(parentWidget()->width(), height);
}
void TopBar::setQuery(const QString &query) { void TopBar::setQuery(const QString &query) {
_select->setQuery(query); if (auto tags = Data::SearchTagsFromQuery(query); !tags.empty()) {
if (_searchTagsSelected != tags) {
_searchTagsSelected = std::move(tags);
refreshTags();
}
_select->setQuery(QString());
} else {
_select->setQuery(query);
}
} }
void TopBar::clearItems() { void TopBar::clearItems() {
@ -404,32 +419,41 @@ void TopBar::clearItems() {
}); });
} }
void TopBar::setupTags( void TopBar::refreshTags() {
not_null<Window::SessionController*> window, if (!_history->peer->isSelf()) {
not_null<History*> history,
PeerData *from) {
if (!_searchTagsSelected.empty()) {
history = history->owner().history(history->session().user());
} else if (!history->peer->isSelf()) {
_searchTags = nullptr; _searchTags = nullptr;
return; return;
} }
const auto reactions = &history->owner().reactions(); const auto from = _from.current();
const auto reactions = &_history->owner().reactions();
const auto sublist = from const auto sublist = from
? history->owner().savedMessages().sublist(from).get() ? _history->owner().savedMessages().sublist(from).get()
: nullptr; : nullptr;
_searchTags = std::make_unique<Dialogs::SearchTags>( _searchTags = std::make_unique<Dialogs::SearchTags>(
&history->owner(), &_history->owner(),
reactions->myTagsValue(sublist), reactions->myTagsValue(sublist),
_searchTagsSelected); _searchTagsSelected);
_searchTags->heightValue(
) | rpl::start_with_next([=] {
updateSize();
}, _searchTags->lifetime());
_searchTags->selectedValue( _searchTags->selectedChanges(
) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) { ) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) {
_searchTagsSelected = std::move(list); _searchTagsSelected = std::move(list);
requestSearch(false); requestSearch(false);
}, _searchTags->lifetime()); }, _searchTags->lifetime());
const auto parent = Ui::CreateChild<Ui::RpWidget>(this); if (!_searchTagsSelected.empty()) {
crl::on_main(this, [=] {
requestSearch(false);
});
}
const auto parent = _searchTags->lifetime().make_state<Ui::RpWidget>(
this);
parent->show();
const auto padding = st::searchInChatTagsPadding; const auto padding = st::searchInChatTagsPadding;
const auto position = QPoint(padding.left(), padding.top()); const auto position = QPoint(padding.left(), padding.top());
@ -478,7 +502,7 @@ void TopBar::setupTags(
ActivateClickHandler(parent, handler, ClickContext{ ActivateClickHandler(parent, handler, ClickContext{
.button = mouse->button(), .button = mouse->button(),
.other = QVariant::fromValue(ClickHandlerContext{ .other = QVariant::fromValue(ClickHandlerContext{
.sessionWindow = window, .sessionWindow = _window,
}), }),
}); });
} }

View file

@ -727,6 +727,10 @@ void MainWidget::searchMessages(const QString &query, Dialogs::Key inChat) {
_dialogs->setInnerFocus(); _dialogs->setInnerFocus();
} }
} else { } else {
if (!Data::SearchTagsFromQuery(query).empty()) {
inChat = controller()->session().data().history(
controller()->session().user());
}
const auto searchIn = [&](not_null<Window::Controller*> window) { const auto searchIn = [&](not_null<Window::Controller*> window) {
if (const auto controller = window->sessionController()) { if (const auto controller = window->sessionController()) {
controller->content()->searchMessages(query, inChat); controller->content()->searchMessages(query, inChat);