mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added initial implementation of separated api class for message search.
This commit is contained in:
parent
41eb223bbf
commit
12fbb53ada
3 changed files with 236 additions and 0 deletions
|
@ -129,6 +129,8 @@ PRIVATE
|
||||||
api/api_invite_links.h
|
api/api_invite_links.h
|
||||||
api/api_media.cpp
|
api/api_media.cpp
|
||||||
api/api_media.h
|
api/api_media.h
|
||||||
|
api/api_messages_search.cpp
|
||||||
|
api/api_messages_search.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
|
||||||
|
|
173
Telegram/SourceFiles/api/api_messages_search.cpp
Normal file
173
Telegram/SourceFiles/api/api_messages_search.cpp
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/*
|
||||||
|
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.h"
|
||||||
|
|
||||||
|
#include "apiwrap.h"
|
||||||
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_histories.h"
|
||||||
|
#include "data/data_peer.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
MessageIdsList HistoryItemsFromTL(
|
||||||
|
not_null<Data::Session*> data,
|
||||||
|
const QVector<MTPMessage> &messages) {
|
||||||
|
auto result = MessageIdsList();
|
||||||
|
for (const auto &message : messages) {
|
||||||
|
const auto peerId = PeerFromMessage(message);
|
||||||
|
if (const auto peer = data->peerLoaded(peerId)) {
|
||||||
|
if (const auto lastDate = DateFromMessage(message)) {
|
||||||
|
const auto item = data->addNewMessage(
|
||||||
|
message,
|
||||||
|
MessageFlags(),
|
||||||
|
NewMessageType::Existing);
|
||||||
|
result.push_back(item->fullId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(("API Error: a search results with not loaded peer %1"
|
||||||
|
).arg(peerId.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
MessagesSearch::MessagesSearch(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
not_null<History*> history)
|
||||||
|
: _session(session)
|
||||||
|
, _history(history)
|
||||||
|
, _api(&session->mtp()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagesSearch::searchMessages(const QString &query, PeerData *from) {
|
||||||
|
_query = query;
|
||||||
|
_from = from;
|
||||||
|
_offsetId = {};
|
||||||
|
searchRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagesSearch::searchMore() {
|
||||||
|
if (_searchInHistoryRequest || _requestId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
searchRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagesSearch::searchRequest() {
|
||||||
|
const auto nextToken = _query
|
||||||
|
+ QString::number(_from ? _from->id.value : 0);
|
||||||
|
auto callback = [=](Fn<void()> finish) {
|
||||||
|
const auto flags = _from
|
||||||
|
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
|
||||||
|
: MTP_flags(0);
|
||||||
|
_requestId = _api.request(MTPmessages_Search(
|
||||||
|
flags,
|
||||||
|
_history->peer->input,
|
||||||
|
MTP_string(_query),
|
||||||
|
(_from
|
||||||
|
? _from->input
|
||||||
|
: MTP_inputPeerEmpty()),
|
||||||
|
MTPint(), // top_msg_id
|
||||||
|
MTP_inputMessagesFilterEmpty(),
|
||||||
|
MTP_int(0), // min_date
|
||||||
|
MTP_int(0), // max_date
|
||||||
|
MTP_int(_offsetId), // offset_id
|
||||||
|
MTP_int(0), // add_offset
|
||||||
|
MTP_int(SearchPerPage),
|
||||||
|
MTP_int(0), // max_id
|
||||||
|
MTP_int(0), // min_id
|
||||||
|
MTP_long(0) // hash
|
||||||
|
)).done([=](const MTPmessages_Messages &result, mtpRequestId id) {
|
||||||
|
_searchInHistoryRequest = 0;
|
||||||
|
searchReceived(result, id, nextToken);
|
||||||
|
finish();
|
||||||
|
}).fail([=](const MTP::Error &error, mtpRequestId id) {
|
||||||
|
_searchInHistoryRequest = 0;
|
||||||
|
|
||||||
|
if (error.type() == u"SEARCH_QUERY_EMPTY"_q) {
|
||||||
|
_messagesFounds.fire({ 0, MessageIdsList(), nextToken });
|
||||||
|
} else if (_requestId == id) {
|
||||||
|
_requestId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish();
|
||||||
|
}).send();
|
||||||
|
return _requestId;
|
||||||
|
};
|
||||||
|
_searchInHistoryRequest = _session->data().histories().sendRequest(
|
||||||
|
_history,
|
||||||
|
Data::Histories::RequestType::History,
|
||||||
|
std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagesSearch::searchReceived(
|
||||||
|
const MTPmessages_Messages &result,
|
||||||
|
mtpRequestId requestId,
|
||||||
|
const QString &nextToken) {
|
||||||
|
if (requestId != _requestId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto &owner = _session->data();
|
||||||
|
auto found = result.match([&](const MTPDmessages_messages &data) {
|
||||||
|
if (_requestId != 0) {
|
||||||
|
// Don't apply cached data!
|
||||||
|
owner.processUsers(data.vusers());
|
||||||
|
owner.processChats(data.vchats());
|
||||||
|
}
|
||||||
|
auto items = HistoryItemsFromTL(&owner, data.vmessages().v);
|
||||||
|
const auto total = int(data.vmessages().v.size());
|
||||||
|
return FoundMessages{ total, std::move(items), nextToken };
|
||||||
|
}, [&](const MTPDmessages_messagesSlice &data) {
|
||||||
|
if (_requestId != 0) {
|
||||||
|
// Don't apply cached data!
|
||||||
|
owner.processUsers(data.vusers());
|
||||||
|
owner.processChats(data.vchats());
|
||||||
|
}
|
||||||
|
auto items = HistoryItemsFromTL(&owner, data.vmessages().v);
|
||||||
|
// data.vnext_rate() is used only in global search.
|
||||||
|
const auto total = int(data.vcount().v);
|
||||||
|
return FoundMessages{ total, std::move(items), nextToken };
|
||||||
|
}, [&](const MTPDmessages_channelMessages &data) {
|
||||||
|
if (const auto channel = _history->peer->asChannel()) {
|
||||||
|
channel->ptsReceived(data.vpts().v);
|
||||||
|
} else {
|
||||||
|
LOG(("API Error: "
|
||||||
|
"received messages.channelMessages when no channel "
|
||||||
|
"was passed!"));
|
||||||
|
}
|
||||||
|
if (_requestId != 0) {
|
||||||
|
// Don't apply cached data!
|
||||||
|
owner.processUsers(data.vusers());
|
||||||
|
owner.processChats(data.vchats());
|
||||||
|
}
|
||||||
|
auto items = HistoryItemsFromTL(&owner, data.vmessages().v);
|
||||||
|
const auto total = int(data.vmessages().v.size());
|
||||||
|
return FoundMessages{ total, std::move(items), nextToken };
|
||||||
|
}, [](const MTPDmessages_messagesNotModified &data) {
|
||||||
|
return FoundMessages{};
|
||||||
|
});
|
||||||
|
_requestId = 0;
|
||||||
|
_offsetId = found.messages.empty()
|
||||||
|
? MsgId()
|
||||||
|
: found.messages.back().msg;
|
||||||
|
_messagesFounds.fire(std::move(found));
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<FoundMessages> MessagesSearch::messagesFounds() const {
|
||||||
|
return _messagesFounds.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Api
|
61
Telegram/SourceFiles/api/api_messages_search.h
Normal file
61
Telegram/SourceFiles/api/api_messages_search.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
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 "mtproto/sender.h"
|
||||||
|
|
||||||
|
class HistoryItem;
|
||||||
|
class History;
|
||||||
|
class PeerData;
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class Session;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
|
||||||
|
struct FoundMessages {
|
||||||
|
int total = -1;
|
||||||
|
MessageIdsList messages;
|
||||||
|
QString nextToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MessagesSearch final {
|
||||||
|
public:
|
||||||
|
explicit MessagesSearch(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
not_null<History*> history);
|
||||||
|
|
||||||
|
void searchMessages(const QString &query, PeerData *from);
|
||||||
|
void searchMore();
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<FoundMessages> messagesFounds() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void searchRequest();
|
||||||
|
void searchReceived(
|
||||||
|
const MTPmessages_Messages &result,
|
||||||
|
mtpRequestId requestId,
|
||||||
|
const QString &nextToken);
|
||||||
|
|
||||||
|
const not_null<Main::Session*> _session;
|
||||||
|
const not_null<History*> _history;
|
||||||
|
MTP::Sender _api;
|
||||||
|
|
||||||
|
QString _query;
|
||||||
|
PeerData *_from = nullptr;
|
||||||
|
MsgId _offsetId;
|
||||||
|
|
||||||
|
int _searchInHistoryRequest = 0; // Not real mtpRequestId.
|
||||||
|
mtpRequestId _requestId = 0;
|
||||||
|
|
||||||
|
rpl::event_stream<FoundMessages> _messagesFounds;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Api
|
Loading…
Add table
Reference in a new issue