mirror of https://github.com/procxx/kepka.git
Add archived results in chats search.
This commit is contained in:
parent
40532e32ab
commit
01d5589594
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_folder.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
@ -235,9 +236,7 @@ void ChatsListBoxController::prepare() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Auth().data().chatsListChanges(
|
Auth().data().chatsListChanges(
|
||||||
) | rpl::filter([=](Data::Folder *folder) {
|
) | rpl::start_with_next([=] {
|
||||||
return !folder;
|
|
||||||
}) | rpl::start_with_next([=] {
|
|
||||||
rebuildRows();
|
rebuildRows();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
@ -267,6 +266,10 @@ void ChatsListBoxController::rebuildRows() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
added += appendList(Auth().data().chatsList()->indexed());
|
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());
|
added += appendList(Auth().data().contactsNoChatsList());
|
||||||
if (!wasEmpty && added > 0) {
|
if (!wasEmpty && added > 0) {
|
||||||
// Place dialogs list before contactsNoDialogs list.
|
// Place dialogs list before contactsNoDialogs list.
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_folder.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "dialogs/dialogs_indexed_list.h"
|
#include "dialogs/dialogs_indexed_list.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
|
@ -1060,7 +1061,6 @@ void AddSpecialBoxSearchController::addChatsContacts() {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto getSmallestIndex = [&](not_null<Dialogs::IndexedList*> list)
|
const auto getSmallestIndex = [&](not_null<Dialogs::IndexedList*> list)
|
||||||
-> const Dialogs::List* {
|
-> const Dialogs::List* {
|
||||||
if (list->empty()) {
|
if (list->empty()) {
|
||||||
|
@ -1079,17 +1079,12 @@ void AddSpecialBoxSearchController::addChatsContacts() {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
const auto dialogsIndex = getSmallestIndex(
|
const auto filterAndAppend = [&](not_null<Dialogs::IndexedList*> list) {
|
||||||
_peer->owner().chatsList()->indexed());
|
const auto index = getSmallestIndex(list);
|
||||||
const auto contactsIndex = getSmallestIndex(
|
if (!index) {
|
||||||
_peer->owner().contactsNoChatsList());
|
|
||||||
|
|
||||||
const auto filterAndAppend = [&](const Dialogs::List *list) {
|
|
||||||
if (!list) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (const auto row : *index) {
|
||||||
for (const auto row : *list) {
|
|
||||||
if (const auto history = row->history()) {
|
if (const auto history = row->history()) {
|
||||||
if (const auto user = history->peer->asUser()) {
|
if (const auto user = history->peer->asUser()) {
|
||||||
if (allWordsAreFound(user->nameWords())) {
|
if (allWordsAreFound(user->nameWords())) {
|
||||||
|
@ -1099,7 +1094,11 @@ void AddSpecialBoxSearchController::addChatsContacts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
filterAndAppend(dialogsIndex);
|
filterAndAppend(_peer->owner().chatsList()->indexed());
|
||||||
filterAndAppend(contactsIndex);
|
const auto id = Data::Folder::kId;
|
||||||
|
if (const auto folder = _peer->owner().folderLoaded(id)) {
|
||||||
|
filterAndAppend(folder->chatsList()->indexed());
|
||||||
|
}
|
||||||
|
filterAndAppend(_peer->owner().contactsNoChatsList());
|
||||||
delegate()->peerListSearchRefreshRows();
|
delegate()->peerListSearchRefreshRows();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_folder.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -131,7 +132,7 @@ private:
|
||||||
ShareBox::FilterCallback _filterCallback;
|
ShareBox::FilterCallback _filterCallback;
|
||||||
std::unique_ptr<Dialogs::IndexedList> _chatsIndexed;
|
std::unique_ptr<Dialogs::IndexedList> _chatsIndexed;
|
||||||
QString _filter;
|
QString _filter;
|
||||||
std::vector<Dialogs::Row*> _filtered;
|
std::vector<not_null<Dialogs::Row*>> _filtered;
|
||||||
|
|
||||||
std::map<not_null<PeerData*>, std::unique_ptr<Chat>> _dataMap;
|
std::map<not_null<PeerData*>, std::unique_ptr<Chat>> _dataMap;
|
||||||
base::flat_set<not_null<PeerData*>> _selected;
|
base::flat_set<not_null<PeerData*>> _selected;
|
||||||
|
@ -489,19 +490,26 @@ ShareBox::Inner::Inner(
|
||||||
_rowHeight = st::shareRowHeight;
|
_rowHeight = st::shareRowHeight;
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
const auto dialogs = Auth().data().chatsList()->indexed();
|
|
||||||
const auto self = Auth().user();
|
const auto self = Auth().user();
|
||||||
if (_filterCallback(self)) {
|
if (_filterCallback(self)) {
|
||||||
_chatsIndexed->addToEnd(self->owner().history(self));
|
_chatsIndexed->addToEnd(self->owner().history(self));
|
||||||
}
|
}
|
||||||
for (const auto row : dialogs->all()) {
|
const auto addList = [&](not_null<Dialogs::IndexedList*> list) {
|
||||||
if (const auto history = row->history()) {
|
for (const auto row : list->all()) {
|
||||||
if (!history->peer->isSelf()
|
if (const auto history = row->history()) {
|
||||||
&& _filterCallback(history->peer)) {
|
if (!history->peer->isSelf()
|
||||||
_chatsIndexed->addToEnd(history);
|
&& _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");
|
_filter = qsl("a");
|
||||||
updateFilter();
|
updateFilter();
|
||||||
|
@ -603,7 +611,7 @@ ShareBox::Inner::Chat *ShareBox::Inner::getChatAtIndex(int index) {
|
||||||
return _chatsIndexed->rowAtY(index, 1);
|
return _chatsIndexed->rowAtY(index, 1);
|
||||||
}
|
}
|
||||||
return (index < _filtered.size())
|
return (index < _filtered.size())
|
||||||
? _filtered[index]
|
? _filtered[index].get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}();
|
}();
|
||||||
if (row) {
|
if (row) {
|
||||||
|
@ -944,45 +952,7 @@ void ShareBox::Inner::updateFilter(QString filter) {
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
refresh();
|
refresh();
|
||||||
} else {
|
} else {
|
||||||
QStringList::const_iterator fb = words.cbegin(), fe = words.cend(), fi;
|
_filtered = _chatsIndexed->filtered(words);
|
||||||
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
_searching = true;
|
_searching = true;
|
||||||
|
|
|
@ -983,7 +983,7 @@ void Session::setupUserIsContactViewer() {
|
||||||
if (user->contactStatus() == UserData::ContactStatus::Contact) {
|
if (user->contactStatus() == UserData::ContactStatus::Contact) {
|
||||||
const auto history = user->owner().history(user->id);
|
const auto history = user->owner().history(user->id);
|
||||||
_contactsList.addByName(history);
|
_contactsList.addByName(history);
|
||||||
if (!_chatsList.indexed()->contains(history)) {
|
if (!history->inChatList()) {
|
||||||
_contactsNoChatsList.addByName(history);
|
_contactsNoChatsList.addByName(history);
|
||||||
}
|
}
|
||||||
} else if (const auto history = user->owner().historyLoaded(user)) {
|
} else if (const auto history = user->owner().historyLoaded(user)) {
|
||||||
|
|
|
@ -200,6 +200,56 @@ void IndexedList::clear() {
|
||||||
_index.clear();
|
_index.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<not_null<Row*>> 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<not_null<Row*>>();
|
||||||
|
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() {
|
IndexedList::~IndexedList() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
const auto i = _index.find(ch);
|
const auto i = _index.find(ch);
|
||||||
return (i != _index.end()) ? &i->second : nullptr;
|
return (i != _index.end()) ? &i->second : nullptr;
|
||||||
}
|
}
|
||||||
|
std::vector<not_null<Row*>> filtered(const QStringList &words) const;
|
||||||
|
|
||||||
~IndexedList();
|
~IndexedList();
|
||||||
|
|
||||||
|
|
|
@ -1685,81 +1685,24 @@ void DialogsInner::applyFilterUpdate(QString newFilter, bool force) {
|
||||||
if (_filter.isEmpty() && !_searchFromUser) {
|
if (_filter.isEmpty() && !_searchFromUser) {
|
||||||
clearFilter();
|
clearFilter();
|
||||||
} else {
|
} else {
|
||||||
QStringList::const_iterator fb = words.cbegin(), fe = words.cend(), fi;
|
|
||||||
|
|
||||||
_state = State::Filtered;
|
_state = State::Filtered;
|
||||||
_waitingForSearch = true;
|
_waitingForSearch = true;
|
||||||
_filterResults.clear();
|
_filterResults.clear();
|
||||||
_filterResultsGlobal.clear();
|
_filterResultsGlobal.clear();
|
||||||
|
const auto append = [&](not_null<Dialogs::IndexedList*> list) {
|
||||||
|
const auto results = list->filtered(words);
|
||||||
|
_filterResults.insert(
|
||||||
|
end(_filterResults),
|
||||||
|
begin(results),
|
||||||
|
end(results));
|
||||||
|
};
|
||||||
if (!_searchInChat && !words.isEmpty()) {
|
if (!_searchInChat && !words.isEmpty()) {
|
||||||
const Dialogs::List *toFilter = nullptr;
|
append(session().data().chatsList()->indexed());
|
||||||
if (const auto list = session().data().chatsList()->indexed(); !list->empty()) {
|
const auto id = Data::Folder::kId;
|
||||||
for (fi = fb; fi != fe; ++fi) {
|
if (const auto folder = session().data().folderLoaded(id)) {
|
||||||
const auto found = list->filtered(fi->at(0));
|
append(folder->chatsList()->indexed());
|
||||||
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().contactsNoChatsList());
|
||||||
}
|
}
|
||||||
refresh(true);
|
refresh(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -316,7 +316,7 @@ private:
|
||||||
bool _hashtagDeleteSelected = false;
|
bool _hashtagDeleteSelected = false;
|
||||||
bool _hashtagDeletePressed = false;
|
bool _hashtagDeletePressed = false;
|
||||||
|
|
||||||
std::vector<Dialogs::Row*> _filterResults;
|
std::vector<not_null<Dialogs::Row*>> _filterResults;
|
||||||
base::flat_map<
|
base::flat_map<
|
||||||
not_null<PeerData*>,
|
not_null<PeerData*>,
|
||||||
std::unique_ptr<Dialogs::Row>> _filterResultsGlobal;
|
std::unique_ptr<Dialogs::Row>> _filterResultsGlobal;
|
||||||
|
|
Loading…
Reference in New Issue