Search through Histories.

This commit is contained in:
John Preston 2020-02-21 16:57:06 +04:00
parent 6f672ecdc3
commit ec7a2dce2f
6 changed files with 168 additions and 110 deletions

View File

@ -549,7 +549,8 @@ int Histories::sendRequest(
Expects(type != RequestType::None); Expects(type != RequestType::None);
auto &state = _states[history]; auto &state = _states[history];
const auto id = ++state.autoincrement; const auto id = ++_requestAutoincrement;
_historyByRequest.emplace(id, history);
if (type == RequestType::History && postponeHistoryRequest(state)) { if (type == RequestType::History && postponeHistoryRequest(state)) {
state.postponed.emplace( state.postponed.emplace(
id, id,
@ -593,19 +594,24 @@ void Histories::checkPostponed(not_null<History*> history, int id) {
finishSentRequest(history, state, id); finishSentRequest(history, state, id);
} }
void Histories::cancelRequest(not_null<History*> history, int id) { void Histories::cancelRequest(int id) {
const auto state = lookup(history); const auto history = _historyByRequest.take(id);
if (!history) {
return;
}
const auto state = lookup(*history);
if (!state) { if (!state) {
return; return;
} }
state->postponed.remove(id); state->postponed.remove(id);
finishSentRequest(history, state, id); finishSentRequest(*history, state, id);
} }
void Histories::finishSentRequest( void Histories::finishSentRequest(
not_null<History*> history, not_null<History*> history,
not_null<State*> state, not_null<State*> state,
int id) { int id) {
_historyByRequest.remove(id);
state->sent.remove(id); state->sent.remove(id);
if (!state->postponed.empty() && !postponeHistoryRequest(*state)) { if (!state->postponed.empty() && !postponeHistoryRequest(*state)) {
for (auto &[id, postponed] : base::take(state->postponed)) { for (auto &[id, postponed] : base::take(state->postponed)) {
@ -626,6 +632,7 @@ void Histories::finishSentRequest(
history, history,
std::move(i->second)); std::move(i->second));
Assert(ok); Assert(ok);
_dialogRequests.erase(i);
state->postponedRequestEntry = false; state->postponedRequestEntry = false;
} }
checkEmptyState(history); checkEmptyState(history);

View File

@ -72,7 +72,7 @@ public:
not_null<History*> history, not_null<History*> history,
RequestType type, RequestType type,
Fn<mtpRequestId(Fn<void()> finish)> generator); Fn<mtpRequestId(Fn<void()> finish)> generator);
void cancelRequest(not_null<History*> history, int id); void cancelRequest(int id);
private: private:
struct PostponedHistoryRequest { struct PostponedHistoryRequest {
@ -88,7 +88,6 @@ private:
base::flat_map<int, SentRequest> sent; base::flat_map<int, SentRequest> sent;
crl::time readWhen = 0; crl::time readWhen = 0;
MsgId readTill = 0; MsgId readTill = 0;
int autoincrement = 0;
bool postponedRequestEntry = false; bool postponedRequestEntry = false;
}; };
@ -112,6 +111,8 @@ private:
std::unordered_map<PeerId, std::unique_ptr<History>> _map; std::unordered_map<PeerId, std::unique_ptr<History>> _map;
base::flat_map<not_null<History*>, State> _states; base::flat_map<not_null<History*>, State> _states;
base::flat_map<int, not_null<History*>> _historyByRequest;
int _requestAutoincrement = 0;
base::Timer _readRequestsTimer; base::Timer _readRequestsTimer;
base::flat_set<not_null<Data::Folder*>> _dialogFolderRequests; base::flat_set<not_null<Data::Folder*>> _dialogFolderRequests;

View File

@ -369,7 +369,7 @@ void SearchController::requestMore(
return; return;
} }
auto &histories = _session->data().histories(); auto &histories = _session->data().histories();
const auto type = Histories::RequestType::History; const auto type = ::Data::Histories::RequestType::History;
const auto history = _session->data().history(listData->peer); const auto history = _session->data().history(listData->peer);
auto requestId = histories.sendRequest(history, type, [=](Fn<void()> finish) { auto requestId = histories.sendRequest(history, type, [=](Fn<void()> finish) {
return _api.request( return _api.request(
@ -392,8 +392,7 @@ void SearchController::requestMore(
}).send(); }).send();
}); });
listData->requests.emplace(key, [=] { listData->requests.emplace(key, [=] {
auto &histories = _session->data().histories(); _session->data().histories().cancelRequest(requestId);
histories.cancelRequest(history, requestId);
}); });
} }

View File

@ -38,6 +38,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_folder.h" #include "data/data_folder.h"
#include "data/data_histories.h"
#include "facades.h" #include "facades.h"
#include "app.h" #include "app.h"
#include "styles/style_dialogs.h" #include "styles/style_dialogs.h"
@ -392,6 +393,7 @@ void Widget::fullSearchRefreshOn(rpl::producer<> events) {
_searchQueries.clear(); _searchQueries.clear();
_searchQuery = QString(); _searchQuery = QString();
_scroll->scrollToY(0); _scroll->scrollToY(0);
cancelSearchRequest();
onSearchMessages(); onSearchMessages();
}, lifetime()); }, lifetime());
} }
@ -736,7 +738,7 @@ bool Widget::onSearchMessages(bool searchCache) {
auto result = false; auto result = false;
auto q = _filter->getLastText().trimmed(); auto q = _filter->getLastText().trimmed();
if (q.isEmpty() && !_searchFromUser) { if (q.isEmpty() && !_searchFromUser) {
MTP::cancel(base::take(_searchRequest)); cancelSearchRequest();
MTP::cancel(base::take(_peerSearchRequest)); MTP::cancel(base::take(_peerSearchRequest));
return true; return true;
} }
@ -753,7 +755,7 @@ bool Widget::onSearchMessages(bool searchCache) {
_searchQueryFrom = _searchFromUser; _searchQueryFrom = _searchFromUser;
_searchNextRate = 0; _searchNextRate = 0;
_searchFull = _searchFullMigrated = false; _searchFull = _searchFullMigrated = false;
MTP::cancel(base::take(_searchRequest)); cancelSearchRequest();
searchReceived( searchReceived(
_searchInChat _searchInChat
? SearchRequestType::PeerFromStart ? SearchRequestType::PeerFromStart
@ -767,19 +769,23 @@ bool Widget::onSearchMessages(bool searchCache) {
_searchQueryFrom = _searchFromUser; _searchQueryFrom = _searchFromUser;
_searchNextRate = 0; _searchNextRate = 0;
_searchFull = _searchFullMigrated = false; _searchFull = _searchFullMigrated = false;
MTP::cancel(base::take(_searchRequest)); cancelSearchRequest();
if (const auto peer = _searchInChat.peer()) { if (const auto peer = _searchInChat.peer()) {
const auto flags = _searchQueryFrom auto &histories = session().data().histories();
? MTP_flags(MTPmessages_Search::Flag::f_from_id) const auto type = Data::Histories::RequestType::History;
: MTP_flags(0); const auto history = session().data().history(peer);
_searchRequest = MTP::send( _searchInHistoryRequest = histories.sendRequest(history, type, [=](Fn<void()> finish) {
MTPmessages_Search( const auto type = SearchRequestType::PeerFromStart;
const auto flags = _searchQueryFrom
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
: MTP_flags(0);
_searchRequest = session().api().request(MTPmessages_Search(
flags, flags,
peer->input, peer->input,
MTP_string(_searchQuery), MTP_string(_searchQuery),
_searchQueryFrom (_searchQueryFrom
? _searchQueryFrom->inputUser ? _searchQueryFrom->inputUser
: MTP_inputUserEmpty(), : MTP_inputUserEmpty()),
MTP_inputMessagesFilterEmpty(), MTP_inputMessagesFilterEmpty(),
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),
@ -788,9 +794,17 @@ bool Widget::onSearchMessages(bool searchCache) {
MTP_int(SearchPerPage), MTP_int(SearchPerPage),
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),
MTP_int(0)), MTP_int(0)
rpcDone(&Widget::searchReceived, SearchRequestType::PeerFromStart), )).done([=](const MTPmessages_Messages &result) {
rpcFail(&Widget::searchFailed, SearchRequestType::PeerFromStart)); searchReceived(type, result, _searchRequest);
finish();
}).fail([=](const RPCError &error) {
searchFailed(type, error, _searchRequest);
finish();
}).send();
_searchQueries.insert(_searchRequest, _searchQuery);
return _searchRequest;
});
//} else if (const auto feed = _searchInChat.feed()) { // #feed //} else if (const auto feed = _searchInChat.feed()) { // #feed
// _searchRequest = MTP::send( // _searchRequest = MTP::send(
// MTPchannels_SearchFeed( // MTPchannels_SearchFeed(
@ -802,6 +816,7 @@ bool Widget::onSearchMessages(bool searchCache) {
// MTP_int(SearchPerPage)), // MTP_int(SearchPerPage)),
// rpcDone(&Widget::searchReceived, SearchRequestType::FromStart), // rpcDone(&Widget::searchReceived, SearchRequestType::FromStart),
// rpcFail(&Widget::searchFailed, SearchRequestType::FromStart)); // rpcFail(&Widget::searchFailed, SearchRequestType::FromStart));
// _searchQueries.insert(_searchRequest, _searchQuery);
} else { } else {
const auto flags = session().settings().skipArchiveInSearch() const auto flags = session().settings().skipArchiveInSearch()
? MTPmessages_SearchGlobal::Flag::f_folder_id ? MTPmessages_SearchGlobal::Flag::f_folder_id
@ -818,8 +833,8 @@ bool Widget::onSearchMessages(bool searchCache) {
MTP_int(SearchPerPage)), MTP_int(SearchPerPage)),
rpcDone(&Widget::searchReceived, SearchRequestType::FromStart), rpcDone(&Widget::searchReceived, SearchRequestType::FromStart),
rpcFail(&Widget::searchFailed, SearchRequestType::FromStart)); rpcFail(&Widget::searchFailed, SearchRequestType::FromStart));
_searchQueries.insert(_searchRequest, _searchQuery);
} }
_searchQueries.insert(_searchRequest, _searchQuery);
} }
const auto query = Api::ConvertPeerSearchQuery(q); const auto query = Api::ConvertPeerSearchQuery(q);
if (searchForPeersRequired(query)) { if (searchForPeersRequired(query)) {
@ -906,93 +921,122 @@ void Widget::searchMessages(
} }
void Widget::onSearchMore() { void Widget::onSearchMore() {
if (!_searchRequest) { if (_searchRequest || _searchInHistoryRequest) {
if (!_searchFull) { return;
auto offsetPeer = _inner->lastSearchPeer(); }
auto offsetId = _inner->lastSearchId(); if (!_searchFull) {
if (const auto peer = _searchInChat.peer()) { auto offsetPeer = _inner->lastSearchPeer();
auto offsetId = _inner->lastSearchId();
if (const auto peer = _searchInChat.peer()) {
auto &histories = session().data().histories();
const auto type = Data::Histories::RequestType::History;
const auto history = session().data().history(peer);
_searchInHistoryRequest = histories.sendRequest(history, type, [=](Fn<void()> finish) {
const auto type = offsetId
? SearchRequestType::PeerFromOffset
: SearchRequestType::PeerFromStart;
auto flags = _searchQueryFrom auto flags = _searchQueryFrom
? MTP_flags(MTPmessages_Search::Flag::f_from_id) ? MTP_flags(MTPmessages_Search::Flag::f_from_id)
: MTP_flags(0); : MTP_flags(0);
_searchRequest = MTP::send( _searchRequest = session().api().request(MTPmessages_Search(
MTPmessages_Search(
flags,
peer->input,
MTP_string(_searchQuery),
_searchQueryFrom
? _searchQueryFrom->inputUser
: MTP_inputUserEmpty(),
MTP_inputMessagesFilterEmpty(),
MTP_int(0),
MTP_int(0),
MTP_int(offsetId),
MTP_int(0),
MTP_int(SearchPerPage),
MTP_int(0),
MTP_int(0),
MTP_int(0)),
rpcDone(&Widget::searchReceived, offsetId ? SearchRequestType::PeerFromOffset : SearchRequestType::PeerFromStart),
rpcFail(&Widget::searchFailed, offsetId ? SearchRequestType::PeerFromOffset : SearchRequestType::PeerFromStart));
//} else if (const auto feed = _searchInChat.feed()) { // #feed
// _searchRequest = MTP::send(
// MTPchannels_SearchFeed(
// MTP_int(feed->id()),
// MTP_string(_searchQuery),
// MTP_int(offsetDate),
// offsetPeer
// ? offsetPeer->input
// : MTP_inputPeerEmpty(),
// MTP_int(offsetId),
// MTP_int(SearchPerPage)),
// rpcDone(&Widget::searchReceived, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart),
// rpcFail(&Widget::searchFailed, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart));
} else {
const auto flags = session().settings().skipArchiveInSearch()
? MTPmessages_SearchGlobal::Flag::f_folder_id
: MTPmessages_SearchGlobal::Flag(0);
const auto folderId = 0;
_searchRequest = MTP::send(
MTPmessages_SearchGlobal(
MTP_flags(flags),
MTP_int(folderId),
MTP_string(_searchQuery),
MTP_int(_searchNextRate),
offsetPeer
? offsetPeer->input
: MTP_inputPeerEmpty(),
MTP_int(offsetId),
MTP_int(SearchPerPage)),
rpcDone(&Widget::searchReceived, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart),
rpcFail(&Widget::searchFailed, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart));
}
if (!offsetId) {
_searchQueries.insert(_searchRequest, _searchQuery);
}
} else if (_searchInMigrated && !_searchFullMigrated) {
auto offsetMigratedId = _inner->lastSearchMigratedId();
auto flags = _searchQueryFrom
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
: MTP_flags(0);
_searchRequest = MTP::send(
MTPmessages_Search(
flags, flags,
_searchInMigrated->peer->input, peer->input,
MTP_string(_searchQuery), MTP_string(_searchQuery),
_searchQueryFrom (_searchQueryFrom
? _searchQueryFrom->inputUser ? _searchQueryFrom->inputUser
: MTP_inputUserEmpty(), : MTP_inputUserEmpty()),
MTP_inputMessagesFilterEmpty(), MTP_inputMessagesFilterEmpty(),
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),
MTP_int(offsetMigratedId), MTP_int(offsetId),
MTP_int(0), MTP_int(0),
MTP_int(SearchPerPage), MTP_int(SearchPerPage),
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),
MTP_int(0)), MTP_int(0)
rpcDone(&Widget::searchReceived, offsetMigratedId ? SearchRequestType::MigratedFromOffset : SearchRequestType::MigratedFromStart), )).done([=](const MTPmessages_Messages &result) {
rpcFail(&Widget::searchFailed, offsetMigratedId ? SearchRequestType::MigratedFromOffset : SearchRequestType::MigratedFromStart)); searchReceived(type, result, _searchRequest);
}).fail([=](const RPCError &error) {
searchFailed(type, error, _searchRequest);
}).send();
if (!offsetId) {
_searchQueries.insert(_searchRequest, _searchQuery);
}
return _searchRequest;
});
//} else if (const auto feed = _searchInChat.feed()) { // #feed
// _searchRequest = MTP::send(
// MTPchannels_SearchFeed(
// MTP_int(feed->id()),
// MTP_string(_searchQuery),
// MTP_int(offsetDate),
// offsetPeer
// ? offsetPeer->input
// : MTP_inputPeerEmpty(),
// MTP_int(offsetId),
// MTP_int(SearchPerPage)),
// rpcDone(&Widget::searchReceived, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart),
// rpcFail(&Widget::searchFailed, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart));
// if (!offsetId) {
// _searchQueries.insert(_searchRequest, _searchQuery);
// }
} else {
const auto flags = session().settings().skipArchiveInSearch()
? MTPmessages_SearchGlobal::Flag::f_folder_id
: MTPmessages_SearchGlobal::Flag(0);
const auto folderId = 0;
_searchRequest = MTP::send(
MTPmessages_SearchGlobal(
MTP_flags(flags),
MTP_int(folderId),
MTP_string(_searchQuery),
MTP_int(_searchNextRate),
offsetPeer
? offsetPeer->input
: MTP_inputPeerEmpty(),
MTP_int(offsetId),
MTP_int(SearchPerPage)),
rpcDone(&Widget::searchReceived, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart),
rpcFail(&Widget::searchFailed, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart));
if (!offsetId) {
_searchQueries.insert(_searchRequest, _searchQuery);
}
} }
} else if (_searchInMigrated && !_searchFullMigrated) {
auto offsetMigratedId = _inner->lastSearchMigratedId();
auto &histories = session().data().histories();
const auto type = Data::Histories::RequestType::History;
const auto history = _searchInMigrated;
_searchInHistoryRequest = histories.sendRequest(history, type, [=](Fn<void()> finish) {
const auto type = offsetMigratedId
? SearchRequestType::MigratedFromOffset
: SearchRequestType::MigratedFromStart;
const auto flags = _searchQueryFrom
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
: MTP_flags(0);
_searchRequest = session().api().request(MTPmessages_Search(
flags,
_searchInMigrated->peer->input,
MTP_string(_searchQuery),
(_searchQueryFrom
? _searchQueryFrom->inputUser
: MTP_inputUserEmpty()),
MTP_inputMessagesFilterEmpty(),
MTP_int(0),
MTP_int(0),
MTP_int(offsetMigratedId),
MTP_int(0),
MTP_int(SearchPerPage),
MTP_int(0),
MTP_int(0),
MTP_int(0)
)).done([=](const MTPmessages_Messages &result) {
searchReceived(type, result, _searchRequest);
}).fail([=](const RPCError &error) {
searchFailed(type, error, _searchRequest);
}).send();
return _searchRequest;
});
} }
} }
@ -1319,7 +1363,7 @@ void Widget::clearSearchCache() {
_searchQueries.clear(); _searchQueries.clear();
_searchQuery = QString(); _searchQuery = QString();
_searchQueryFrom = nullptr; _searchQueryFrom = nullptr;
MTP::cancel(base::take(_searchRequest)); cancelSearchRequest();
} }
void Widget::showJumpToDate() { void Widget::showJumpToDate() {
@ -1615,12 +1659,20 @@ void Widget::removeDialog(Key key) {
_inner->removeDialog(key); _inner->removeDialog(key);
} }
bool Widget::onCancelSearch() { void Widget::cancelSearchRequest() {
bool clearing = !_filter->getLastText().isEmpty();
if (_searchRequest) { if (_searchRequest) {
MTP::cancel(_searchRequest); MTP::cancel(_searchRequest);
_searchRequest = 0; _searchRequest = 0;
} }
if (_searchInHistoryRequest) {
session().data().histories().cancelRequest(_searchInHistoryRequest);
_searchInHistoryRequest = 0;
}
}
bool Widget::onCancelSearch() {
bool clearing = !_filter->getLastText().isEmpty();
cancelSearchRequest();
if (_searchInChat && !clearing) { if (_searchInChat && !clearing) {
if (Adaptive::OneColumn()) { if (Adaptive::OneColumn()) {
if (const auto peer = _searchInChat.peer()) { if (const auto peer = _searchInChat.peer()) {
@ -1642,10 +1694,7 @@ bool Widget::onCancelSearch() {
} }
void Widget::onCancelSearchInChat() { void Widget::onCancelSearchInChat() {
if (_searchRequest) { cancelSearchRequest();
MTP::cancel(_searchRequest);
_searchRequest = 0;
}
if (_searchInChat) { if (_searchInChat) {
if (Adaptive::OneColumn() && !App::main()->selectingPeer()) { if (Adaptive::OneColumn() && !App::main()->selectingPeer()) {
if (const auto peer = _searchInChat.peer()) { if (const auto peer = _searchInChat.peer()) {

View File

@ -136,6 +136,7 @@ private:
const MTPcontacts_Found &result, const MTPcontacts_Found &result,
mtpRequestId requestId); mtpRequestId requestId);
void escape(); void escape();
void cancelSearchRequest();
void setupSupportMode(); void setupSupportMode();
void setupConnectingWidget(); void setupConnectingWidget();
@ -219,6 +220,7 @@ private:
int32 _searchNextRate = 0; int32 _searchNextRate = 0;
bool _searchFull = false; bool _searchFull = false;
bool _searchFullMigrated = false; bool _searchFullMigrated = false;
int _searchInHistoryRequest = 0; // Not real mtpRequestId.
mtpRequestId _searchRequest = 0; mtpRequestId _searchRequest = 0;
QMap<QString, MTPmessages_Messages> _searchCache; QMap<QString, MTPmessages_Messages> _searchCache;

View File

@ -1920,9 +1920,7 @@ void HistoryWidget::clearDelayedShowAt() {
_delayedShowAtMsgId = -1; _delayedShowAtMsgId = -1;
if (_delayedShowAtRequest) { if (_delayedShowAtRequest) {
_history->owner().histories().cancelRequest( _history->owner().histories().cancelRequest(_delayedShowAtRequest);
_history,
_delayedShowAtRequest);
_delayedShowAtRequest = 0; _delayedShowAtRequest = 0;
} }
} }
@ -1933,15 +1931,15 @@ void HistoryWidget::clearAllLoadRequests() {
auto &histories = _history->owner().histories(); auto &histories = _history->owner().histories();
clearDelayedShowAt(); clearDelayedShowAt();
if (_firstLoadRequest) { if (_firstLoadRequest) {
histories.cancelRequest(_history, _firstLoadRequest); histories.cancelRequest(_firstLoadRequest);
_firstLoadRequest = 0; _firstLoadRequest = 0;
} }
if (_preloadRequest) { if (_preloadRequest) {
histories.cancelRequest(_history, _preloadRequest); histories.cancelRequest(_preloadRequest);
_preloadRequest = 0; _preloadRequest = 0;
} }
if (_preloadDownRequest) { if (_preloadDownRequest) {
histories.cancelRequest(_history, _preloadDownRequest); histories.cancelRequest(_preloadDownRequest);
_preloadDownRequest = 0; _preloadDownRequest = 0;
} }
} }
@ -7032,6 +7030,8 @@ void HistoryWidget::synteticScrollToY(int y) {
} }
HistoryWidget::~HistoryWidget() { HistoryWidget::~HistoryWidget() {
clearAllLoadRequests(); if (_history) {
clearAllLoadRequests();
}
setTabbedPanel(nullptr); setTabbedPanel(nullptr);
} }