diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index e90aa366b..9bbf0d2ee 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -5805,10 +5805,10 @@ searchMessages chat_list:ChatList query:string offset:string limit:int32 filter: searchSecretMessages chat_id:int53 query:string offset:string limit:int32 filter:SearchMessagesFilter = FoundMessages; //@description Searches for call messages. Returns the results in reverse chronological order (i.e., in order of decreasing message_id). For optimal performance, the number of returned messages is chosen by TDLib -//@from_message_id Identifier of the message from which to search; use 0 to get results from the last message +//@offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results //@limit The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit //@only_missed Pass true to search only for messages with missed/declined calls -searchCallMessages from_message_id:int53 limit:int32 only_missed:Bool = Messages; +searchCallMessages offset:string limit:int32 only_missed:Bool = FoundMessages; //@description Searches for outgoing messages with content of the type messageDocument in all chats except secret chats. Returns the results in reverse chronological order //@query Query to search for in document file name and message caption diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index d562787d9..a87f6b68e 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -10285,10 +10285,15 @@ void MessagesManager::on_get_dialog_messages_search_result( first_added_message_id = MessageId::min(); } - auto &result = it->second.second; + auto &result = it->second.full_message_ids; CHECK(result.empty()); int32 added_message_count = 0; + MessageId next_offset_message_id; for (auto &message : messages) { + auto message_id = MessageId::get_message_id(message, false); + if (message_id.is_valid() && (!next_offset_message_id.is_valid() || message_id < next_offset_message_id)) { + next_offset_message_id = message_id; + } auto new_full_message_id = on_get_message(std::move(message), false, false, false, false, false, "search call messages"); if (new_full_message_id == FullMessageId()) { @@ -10298,7 +10303,7 @@ void MessagesManager::on_get_dialog_messages_search_result( result.push_back(new_full_message_id); added_message_count++; - auto message_id = new_full_message_id.get_message_id(); + CHECK(message_id == new_full_message_id.get_message_id()); CHECK(message_id.is_valid()); if (message_id < first_added_message_id || !first_added_message_id.is_valid()) { first_added_message_id = message_id; @@ -10334,7 +10339,10 @@ void MessagesManager::on_get_dialog_messages_search_result( save_calls_db_state(); } } - it->second.first = total_count; + it->second.total_count = total_count; + if (next_offset_message_id.is_valid()) { + it->second.next_offset = PSTRING() << next_offset_message_id.get_server_message_id().get(); + } promise.set_value(Unit()); return; } @@ -10357,7 +10365,7 @@ void MessagesManager::on_get_dialog_messages_search_result( 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) { + if (message_id.is_valid() && (!next_from_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, @@ -23080,9 +23088,9 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( return result; } -std::pair> MessagesManager::search_call_messages(MessageId from_message_id, int32 limit, - bool only_missed, int64 &random_id, - bool use_db, Promise &&promise) { +MessagesManager::FoundMessages MessagesManager::search_call_messages(const string &offset, int32 limit, + bool only_missed, int64 &random_id, bool use_db, + Promise &&promise) { if (random_id != 0) { // request has already been sent before auto it = found_call_messages_.find(random_id); @@ -23094,9 +23102,9 @@ std::pair> MessagesManager::search_call_messages(Me } random_id = 0; } - LOG(INFO) << "Search call messages from " << from_message_id << " with limit " << limit; + LOG(INFO) << "Search call messages from " << offset << " with limit " << limit; - std::pair> result; + FoundMessages result; if (limit <= 0) { promise.set_error(Status::Error(400, "Parameter limit must be positive")); return result; @@ -23105,15 +23113,16 @@ std::pair> MessagesManager::search_call_messages(Me limit = MAX_SEARCH_MESSAGES; } - if (from_message_id.get() > MessageId::max().get()) { - from_message_id = MessageId::max(); - } + MessageId offset_message_id; + if (!offset.empty()) { + auto r_offset_server_message_id = to_integer_safe(offset); + if (r_offset_server_message_id.is_error()) { + promise.set_error(Status::Error(400, "Invalid offset specified")); + return result; + } - if (!from_message_id.is_valid() && from_message_id != MessageId()) { - promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of a chat message or 0")); - return result; + offset_message_id = MessageId(ServerMessageId(r_offset_server_message_id.ok())); } - from_message_id = from_message_id.get_next_server_message_id(); do { random_id = Random::secure_int64(); @@ -23127,7 +23136,7 @@ std::pair> MessagesManager::search_call_messages(Me MessageId first_db_message_id = calls_db_state_.first_calls_database_message_id_by_index[call_message_search_filter_index(filter)]; int32 message_count = calls_db_state_.message_count_by_index[call_message_search_filter_index(filter)]; - auto fixed_from_message_id = from_message_id; + auto fixed_from_message_id = offset_message_id; if (fixed_from_message_id == MessageId()) { fixed_from_message_id = MessageId::max(); } @@ -23152,7 +23161,7 @@ std::pair> MessagesManager::search_call_messages(Me } td_->create_handler(std::move(promise)) - ->send(DialogId(), "", DialogId(), from_message_id, 0, limit, filter, MessageId(), random_id); + ->send(DialogId(), "", DialogId(), offset_message_id, 0, limit, filter, MessageId(), random_id); return result; } @@ -23190,7 +23199,7 @@ void MessagesManager::search_dialog_recent_location_messages(DialogId dialog_id, case DialogType::Channel: return td_->create_handler(std::move(promise))->send(dialog_id, limit); case DialogType::SecretChat: - return promise.set_value(get_messages_object(0, vector>(), true)); + return promise.set_value(get_messages_object(0, vector>(), false)); default: UNREACHABLE(); promise.set_error(Status::Error(500, "Search messages is not supported")); @@ -23602,7 +23611,7 @@ void MessagesManager::on_search_dialog_message_db_result(int64 random_id, Dialog 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) { + if (!next_from_message_id.is_valid() || m->message_id < next_from_message_id) { next_from_message_id = m->message_id; } if (filter == MessageSearchFilter::UnreadMention && !m->contains_unread_mention) { @@ -23791,18 +23800,24 @@ void MessagesManager::on_message_db_calls_result(Result re auto it = found_call_messages_.find(random_id); CHECK(it != found_call_messages_.end()); - auto &res = it->second.second; + auto &res = it->second.full_message_ids; CHECK(!first_db_message_id.is_scheduled()); res.reserve(calls_result.messages.size()); + MessageId next_offset_message_id; for (auto &message : calls_result.messages) { auto m = on_get_message_from_database(message, false, "on_message_db_calls_result"); - if (m != nullptr && first_db_message_id <= m->message_id) { + if (!next_offset_message_id.is_valid() || m->message_id < next_offset_message_id) { + next_offset_message_id = m->message_id; + } res.emplace_back(message.dialog_id, m->message_id); } } - it->second.first = calls_db_state_.message_count_by_index[call_message_search_filter_index(filter)]; + it->second.total_count = calls_db_state_.message_count_by_index[call_message_search_filter_index(filter)]; + if (next_offset_message_id.is_valid()) { + it->second.next_offset = PSTRING() << next_offset_message_id.get_server_message_id().get(); + } if (res.empty() && first_db_message_id != MessageId::min()) { LOG(INFO) << "No messages found in database"; @@ -25293,7 +25308,7 @@ void MessagesManager::send_get_message_public_forwards_query( int32 offset_date = std::numeric_limits::max(); DialogId offset_dialog_id; - ServerMessageId offset_message_id; + ServerMessageId offset_server_message_id; if (!offset.empty()) { auto parts = full_split(offset, ','); @@ -25302,18 +25317,18 @@ void MessagesManager::send_get_message_public_forwards_query( } auto r_offset_date = to_integer_safe(parts[0]); auto r_offset_dialog_id = to_integer_safe(parts[1]); - auto r_offset_message_id = to_integer_safe(parts[2]); - if (r_offset_date.is_error() || r_offset_dialog_id.is_error() || r_offset_message_id.is_error()) { + auto r_offset_server_message_id = to_integer_safe(parts[2]); + if (r_offset_date.is_error() || r_offset_dialog_id.is_error() || r_offset_server_message_id.is_error()) { return promise.set_error(Status::Error(400, "Invalid offset specified")); } offset_date = r_offset_date.ok(); offset_dialog_id = DialogId(r_offset_dialog_id.ok()); - offset_message_id = ServerMessageId(r_offset_message_id.ok()); + offset_server_message_id = ServerMessageId(r_offset_server_message_id.ok()); } td_->create_handler(std::move(promise)) - ->send(dc_id, full_message_id, offset_date, offset_dialog_id, offset_message_id, limit); + ->send(dc_id, full_message_id, offset_date, offset_dialog_id, offset_server_message_id, limit); } Result MessagesManager::get_message_schedule_date( diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 4ef868c6c..38c18e30b 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -779,8 +779,8 @@ class MessagesManager final : public Actor { int32 limit, MessageSearchFilter filter, int32 min_date, int32 max_date, int64 &random_id, Promise &&promise); - std::pair> search_call_messages(MessageId from_message_id, int32 limit, bool only_missed, - int64 &random_id, bool use_db, Promise &&promise); + FoundMessages search_call_messages(const string &offset, int32 limit, bool only_missed, int64 &random_id, bool use_db, + Promise &&promise); void search_outgoing_document_messages(const string &query, int32 limit, Promise> &&promise); @@ -3559,8 +3559,7 @@ class MessagesManager final : public Actor { 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]...] + FlatHashMap found_call_messages_; // random_id -> FoundMessages FlatHashMap found_fts_messages_; // random_id -> FoundMessages diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 44ac76eda..4bfc1b3e0 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -1465,27 +1465,26 @@ class SearchMessagesRequest final : public RequestActor<> { }; class SearchCallMessagesRequest final : public RequestActor<> { - MessageId from_message_id_; + string offset_; int32 limit_; bool only_missed_; int64 random_id_; - std::pair> messages_; + MessagesManager::FoundMessages messages_; void do_run(Promise &&promise) final { - messages_ = td_->messages_manager_->search_call_messages(from_message_id_, limit_, only_missed_, random_id_, + messages_ = td_->messages_manager_->search_call_messages(offset_, limit_, only_missed_, random_id_, get_tries() == 3, std::move(promise)); } void do_send_result() final { - send_result(td_->messages_manager_->get_messages_object(messages_.first, messages_.second, true, - "SearchCallMessagesRequest")); + send_result(td_->messages_manager_->get_found_messages_object(messages_, "SearchCallMessagesRequest")); } public: - SearchCallMessagesRequest(ActorShared td, uint64 request_id, int64 from_message_id, int32 limit, bool only_missed) + SearchCallMessagesRequest(ActorShared td, uint64 request_id, string offset, int32 limit, bool only_missed) : RequestActor(std::move(td), request_id) - , from_message_id_(from_message_id) + , offset_(std::move(offset)) , limit_(limit) , only_missed_(only_missed) , random_id_(0) { @@ -5165,7 +5164,7 @@ void Td::on_request(uint64 id, td_api::searchMessages &request) { void Td::on_request(uint64 id, const td_api::searchCallMessages &request) { CHECK_IS_USER(); - CREATE_REQUEST(SearchCallMessagesRequest, request.from_message_id_, request.limit_, request.only_missed_); + CREATE_REQUEST(SearchCallMessagesRequest, std::move(request.offset_), request.limit_, request.only_missed_); } void Td::on_request(uint64 id, td_api::searchOutgoingDocumentMessages &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index a3723da65..ea036b345 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2360,10 +2360,10 @@ class CliClient final : public Actor { chat_id, "", nullptr, offset_message_id, offset, as_limit(limit), as_search_messages_filter(filter), 0)); } else if (op == "SC") { string limit; - MessageId offset_message_id; + string offset; bool only_missed; - get_args(args, limit, offset_message_id, only_missed); - send_request(td_api::make_object(offset_message_id, as_limit(limit), only_missed)); + get_args(args, limit, offset, only_missed); + send_request(td_api::make_object(offset, as_limit(limit), only_missed)); } else if (op == "sodm") { SearchQuery query; get_args(args, query);