From 01d55895940ab974a43d5b3f365d74d3a6bc71e8 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 22 Apr 2019 22:18:57 +0400 Subject: [PATCH] Add archived results in chats search. --- .../boxes/peer_list_controllers.cpp | 9 ++- .../boxes/peers/add_participants_box.cpp | 23 +++--- Telegram/SourceFiles/boxes/share_box.cpp | 64 ++++----------- Telegram/SourceFiles/data/data_session.cpp | 2 +- .../dialogs/dialogs_indexed_list.cpp | 50 ++++++++++++ .../dialogs/dialogs_indexed_list.h | 1 + .../dialogs/dialogs_inner_widget.cpp | 81 +++---------------- .../dialogs/dialogs_inner_widget.h | 2 +- 8 files changed, 99 insertions(+), 133 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 1d017d2fb9..db0439c641 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" +#include "data/data_folder.h" #include "apiwrap.h" #include "mainwidget.h" #include "lang/lang_keys.h" @@ -235,9 +236,7 @@ void ChatsListBoxController::prepare() { } Auth().data().chatsListChanges( - ) | rpl::filter([=](Data::Folder *folder) { - return !folder; - }) | rpl::start_with_next([=] { + ) | rpl::start_with_next([=] { rebuildRows(); }, lifetime()); @@ -267,6 +266,10 @@ void ChatsListBoxController::rebuildRows() { } } added += appendList(Auth().data().chatsList()->indexed()); + const auto id = Data::Folder::kId; + if (const auto folder = Auth().data().folderLoaded(id)) { + added += appendList(folder->chatsList()->indexed()); + } added += appendList(Auth().data().contactsNoChatsList()); if (!wasEmpty && added > 0) { // Place dialogs list before contactsNoDialogs list. diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index e069043560..2384562cef 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat.h" #include "data/data_user.h" #include "data/data_session.h" +#include "data/data_folder.h" #include "history/history.h" #include "dialogs/dialogs_indexed_list.h" #include "auth_session.h" @@ -1060,7 +1061,6 @@ void AddSpecialBoxSearchController::addChatsContacts() { } return true; }; - const auto getSmallestIndex = [&](not_null list) -> const Dialogs::List* { if (list->empty()) { @@ -1079,17 +1079,12 @@ void AddSpecialBoxSearchController::addChatsContacts() { } return result; }; - const auto dialogsIndex = getSmallestIndex( - _peer->owner().chatsList()->indexed()); - const auto contactsIndex = getSmallestIndex( - _peer->owner().contactsNoChatsList()); - - const auto filterAndAppend = [&](const Dialogs::List *list) { - if (!list) { + const auto filterAndAppend = [&](not_null list) { + const auto index = getSmallestIndex(list); + if (!index) { return; } - - for (const auto row : *list) { + for (const auto row : *index) { if (const auto history = row->history()) { if (const auto user = history->peer->asUser()) { if (allWordsAreFound(user->nameWords())) { @@ -1099,7 +1094,11 @@ void AddSpecialBoxSearchController::addChatsContacts() { } } }; - filterAndAppend(dialogsIndex); - filterAndAppend(contactsIndex); + filterAndAppend(_peer->owner().chatsList()->indexed()); + const auto id = Data::Folder::kId; + if (const auto folder = _peer->owner().folderLoaded(id)) { + filterAndAppend(folder->chatsList()->indexed()); + } + filterAndAppend(_peer->owner().contactsNoChatsList()); delegate()->peerListSearchRefreshRows(); } diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index 1257cdcfda..2fe6d7c97d 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_user.h" #include "data/data_session.h" +#include "data/data_folder.h" #include "auth_session.h" #include "core/application.h" #include "styles/style_boxes.h" @@ -131,7 +132,7 @@ private: ShareBox::FilterCallback _filterCallback; std::unique_ptr _chatsIndexed; QString _filter; - std::vector _filtered; + std::vector> _filtered; std::map, std::unique_ptr> _dataMap; base::flat_set> _selected; @@ -489,19 +490,26 @@ ShareBox::Inner::Inner( _rowHeight = st::shareRowHeight; setAttribute(Qt::WA_OpaquePaintEvent); - const auto dialogs = Auth().data().chatsList()->indexed(); const auto self = Auth().user(); if (_filterCallback(self)) { _chatsIndexed->addToEnd(self->owner().history(self)); } - for (const auto row : dialogs->all()) { - if (const auto history = row->history()) { - if (!history->peer->isSelf() - && _filterCallback(history->peer)) { - _chatsIndexed->addToEnd(history); + const auto addList = [&](not_null list) { + for (const auto row : list->all()) { + if (const auto history = row->history()) { + if (!history->peer->isSelf() + && _filterCallback(history->peer)) { + _chatsIndexed->addToEnd(history); + } } } + }; + addList(Auth().data().chatsList()->indexed()); + const auto id = Data::Folder::kId; + if (const auto folder = Auth().data().folderLoaded(id)) { + addList(folder->chatsList()->indexed()); } + addList(Auth().data().contactsNoChatsList()); _filter = qsl("a"); updateFilter(); @@ -603,7 +611,7 @@ ShareBox::Inner::Chat *ShareBox::Inner::getChatAtIndex(int index) { return _chatsIndexed->rowAtY(index, 1); } return (index < _filtered.size()) - ? _filtered[index] + ? _filtered[index].get() : nullptr; }(); if (row) { @@ -944,45 +952,7 @@ void ShareBox::Inner::updateFilter(QString filter) { if (_filter.isEmpty()) { refresh(); } else { - QStringList::const_iterator fb = words.cbegin(), fe = words.cend(), fi; - - _filtered.clear(); - if (!words.isEmpty()) { - const Dialogs::List *toFilter = nullptr; - if (!_chatsIndexed->empty()) { - for (fi = fb; fi != fe; ++fi) { - const auto found = _chatsIndexed->filtered(fi->at(0)); - if (!found || found->empty()) { - toFilter = nullptr; - break; - } - if (!toFilter || toFilter->size() > found->size()) { - toFilter = found; - } - } - } - if (toFilter) { - _filtered.reserve(toFilter->size()); - for (const auto row : *toFilter) { - const auto &nameWords = row->entry()->chatListNameWords(); - auto nb = nameWords.cbegin(), ne = nameWords.cend(), ni = nb; - for (fi = fb; fi != fe; ++fi) { - auto filterName = *fi; - for (ni = nb; ni != ne; ++ni) { - if (ni->startsWith(*fi)) { - break; - } - } - if (ni == ne) { - break; - } - } - if (fi == fe) { - _filtered.push_back(row); - } - } - } - } + _filtered = _chatsIndexed->filtered(words); refresh(); _searching = true; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index b22367e587..a9ba6454f9 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -983,7 +983,7 @@ void Session::setupUserIsContactViewer() { if (user->contactStatus() == UserData::ContactStatus::Contact) { const auto history = user->owner().history(user->id); _contactsList.addByName(history); - if (!_chatsList.indexed()->contains(history)) { + if (!history->inChatList()) { _contactsNoChatsList.addByName(history); } } else if (const auto history = user->owner().historyLoaded(user)) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp index 623df9af94..1cb769ee8c 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp @@ -200,6 +200,56 @@ void IndexedList::clear() { _index.clear(); } +std::vector> IndexedList::filtered( + const QStringList &words) const { + const auto minimal = [&]() -> const Dialogs::List* { + if (empty()) { + return nullptr; + } + auto result = (const Dialogs::List*)nullptr; + for (const auto &word : words) { + if (word.isEmpty()) { + continue; + } + const auto found = filtered(word[0]); + if (!found || found->empty()) { + return nullptr; + } else if (!result || result->size() > found->size()) { + result = found; + } + } + return result; + }(); + auto result = std::vector>(); + if (!minimal || minimal->empty()) { + return result; + } + result.reserve(minimal->size()); + for (const auto row : *minimal) { + const auto &nameWords = row->entry()->chatListNameWords(); + const auto found = [&](const QString &word) { + for (const auto &name : nameWords) { + if (name.startsWith(word)) { + return true; + } + } + return false; + }; + const auto allFound = [&] { + for (const auto &word : words) { + if (!found(word)) { + return false; + } + } + return true; + }(); + if (allFound) { + result.push_back(row); + } + } + return result; +} + IndexedList::~IndexedList() { clear(); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h index e19214b2f8..05b4fb987c 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h +++ b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h @@ -47,6 +47,7 @@ public: const auto i = _index.find(ch); return (i != _index.end()) ? &i->second : nullptr; } + std::vector> filtered(const QStringList &words) const; ~IndexedList(); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index d8dd8c2739..81f095ec10 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -1685,81 +1685,24 @@ void DialogsInner::applyFilterUpdate(QString newFilter, bool force) { if (_filter.isEmpty() && !_searchFromUser) { clearFilter(); } else { - QStringList::const_iterator fb = words.cbegin(), fe = words.cend(), fi; - _state = State::Filtered; _waitingForSearch = true; _filterResults.clear(); _filterResultsGlobal.clear(); + const auto append = [&](not_null list) { + const auto results = list->filtered(words); + _filterResults.insert( + end(_filterResults), + begin(results), + end(results)); + }; if (!_searchInChat && !words.isEmpty()) { - const Dialogs::List *toFilter = nullptr; - if (const auto list = session().data().chatsList()->indexed(); !list->empty()) { - for (fi = fb; fi != fe; ++fi) { - const auto found = list->filtered(fi->at(0)); - if (!found || found->empty()) { - toFilter = nullptr; - break; - } - if (!toFilter || toFilter->size() > found->size()) { - toFilter = found; - } - } - } - const Dialogs::List *toFilterContacts = nullptr; - if (const auto list = session().data().contactsNoChatsList(); !list->empty()) { - for (fi = fb; fi != fe; ++fi) { - const auto found = list->filtered(fi->at(0)); - if (!found || found->empty()) { - toFilterContacts = nullptr; - break; - } - if (!toFilterContacts || toFilterContacts->size() > found->size()) { - toFilterContacts = found; - } - } - } - _filterResults.reserve((toFilter ? toFilter->size() : 0) - + (toFilterContacts ? toFilterContacts->size() : 0)); - if (toFilter) { - for (const auto row : *toFilter) { - const auto &nameWords = row->entry()->chatListNameWords(); - auto nb = nameWords.cbegin(), ne = nameWords.cend(), ni = nb; - for (fi = fb; fi != fe; ++fi) { - auto filterWord = *fi; - for (ni = nb; ni != ne; ++ni) { - if (ni->startsWith(filterWord)) { - break; - } - } - if (ni == ne) { - break; - } - } - if (fi == fe) { - _filterResults.push_back(row); - } - } - } - if (toFilterContacts) { - for (const auto row : *toFilterContacts) { - const auto &nameWords = row->entry()->chatListNameWords(); - auto nb = nameWords.cbegin(), ne = nameWords.cend(), ni = nb; - for (fi = fb; fi != fe; ++fi) { - auto filterWord = *fi; - for (ni = nb; ni != ne; ++ni) { - if (ni->startsWith(filterWord)) { - break; - } - } - if (ni == ne) { - break; - } - } - if (fi == fe) { - _filterResults.push_back(row); - } - } + append(session().data().chatsList()->indexed()); + const auto id = Data::Folder::kId; + if (const auto folder = session().data().folderLoaded(id)) { + append(folder->chatsList()->indexed()); } + append(session().data().contactsNoChatsList()); } refresh(true); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 9dace8978c..27626dc8b8 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -316,7 +316,7 @@ private: bool _hashtagDeleteSelected = false; bool _hashtagDeletePressed = false; - std::vector _filterResults; + std::vector> _filterResults; base::flat_map< not_null, std::unique_ptr> _filterResultsGlobal;