diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 54f62e46e..4a71fb634 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -7196,7 +7196,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 -//@saved_messages_topic If not null, only messages in the specified Saved Messages topic will be returned; pass null to return all messages or for chats other than Saved Messages +//@saved_messages_topic If not null, only messages in the specified Saved Messages topic will be returned; pass null to return all messages, or for chats other than Saved Messages searchChatMessages chat_id:int53 query:string sender_id:MessageSender from_message_id:int53 offset:int32 limit:int32 filter:SearchMessagesFilter message_thread_id:int53 saved_messages_topic:SavedMessagesTopic = 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)). @@ -7253,12 +7253,13 @@ getChatSparseMessagePositions chat_id:int53 filter:SearchMessagesFilter from_mes //@chat_id Identifier of the chat in which to return information about messages //@filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterMention, searchMessagesFilterUnreadMention, and searchMessagesFilterUnreadReaction are unsupported in this function //@from_message_id The message identifier from which to return information about messages; use 0 to get results from the last message -getChatMessageCalendar chat_id:int53 filter:SearchMessagesFilter from_message_id:int53 = MessageCalendar; +//@saved_messages_topic If not null, only messages in the specified Saved Messages topic will be considered; pass null to consider all messages, or for chats other than Saved Messages +getChatMessageCalendar chat_id:int53 filter:SearchMessagesFilter from_message_id:int53 saved_messages_topic:SavedMessagesTopic = MessageCalendar; //@description Returns approximate number of messages of the specified type in the chat //@chat_id Identifier of the chat in which to count messages //@filter Filter for message content; searchMessagesFilterEmpty is unsupported in this function -//@saved_messages_topic If not null, only messages in the specified Saved Messages topic will be counted; pass null to count all messages or for chats other than Saved Messages +//@saved_messages_topic If not null, only messages in the specified Saved Messages topic will be counted; pass null to count all messages, or for chats other than Saved Messages //@return_local Pass true to get the number of messages without sending network requests, or -1 if the number of messages is unknown locally getChatMessageCount chat_id:int53 filter:SearchMessagesFilter saved_messages_topic:SavedMessagesTopic return_local:Bool = Count; @@ -7267,7 +7268,7 @@ getChatMessageCount chat_id:int53 filter:SearchMessagesFilter saved_messages_top //@message_id Message identifier //@filter Filter for message content; searchMessagesFilterEmpty, searchMessagesFilterUnreadMention, searchMessagesFilterUnreadReaction, and searchMessagesFilterFailedToSend are unsupported in this function //@message_thread_id If not 0, only messages in the specified thread will be considered; supergroups only -//@saved_messages_topic If not null, only messages in the specified Saved Messages topic will be considered; pass null for chats other than Saved Messages or to consider all relevant messages +//@saved_messages_topic If not null, only messages in the specified Saved Messages topic will be considered; pass null to consider all relevant messages, or for chats other than Saved Messages getChatMessagePosition chat_id:int53 message_id:int53 filter:SearchMessagesFilter message_thread_id:int53 saved_messages_topic:SavedMessagesTopic = Count; //@description Returns all scheduled messages in a chat. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id) @chat_id Chat identifier diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 40804c922..c49380748 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -1562,6 +1562,7 @@ class ReadDiscussionQuery final : public Td::ResultHandler { class GetSearchResultCalendarQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; + SavedMessagesTopicId saved_messages_topic_id_; MessageId from_message_id_; MessageSearchFilter filter_; int64 random_id_; @@ -1570,18 +1571,26 @@ class GetSearchResultCalendarQuery final : public Td::ResultHandler { explicit GetSearchResultCalendarQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, int64 random_id) { + void send(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, + MessageSearchFilter filter, int64 random_id) { auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); dialog_id_ = dialog_id; + saved_messages_topic_id_ = saved_messages_topic_id; from_message_id_ = from_message_id; filter_ = filter; random_id_ = random_id; int32 flags = 0; + telegram_api::object_ptr saved_input_peer; + if (saved_messages_topic_id.is_valid()) { + flags |= telegram_api::messages_getSearchResultsCalendar::SAVED_PEER_ID_MASK; + saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + } send_query(G()->net_query_creator().create(telegram_api::messages_getSearchResultsCalendar( - flags, std::move(input_peer), nullptr, get_input_messages_filter(filter), + flags, std::move(input_peer), std::move(saved_input_peer), get_input_messages_filter(filter), from_message_id.get_server_message_id().get(), 0))); } @@ -1606,16 +1615,16 @@ class GetSearchResultCalendarQuery final : public Td::ResultHandler { td_->messages_manager_->get_channel_difference_if_needed( dialog_id_, std::move(info), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, - from_message_id = from_message_id_, filter = filter_, random_id = random_id_, - periods = std::move(result->periods_), + saved_messages_topic_id = saved_messages_topic_id_, from_message_id = from_message_id_, + filter = filter_, random_id = random_id_, periods = std::move(result->periods_), promise = std::move(promise_)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { auto info = result.move_as_ok(); - send_closure(actor_id, &MessagesManager::on_get_message_search_result_calendar, dialog_id, from_message_id, - filter, random_id, info.total_count, std::move(info.messages), std::move(periods), - std::move(promise)); + send_closure(actor_id, &MessagesManager::on_get_message_search_result_calendar, dialog_id, + saved_messages_topic_id, from_message_id, filter, random_id, info.total_count, + std::move(info.messages), std::move(periods), std::move(promise)); } }), "GetSearchResultCalendarQuery"); @@ -1623,7 +1632,7 @@ class GetSearchResultCalendarQuery final : public Td::ResultHandler { void on_error(Status status) final { td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetSearchResultCalendarQuery"); - td_->messages_manager_->on_failed_get_message_search_result_calendar(dialog_id_, random_id_); + td_->messages_manager_->on_failed_get_message_search_result_calendar(random_id_); promise_.set_error(std::move(status)); } }; @@ -8682,7 +8691,8 @@ void MessagesManager::on_failed_public_dialogs_search(const string &query, Statu } void MessagesManager::on_get_message_search_result_calendar( - DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, int64 random_id, int32 total_count, + DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, + MessageSearchFilter filter, int64 random_id, int32 total_count, vector> &&messages, vector> &&periods, Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); @@ -8715,10 +8725,12 @@ void MessagesManager::on_get_message_search_result_calendar( Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - auto &old_message_count = d->message_count_by_index[message_search_filter_index(filter)]; - if (old_message_count != total_count) { - old_message_count = total_count; - on_dialog_updated(dialog_id, "on_get_message_search_result_calendar"); + if (!saved_messages_topic_id.is_valid()) { + auto &old_message_count = d->message_count_by_index[message_search_filter_index(filter)]; + if (old_message_count != total_count) { + old_message_count = total_count; + on_dialog_updated(dialog_id, "on_get_message_search_result_calendar"); + } } vector> days; @@ -8740,7 +8752,7 @@ void MessagesManager::on_get_message_search_result_calendar( promise.set_value(Unit()); } -void MessagesManager::on_failed_get_message_search_result_calendar(DialogId dialog_id, int64 random_id) { +void MessagesManager::on_failed_get_message_search_result_calendar(int64 random_id) { auto it = found_dialog_message_calendars_.find(random_id); CHECK(it != found_dialog_message_calendars_.end()); found_dialog_message_calendars_.erase(it); @@ -19756,11 +19768,9 @@ std::pair> MessagesManager::get_message_thread_histo return {}; } -td_api::object_ptr MessagesManager::get_dialog_message_calendar(DialogId dialog_id, - MessageId from_message_id, - MessageSearchFilter filter, - int64 &random_id, bool use_db, - Promise &&promise) { +td_api::object_ptr MessagesManager::get_dialog_message_calendar( + DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, + MessageSearchFilter filter, int64 &random_id, bool use_db, Promise &&promise) { if (random_id != 0) { // request has already been sent before auto it = found_dialog_message_calendars_.find(random_id); @@ -19772,7 +19782,8 @@ td_api::object_ptr MessagesManager::get_dialog_message_ } random_id = 0; } - LOG(INFO) << "Get message calendar in " << dialog_id << " filtered by " << filter << " from " << from_message_id; + LOG(INFO) << "Get message calendar in " << dialog_id << " with " << saved_messages_topic_id << " filtered by " + << filter << " from " << from_message_id; if (from_message_id.get() > MessageId::max().get()) { from_message_id = MessageId::max(); @@ -19793,21 +19804,31 @@ td_api::object_ptr MessagesManager::get_dialog_message_ promise.set_error(Status::Error(400, "Can't access the chat")); return {}; } + { + auto status = saved_messages_topic_id.is_valid_in(td_, dialog_id); + if (status.is_error()) { + promise.set_error(std::move(status)); + return {}; + } + } + + CHECK(filter != MessageSearchFilter::Call && filter != MessageSearchFilter::MissedCall); + if (filter == MessageSearchFilter::Empty || filter == MessageSearchFilter::Mention || + filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::UnreadReaction) { + if (filter != MessageSearchFilter::Empty && saved_messages_topic_id.is_valid()) { + return td_api::make_object(); + } + promise.set_error(Status::Error(400, "The filter is not supported")); + return {}; + } do { random_id = Random::secure_int64(); } while (random_id == 0 || found_dialog_message_calendars_.count(random_id) > 0); found_dialog_message_calendars_[random_id]; // reserve place for result - CHECK(filter != MessageSearchFilter::Call && filter != MessageSearchFilter::MissedCall); - if (filter == MessageSearchFilter::Empty || filter == MessageSearchFilter::Mention || - filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::UnreadReaction) { - promise.set_error(Status::Error(400, "The filter is not supported")); - return {}; - } - // Trying to use database - if (use_db && G()->use_message_database()) { + if (use_db && G()->use_message_database() && !saved_messages_topic_id.is_valid()) { MessageId first_db_message_id = get_first_database_message_id_by_index(d, filter); int32 message_count = d->message_count_by_index[message_search_filter_index(filter)]; auto fixed_from_message_id = from_message_id; @@ -19835,19 +19856,18 @@ td_api::object_ptr MessagesManager::get_dialog_message_ } } if (filter == MessageSearchFilter::FailedToSend) { + found_dialog_message_calendars_.erase(random_id); promise.set_value(Unit()); - return {}; + return td_api::make_object(); } - LOG(DEBUG) << "Get message calendar from server in " << dialog_id << " from " << from_message_id; - switch (dialog_id.get_type()) { case DialogType::None: case DialogType::User: case DialogType::Chat: case DialogType::Channel: td_->create_handler(std::move(promise)) - ->send(dialog_id, from_message_id, filter, random_id); + ->send(dialog_id, saved_messages_topic_id, from_message_id, filter, random_id); break; case DialogType::SecretChat: promise.set_value(Unit()); @@ -20070,6 +20090,7 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( } } if (filter == MessageSearchFilter::FailedToSend) { + found_dialog_messages_.erase(random_id); promise.set_value(Unit()); return result; } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 8a1fa41ce..34e797b33 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -165,12 +165,12 @@ class MessagesManager final : public Actor { vector> &&peers); void on_failed_public_dialogs_search(const string &query, Status &&error); - void on_get_message_search_result_calendar(DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, - int64 random_id, int32 total_count, - vector> &&messages, + void on_get_message_search_result_calendar(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, int64 random_id, + int32 total_count, vector> &&messages, vector> &&periods, Promise &&promise); - void on_failed_get_message_search_result_calendar(DialogId dialog_id, int64 random_id); + void on_failed_get_message_search_result_calendar(int64 random_id); void on_get_dialog_messages_search_result(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, const string &query, DialogId sender_dialog_id, MessageId from_message_id, @@ -679,7 +679,9 @@ class MessagesManager final : public Actor { int32 limit, int64 &random_id, Promise &&promise); - td_api::object_ptr get_dialog_message_calendar(DialogId dialog_id, MessageId from_message_id, + td_api::object_ptr get_dialog_message_calendar(DialogId dialog_id, + SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, int64 &random_id, bool use_db, Promise &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 676a7d1ee..753a43456 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -1361,6 +1361,7 @@ class GetMessageThreadHistoryRequest final : public RequestActor<> { class GetChatMessageCalendarRequest final : public RequestActor<> { DialogId dialog_id_; + SavedMessagesTopicId saved_messages_topic_id_; MessageId from_message_id_; MessageSearchFilter filter_; int64 random_id_; @@ -1368,8 +1369,9 @@ class GetChatMessageCalendarRequest final : public RequestActor<> { td_api::object_ptr calendar_; void do_run(Promise &&promise) final { - calendar_ = td_->messages_manager_->get_dialog_message_calendar(dialog_id_, from_message_id_, filter_, random_id_, - get_tries() == 3, std::move(promise)); + calendar_ = + td_->messages_manager_->get_dialog_message_calendar(dialog_id_, saved_messages_topic_id_, from_message_id_, + filter_, random_id_, get_tries() == 3, std::move(promise)); } void do_send_result() final { @@ -1377,10 +1379,12 @@ class GetChatMessageCalendarRequest final : public RequestActor<> { } public: - GetChatMessageCalendarRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 from_message_id, + GetChatMessageCalendarRequest(ActorShared td, uint64 request_id, int64 dialog_id, + SavedMessagesTopicId saved_messages_topic_id, int64 from_message_id, tl_object_ptr filter) : RequestActor(std::move(td), request_id) , dialog_id_(dialog_id) + , saved_messages_topic_id_(saved_messages_topic_id) , from_message_id_(from_message_id) , filter_(get_message_search_filter(filter)) , random_id_(0) { @@ -5209,7 +5213,9 @@ void Td::on_request(uint64 id, const td_api::getMessageThreadHistory &request) { void Td::on_request(uint64 id, td_api::getChatMessageCalendar &request) { CHECK_IS_USER(); - CREATE_REQUEST(GetChatMessageCalendarRequest, request.chat_id_, request.from_message_id_, std::move(request.filter_)); + CREATE_REQUEST(GetChatMessageCalendarRequest, request.chat_id_, + SavedMessagesTopicId(this, request.saved_messages_topic_), request.from_message_id_, + std::move(request.filter_)); } void Td::on_request(uint64 id, td_api::searchChatMessages &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 3c6673407..c5e7aa757 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2927,7 +2927,7 @@ class CliClient final : public Actor { MessageId from_message_id; get_args(args, chat_id, filter, from_message_id); send_request(td_api::make_object(chat_id, as_search_messages_filter(filter), - from_message_id)); + from_message_id, get_saved_messages_topic())); } else if (op == "SearchAudio" || op == "SearchDocument" || op == "SearchPhoto" || op == "SearchChatPhoto") { ChatId chat_id; MessageId offset_message_id;