diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 53be9b9de..0b0c78659 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -6599,8 +6599,8 @@ updateQuickReplyShortcut shortcut:quickReplyShortcut = Update; //@description A quick reply shortcut was deleted @name The name of the deleted shortcut updateQuickReplyShortcutDeleted name:string = Update; -//@description The list of quick reply shortcuts has changed @shortcuts The new list of existing quick reply shortcuts -updateQuickReplyShortcuts shortcuts:vector = Update; +//@description The list of quick reply shortcuts has changed @shortcut_names The new list of names of quick reply shortcuts +updateQuickReplyShortcuts shortcut_names:vector = Update; //@description Basic information about a topic in a forum chat was changed @chat_id Chat identifier @info New information about the topic updateForumTopicInfo chat_id:int53 info:forumTopicInfo = Update; @@ -7732,8 +7732,11 @@ editMessageSchedulingState chat_id:int53 message_id:int53 scheduling_state:Messa //@description Loads quick reply shortcuts created by the current user. The loaded topics will be sent through updateQuickReplyShortcuts loadQuickReplyShortcuts = Ok; -//@description Deletes a quick reply shortcut @name The name of the quick reply shortcut -deleteQuickReplyShortcut name:string = Ok; +//@description Deletes a quick reply shortcut @shortcut_name The name of the quick reply shortcut +deleteQuickReplyShortcut shortcut_name:string = Ok; + +//@description Changes the order of quick reply shortcuts @shortcut_names The new order of quick reply shortcuts +reorderQuickReplyShortcuts shortcut_names:vector = Ok; //@description Returns list of custom emojis, which can be used as forum topic icon by all users diff --git a/td/telegram/QuickReplyManager.cpp b/td/telegram/QuickReplyManager.cpp index b5d581cbb..426ec67b7 100644 --- a/td/telegram/QuickReplyManager.cpp +++ b/td/telegram/QuickReplyManager.cpp @@ -79,6 +79,36 @@ class DeleteQuickReplyShortcutQuery final : public Td::ResultHandler { } void on_error(Status status) final { + td_->quick_reply_manager_->reload_quick_reply_shortcuts(); + promise_.set_error(std::move(status)); + } +}; + +class ReorderQuickRepliesQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ReorderQuickRepliesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(vector shortcut_ids) { + send_query( + G()->net_query_creator().create(telegram_api::messages_reorderQuickReplies( + QuickReplyShortcutId::get_input_quick_reply_shortcut_ids(shortcut_ids)), + {{"me"}})); + } + + 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()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->quick_reply_manager_->reload_quick_reply_shortcuts(); promise_.set_error(std::move(status)); } }; @@ -711,6 +741,53 @@ void QuickReplyManager::delete_quick_reply_shortcut_from_server(QuickReplyShortc td_->create_handler(std::move(promise))->send(shortcut_id); } +void QuickReplyManager::reorder_quick_reply_shortcuts(const vector &names, Promise &&promise) { + FlatHashSet unique_names; + for (const auto &name : names) { + if (get_shortcut(name) == nullptr) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + unique_names.insert(name); + } + if (unique_names.size() != names.size()) { + return promise.set_error(Status::Error(400, "Duplicate shortcut names specified")); + } + if (!shortcuts_.are_inited_) { + return promise.set_value(Unit()); + } + vector> shortcuts; + for (const auto &name : names) { + auto it = get_shortcut_it(name); + CHECK(it != shortcuts_.shortcuts_.end() && *it != nullptr); + shortcuts.push_back(std::move(*it)); + } + for (auto &shortcut : shortcuts_.shortcuts_) { + if (shortcut != nullptr) { + CHECK(unique_names.count(shortcut->name_) == 0); + shortcuts.push_back(std::move(shortcut)); + } + } + auto old_server_shortcut_ids = get_server_shortcut_ids(); + bool is_list_changed = is_shortcut_list_changed(shortcuts); + shortcuts_.shortcuts_ = std::move(shortcuts); + if (!is_list_changed) { + return promise.set_value(Unit()); + } + send_update_quick_reply_shortcuts(); + + auto new_server_shortcut_ids = get_server_shortcut_ids(); + if (new_server_shortcut_ids == old_server_shortcut_ids || new_server_shortcut_ids.empty()) { + return promise.set_value(Unit()); + } + + reorder_quick_reply_shortcuts_on_server(new_server_shortcut_ids, std::move(promise)); +} + +void QuickReplyManager::reorder_quick_reply_shortcuts_on_server(vector shortcut_ids, + Promise &&promise) { + td_->create_handler(std::move(promise))->send(std::move(shortcut_ids)); +} + QuickReplyManager::Shortcut *QuickReplyManager::get_shortcut(QuickReplyShortcutId shortcut_id) { if (!shortcuts_.are_inited_) { return nullptr; @@ -744,6 +821,16 @@ vector>::iterator QuickReplyManager::get return shortcuts_.shortcuts_.end(); } +vector QuickReplyManager::get_server_shortcut_ids() const { + vector shortcut_ids; + for (auto &shortcut : shortcuts_.shortcuts_) { + if (shortcut->shortcut_id_.is_server()) { + shortcut_ids.push_back(shortcut->shortcut_id_); + } + } + return shortcut_ids; +} + void QuickReplyManager::sort_quick_reply_messages(vector> &messages) { std::sort(messages.begin(), messages.end(), [](const unique_ptr &lhs, const unique_ptr &rhs) { diff --git a/td/telegram/QuickReplyManager.h b/td/telegram/QuickReplyManager.h index 0f49dacba..df488c497 100644 --- a/td/telegram/QuickReplyManager.h +++ b/td/telegram/QuickReplyManager.h @@ -35,6 +35,8 @@ class QuickReplyManager final : public Actor { void delete_quick_reply_shortcut(const string &name, Promise &&promise); + void reorder_quick_reply_shortcuts(const vector &names, Promise &&promise); + void reload_quick_reply_shortcuts(); void get_current_state(vector> &updates) const; @@ -172,6 +174,8 @@ class QuickReplyManager final : public Actor { bool is_shortcut_list_changed(const vector> &new_shortcuts) const; + vector get_server_shortcut_ids() const; + static void sort_quick_reply_messages(vector> &messages); using QuickReplyMessageUniqueId = std::pair; @@ -203,6 +207,8 @@ class QuickReplyManager final : public Actor { void delete_quick_reply_shortcut_from_server(QuickReplyShortcutId shortcut_id, Promise &&promise); + void reorder_quick_reply_shortcuts_on_server(vector shortcut_ids, Promise &&promise); + Shortcuts shortcuts_; FlatHashSet deleted_shortcut_ids_; diff --git a/td/telegram/QuickReplyShortcutId.h b/td/telegram/QuickReplyShortcutId.h index 03ac9bd5a..7b8b5b5e7 100644 --- a/td/telegram/QuickReplyShortcutId.h +++ b/td/telegram/QuickReplyShortcutId.h @@ -31,6 +31,16 @@ class QuickReplyShortcutId { return id; } + static vector get_input_quick_reply_shortcut_ids( + const vector &quick_reply_shortcut_ids) { + vector input_quick_reply_shortcut_ids; + input_quick_reply_shortcut_ids.reserve(quick_reply_shortcut_ids.size()); + for (auto &quick_reply_shortcut_id : quick_reply_shortcut_ids) { + input_quick_reply_shortcut_ids.emplace_back(quick_reply_shortcut_id.get()); + } + return input_quick_reply_shortcut_ids; + } + bool operator==(const QuickReplyShortcutId &other) const { return id == other.id; } diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 8970f39a2..a5a258451 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5768,7 +5768,13 @@ void Td::on_request(uint64 id, const td_api::loadQuickReplyShortcuts &request) { void Td::on_request(uint64 id, const td_api::deleteQuickReplyShortcut &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); - quick_reply_manager_->delete_quick_reply_shortcut(request.name_, std::move(promise)); + quick_reply_manager_->delete_quick_reply_shortcut(request.shortcut_name_, std::move(promise)); +} + +void Td::on_request(uint64 id, const td_api::reorderQuickReplyShortcuts &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + quick_reply_manager_->reorder_quick_reply_shortcuts(request.shortcut_names_, std::move(promise)); } void Td::on_request(uint64 id, const td_api::getStory &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index b2516f7dc..53dd91e78 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -868,6 +868,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::deleteQuickReplyShortcut &request); + void on_request(uint64 id, const td_api::reorderQuickReplyShortcuts &request); + void on_request(uint64 id, const td_api::getStory &request); void on_request(uint64 id, const td_api::getChatsToSendStories &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 6a6d56000..0d0b40dd0 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -4831,6 +4831,10 @@ class CliClient final : public Actor { string name; get_args(args, name); send_request(td_api::make_object(name)); + } else if (op == "rqrs") { + string names; + get_args(args, names); + send_request(td_api::make_object(autosplit_str(names))); } else if (op == "gftdi") { send_request(td_api::make_object()); } else if (op == "cft") {