Start chats search rewrite.
This commit is contained in:
parent
787cf7853e
commit
dd5643ac67
9 changed files with 474 additions and 491 deletions
|
@ -157,13 +157,11 @@ InnerWidget::InnerWidget(
|
||||||
, _narrowWidth(st::defaultDialogRow.padding.left()
|
, _narrowWidth(st::defaultDialogRow.padding.left()
|
||||||
+ st::defaultDialogRow.photoSize
|
+ st::defaultDialogRow.photoSize
|
||||||
+ st::defaultDialogRow.padding.left())
|
+ st::defaultDialogRow.padding.left())
|
||||||
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
|
||||||
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer)
|
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer)
|
||||||
, _chatPreviewTimer([=] { showChatPreview(true); })
|
, _chatPreviewTimer([=] { showChatPreview(true); })
|
||||||
, _childListShown(std::move(childListShown)) {
|
, _childListShown(std::move(childListShown)) {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||||
|
|
||||||
_cancelSearchInChat->hide();
|
|
||||||
_cancelSearchFromUser->hide();
|
_cancelSearchFromUser->hide();
|
||||||
|
|
||||||
style::PaletteChanged(
|
style::PaletteChanged(
|
||||||
|
@ -509,13 +507,7 @@ int InnerWidget::searchInChatSkip() const {
|
||||||
if (_searchTags) {
|
if (_searchTags) {
|
||||||
result += _searchTags->height();
|
result += _searchTags->height();
|
||||||
}
|
}
|
||||||
if (_searchInChat) {
|
|
||||||
result += st::searchedBarHeight + st::dialogsSearchInHeight;
|
|
||||||
}
|
|
||||||
if (_searchFromShown) {
|
if (_searchFromShown) {
|
||||||
if (_searchInChat) {
|
|
||||||
result += st::lineWidth;
|
|
||||||
}
|
|
||||||
result += st::dialogsSearchInHeight;
|
result += st::dialogsSearchInHeight;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -856,7 +848,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_searchInChat || _searchFromPeer) {
|
if (_searchFromShown) {
|
||||||
paintSearchInChat(p, {
|
paintSearchInChat(p, {
|
||||||
.st = &st::forumTopicRow,
|
.st = &st::forumTopicRow,
|
||||||
.currentBg = currentBg(),
|
.currentBg = currentBg(),
|
||||||
|
@ -1141,37 +1133,8 @@ void InnerWidget::paintSearchInChat(
|
||||||
top += height;
|
top += height;
|
||||||
}
|
}
|
||||||
p.setFont(st::searchedBarFont);
|
p.setFont(st::searchedBarFont);
|
||||||
if (_searchInChat) {
|
|
||||||
const auto bar = st::searchedBarHeight;
|
|
||||||
p.fillRect(0, top, width(), top + bar, st::searchedBarBg);
|
|
||||||
p.setPen(st::searchedBarFg);
|
|
||||||
p.drawTextLeft(st::searchedBarPosition.x(), top + st::searchedBarPosition.y(), width(), tr::lng_dlg_search_in(tr::now));
|
|
||||||
top += bar;
|
|
||||||
}
|
|
||||||
auto fullRect = QRect(0, top, width(), height - top);
|
auto fullRect = QRect(0, top, width(), height - top);
|
||||||
p.fillRect(fullRect, currentBg());
|
p.fillRect(fullRect, currentBg());
|
||||||
if (_searchInChat) {
|
|
||||||
if (_searchFromShown) {
|
|
||||||
p.fillRect(QRect(0, top + st::dialogsSearchInHeight, width(), st::lineWidth), st::shadowFg);
|
|
||||||
}
|
|
||||||
p.setPen(st::dialogsNameFg);
|
|
||||||
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()) {
|
|
||||||
paintSearchInReplies(p, top, _searchInChatText);
|
|
||||||
} else {
|
|
||||||
paintSearchInPeer(p, peer, _searchInChatUserpic, top, _searchInChatText);
|
|
||||||
}
|
|
||||||
} else if (const auto sublist = _searchInChat.sublist()) {
|
|
||||||
paintSearchInSaved(p, top, _searchInChatText);
|
|
||||||
} else {
|
|
||||||
Unexpected("Empty Key in paintSearchInChat.");
|
|
||||||
}
|
|
||||||
top += st::dialogsSearchInHeight + st::lineWidth;
|
|
||||||
}
|
|
||||||
if (_searchFromShown) {
|
if (_searchFromShown) {
|
||||||
p.setPen(st::dialogsTextFg);
|
p.setPen(st::dialogsTextFg);
|
||||||
p.setTextPalette(st::dialogsSearchFromPalette);
|
p.setTextPalette(st::dialogsSearchFromPalette);
|
||||||
|
@ -1930,12 +1893,10 @@ void InnerWidget::moveCancelSearchButtons() {
|
||||||
const auto widthForCancelButton = qMax(
|
const auto widthForCancelButton = qMax(
|
||||||
width(),
|
width(),
|
||||||
st::columnMinimalWidthLeft - _narrowWidth);
|
st::columnMinimalWidthLeft - _narrowWidth);
|
||||||
const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInChat->width();
|
const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchFromUser->width();
|
||||||
const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2;
|
const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2;
|
||||||
const auto skip = st::searchedBarHeight + (_searchTags ? _searchTags->height() : 0);
|
const auto skip = st::searchedBarHeight + (_searchTags ? _searchTags->height() : 0);
|
||||||
_cancelSearchInChat->moveToLeft(left, skip + top);
|
_cancelSearchFromUser->moveToLeft(left, skip + top);
|
||||||
const auto next = _searchInChat ? (skip + st::dialogsSearchInHeight + st::lineWidth) : 0;
|
|
||||||
_cancelSearchFromUser->moveToLeft(left, next + top);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::dialogRowReplaced(
|
void InnerWidget::dialogRowReplaced(
|
||||||
|
@ -2334,7 +2295,7 @@ void InnerWidget::fillArchiveSearchMenu(not_null<Ui::PopupMenu*> menu) {
|
||||||
const auto folder = session().data().folderLoaded(Data::Folder::kId);
|
const auto folder = session().data().folderLoaded(Data::Folder::kId);
|
||||||
if (!folder
|
if (!folder
|
||||||
|| !folder->chatsList()->fullSize().current()
|
|| !folder->chatsList()->fullSize().current()
|
||||||
|| _searchInChat) {
|
|| _searchState.inChat) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto skip = session().settings().skipArchiveInSearch();
|
const auto skip = session().settings().skipArchiveInSearch();
|
||||||
|
@ -2491,17 +2452,26 @@ void InnerWidget::parentGeometryChanged() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::applyFilterUpdate(QString newFilter, bool force) {
|
void InnerWidget::applySearchState(SearchState state) {
|
||||||
|
if (_searchState == state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto withSameQuery = state;
|
||||||
|
withSameQuery.query = _searchState.query;
|
||||||
|
const auto otherChanged = (_searchState != withSameQuery);
|
||||||
|
|
||||||
|
_searchState = std::move(state);
|
||||||
|
auto newFilter = _searchState.query;
|
||||||
const auto mentionsSearch = (newFilter == u"@"_q);
|
const auto mentionsSearch = (newFilter == u"@"_q);
|
||||||
const auto words = mentionsSearch
|
const auto words = mentionsSearch
|
||||||
? QStringList(newFilter)
|
? QStringList(newFilter)
|
||||||
: TextUtilities::PrepareSearchWords(newFilter);
|
: TextUtilities::PrepareSearchWords(newFilter);
|
||||||
newFilter = words.isEmpty() ? QString() : words.join(' ');
|
newFilter = words.isEmpty() ? QString() : words.join(' ');
|
||||||
if (newFilter != _filter || force) {
|
if (newFilter != _filter || otherChanged) {
|
||||||
_filter = newFilter;
|
_filter = newFilter;
|
||||||
if (_filter.isEmpty()
|
if (_filter.isEmpty()
|
||||||
&& !_searchFromPeer
|
&& !_searchState.fromPeer
|
||||||
&& _searchTagsSelected.empty()) {
|
&& _searchState.tags.empty()) {
|
||||||
clearFilter();
|
clearFilter();
|
||||||
} else {
|
} else {
|
||||||
setState(WidgetState::Filtered);
|
setState(WidgetState::Filtered);
|
||||||
|
@ -2521,9 +2491,7 @@ void InnerWidget::applyFilterUpdate(QString newFilter, bool force) {
|
||||||
top += i->row->height();
|
top += i->row->height();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (!_searchInChat
|
if (_searchState.filterChatsList() && !words.isEmpty()) {
|
||||||
&& !_searchFromPeer
|
|
||||||
&& !words.isEmpty()) {
|
|
||||||
if (_savedSublists) {
|
if (_savedSublists) {
|
||||||
const auto owner = &session().data();
|
const auto owner = &session().data();
|
||||||
append(owner->savedMessages().chatsList()->indexed());
|
append(owner->savedMessages().chatsList()->indexed());
|
||||||
|
@ -2549,7 +2517,9 @@ void InnerWidget::applyFilterUpdate(QString newFilter, bool force) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::onHashtagFilterUpdate(QStringView newFilter) {
|
void InnerWidget::onHashtagFilterUpdate(QStringView newFilter) {
|
||||||
if (newFilter.isEmpty() || newFilter.at(0) != '#' || _searchInChat) {
|
if (newFilter.isEmpty()
|
||||||
|
|| newFilter.at(0) != '#'
|
||||||
|
|| _searchState.inChat) {
|
||||||
_hashtagFilter = QString();
|
_hashtagFilter = QString();
|
||||||
if (!_hashtagResults.empty()) {
|
if (!_hashtagResults.empty()) {
|
||||||
_hashtagResults.clear();
|
_hashtagResults.clear();
|
||||||
|
@ -2751,10 +2721,6 @@ rpl::producer<> InnerWidget::searchMessages() const {
|
||||||
return _searchMessages.events();
|
return _searchMessages.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> InnerWidget::cancelSearchInChatRequests() const {
|
|
||||||
return _cancelSearchInChat->clicks() | rpl::to_empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<QString> InnerWidget::completeHashtagRequests() const {
|
rpl::producer<QString> InnerWidget::completeHashtagRequests() const {
|
||||||
return _completeHashtagRequests.events();
|
return _completeHashtagRequests.events();
|
||||||
}
|
}
|
||||||
|
@ -2847,12 +2813,12 @@ void InnerWidget::searchReceived(
|
||||||
const auto isMigratedSearch = (type == SearchRequestType::MigratedFromStart)
|
const auto isMigratedSearch = (type == SearchRequestType::MigratedFromStart)
|
||||||
|| (type == SearchRequestType::MigratedFromOffset);
|
|| (type == SearchRequestType::MigratedFromOffset);
|
||||||
|
|
||||||
const auto key = (!_openedForum || _searchInChat.topic())
|
const auto key = (!_openedForum || _searchState.inChat.topic())
|
||||||
? _searchInChat
|
? _searchState.inChat
|
||||||
: Key(_openedForum->history());
|
: Key(_openedForum->history());
|
||||||
if (inject
|
if (inject
|
||||||
&& (!_searchInChat
|
&& (!_searchState.inChat
|
||||||
|| inject->history() == _searchInChat.history())) {
|
|| inject->history() == _searchState.inChat.history())) {
|
||||||
Assert(_searchResults.empty());
|
Assert(_searchResults.empty());
|
||||||
const auto index = int(_searchResults.size());
|
const auto index = int(_searchResults.size());
|
||||||
_searchResults.push_back(
|
_searchResults.push_back(
|
||||||
|
@ -2984,7 +2950,7 @@ void InnerWidget::refresh(bool toTop) {
|
||||||
}
|
}
|
||||||
} else if (_state == WidgetState::Filtered) {
|
} else if (_state == WidgetState::Filtered) {
|
||||||
if (_waitingForSearch) {
|
if (_waitingForSearch) {
|
||||||
h = searchedOffset() + (_searchResults.size() * _st->height) + ((_searchResults.empty() && !_searchInChat) ? -st::searchedBarHeight : 0);
|
h = searchedOffset() + (_searchResults.size() * _st->height) + ((_searchResults.empty() && !_searchState.inChat) ? -st::searchedBarHeight : 0);
|
||||||
} else {
|
} else {
|
||||||
h = searchedOffset() + (_searchResults.size() * _st->height);
|
h = searchedOffset() + (_searchResults.size() * _st->height);
|
||||||
}
|
}
|
||||||
|
@ -3124,7 +3090,7 @@ void InnerWidget::searchInChat(
|
||||||
|
|
||||||
_searchTags->selectedChanges(
|
_searchTags->selectedChanges(
|
||||||
) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) {
|
) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) {
|
||||||
_searchTagsSelected = std::move(list);
|
_searchState.tags = std::move(list);
|
||||||
}, _searchTags->lifetime());
|
}, _searchTags->lifetime());
|
||||||
|
|
||||||
_searchTags->repaintRequests() | rpl::start_with_next([=] {
|
_searchTags->repaintRequests() | rpl::start_with_next([=] {
|
||||||
|
@ -3150,20 +3116,17 @@ void InnerWidget::searchInChat(
|
||||||
}, _searchTags->lifetime());
|
}, _searchTags->lifetime());
|
||||||
} else {
|
} else {
|
||||||
_searchTags = nullptr;
|
_searchTags = nullptr;
|
||||||
_searchTagsSelected.clear();
|
_searchState.tags.clear();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_searchTags = nullptr;
|
_searchTags = nullptr;
|
||||||
_searchTagsSelected.clear();
|
_searchState.tags.clear();
|
||||||
}
|
}
|
||||||
_searchInChat = key;
|
_searchState.inChat = key;
|
||||||
_searchFromPeer = from;
|
_searchState.fromPeer = from;
|
||||||
_searchFromShown = key.sublist() ? key.sublist()->peer().get() : from;
|
_searchFromShown = key.sublist() ? key.sublist()->peer().get() : from;
|
||||||
if (_searchInChat) {
|
if (_searchState.inChat) {
|
||||||
onHashtagFilterUpdate(QStringView());
|
onHashtagFilterUpdate(QStringView());
|
||||||
_cancelSearchInChat->show();
|
|
||||||
} else {
|
|
||||||
_cancelSearchInChat->hide();
|
|
||||||
}
|
}
|
||||||
if (_searchFromShown) {
|
if (_searchFromShown) {
|
||||||
_cancelSearchFromUser->show();
|
_cancelSearchFromUser->show();
|
||||||
|
@ -3172,15 +3135,9 @@ void InnerWidget::searchInChat(
|
||||||
_cancelSearchFromUser->hide();
|
_cancelSearchFromUser->hide();
|
||||||
_searchFromUserUserpic = {};
|
_searchFromUserUserpic = {};
|
||||||
}
|
}
|
||||||
if (_searchInChat || _searchFromPeer) {
|
if (_searchState.inChat || _searchState.fromPeer) {
|
||||||
refreshSearchInChatLabel();
|
refreshSearchInChatLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peer) {
|
|
||||||
_searchInChatUserpic = peer->createUserpicView();
|
|
||||||
} else {
|
|
||||||
_searchInChatUserpic = {};
|
|
||||||
}
|
|
||||||
moveCancelSearchButtons();
|
moveCancelSearchButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3192,27 +3149,6 @@ auto InnerWidget::searchTagsChanges() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::refreshSearchInChatLabel() {
|
void InnerWidget::refreshSearchInChatLabel() {
|
||||||
const auto dialog = [&] {
|
|
||||||
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()) {
|
|
||||||
return tr::lng_replies_messages(tr::now);
|
|
||||||
}
|
|
||||||
return peer->name();
|
|
||||||
} else if (_searchInChat.sublist()) {
|
|
||||||
return tr::lng_saved_messages(tr::now);
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}();
|
|
||||||
if (!dialog.isEmpty()) {
|
|
||||||
_searchInChatText.setText(
|
|
||||||
st::semiboldTextStyle,
|
|
||||||
dialog,
|
|
||||||
Ui::DialogTextOptions());
|
|
||||||
}
|
|
||||||
const auto from = _searchFromShown ? _searchFromShown->name() : u""_q;
|
const auto from = _searchFromShown ? _searchFromShown->name() : u""_q;
|
||||||
if (!from.isEmpty()) {
|
if (!from.isEmpty()) {
|
||||||
const auto fromUserText = tr::lng_dlg_search_from(
|
const auto fromUserText = tr::lng_dlg_search_from(
|
||||||
|
@ -3236,8 +3172,8 @@ void InnerWidget::repaintSearchResult(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::clearFilter() {
|
void InnerWidget::clearFilter() {
|
||||||
if (_state == WidgetState::Filtered || _searchInChat) {
|
if (_state == WidgetState::Filtered || _searchState.inChat) {
|
||||||
if (_searchInChat) {
|
if (_searchState.inChat) {
|
||||||
setState(WidgetState::Filtered);
|
setState(WidgetState::Filtered);
|
||||||
_waitingForSearch = true;
|
_waitingForSearch = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -145,6 +145,7 @@ public:
|
||||||
}
|
}
|
||||||
[[nodiscard]] bool hasFilteredResults() const;
|
[[nodiscard]] bool hasFilteredResults() const;
|
||||||
|
|
||||||
|
void applySearchState(SearchState state);
|
||||||
void searchInChat(
|
void searchInChat(
|
||||||
Key key,
|
Key key,
|
||||||
PeerData *from,
|
PeerData *from,
|
||||||
|
@ -152,7 +153,6 @@ public:
|
||||||
[[nodiscard]] auto searchTagsChanges() 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 onHashtagFilterUpdate(QStringView newFilter);
|
void onHashtagFilterUpdate(QStringView newFilter);
|
||||||
void appendToFiltered(Key key);
|
void appendToFiltered(Key key);
|
||||||
|
|
||||||
|
@ -169,7 +169,6 @@ public:
|
||||||
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> mustScrollTo() const;
|
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> mustScrollTo() const;
|
||||||
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> dialogMoved() const;
|
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> dialogMoved() const;
|
||||||
[[nodiscard]] rpl::producer<> searchMessages() const;
|
[[nodiscard]] rpl::producer<> searchMessages() const;
|
||||||
[[nodiscard]] rpl::producer<> cancelSearchInChatRequests() const;
|
|
||||||
[[nodiscard]] rpl::producer<QString> completeHashtagRequests() const;
|
[[nodiscard]] rpl::producer<QString> completeHashtagRequests() const;
|
||||||
[[nodiscard]] rpl::producer<> refreshHashtagsRequests() const;
|
[[nodiscard]] rpl::producer<> refreshHashtagsRequests() const;
|
||||||
|
|
||||||
|
@ -486,21 +485,16 @@ private:
|
||||||
WidgetState _state = WidgetState::Default;
|
WidgetState _state = WidgetState::Default;
|
||||||
|
|
||||||
object_ptr<Ui::FlatLabel> _empty = { nullptr };
|
object_ptr<Ui::FlatLabel> _empty = { nullptr };
|
||||||
object_ptr<Ui::IconButton> _cancelSearchInChat;
|
|
||||||
object_ptr<Ui::IconButton> _cancelSearchFromUser;
|
object_ptr<Ui::IconButton> _cancelSearchFromUser;
|
||||||
|
|
||||||
Ui::DraggingScrollManager _draggingScroll;
|
Ui::DraggingScrollManager _draggingScroll;
|
||||||
|
|
||||||
Key _searchInChat;
|
SearchState _searchState;
|
||||||
History *_searchInMigrated = nullptr;
|
History *_searchInMigrated = nullptr;
|
||||||
PeerData *_searchFromPeer = nullptr;
|
|
||||||
PeerData *_searchFromShown = nullptr;
|
PeerData *_searchFromShown = nullptr;
|
||||||
mutable Ui::PeerUserpicView _searchInChatUserpic;
|
|
||||||
mutable Ui::PeerUserpicView _searchFromUserUserpic;
|
mutable Ui::PeerUserpicView _searchFromUserUserpic;
|
||||||
Ui::Text::String _searchInChatText;
|
|
||||||
Ui::Text::String _searchFromUserText;
|
Ui::Text::String _searchFromUserText;
|
||||||
std::unique_ptr<SearchTags> _searchTags;
|
std::unique_ptr<SearchTags> _searchTags;
|
||||||
std::vector<Data::ReactionId> _searchTagsSelected;
|
|
||||||
int _searchTagsLeft = 0;
|
int _searchTagsLeft = 0;
|
||||||
RowDescriptor _menuRow;
|
RowDescriptor _menuRow;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_folder.h"
|
#include "data/data_folder.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_saved_sublist.h"
|
#include "data/data_saved_sublist.h"
|
||||||
|
#include "dialogs/ui/chat_search_tabs.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
|
||||||
namespace Dialogs {
|
namespace Dialogs {
|
||||||
|
@ -84,4 +85,21 @@ PeerData *Key::peer() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool SearchState::empty() const {
|
||||||
|
return !inChat
|
||||||
|
&& QStringView(query).trimmed().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatSearchTab SearchState::defaultTabForMe() const {
|
||||||
|
return inChat.topic()
|
||||||
|
? ChatSearchTab::ThisTopic
|
||||||
|
: inChat.history()
|
||||||
|
? ChatSearchTab::ThisPeer
|
||||||
|
: ChatSearchTab::MyMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SearchState::filterChatsList() const {
|
||||||
|
return !inChat && (tab == ChatSearchTab::MyMessages);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Dialogs
|
} // namespace Dialogs
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/qt/qt_compare.h"
|
||||||
|
|
||||||
class History;
|
class History;
|
||||||
class PeerData;
|
class PeerData;
|
||||||
|
|
||||||
|
@ -15,11 +17,13 @@ class Thread;
|
||||||
class Folder;
|
class Folder;
|
||||||
class ForumTopic;
|
class ForumTopic;
|
||||||
class SavedSublist;
|
class SavedSublist;
|
||||||
|
struct ReactionId;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace Dialogs {
|
namespace Dialogs {
|
||||||
|
|
||||||
class Entry;
|
class Entry;
|
||||||
|
enum class ChatSearchTab : uchar;
|
||||||
|
|
||||||
class Key {
|
class Key {
|
||||||
public:
|
public:
|
||||||
|
@ -120,4 +124,29 @@ struct EntryState {
|
||||||
= default;
|
= default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SearchState {
|
||||||
|
Key inChat;
|
||||||
|
PeerData *fromPeer = nullptr;
|
||||||
|
std::vector<Data::ReactionId> tags;
|
||||||
|
ChatSearchTab tab = {};
|
||||||
|
QString query;
|
||||||
|
|
||||||
|
[[nodiscard]] bool empty() const;
|
||||||
|
[[nodiscard]] ChatSearchTab defaultTabForMe() const;
|
||||||
|
[[nodiscard]] bool filterChatsList() const;
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return !empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend inline auto operator<=>(
|
||||||
|
const SearchState&,
|
||||||
|
const SearchState&) noexcept = default;
|
||||||
|
friend inline bool operator==(
|
||||||
|
const SearchState&,
|
||||||
|
const SearchState&) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
} // namespace Dialogs
|
} // namespace Dialogs
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -100,7 +100,6 @@ public:
|
||||||
void showForum(
|
void showForum(
|
||||||
not_null<Data::Forum*> forum,
|
not_null<Data::Forum*> forum,
|
||||||
const Window::SectionShow ¶ms);
|
const Window::SectionShow ¶ms);
|
||||||
void searchInChat(Key chat);
|
|
||||||
void setInnerFocus(bool unfocusSearch = false);
|
void setInnerFocus(bool unfocusSearch = false);
|
||||||
[[nodiscard]] bool searchHasFocus() const;
|
[[nodiscard]] bool searchHasFocus() const;
|
||||||
|
|
||||||
|
@ -122,9 +121,7 @@ public:
|
||||||
|
|
||||||
void scrollToEntry(const RowDescriptor &entry);
|
void scrollToEntry(const RowDescriptor &entry);
|
||||||
|
|
||||||
void searchMessages(QString query, Key inChat = {});
|
void searchMessages(SearchState state);
|
||||||
void searchTopics();
|
|
||||||
void searchMore();
|
|
||||||
|
|
||||||
[[nodiscard]] RowDescriptor resolveChatNext(RowDescriptor from = {}) const;
|
[[nodiscard]] RowDescriptor resolveChatNext(RowDescriptor from = {}) const;
|
||||||
[[nodiscard]] RowDescriptor resolveChatPrevious(RowDescriptor from = {}) const;
|
[[nodiscard]] RowDescriptor resolveChatPrevious(RowDescriptor from = {}) const;
|
||||||
|
@ -154,14 +151,16 @@ protected:
|
||||||
private:
|
private:
|
||||||
void chosenRow(const ChosenRow &row);
|
void chosenRow(const ChosenRow &row);
|
||||||
void listScrollUpdated();
|
void listScrollUpdated();
|
||||||
void cancelSearchInChat();
|
|
||||||
void searchCursorMoved();
|
void searchCursorMoved();
|
||||||
void completeHashtag(QString tag);
|
void completeHashtag(QString tag);
|
||||||
|
|
||||||
[[nodiscard]] QString currentSearchQuery() const;
|
[[nodiscard]] QString currentSearchQuery() const;
|
||||||
|
[[nodiscard]] int currentSearchQueryCursorPosition() const;
|
||||||
void clearSearchField();
|
void clearSearchField();
|
||||||
bool searchMessages(bool searchCache = false);
|
void searchRequested();
|
||||||
void needSearchMessages();
|
bool search(bool inCache = false);
|
||||||
|
void searchTopics();
|
||||||
|
void searchMore();
|
||||||
|
|
||||||
void slideFinished();
|
void slideFinished();
|
||||||
void searchReceived(
|
void searchReceived(
|
||||||
|
@ -176,6 +175,8 @@ private:
|
||||||
void cancelSearchRequest();
|
void cancelSearchRequest();
|
||||||
[[nodiscard]] PeerData *searchInPeer() const;
|
[[nodiscard]] PeerData *searchInPeer() const;
|
||||||
[[nodiscard]] Data::ForumTopic *searchInTopic() const;
|
[[nodiscard]] Data::ForumTopic *searchInTopic() const;
|
||||||
|
[[nodiscard]] PeerData *searchFromPeer() const;
|
||||||
|
[[nodiscard]] const std::vector<Data::ReactionId> &searchInTags() const;
|
||||||
|
|
||||||
void setupSupportMode();
|
void setupSupportMode();
|
||||||
void setupConnectingWidget();
|
void setupConnectingWidget();
|
||||||
|
@ -190,18 +191,15 @@ private:
|
||||||
void trackScroll(not_null<Ui::RpWidget*> widget);
|
void trackScroll(not_null<Ui::RpWidget*> widget);
|
||||||
[[nodiscard]] bool searchForPeersRequired(const QString &query) const;
|
[[nodiscard]] bool searchForPeersRequired(const QString &query) const;
|
||||||
[[nodiscard]] bool searchForTopicsRequired(const QString &query) const;
|
[[nodiscard]] bool searchForTopicsRequired(const QString &query) const;
|
||||||
bool setSearchInChat(
|
|
||||||
Key chat,
|
// Child list may be unable to set specific search state.
|
||||||
PeerData *from,
|
bool applySearchState(SearchState state);
|
||||||
std::vector<Data::ReactionId> tags);
|
|
||||||
bool setSearchInChat(
|
|
||||||
Key chat,
|
|
||||||
PeerData *from = nullptr);
|
|
||||||
void showCalendar();
|
void showCalendar();
|
||||||
void showSearchFrom();
|
void showSearchFrom();
|
||||||
void showMainMenu();
|
void showMainMenu();
|
||||||
void clearSearchCache();
|
void clearSearchCache();
|
||||||
void setSearchQuery(const QString &query);
|
void setSearchQuery(const QString &query, int cursorPosition = -1);
|
||||||
void updateControlsVisibility(bool fast = false);
|
void updateControlsVisibility(bool fast = false);
|
||||||
void updateLockUnlockVisibility(
|
void updateLockUnlockVisibility(
|
||||||
anim::type animated = anim::type::instant);
|
anim::type animated = anim::type::instant);
|
||||||
|
@ -227,7 +225,6 @@ private:
|
||||||
QPixmap newContentCache,
|
QPixmap newContentCache,
|
||||||
Window::SlideDirection direction);
|
Window::SlideDirection direction);
|
||||||
|
|
||||||
void applySearchTab();
|
|
||||||
void openChildList(
|
void openChildList(
|
||||||
not_null<Data::Forum*> forum,
|
not_null<Data::Forum*> forum,
|
||||||
const Window::SectionShow ¶ms);
|
const Window::SectionShow ¶ms);
|
||||||
|
@ -236,7 +233,7 @@ private:
|
||||||
void fullSearchRefreshOn(rpl::producer<> events);
|
void fullSearchRefreshOn(rpl::producer<> events);
|
||||||
void updateCancelSearch();
|
void updateCancelSearch();
|
||||||
bool fixSearchQuery();
|
bool fixSearchQuery();
|
||||||
void applySearchUpdate(bool force = false);
|
void applySearchUpdate();
|
||||||
void refreshLoadMoreButton(bool mayBlock, bool isBlocked);
|
void refreshLoadMoreButton(bool mayBlock, bool isBlocked);
|
||||||
void loadMoreBlockedByDate();
|
void loadMoreBlockedByDate();
|
||||||
|
|
||||||
|
@ -271,7 +268,7 @@ private:
|
||||||
Layout _layout = Layout::Main;
|
Layout _layout = Layout::Main;
|
||||||
int _narrowWidth = 0;
|
int _narrowWidth = 0;
|
||||||
object_ptr<Ui::RpWidget> _searchControls;
|
object_ptr<Ui::RpWidget> _searchControls;
|
||||||
object_ptr<HistoryView::TopBarWidget> _subsectionTopBar = { nullptr } ;
|
object_ptr<HistoryView::TopBarWidget> _subsectionTopBar = { nullptr };
|
||||||
struct {
|
struct {
|
||||||
object_ptr<Ui::IconButton> toggle;
|
object_ptr<Ui::IconButton> toggle;
|
||||||
object_ptr<Ui::AbstractButton> under;
|
object_ptr<Ui::AbstractButton> under;
|
||||||
|
@ -312,23 +309,16 @@ private:
|
||||||
bool _forumSearchRequested = false;
|
bool _forumSearchRequested = false;
|
||||||
bool _fixingSearchQuery = false;
|
bool _fixingSearchQuery = false;
|
||||||
bool _searchingHashtag = false;
|
bool _searchingHashtag = false;
|
||||||
ChatSearchTab _searchTab = ChatSearchTab();
|
|
||||||
|
|
||||||
Data::Folder *_openedFolder = nullptr;
|
Data::Folder *_openedFolder = nullptr;
|
||||||
Data::Forum *_openedForum = nullptr;
|
Data::Forum *_openedForum = nullptr;
|
||||||
Key _searchInChat;
|
SearchState _searchState;
|
||||||
History *_searchInMigrated = nullptr;
|
History *_searchInMigrated = nullptr;
|
||||||
PeerData *_searchFromAuthor = nullptr;
|
|
||||||
std::vector<Data::ReactionId> _searchTags;
|
|
||||||
rpl::lifetime _searchTagsLifetime;
|
rpl::lifetime _searchTagsLifetime;
|
||||||
QString _lastSearchText;
|
QString _lastSearchText;
|
||||||
bool _searchSuggestionsLocked = false;
|
bool _searchSuggestionsLocked = false;
|
||||||
bool _searchHasFocus = false;
|
bool _searchHasFocus = false;
|
||||||
|
|
||||||
Key _hiddenSearchInChat;
|
|
||||||
PeerData *_hiddenSearchFromAuthor = nullptr;
|
|
||||||
std::vector<Data::ReactionId> _hiddenSearchTags;
|
|
||||||
|
|
||||||
rpl::event_stream<rpl::producer<Stories::Content>> _storiesContents;
|
rpl::event_stream<rpl::producer<Stories::Content>> _storiesContents;
|
||||||
base::flat_map<PeerId, Ui::PeerUserpicView> _storiesUserpicsViewsHidden;
|
base::flat_map<PeerId, Ui::PeerUserpicView> _storiesUserpicsViewsHidden;
|
||||||
base::flat_map<PeerId, Ui::PeerUserpicView> _storiesUserpicsViewsShown;
|
base::flat_map<PeerId, Ui::PeerUserpicView> _storiesUserpicsViewsShown;
|
||||||
|
@ -357,6 +347,7 @@ private:
|
||||||
QString _searchQuery;
|
QString _searchQuery;
|
||||||
PeerData *_searchQueryFrom = nullptr;
|
PeerData *_searchQueryFrom = nullptr;
|
||||||
std::vector<Data::ReactionId> _searchQueryTags;
|
std::vector<Data::ReactionId> _searchQueryTags;
|
||||||
|
ChatSearchTab _searchQueryTab = {};
|
||||||
int32 _searchNextRate = 0;
|
int32 _searchNextRate = 0;
|
||||||
bool _searchFull = false;
|
bool _searchFull = false;
|
||||||
bool _searchFullMigrated = false;
|
bool _searchFullMigrated = false;
|
||||||
|
|
|
@ -1412,15 +1412,25 @@ QString TopBarWidget::searchQueryCurrent() const {
|
||||||
return _searchQuery.current();
|
return _searchQuery.current();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TopBarWidget::searchQueryCursorPosition() const {
|
||||||
|
return _searchMode
|
||||||
|
? _searchField->textCursor().position()
|
||||||
|
: _searchQuery.current().size();
|
||||||
|
}
|
||||||
|
|
||||||
void TopBarWidget::searchClear() {
|
void TopBarWidget::searchClear() {
|
||||||
if (_searchMode) {
|
if (_searchMode) {
|
||||||
_searchField->clear();
|
_searchField->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopBarWidget::searchSetText(const QString &query) {
|
void TopBarWidget::searchSetText(const QString &query, int cursorPosition) {
|
||||||
if (_searchMode) {
|
if (_searchMode) {
|
||||||
|
if (cursorPosition < 0) {
|
||||||
|
cursorPosition = query.size();
|
||||||
|
}
|
||||||
_searchField->setText(query);
|
_searchField->setText(query);
|
||||||
|
_searchField->setCursorPosition(cursorPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,9 @@ public:
|
||||||
[[nodiscard]] rpl::producer<> searchSubmitted() const;
|
[[nodiscard]] rpl::producer<> searchSubmitted() const;
|
||||||
[[nodiscard]] rpl::producer<QString> searchQuery() const;
|
[[nodiscard]] rpl::producer<QString> searchQuery() const;
|
||||||
[[nodiscard]] QString searchQueryCurrent() const;
|
[[nodiscard]] QString searchQueryCurrent() const;
|
||||||
|
[[nodiscard]] int searchQueryCursorPosition() const;
|
||||||
void searchClear();
|
void searchClear();
|
||||||
void searchSetText(const QString &query);
|
void searchSetText(const QString &query, int cursorPosition = -1);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> forwardSelectionRequest() const {
|
[[nodiscard]] rpl::producer<> forwardSelectionRequest() const {
|
||||||
return _forwardSelection.events();
|
return _forwardSelection.events();
|
||||||
|
|
|
@ -731,8 +731,18 @@ void MainWidget::hideSingleUseKeyboard(FullMsgId replyToId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::searchMessages(const QString &query, Dialogs::Key inChat) {
|
void MainWidget::searchMessages(const QString &query, Dialogs::Key inChat) {
|
||||||
|
auto tags = Data::SearchTagsFromQuery(query);
|
||||||
if (controller()->isPrimary()) {
|
if (controller()->isPrimary()) {
|
||||||
_dialogs->searchMessages(query, inChat);
|
using Tab = Dialogs::ChatSearchTab;
|
||||||
|
auto state = Dialogs::SearchState{
|
||||||
|
.inChat = ((tags.empty() || inChat.sublist())
|
||||||
|
? inChat
|
||||||
|
: session().data().history(session().user())),
|
||||||
|
.tags = tags,
|
||||||
|
.query = tags.empty() ? query : QString(),
|
||||||
|
};
|
||||||
|
state.tab = state.defaultTabForMe();
|
||||||
|
_dialogs->searchMessages(std::move(state));
|
||||||
if (isOneColumn()) {
|
if (isOneColumn()) {
|
||||||
_controller->clearSectionStack();
|
_controller->clearSectionStack();
|
||||||
} else {
|
} else {
|
||||||
|
@ -742,7 +752,7 @@ void MainWidget::searchMessages(const QString &query, Dialogs::Key inChat) {
|
||||||
if (const auto sublist = inChat.sublist()) {
|
if (const auto sublist = inChat.sublist()) {
|
||||||
controller()->showSection(
|
controller()->showSection(
|
||||||
std::make_shared<HistoryView::SublistMemento>(sublist));
|
std::make_shared<HistoryView::SublistMemento>(sublist));
|
||||||
} else if (!Data::SearchTagsFromQuery(query).empty()) {
|
} else if (!tags.empty()) {
|
||||||
inChat = controller()->session().data().history(
|
inChat = controller()->session().data().history(
|
||||||
controller()->session().user());
|
controller()->session().user());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue