From 118c336c016a955e151f17188c54305fabe11c3e Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 29 Dec 2022 23:23:09 +0300 Subject: [PATCH] Add td_api::toggleForumTopicIsPinned. --- td/generate/scheme/td_api.tl | 14 +++++--- td/telegram/DialogParticipant.h | 5 +++ td/telegram/ForumTopicManager.cpp | 54 +++++++++++++++++++++++++++++++ td/telegram/ForumTopicManager.h | 3 ++ td/telegram/Td.cpp | 7 ++++ td/telegram/Td.h | 2 ++ td/telegram/cli.cpp | 6 ++++ 7 files changed, 87 insertions(+), 4 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d3975f8df..08d4876a6 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -6074,7 +6074,7 @@ getForumTopicDefaultIcons = Stickers; //@icon Icon of the topic. Icon color must be one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, 0x8EEE98, 0xFF93B2, or 0xFB6F5F. Telegram Premium users can use any custom emoji as topic icon, other users can use only a custom emoji returned by getForumTopicDefaultIcons createForumTopic chat_id:int53 name:string icon:forumTopicIcon = ForumTopicInfo; -//@description Edits title and icon of a topic in a forum supergroup chat; requires can_manage_topics administrator rights in the supergroup unless the user is creator of the topic +//@description Edits title and icon of a topic in a forum supergroup chat; requires can_manage_topics administrator right in the supergroup unless the user is creator of the topic //@chat_id Identifier of the chat //@message_thread_id Message thread identifier of the forum topic //@name New name of the topic; 0-128 characters. If empty, the previous topic name is kept @@ -6103,18 +6103,24 @@ getForumTopics chat_id:int53 query:string offset_date:int32 offset_message_id:in //@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; -//@description Toggles whether a topic is closed in a forum supergroup chat; requires can_manage_topics administrator rights in the supergroup unless the user is creator of the topic +//@description Toggles whether a topic is closed in a forum supergroup chat; requires can_manage_topics administrator right in the supergroup unless the user is creator of the topic //@chat_id Identifier of the chat //@message_thread_id Message thread identifier of the forum topic //@is_closed Pass true to close the topic; pass false to reopen it toggleForumTopicIsClosed chat_id:int53 message_thread_id:int53 is_closed:Bool = Ok; -//@description Toggles whether a General topic is hidden in a forum supergroup chat; requires can_manage_topics administrator rights in the supergroup +//@description Toggles whether a General topic is hidden in a forum supergroup chat; requires can_manage_topics administrator right in the supergroup //@chat_id Identifier of the chat //@is_hidden Pass true to hide and close the General topic; pass false to unhide it toggleGeneralForumTopicIsHidden chat_id:int53 is_hidden:Bool = Ok; -//@description Deletes all messages in a forum topic; requires can_delete_messages administrator rights in the supergroup unless the user is creator of the topic, the topic has no messages from other users and has at most 11 messages +//@description Changes the pinned state of a forum topic; requires can_manage_topics administrator right in the supergroup. There can be up to getOption("pinned_forum_topic_count_max") pinned forum topics +//@chat_id Chat identifier +//@message_thread_id Message thread identifier of the forum topic +//@is_pinned Pass true to pin the topic; pass false to unpin it +toggleForumTopicIsPinned chat_id:int53 message_thread_id:int53 is_pinned:Bool = Ok; + +//@description Deletes all messages in a forum topic; requires can_delete_messages administrator right in the supergroup unless the user is creator of the topic, the topic has no messages from other users and has at most 11 messages //@chat_id Identifier of the chat //@message_thread_id Message thread identifier of the forum topic deleteForumTopic chat_id:int53 message_thread_id:int53 = Ok; diff --git a/td/telegram/DialogParticipant.h b/td/telegram/DialogParticipant.h index 105531a11..defd2af70 100644 --- a/td/telegram/DialogParticipant.h +++ b/td/telegram/DialogParticipant.h @@ -360,6 +360,11 @@ class DialogParticipantStatus { return get_administrator_rights().can_manage_topics(); } + bool can_pin_topics() const { + // topics can be pinned, only if administrator was explicitly granted the right + return get_administrator_rights().can_manage_topics(); + } + bool can_create_topics() const { return get_administrator_rights().can_manage_topics() || get_restricted_rights().can_manage_topics(); } diff --git a/td/telegram/ForumTopicManager.cpp b/td/telegram/ForumTopicManager.cpp index 4bcf4e78e..f3a4fe9b7 100644 --- a/td/telegram/ForumTopicManager.cpp +++ b/td/telegram/ForumTopicManager.cpp @@ -201,6 +201,46 @@ class EditForumTopicQuery final : public Td::ResultHandler { } }; +class UpdatePinnedForumTopicQuery final : public Td::ResultHandler { + Promise promise_; + ChannelId channel_id_; + + public: + explicit UpdatePinnedForumTopicQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, MessageId top_thread_message_id, bool is_pinned) { + channel_id_ = channel_id; + + auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + CHECK(input_channel != nullptr); + + send_query(G()->net_query_creator().create( + telegram_api::channels_updatePinnedForumTopic(std::move(input_channel), + top_thread_message_id.get_server_message_id().get(), is_pinned), + {{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 UpdatePinnedForumTopicQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + if (status.message() == "PINNED_TOPIC_NOT_MODIFIED" && !td_->auth_manager_->is_bot()) { + return promise_.set_value(Unit()); + } + td_->contacts_manager_->on_get_channel_error(channel_id_, status, "UpdatePinnedForumTopicQuery"); + promise_.set_error(std::move(status)); + } +}; + class GetForumTopicQuery final : public Td::ResultHandler { Promise> promise_; ChannelId channel_id_; @@ -693,6 +733,20 @@ void ForumTopicManager::toggle_forum_topic_is_hidden(DialogId dialog_id, bool is td_->create_handler(std::move(promise))->send(channel_id, is_hidden); } +void ForumTopicManager::toggle_forum_topic_is_pinned(DialogId dialog_id, MessageId top_thread_message_id, + bool is_pinned, Promise &&promise) { + TRY_STATUS_PROMISE(promise, is_forum(dialog_id)); + TRY_STATUS_PROMISE(promise, can_be_message_thread_id(top_thread_message_id)); + auto channel_id = dialog_id.get_channel_id(); + + if (!td_->contacts_manager_->get_channel_permissions(channel_id).can_pin_topics()) { + return promise.set_error(Status::Error(400, "Not enough rights to pin or unpin the topic")); + } + + td_->create_handler(std::move(promise)) + ->send(channel_id, top_thread_message_id, is_pinned); +} + void ForumTopicManager::delete_forum_topic(DialogId dialog_id, MessageId top_thread_message_id, Promise &&promise) { TRY_STATUS_PROMISE(promise, is_forum(dialog_id)); diff --git a/td/telegram/ForumTopicManager.h b/td/telegram/ForumTopicManager.h index 4471d5adf..97edda4a5 100644 --- a/td/telegram/ForumTopicManager.h +++ b/td/telegram/ForumTopicManager.h @@ -78,6 +78,9 @@ class ForumTopicManager final : public Actor { void toggle_forum_topic_is_hidden(DialogId dialog_id, bool is_hidden, Promise &&promise); + void toggle_forum_topic_is_pinned(DialogId dialog_id, MessageId top_thread_message_id, bool is_pinned, + Promise &&promise); + void delete_forum_topic(DialogId dialog_id, MessageId top_thread_message_id, Promise &&promise); void delete_all_dialog_topics(DialogId dialog_id); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 4e69b52da..20fb60f33 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5589,6 +5589,13 @@ void Td::on_request(uint64 id, const td_api::toggleGeneralForumTopicIsHidden &re std::move(promise)); } +void Td::on_request(uint64 id, const td_api::toggleForumTopicIsPinned &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + forum_topic_manager_->toggle_forum_topic_is_pinned(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + request.is_pinned_, std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::deleteForumTopic &request) { CREATE_OK_REQUEST_PROMISE(); forum_topic_manager_->delete_forum_topic(DialogId(request.chat_id_), MessageId(request.message_thread_id_), diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 06ff74414..3e07ec591 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -758,6 +758,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::toggleGeneralForumTopicIsHidden &request); + void on_request(uint64 id, const td_api::toggleForumTopicIsPinned &request); + void on_request(uint64 id, const td_api::deleteForumTopic &request); void on_request(uint64 id, td_api::setGameScore &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 539db7879..cf96a91d6 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3932,6 +3932,12 @@ class CliClient final : public Actor { bool is_hidden; get_args(args, chat_id, is_hidden); send_request(td_api::make_object(chat_id, is_hidden)); + } else if (op == "tftip") { + ChatId chat_id; + MessageThreadId message_thread_id; + bool is_pinned; + get_args(args, chat_id, message_thread_id, is_pinned); + send_request(td_api::make_object(chat_id, message_thread_id, is_pinned)); } else if (op == "dft") { ChatId chat_id; MessageThreadId message_thread_id;