Moved out nested class for merged message search to separated file.

This commit is contained in:
23rd 2022-04-07 15:33:37 +03:00
parent 4ad31ce4e0
commit 08f2bbef4e
7 changed files with 192 additions and 160 deletions

View file

@ -131,6 +131,8 @@ PRIVATE
api/api_media.h api/api_media.h
api/api_messages_search.cpp api/api_messages_search.cpp
api/api_messages_search.h api/api_messages_search.h
api/api_messages_search_merged.cpp
api/api_messages_search_merged.h
api/api_peer_photo.cpp api/api_peer_photo.cpp
api/api_peer_photo.h api/api_peer_photo.h
api/api_polls.cpp api/api_polls.cpp

View file

@ -44,12 +44,9 @@ MessageIdsList HistoryItemsFromTL(
} // namespace } // namespace
MessagesSearch::MessagesSearch( MessagesSearch::MessagesSearch(not_null<History*> history)
not_null<Main::Session*> session, : _history(history)
not_null<History*> history) , _api(&history->session().mtp()) {
: _session(session)
, _history(history)
, _api(&session->mtp()) {
} }
void MessagesSearch::searchMessages(const QString &query, PeerData *from) { void MessagesSearch::searchMessages(const QString &query, PeerData *from) {
@ -115,7 +112,7 @@ void MessagesSearch::searchRequest() {
}).send(); }).send();
return _requestId; return _requestId;
}; };
_searchInHistoryRequest = _session->data().histories().sendRequest( _searchInHistoryRequest = _history->owner().histories().sendRequest(
_history, _history,
Data::Histories::RequestType::History, Data::Histories::RequestType::History,
std::move(callback)); std::move(callback));
@ -128,7 +125,7 @@ void MessagesSearch::searchReceived(
if (requestId != _requestId) { if (requestId != _requestId) {
return; return;
} }
auto &owner = _session->data(); auto &owner = _history->owner();
auto found = result.match([&](const MTPDmessages_messages &data) { auto found = result.match([&](const MTPDmessages_messages &data) {
if (_requestId != 0) { if (_requestId != 0) {
// Don't apply cached data! // Don't apply cached data!

View file

@ -13,10 +13,6 @@ class HistoryItem;
class History; class History;
class PeerData; class PeerData;
namespace Main {
class Session;
} // namespace Main
namespace Api { namespace Api {
struct FoundMessages { struct FoundMessages {
@ -27,9 +23,7 @@ struct FoundMessages {
class MessagesSearch final { class MessagesSearch final {
public: public:
explicit MessagesSearch( explicit MessagesSearch(not_null<History*> history);
not_null<Main::Session*> session,
not_null<History*> history);
void searchMessages(const QString &query, PeerData *from); void searchMessages(const QString &query, PeerData *from);
void searchMore(); void searchMore();
@ -44,7 +38,6 @@ private:
mtpRequestId requestId, mtpRequestId requestId,
const QString &nextToken); const QString &nextToken);
const not_null<Main::Session*> _session;
const not_null<History*> _history; const not_null<History*> _history;
MTP::Sender _api; MTP::Sender _api;

View file

@ -0,0 +1,113 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_messages_search_merged.h"
#include "history/history.h"
namespace Api {
bool MessagesSearchMerged::RequestCompare::operator()(
const Request &a,
const Request &b) const {
return (a.query < b.query) && (a.from < b.from);
}
MessagesSearchMerged::MessagesSearchMerged(not_null<History*> history)
: _apiSearch(history)
, _migratedSearch(history->migrateFrom()
? std::make_optional<MessagesSearch>(history->migrateFrom())
: std::nullopt) {
const auto checkWaitingForTotal = [=] {
if (_waitingForTotal) {
if (_concatedFound.total >= 0 && _migratedFirstFound.total >= 0) {
_waitingForTotal = false;
_concatedFound.total += _migratedFirstFound.total;
_newFounds.fire({});
}
} else {
_newFounds.fire({});
}
};
const auto checkFull = [=](const FoundMessages &data) {
if (data.total == int(_concatedFound.messages.size())) {
_isFull = true;
addFound(_migratedFirstFound);
}
};
_apiSearch.messagesFounds(
) | rpl::start_with_next([=](const FoundMessages &data) {
if (data.nextToken == _concatedFound.nextToken) {
addFound(data);
checkFull(data);
_nextFounds.fire({});
} else {
_concatedFound = data;
checkFull(data);
checkWaitingForTotal();
}
}, _lifetime);
if (_migratedSearch) {
_migratedSearch->messagesFounds(
) | rpl::start_with_next([=](const FoundMessages &data) {
if (_isFull) {
addFound(data);
}
if (data.nextToken == _migratedFirstFound.nextToken) {
_nextFounds.fire({});
} else {
_migratedFirstFound = data;
checkWaitingForTotal();
}
}, _lifetime);
}
}
void MessagesSearchMerged::addFound(const FoundMessages &data) {
for (const auto &message : data.messages) {
_concatedFound.messages.push_back(message);
}
}
const FoundMessages &MessagesSearchMerged::messages() const {
return _concatedFound;
}
void MessagesSearchMerged::clear() {
_concatedFound = {};
_migratedFirstFound = {};
}
void MessagesSearchMerged::search(const Request &search) {
if (_migratedSearch) {
_waitingForTotal = true;
_migratedSearch->searchMessages(search.query, search.from);
}
_apiSearch.searchMessages(search.query, search.from);
}
void MessagesSearchMerged::searchMore() {
if (_migratedSearch && _isFull) {
_migratedSearch->searchMore();
} else {
_apiSearch.searchMore();
}
}
rpl::producer<> MessagesSearchMerged::newFounds() const {
return _newFounds.events();
}
rpl::producer<> MessagesSearchMerged::nextFounds() const {
return _nextFounds.events();
}
} // namespace Api

View file

@ -0,0 +1,60 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "api/api_messages_search.h"
class History;
class PeerData;
namespace Api {
// Search in both of history and migrated history, if it exists.
class MessagesSearchMerged final {
public:
struct Request {
QString query;
PeerData *from = nullptr;
};
struct RequestCompare {
bool operator()(const Request &a, const Request &b) const;
};
using CachedRequests = std::set<Request, RequestCompare>;
MessagesSearchMerged(not_null<History*> history);
void clear();
void search(const Request &search);
void searchMore();
[[nodiscard]] const FoundMessages &messages() const;
[[nodiscard]] rpl::producer<> newFounds() const;
[[nodiscard]] rpl::producer<> nextFounds() const;
private:
void addFound(const FoundMessages &data);
MessagesSearch _apiSearch;
std::optional<MessagesSearch> _migratedSearch;
FoundMessages _migratedFirstFound;
FoundMessages _concatedFound;
bool _waitingForTotal = false;
bool _isFull = false;
rpl::event_stream<> _newFounds;
rpl::event_stream<> _nextFounds;
rpl::lifetime _lifetime;
};
} // namespace Api

View file

@ -184,7 +184,6 @@ void DeleteMessagesBox::prepare() {
st::defaultBoxCheckbox); st::defaultBoxCheckbox);
if (_moderateDeleteAll) { if (_moderateDeleteAll) {
const auto search = lifetime().make_state<Api::MessagesSearch>( const auto search = lifetime().make_state<Api::MessagesSearch>(
_session,
_session->data().message(_ids.front())->history()); _session->data().message(_ids.front())->history());
_deleteAll.create( _deleteAll.create(
this, this,

View file

@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "history/view/controls/history_view_compose_search.h" #include "history/view/controls/history_view_compose_search.h"
#include "api/api_messages_search.h" #include "api/api_messages_search_merged.h"
#include "boxes/peer_list_box.h" #include "boxes/peer_list_box.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "dialogs/dialogs_search_from_controllers.h" // SearchFromBox #include "dialogs/dialogs_search_from_controllers.h" // SearchFromBox
@ -29,6 +29,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView { namespace HistoryView {
namespace { namespace {
using SearchRequest = Api::MessagesSearchMerged::Request;
[[nodiscard]] inline bool HasChooseFrom(not_null<History*> history) { [[nodiscard]] inline bool HasChooseFrom(not_null<History*> history) {
if (const auto peer = history->peer) { if (const auto peer = history->peer) {
return (peer->isChat() || peer->isMegagroup()); return (peer->isChat() || peer->isMegagroup());
@ -36,11 +38,6 @@ namespace {
return false; return false;
} }
struct SearchRequest {
QString query;
PeerData *from = nullptr;
};
class Row final : public PeerListRow { class Row final : public PeerListRow {
public: public:
Row(std::unique_ptr<Dialogs::FakeRow> fakeRow); Row(std::unique_ptr<Dialogs::FakeRow> fakeRow);
@ -269,7 +266,7 @@ private:
base::Timer _searchTimer; base::Timer _searchTimer;
std::vector<SearchRequest> _typedRequests; Api::MessagesSearchMerged::CachedRequests _typedRequests;
rpl::event_stream<SearchRequest> _searchRequests; rpl::event_stream<SearchRequest> _searchRequests;
rpl::event_stream<> _queryChanges; rpl::event_stream<> _queryChanges;
@ -342,18 +339,17 @@ void TopBar::clearItems() {
void TopBar::requestSearch(bool cache) { void TopBar::requestSearch(bool cache) {
const auto search = SearchRequest{ _select->getQuery(), _from.current() }; const auto search = SearchRequest{ _select->getQuery(), _from.current() };
if (cache) { if (cache) {
_typedRequests.push_back(search); _typedRequests.insert(search);
} }
_searchRequests.fire_copy(search); _searchRequests.fire_copy(search);
} }
void TopBar::requestSearchDelayed() { void TopBar::requestSearchDelayed() {
// Check cached queries. // Check cached queries.
for (const auto &t : _typedRequests) { const auto search = SearchRequest{ _select->getQuery(), _from.current() };
if (t.query == _select->getQuery() && t.from == _from.current()) { if (_typedRequests.contains(search)) {
requestSearch(false); requestSearch(false);
return; return;
}
} }
_searchTimer.callOnce(AutoSearchTimeout); _searchTimer.callOnce(AutoSearchTimeout);
@ -575,134 +571,6 @@ void BottomBar::buttonCalendarToggleOn(rpl::producer<bool> &&visible) {
}, _jumpToDate->lifetime()); }, _jumpToDate->lifetime());
} }
class ApiSearch final {
public:
ApiSearch(not_null<Main::Session*> session, not_null<History*> history);
void clear();
void search(const SearchRequest &search);
void searchMore();
const Api::FoundMessages &messages() const;
[[nodiscard]] rpl::producer<> newFounds() const;
[[nodiscard]] rpl::producer<> nextFounds() const;
private:
void addFound(const Api::FoundMessages &data);
Api::MessagesSearch _apiSearch;
std::optional<Api::MessagesSearch> _migratedSearch;
Api::FoundMessages _migratedFirstFound;
Api::FoundMessages _concatedFound;
bool _waitingForTotal = false;
bool _isFull = false;
rpl::event_stream<> _newFounds;
rpl::event_stream<> _nextFounds;
rpl::lifetime _lifetime;
};
ApiSearch::ApiSearch(
not_null<Main::Session*> session,
not_null<History*> history)
: _apiSearch(session, history)
, _migratedSearch(history->migrateFrom()
? std::make_optional<Api::MessagesSearch>(session, history->migrateFrom())
: std::nullopt) {
const auto checkWaitingForTotal = [=] {
if (_waitingForTotal) {
if (_concatedFound.total >= 0 && _migratedFirstFound.total >= 0) {
_waitingForTotal = false;
_concatedFound.total += _migratedFirstFound.total;
_newFounds.fire({});
}
} else {
_newFounds.fire({});
}
};
const auto checkFull = [=](const Api::FoundMessages &data) {
if (data.total == int(_concatedFound.messages.size())) {
_isFull = true;
addFound(_migratedFirstFound);
}
};
_apiSearch.messagesFounds(
) | rpl::start_with_next([=](const Api::FoundMessages &data) {
if (data.nextToken == _concatedFound.nextToken) {
addFound(data);
checkFull(data);
_nextFounds.fire({});
} else {
_concatedFound = data;
checkFull(data);
checkWaitingForTotal();
}
}, _lifetime);
if (_migratedSearch) {
_migratedSearch->messagesFounds(
) | rpl::start_with_next([=](const Api::FoundMessages &data) {
if (_isFull) {
addFound(data);
}
if (data.nextToken == _migratedFirstFound.nextToken) {
_nextFounds.fire({});
} else {
_migratedFirstFound = data;
checkWaitingForTotal();
}
}, _lifetime);
}
}
void ApiSearch::addFound(const Api::FoundMessages &data) {
for (const auto &message : data.messages) {
_concatedFound.messages.push_back(message);
}
}
const Api::FoundMessages &ApiSearch::messages() const {
return _concatedFound;
}
void ApiSearch::clear() {
_concatedFound = {};
_migratedFirstFound = {};
}
void ApiSearch::search(const SearchRequest &search) {
if (_migratedSearch) {
_waitingForTotal = true;
_migratedSearch->searchMessages(search.query, search.from);
}
_apiSearch.searchMessages(search.query, search.from);
}
void ApiSearch::searchMore() {
if (_migratedSearch && _isFull) {
_migratedSearch->searchMore();
} else {
_apiSearch.searchMore();
}
}
rpl::producer<> ApiSearch::newFounds() const {
return _newFounds.events();
}
rpl::producer<> ApiSearch::nextFounds() const {
return _nextFounds.events();
}
} // namespace } // namespace
class ComposeSearch::Inner final { class ComposeSearch::Inner final {
@ -729,7 +597,7 @@ private:
const base::unique_qptr<BottomBar> _bottomBar; const base::unique_qptr<BottomBar> _bottomBar;
const List _list; const List _list;
ApiSearch _apiSearch; Api::MessagesSearchMerged _apiSearch;
struct { struct {
struct { struct {
@ -752,7 +620,7 @@ ComposeSearch::Inner::Inner(
, _topBar(base::make_unique_q<TopBar>(parent)) , _topBar(base::make_unique_q<TopBar>(parent))
, _bottomBar(base::make_unique_q<BottomBar>(parent, HasChooseFrom(history))) , _bottomBar(base::make_unique_q<BottomBar>(parent, HasChooseFrom(history)))
, _list(CreateList(parent, history)) , _list(CreateList(parent, history))
, _apiSearch(&window->session(), history) { , _apiSearch(history) {
showAnimated(); showAnimated();
rpl::combine( rpl::combine(