diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index c29b5f4f0..b8ce61586 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1338,6 +1338,14 @@ forumTopicInfo message_thread_id:int53 name:string icon:forumTopicIcon creation_ //@draft_message A draft of a message in the topic; may be null forumTopic info:forumTopicInfo last_message:message is_pinned:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 unread_reaction_count:int32 notification_settings:chatNotificationSettings draft_message:draftMessage = ForumTopic; +//@description Describes a list of forum topics +//@total_count Approximate total number of forum topics found +//@topics List of forum topics +//@next_offset_date Offset date for the next getForumTopics request +//@next_offset_message_id Offset message identifier for the next getForumTopics request +//@next_offset_message_thread_id Offset message thread identifier for the next getForumTopics request +forumTopics total_count:int32 topics:vector next_offset_date:int32 next_offset_message_id:int53 next_offset_message_thread_id:int53 = ForumTopics; + //@class RichText @description Describes a text object inside an instant-view web page @@ -5346,6 +5354,15 @@ getForumTopic chat_id:int53 message_thread_id:int53 = ForumTopic; //@description Returns an HTTPS link to a topic in a forum chat. This is an offline request @chat_id Identifier of the chat @message_thread_id Message thread identifier of the forum topic getForumTopicLink chat_id:int53 message_thread_id:int53 = HttpUrl; +//@description Returns found forum topics in a forum chat. This is a temporary method for getting information about topic list from the server +//@chat_id Identifier of the forum chat +//@query Query to search for in the forum topic's name +//@offset_date The date starting from which the results need to be fetched. Use 0 or any date in the future to get results from the last topic +//@offset_message_id The message identifier of the last message in the last found topic, or 0 for the first request +//@offset_message_thread_id The message thread identifier of the last found topic, or 0 for the first request +//@limit The maximum number of forum topics to be returned; up to 100. For optimal performance, the number of returned forum topics is chosen by TDLib and can be smaller than the specified limit +getForumTopics chat_id:int53 query:string offset_date:int32 offset_message_id:int53 offset_message_thread_id:int53 limit:int32 = ForumTopics; + //@description Changes the notification settings of a forum topic //@chat_id Chat identifier @message_thread_id Message thread identifier of the forum topic @notification_settings New notification settings for the forum topic. If the topic is muted for more than 366 days, it is considered to be muted forever setForumTopicNotificationSettings chat_id:int53 message_thread_id:int53 notification_settings:chatNotificationSettings = Ok; diff --git a/td/telegram/ForumTopicManager.cpp b/td/telegram/ForumTopicManager.cpp index 449eb3970..c45c41b34 100644 --- a/td/telegram/ForumTopicManager.cpp +++ b/td/telegram/ForumTopicManager.cpp @@ -255,6 +255,84 @@ class GetForumTopicQuery final : public Td::ResultHandler { } }; +class GetForumTopicsQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit GetForumTopicsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, const string &query, int32 offset_date, MessageId offset_message_id, + MessageId offset_top_thread_message_id, int32 limit) { + channel_id_ = channel_id; + + auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + CHECK(input_channel != nullptr); + + int32 flags = 0; + if (!query.empty()) { + flags |= telegram_api::channels_getForumTopics::Q_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::channels_getForumTopics(flags, std::move(input_channel), query, offset_date, + offset_message_id.get_server_message_id().get(), + offset_top_thread_message_id.get_server_message_id().get(), limit), + {{channel_id}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetForumTopicsQuery: " << to_string(ptr); + + td_->contacts_manager_->on_get_users(std::move(ptr->users_), "GetForumTopicsQuery"); + td_->contacts_manager_->on_get_chats(std::move(ptr->chats_), "GetForumTopicsQuery"); + td_->messages_manager_->on_get_messages(std::move(ptr->messages_), true, false, Promise(), + "GetForumTopicsQuery"); + // ignore ptr->pts_ + auto order_by_creation_date = ptr->order_by_create_date_; + vector> forum_topics; + int32 next_offset_date = 0; + MessageId next_offset_message_id; + MessageId next_offset_top_thread_message_id; + for (auto &topic : ptr->topics_) { + auto top_thread_message_id = + td_->forum_topic_manager_->on_get_forum_topic(DialogId(channel_id_), std::move(topic)); + if (!top_thread_message_id.is_valid()) { + continue; + } + auto forum_topic_object = + td_->forum_topic_manager_->get_forum_topic_object(DialogId(channel_id_), top_thread_message_id); + CHECK(forum_topic_object != nullptr); + if (order_by_creation_date || forum_topic_object->last_message_ == nullptr) { + next_offset_date = forum_topic_object->info_->creation_date_; + } else { + next_offset_date = forum_topic_object->last_message_->date_; + } + next_offset_message_id = forum_topic_object->last_message_ != nullptr + ? MessageId(forum_topic_object->last_message_->id_) + : MessageId(); + next_offset_top_thread_message_id = top_thread_message_id; + forum_topics.push_back(std::move(forum_topic_object)); + } + + promise_.set_value(td_api::make_object(ptr->count_, std::move(forum_topics), next_offset_date, + next_offset_message_id.get(), + next_offset_top_thread_message_id.get())); + } + + void on_error(Status status) final { + td_->contacts_manager_->on_get_channel_error(channel_id_, status, "GetForumTopicsQuery"); + promise_.set_error(std::move(status)); + } +}; + template void ForumTopicManager::Topic::store(StorerT &storer) const { CHECK(info_ != nullptr); @@ -490,6 +568,28 @@ void ForumTopicManager::get_forum_topic_link(DialogId dialog_id, MessageId top_t promise.set_value(sb.as_cslice().str()); } +void ForumTopicManager::get_forum_topics(DialogId dialog_id, string query, int32 offset_date, + MessageId offset_message_id, MessageId offset_top_thread_message_id, + int32 limit, Promise> promise) { + TRY_STATUS_PROMISE(promise, is_forum(dialog_id)); + auto channel_id = dialog_id.get_channel_id(); + + if (offset_date < 0) { + return promise.set_error(Status::Error(400, "Invalid offset date specified")); + } + if (offset_message_id != MessageId() && !offset_message_id.is_valid() && !offset_message_id.is_server()) { + return promise.set_error(Status::Error(400, "Invalid offset message identifier specified")); + } + if (offset_top_thread_message_id != MessageId()) { + TRY_STATUS_PROMISE(promise, can_be_message_thread_id(offset_top_thread_message_id)); + } + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Invalid limit specified")); + } + td_->create_handler(std::move(promise)) + ->send(channel_id, query, offset_date, offset_message_id, offset_top_thread_message_id, limit); +} + void ForumTopicManager::toggle_forum_topic_is_closed(DialogId dialog_id, MessageId top_thread_message_id, bool is_closed, Promise &&promise) { TRY_STATUS_PROMISE(promise, is_forum(dialog_id)); diff --git a/td/telegram/ForumTopicManager.h b/td/telegram/ForumTopicManager.h index 6eedf2e00..5e881c018 100644 --- a/td/telegram/ForumTopicManager.h +++ b/td/telegram/ForumTopicManager.h @@ -49,6 +49,10 @@ class ForumTopicManager final : public Actor { void get_forum_topic_link(DialogId dialog_id, MessageId top_thread_message_id, Promise &&promise); + void get_forum_topics(DialogId dialog_id, string query, int32 offset_date, MessageId offset_message_id, + MessageId offset_top_thread_message_id, int32 limit, + Promise> promise); + void toggle_forum_topic_is_closed(DialogId dialog_id, MessageId top_thread_message_id, bool is_closed, Promise &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index eb56c1b78..1ab24caea 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5581,6 +5581,16 @@ void Td::on_request(uint64 id, const td_api::getForumTopicLink &request) { std::move(query_promise)); } +void Td::on_request(uint64 id, td_api::getForumTopics &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST_PROMISE(); + forum_topic_manager_->get_forum_topics(DialogId(request.chat_id_), std::move(request.query_), request.offset_date_, + MessageId(request.offset_message_id_), + MessageId(request.offset_message_thread_id_), request.limit_, + std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::toggleForumTopicIsClosed &request) { CREATE_OK_REQUEST_PROMISE(); forum_topic_manager_->toggle_forum_topic_is_closed(DialogId(request.chat_id_), MessageId(request.message_thread_id_), diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 007f81b8b..c57cac7fe 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -752,6 +752,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::getForumTopicLink &request); + void on_request(uint64 id, td_api::getForumTopics &request); + void on_request(uint64 id, const td_api::toggleForumTopicIsClosed &request); void on_request(uint64 id, const td_api::toggleGeneralForumTopicIsHidden &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 643952fc5..075c61f08 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3892,6 +3892,16 @@ class CliClient final : public Actor { MessageThreadId message_thread_id; get_args(args, chat_id, message_thread_id); send_request(td_api::make_object(chat_id, message_thread_id)); + } else if (op == "gfts") { + ChatId chat_id; + string query; + int32 offset_date; + MessageId offset_message_id; + MessageThreadId offset_message_thread_id; + string limit; + get_args(args, chat_id, query, offset_date, offset_message_id, offset_message_thread_id, limit); + send_request(td_api::make_object(chat_id, query, offset_date, offset_message_id, + offset_message_thread_id, as_limit(limit))); } else if (op == "tftic") { ChatId chat_id; MessageThreadId message_thread_id;