diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d52ea69f1..e90aa366b 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1075,6 +1075,9 @@ messages total_count:int32 messages:vector = Messages; //@description Contains a list of messages found by a search @total_count Approximate total number of messages found; -1 if unknown @messages List of messages @next_offset The offset for the next request. If empty, there are no more results foundMessages total_count:int32 messages:vector next_offset:string = FoundMessages; +//@description Contains a list of messages found by a search in a given chat @total_count Approximate total number of messages found; -1 if unknown @messages List of messages @next_from_message_id The offset for the next request. If 0, there are no more results +foundChatMessages total_count:int32 messages:vector next_from_message_id:int53 = FoundChatMessages; + //@description Contains information about a message in a specific position @position 0-based message position in the full list of suitable messages @message_id Message identifier @date Point in time (Unix timestamp) when the message was sent messagePosition position:int32 message_id:int53 date:int32 = MessagePosition; @@ -5780,7 +5783,7 @@ deleteChat chat_id:int53 = Ok; //-For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit //@filter Additional filter for messages to search; pass null to search for all messages //@message_thread_id If not 0, only messages in the specified thread will be returned; supergroups only -searchChatMessages chat_id:int53 query:string sender_id:MessageSender from_message_id:int53 offset:int32 limit:int32 filter:SearchMessagesFilter message_thread_id:int53 = Messages; +searchChatMessages chat_id:int53 query:string sender_id:MessageSender from_message_id:int53 offset:int32 limit:int32 filter:SearchMessagesFilter message_thread_id:int53 = FoundChatMessages; //@description Searches for messages in all chats except secret chats. Returns the results in reverse chronological order (i.e., in order of decreasing (date, chat_id, message_id)). //-For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index b7f64715f..d562787d9 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -10342,7 +10342,7 @@ void MessagesManager::on_get_dialog_messages_search_result( auto it = found_dialog_messages_.find(random_id); CHECK(it != found_dialog_messages_.end()); - auto &result = it->second.second; + auto &result = it->second.message_ids; CHECK(result.empty()); MessageId first_added_message_id; if (messages.empty()) { @@ -10352,9 +10352,14 @@ void MessagesManager::on_get_dialog_messages_search_result( } bool can_be_in_different_dialog = top_thread_message_id.is_valid() && is_broadcast_channel(dialog_id); DialogId real_dialog_id; + MessageId next_from_message_id; Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); for (auto &message : messages) { + auto message_id = MessageId::get_message_id(message, false); + if (message_id.is_valid() && message_id < next_from_message_id) { + next_from_message_id = message_id; + } auto new_full_message_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, false, false, false, "on_get_dialog_messages_search_result"); if (new_full_message_id == FullMessageId()) { @@ -10380,7 +10385,7 @@ void MessagesManager::on_get_dialog_messages_search_result( } } - auto message_id = new_full_message_id.get_message_id(); + CHECK(message_id == new_full_message_id.get_message_id()); if (filter == MessageSearchFilter::UnreadMention && message_id <= d->last_read_all_mentions_message_id && !real_dialog_id.is_valid()) { total_count--; @@ -10437,7 +10442,8 @@ void MessagesManager::on_get_dialog_messages_search_result( } } - it->second.first = total_count; + it->second.total_count = total_count; + it->second.next_from_message_id = next_from_message_id; promise.set_value(Unit()); } @@ -22660,7 +22666,7 @@ std::pair> MessagesManager::get_message_thread_histo // request has already been sent before auto it = found_dialog_messages_.find(random_id); CHECK(it != found_dialog_messages_.end()); - auto result = std::move(it->second.second); + auto result = std::move(it->second.message_ids); found_dialog_messages_.erase(it); auto dialog_id_it = found_dialog_messages_dialog_id_.find(random_id); @@ -22898,7 +22904,7 @@ void MessagesManager::on_get_message_calendar_from_database(int64 random_id, Dia promise.set_value(Unit()); } -std::pair> MessagesManager::search_dialog_messages( +MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( DialogId dialog_id, const string &query, const td_api::object_ptr &sender, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, int64 &random_id, bool use_db, Promise &&promise) { @@ -22918,7 +22924,7 @@ std::pair> MessagesManager::search_dialog_messages( << oneline(to_string(sender)) << " in thread of " << top_thread_message_id << " filtered by " << filter << " from " << from_message_id << " with offset " << offset << " and limit " << limit; - std::pair> result; + FoundDialogMessages result; if (limit <= 0) { promise.set_error(Status::Error(400, "Parameter limit must be positive")); return result; @@ -23589,12 +23595,16 @@ void MessagesManager::on_search_dialog_message_db_result(int64 random_id, Dialog auto it = found_dialog_messages_.find(random_id); CHECK(it != found_dialog_messages_.end()); - auto &res = it->second.second; + auto &res = it->second.message_ids; + MessageId next_from_message_id; res.reserve(messages.size()); for (auto &message : messages) { auto m = on_get_message_from_database(d, message, false, "on_search_dialog_message_db_result"); if (m != nullptr && first_db_message_id <= m->message_id) { + if (m->message_id < next_from_message_id) { + next_from_message_id = m->message_id; + } if (filter == MessageSearchFilter::UnreadMention && !m->contains_unread_mention) { // skip already read by d->last_read_all_mentions_message_id mentions } else { @@ -23625,7 +23635,8 @@ void MessagesManager::on_search_dialog_message_db_result(int64 random_id, Dialog } on_dialog_updated(dialog_id, "on_search_dialog_message_db_result"); } - it->second.first = message_count; + it->second.total_count = message_count; + it->second.next_from_message_id = next_from_message_id; if (res.empty() && first_db_message_id != MessageId::min() && dialog_id.get_type() != DialogType::SecretChat) { LOG(INFO) << "No messages found in database"; found_dialog_messages_.erase(it); @@ -23638,6 +23649,23 @@ void MessagesManager::on_search_dialog_message_db_result(int64 random_id, Dialog promise.set_value(Unit()); } +td_api::object_ptr MessagesManager::get_found_chat_messages_object( + DialogId dialog_id, const FoundDialogMessages &found_dialog_messages, const char *source) { + auto *d = get_dialog(dialog_id); + CHECK(d != nullptr); + vector> result; + result.reserve(found_dialog_messages.message_ids.size()); + for (const auto &message_id : found_dialog_messages.message_ids) { + auto message = get_message_object(dialog_id, get_message_force(d, message_id, source), source); + if (message != nullptr) { + result.push_back(std::move(message)); + } + } + + return td_api::make_object(found_dialog_messages.total_count, std::move(result), + found_dialog_messages.next_from_message_id.get()); +} + td_api::object_ptr MessagesManager::get_found_messages_object( const FoundMessages &found_messages, const char *source) { vector> result; diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index ff795ddbf..4ef868c6c 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -748,12 +748,20 @@ class MessagesManager final : public Actor { MessageSearchFilter filter, int64 &random_id, bool use_db, Promise &&promise); - std::pair> search_dialog_messages(DialogId dialog_id, const string &query, - const td_api::object_ptr &sender, - MessageId from_message_id, int32 offset, int32 limit, - MessageSearchFilter filter, - MessageId top_thread_message_id, int64 &random_id, - bool use_db, Promise &&promise); + struct FoundDialogMessages { + vector message_ids; + MessageId next_from_message_id; + int32 total_count = 0; + }; + + td_api::object_ptr get_found_chat_messages_object( + DialogId dialog_id, const FoundDialogMessages &found_dialog_messages, const char *source); + + FoundDialogMessages search_dialog_messages(DialogId dialog_id, const string &query, + const td_api::object_ptr &sender, + MessageId from_message_id, int32 offset, int32 limit, + MessageSearchFilter filter, MessageId top_thread_message_id, + int64 &random_id, bool use_db, Promise &&promise); struct FoundMessages { vector full_message_ids; @@ -3548,10 +3556,9 @@ class MessagesManager final : public Actor { FlatHashMap get_dialog_message_by_date_results_; FlatHashMap> found_dialog_message_calendars_; - FlatHashMap>> - found_dialog_messages_; // random_id -> [total_count, [message_id]...] - FlatHashMap found_dialog_messages_dialog_id_; // random_id -> dialog_id - FlatHashMap found_messages_; // random_id -> FoundMessages + FlatHashMap found_dialog_messages_; // random_id -> FoundDialogMessages + FlatHashMap found_dialog_messages_dialog_id_; // random_id -> dialog_id + FlatHashMap found_messages_; // random_id -> FoundMessages FlatHashMap>> found_call_messages_; // random_id -> [total_count, [full_message_id]...] diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp index b8c387588..ba5015d61 100644 --- a/td/telegram/OptionManager.cpp +++ b/td/telegram/OptionManager.cpp @@ -120,6 +120,7 @@ OptionManager::OptionManager(Td *td) } set_option_empty("themed_emoji_statuses_sticker_set_id"); + set_option_empty("themed_premium_statuses_sticker_set_id"); } OptionManager::~OptionManager() = default; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 3f734311d..44ac76eda 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -1346,7 +1346,7 @@ class SearchChatMessagesRequest final : public RequestActor<> { MessageId top_thread_message_id_; int64 random_id_; - std::pair> messages_; + MessagesManager::FoundDialogMessages messages_; void do_run(Promise &&promise) final { messages_ = td_->messages_manager_->search_dialog_messages(dialog_id_, query_, sender_id_, from_message_id_, @@ -1355,14 +1355,13 @@ class SearchChatMessagesRequest final : public RequestActor<> { } void do_send_result() final { - send_result(td_->messages_manager_->get_messages_object(messages_.first, dialog_id_, messages_.second, true, - "SearchChatMessagesRequest")); + send_result( + td_->messages_manager_->get_found_chat_messages_object(dialog_id_, messages_, "SearchChatMessagesRequest")); } void do_send_error(Status &&status) final { if (status.message() == "SEARCH_QUERY_EMPTY") { - messages_.first = 0; - messages_.second.clear(); + messages_ = {}; return do_send_result(); } send_error(std::move(status));