diff --git a/CMakeLists.txt b/CMakeLists.txt index 848f7b7b9..e87a9bc64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -332,6 +332,7 @@ set(TDLIB_SOURCE td/telegram/DraftMessage.cpp td/telegram/EmailVerification.cpp td/telegram/EmojiGroup.cpp + td/telegram/EmojiGroupType.cpp td/telegram/EmojiStatus.cpp td/telegram/FileReferenceManager.cpp td/telegram/files/FileBitmask.cpp @@ -564,6 +565,7 @@ set(TDLIB_SOURCE td/telegram/DraftMessage.h td/telegram/EmailVerification.h td/telegram/EmojiGroup.h + td/telegram/EmojiGroupType.h td/telegram/EmojiStatus.h td/telegram/EncryptedFile.h td/telegram/FileReferenceManager.h diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 36806fdb1..295b9ab57 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2950,6 +2950,15 @@ emojiCategory name:string icon_custom_emoji_id:int64 emojis:vector = Emo emojiCategories categories:vector = EmojiCategories; +//@class EmojiCategoryType @description Describes type of an emoji category + +//@description The category should be used by default +emojiCategoryTypeDefault = EmojiCategoryType; + +//@description The category should be used for emoji status selection +emojiCategoryTypeEmojiStatus = EmojiCategoryType; + + //@class CallDiscardReason @description Describes the reason why a call was discarded //@description The call wasn't discarded, or the reason is unknown @@ -7306,8 +7315,8 @@ getStickerEmojis sticker:InputFile = Emojis; //@input_language_codes List of possible IETF language tags of the user's input language; may be empty if unknown searchEmojis text:string exact_match:Bool input_language_codes:vector = Emojis; -//@description Returns available emojis categories -getEmojiCategories = EmojiCategories; +//@description Returns available emojis categories @type Type of emoji categories to return; pass null to get default emoji categories +getEmojiCategories type:EmojiCategoryType = EmojiCategories; //@description Returns an animated emoji corresponding to a given emoji. Returns a 404 error if the emoji has no animated emoji @emoji The emoji getAnimatedEmoji emoji:string = AnimatedEmoji; diff --git a/td/telegram/EmojiGroup.cpp b/td/telegram/EmojiGroup.cpp index 20894a65d..e7d501de2 100644 --- a/td/telegram/EmojiGroup.cpp +++ b/td/telegram/EmojiGroup.cpp @@ -45,5 +45,4 @@ void EmojiGroupList::update_next_reload_time() { next_reload_time_ = Time::now() + 3600; } - } // namespace td diff --git a/td/telegram/EmojiGroupType.cpp b/td/telegram/EmojiGroupType.cpp new file mode 100644 index 000000000..f58ff2946 --- /dev/null +++ b/td/telegram/EmojiGroupType.cpp @@ -0,0 +1,38 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/EmojiGroupType.h" + +namespace td { + +EmojiGroupType get_emoji_group_type(const td_api::object_ptr &type) { + if (type == nullptr) { + return EmojiGroupType::Default; + } + switch (type->get_id()) { + case td_api::emojiCategoryTypeDefault::ID: + return EmojiGroupType::Default; + case td_api::emojiCategoryTypeEmojiStatus::ID: + return EmojiGroupType::EmojiStatus; + default: + UNREACHABLE(); + return EmojiGroupType::Default; + } +} + +StringBuilder &operator<<(StringBuilder &string_builder, EmojiGroupType emoji_group_type) { + switch (emoji_group_type) { + case EmojiGroupType::Default: + return string_builder << "Default"; + case EmojiGroupType::EmojiStatus: + return string_builder << "EmojiStatus"; + default: + UNREACHABLE(); + return string_builder; + } +} + +} // namespace td diff --git a/td/telegram/EmojiGroupType.h b/td/telegram/EmojiGroupType.h new file mode 100644 index 000000000..76d97db76 --- /dev/null +++ b/td/telegram/EmojiGroupType.h @@ -0,0 +1,24 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +enum class EmojiGroupType : int32 { Default, EmojiStatus }; + +static constexpr int32 MAX_EMOJI_GROUP_TYPE = 2; + +EmojiGroupType get_emoji_group_type(const td_api::object_ptr &type); + +StringBuilder &operator<<(StringBuilder &string_builder, EmojiGroupType emoji_group_type); + +} // namespace td diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index b116f7ecd..d156fff05 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1353,11 +1353,23 @@ class GetEmojiGroupsQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(int32 hash) { - send_query(G()->net_query_creator().create(telegram_api::messages_getEmojiGroups(hash))); + void send(EmojiGroupType group_type, int32 hash) { + switch (group_type) { + case EmojiGroupType::Default: + send_query(G()->net_query_creator().create(telegram_api::messages_getEmojiGroups(hash))); + break; + case EmojiGroupType::EmojiStatus: + send_query(G()->net_query_creator().create(telegram_api::messages_getEmojiStatusGroups(hash))); + break; + default: + UNREACHABLE(); + } } void on_result(BufferSlice packet) final { + static_assert(std::is_same::value, + ""); auto result_ptr = fetch_result(packet); if (result_ptr.is_error()) { return on_error(result_ptr.move_as_error()); @@ -9955,34 +9967,39 @@ td_api::object_ptr StickersManager::get_emoji_suggestions_url_r return result; } -void StickersManager::get_emoji_categories(Promise> &&promise) { +void StickersManager::get_emoji_groups(EmojiGroupType group_type, + Promise> &&promise) { + auto type = static_cast(group_type); auto used_language_codes = implode(get_used_language_codes({}, Slice()), '$'); LOG(INFO) << "Have language codes " << used_language_codes; - if (emoji_group_list_.get_used_language_codes() == used_language_codes) { - promise.set_value(emoji_group_list_.get_emoji_categories_object()); - if (!emoji_group_list_.is_expired()) { + if (emoji_group_list_[type].get_used_language_codes() == used_language_codes) { + promise.set_value(emoji_group_list_[type].get_emoji_categories_object()); + if (!emoji_group_list_[type].is_expired()) { return; } promise = Promise>(); } - emoji_group_load_queries_.push_back(std::move(promise)); - if (emoji_group_load_queries_.size() != 1) { + emoji_group_load_queries_[type].push_back(std::move(promise)); + if (emoji_group_load_queries_[type].size() != 1) { // query has already been sent, just wait for the result return; } - auto query_promise = - PromiseCreator::lambda([actor_id = actor_id(this), used_language_codes = std::move(used_language_codes)]( - Result> r_emoji_groups) { - send_closure(actor_id, &StickersManager::on_get_emoji_categories, std::move(used_language_codes), + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), group_type, used_language_codes = std::move(used_language_codes)]( + Result> r_emoji_groups) { + send_closure(actor_id, &StickersManager::on_get_emoji_groups, group_type, std::move(used_language_codes), std::move(r_emoji_groups)); }); - td_->create_handler(std::move(query_promise))->send(emoji_group_list_.get_hash()); + td_->create_handler(std::move(query_promise)) + ->send(group_type, emoji_group_list_[type].get_hash()); } -void StickersManager::on_get_emoji_categories( - string used_language_codes, Result> r_emoji_groups) { +void StickersManager::on_get_emoji_groups( + EmojiGroupType group_type, string used_language_codes, + Result> r_emoji_groups) { + auto type = static_cast(group_type); if (G()->close_flag()) { r_emoji_groups = Global::request_aborted_error(); } @@ -9990,7 +10007,7 @@ void StickersManager::on_get_emoji_categories( if (!G()->is_expected_error(r_emoji_groups.error())) { LOG(ERROR) << "Receive " << r_emoji_groups.error() << " from GetEmojiGroupsQuery"; } - return fail_promises(emoji_group_load_queries_, r_emoji_groups.move_as_error()); + return fail_promises(emoji_group_load_queries_[type], r_emoji_groups.move_as_error()); } auto new_used_language_codes = implode(get_used_language_codes({}, Slice()), '$'); @@ -10001,21 +10018,22 @@ void StickersManager::on_get_emoji_categories( auto emoji_groups = r_emoji_groups.move_as_ok(); switch (emoji_groups->get_id()) { case telegram_api::messages_emojiGroupsNotModified::ID: - emoji_group_list_.update_next_reload_time(); + emoji_group_list_[type].update_next_reload_time(); break; case telegram_api::messages_emojiGroups::ID: { auto groups = telegram_api::move_object_as(emoji_groups); - emoji_group_list_ = EmojiGroupList(std::move(used_language_codes), groups->hash_, std::move(groups->groups_)); + emoji_group_list_[type] = + EmojiGroupList(std::move(used_language_codes), groups->hash_, std::move(groups->groups_)); break; } default: UNREACHABLE(); } - auto promises = std::move(emoji_group_load_queries_); - reset_to_empty(emoji_group_load_queries_); + auto promises = std::move(emoji_group_load_queries_[type]); + reset_to_empty(emoji_group_load_queries_[type]); for (auto &promise : promises) { - promise.set_value(emoji_group_list_.get_emoji_categories_object()); + promise.set_value(emoji_group_list_[type].get_emoji_categories_object()); } } diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index 17bc633a1..430bc3c4d 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -10,6 +10,7 @@ #include "td/telegram/DialogId.h" #include "td/telegram/Dimensions.h" #include "td/telegram/EmojiGroup.h" +#include "td/telegram/EmojiGroupType.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileSourceId.h" #include "td/telegram/FullMessageId.h" @@ -365,7 +366,7 @@ class StickersManager final : public Actor { int64 get_emoji_suggestions_url(const string &language_code, Promise &&promise); - void get_emoji_categories(Promise> &&promise); + void get_emoji_groups(EmojiGroupType group_type, Promise> &&promise); td_api::object_ptr get_emoji_suggestions_url_result(int64 random_id); @@ -1001,8 +1002,8 @@ class StickersManager final : public Actor { void on_get_emoji_suggestions_url(int64 random_id, Promise &&promise, Result> &&r_emoji_url); - void on_get_emoji_categories(string used_language_codes, - Result> r_emoji_groups); + void on_get_emoji_groups(EmojiGroupType group_type, string used_language_codes, + Result> r_emoji_groups); Td *td_; ActorShared<> parent_; @@ -1181,8 +1182,8 @@ class StickersManager final : public Actor { string emoji_sounds_str_; FlatHashMap emoji_sounds_; - EmojiGroupList emoji_group_list_; - vector>> emoji_group_load_queries_; + EmojiGroupList emoji_group_list_[MAX_EMOJI_GROUP_TYPE]; + vector>> emoji_group_load_queries_[MAX_EMOJI_GROUP_TYPE]; vector default_dialog_photo_custom_emoji_ids_[2]; int64 default_dialog_photo_custom_emoji_ids_hash_[2] = {0, 0}; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 33db70e0d..3d5374d5c 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -43,6 +43,7 @@ #include "td/telegram/DownloadManager.h" #include "td/telegram/DownloadManagerCallback.h" #include "td/telegram/EmailVerification.h" +#include "td/telegram/EmojiGroupType.h" #include "td/telegram/EmojiStatus.h" #include "td/telegram/FileReferenceManager.h" #include "td/telegram/files/FileGcParameters.h" @@ -7351,7 +7352,7 @@ void Td::on_request(uint64 id, td_api::searchEmojis &request) { void Td::on_request(uint64 id, const td_api::getEmojiCategories &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); - stickers_manager_->get_emoji_categories(std::move(promise)); + stickers_manager_->get_emoji_groups(get_emoji_group_type(request.type_), std::move(promise)); } void Td::on_request(uint64 id, td_api::getAnimatedEmoji &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 68cea0c95..c26cf37ff 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2921,8 +2921,9 @@ class CliClient final : public Actor { send_request(td_api::make_object(args, true, vector())); } else if (op == "seru") { send_request(td_api::make_object(args, false, vector{"ru_RU"})); - } else if (op == "gec") { - send_request(td_api::make_object()); + } else if (op == "gec" || op == "geces") { + auto type = op == "geces" ? td_api::make_object() : nullptr; + send_request(td_api::make_object(std::move(type))); } else if (op == "gae") { send_request(td_api::make_object(args)); } else if (op == "gesu") {