Skip to content

Commit

Permalink
[Search] Add search prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
Arseny Bochkarev committed Nov 7, 2024
1 parent ebff6c6 commit 3d8f962
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 0 deletions.
60 changes: 60 additions & 0 deletions Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ For license and copyright information please follow this link:

#include <QtWidgets/QApplication>

#include <iostream>

namespace Dialogs {
namespace {

Expand Down Expand Up @@ -3209,6 +3211,7 @@ void InnerWidget::searchReceived(
}
}
}

if (type.migrated) {
_searchedMigratedCount = fullCount;
} else if (!withPreview || !toPreview) {
Expand All @@ -3220,6 +3223,63 @@ void InnerWidget::searchReceived(
refresh();
}

void InnerWidget::encryptedSearchReceived(
std::vector<not_null<HistoryItem*>> messages,
HistoryItem *inject,
SearchRequestType type,
const QString &searchQuery,
int fullCount) {
_searchWaiting = false;
_searchLoading = false;

// We need to decrypt message here
// And push it if we match

const auto uniquePeers = uniqueSearchResults();
const auto withPreview = _searchWithPostsPreview;
const auto toPreview = withPreview && type.posts;

const auto key = (!_openedForum || _searchState.inChat.topic())
? _searchState.inChat
: Key(_openedForum->history());
if (inject
&& (!_searchState.inChat
|| inject->history() == _searchState.inChat.history())) {
Assert(!toPreview);
const auto index = int(_searchResults.size());
// TODO: Check if we need to set predicate for push_back below
_searchResults.push_back(
std::make_unique<FakeRow>(
key,
inject,
[=] { repaintSearchResult(index); }));
trackResultsHistory(inject->history());
++fullCount;
}
auto &results = toPreview ? _previewResults : _searchResults;
for (const auto &item : messages) {
const auto history = item->history();
if (toPreview || !uniquePeers || !hasHistoryInResults(history)) {
const auto index = int(results.size());
const auto repaint = toPreview
? Fn<void()>([=] { repaintSearchResult(index); })
: [=] { repaintPreviewResult(index); };
QString pred = "the";
if (item.get()->getText().text == pred) {
// if (decrypt(item.getText().text) == searchQuery) {
results.push_back(
std::make_unique<FakeRow>(key, item, repaint));
trackResultsHistory(history);
if (!toPreview && uniquePeers && !history->unreadCountKnown()) {
history->owner().histories().requestDialogEntry(history);
} else if (toPreview && results.size() >= kPreviewPostsLimit) {
break;
}
}
}
}
}

void InnerWidget::peerSearchReceived(
const QString &query,
const QVector<MTPPeer> &my,
Expand Down
6 changes: 6 additions & 0 deletions Telegram/SourceFiles/dialogs/dialogs_inner_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ class InnerWidget final : public Ui::RpWidget {
HistoryItem *inject,
SearchRequestType type,
int fullCount);
void encryptedSearchReceived(
std::vector<not_null<HistoryItem*>> result,
HistoryItem *inject,
SearchRequestType type,
const QString &searchQuery,
int fullCount);
void peerSearchReceived(
const QString &query,
const QVector<MTPPeer> &my,
Expand Down
168 changes: 168 additions & 0 deletions Telegram/SourceFiles/dialogs/dialogs_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2217,6 +2217,54 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) {
process->queries.emplace(process->requestId, _searchQuery);
return process->requestId;
});

// ANOTHER request to get all messages with encryption prefix
auto encryptionPrefixQuery = QString("the");
histories.sendRequest(history, type, [=](
Fn<void()> finish) {
const auto type = SearchRequestType{
.start = true,
.peer = true,
};
using Flag = MTPmessages_Search::Flag;
process->requestId = session().api().request(
MTPmessages_Search(
MTP_flags((topic ? Flag::f_top_msg_id : Flag())
| (fromPeer ? Flag::f_from_id : Flag())
| (savedPeer ? Flag::f_saved_peer_id : Flag())
| (_searchQueryTags.empty()
? Flag()
: Flag::f_saved_reaction)),
inPeer->input,
MTP_string(encryptionPrefixQuery),
(fromPeer ? fromPeer->input : MTP_inputPeerEmpty()),
(savedPeer ? savedPeer->input : MTP_inputPeerEmpty()),
MTP_vector_from_range(
_searchQueryTags | ranges::views::transform(
Data::ReactionToMTP
)),
MTP_int(topic ? topic->rootId() : 0),
MTP_inputMessagesFilterEmpty(),
MTP_int(0), // min_date
MTP_int(0), // max_date
MTP_int(0), // offset_id
MTP_int(0), // add_offset
MTP_int(kSearchPerPage),
MTP_int(0), // max_id
MTP_int(0), // min_id
MTP_long(0)) // hash
).done([=](const MTPmessages_Messages &result) {
_historiesRequest = 0;
encryptedSearchReceived(type, result, process, _searchQuery);
finish();
}).fail([=](const MTP::Error &error) {
_historiesRequest = 0;
searchFailed(type, error, process);
finish();
}).send();
process->queries.emplace(process->requestId, encryptionPrefixQuery);
return process->requestId;
});
} else if (_searchState.tab == ChatSearchTab::PublicPosts) {
requestPublicPosts(true);
} else {
Expand Down Expand Up @@ -2669,6 +2717,126 @@ void Widget::searchReceived(
update();
}

void Widget::encryptedSearchReceived(
SearchRequestType type,
const MTPmessages_Messages &result,
not_null<SearchProcessState*> process,
const QString &searchQuery,
bool cacheResults) {
const auto state = _inner->state();
if (!cacheResults
&& (state == WidgetState::Filtered)
&& type.start) {
const auto i = process->queries.find(process->requestId);
if (i != process->queries.end()) {
process->cache[i->second] = result;
process->queries.erase(i);
}
}
const auto inject = (type.start && !type.posts)
? *_singleMessageSearch.lookup(_searchQuery)
: nullptr;
if (cacheResults && process->requestId) {
return;
}
if (type.start) {
process->lastPeer = nullptr;
process->lastId = 0;
}
const auto processList = [&](const MTPVector<MTPMessage> &messages) {
auto result = std::vector<not_null<HistoryItem*>>();
for (const auto &message : messages.v) {
const auto msgId = IdFromMessage(message);
const auto peerId = PeerFromMessage(message);
const auto lastDate = DateFromMessage(message);
if (const auto peer = session().data().peerLoaded(peerId)) {
if (lastDate) {
const auto item = session().data().addNewMessage(
message,
MessageFlags(),
NewMessageType::Existing);
result.push_back(item);
}
process->lastPeer = peer;
} else {
LOG(("API Error: a search results with not loaded peer %1"
).arg(peerId.value));
}
process->lastId = msgId;
}
return result;
};
auto fullCount = 0;
auto messages = result.match([&](const MTPDmessages_messages &data) {
if (!cacheResults) {
// Don't apply cached data!
session().data().processUsers(data.vusers());
session().data().processChats(data.vchats());
}
process->full = true;
auto list = processList(data.vmessages());
fullCount = list.size();
return list;
}, [&](const MTPDmessages_messagesSlice &data) {
if (!cacheResults) {
// Don't apply cached data!
session().data().processUsers(data.vusers());
session().data().processChats(data.vchats());
}
auto list = processList(data.vmessages());
const auto nextRate = data.vnext_rate();
const auto rateUpdated = nextRate
&& (nextRate->v != process->nextRate);
const auto finished = (type.peer || type.migrated || type.posts)
? list.empty()
: !rateUpdated;
if (rateUpdated) {
process->nextRate = nextRate->v;
}
if (finished) {
process->full = true;
}
fullCount = data.vcount().v;
return list;
}, [&](const MTPDmessages_channelMessages &data) {
if (const auto peer = searchInPeer()) {
if (const auto channel = peer->asChannel()) {
channel->ptsReceived(data.vpts().v);
channel->processTopics(data.vtopics());
} else {
LOG(("API Error: "
"received messages.channelMessages when no channel "
"was passed! (Widget::searchReceived)"));
}
} else {
LOG(("API Error: "
"received messages.channelMessages when no channel "
"was passed! (Widget::searchReceived)"));
}
if (!cacheResults) {
// Don't apply cached data!
session().data().processUsers(data.vusers());
session().data().processChats(data.vchats());
}
auto list = processList(data.vmessages());
if (list.empty()) {
process->full = true;
}
fullCount = data.vcount().v;
return list;
}, [&](const MTPDmessages_messagesNotModified &) {
LOG(("API Error: received messages.messagesNotModified! "
"(Widget::searchReceived)"));
process->full = true;
return std::vector<not_null<HistoryItem*>>();
});
_inner->encryptedSearchReceived(messages, inject, type, searchQuery, fullCount);

process->requestId = 0;
listScrollUpdated();
update();
}

void Widget::peerSearchReceived(
const MTPcontacts_Found &result,
mtpRequestId requestId) {
Expand Down
6 changes: 6 additions & 0 deletions Telegram/SourceFiles/dialogs/dialogs_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ class Widget final : public Window::AbstractSectionWidget {
const MTPmessages_Messages &result,
not_null<SearchProcessState*> process,
bool cacheResults = false);
void encryptedSearchReceived(
SearchRequestType type,
const MTPmessages_Messages &result,
not_null<SearchProcessState*> process,
const QString &searchQuery,
bool cacheResults = false);
void peerSearchReceived(
const MTPcontacts_Found &result,
mtpRequestId requestId);
Expand Down
4 changes: 4 additions & 0 deletions Telegram/SourceFiles/history/history_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ class HistoryItem final : public RuntimeComposer<HistoryItem> {
void incrementReplyToTopCounter();
void applyEffectWatchedOnUnreadKnown();

TextWithEntities getText() const {
return _text;
}

[[nodiscard]] bool emptyText() const {
return _text.empty();
}
Expand Down

0 comments on commit 3d8f962

Please sign in to comment.