diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index fb8d6ad20..dc71105c9 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -260,6 +260,9 @@ stickerTypeRegular = StickerType; //@description The sticker is a mask in WEBP format to be placed on photos or videos stickerTypeMask = StickerType; +//@description The sticker is an emoji to be used inside message text and caption +stickerTypeEmoji = StickerType; + //@description Represents a closed vector path. The path begins at the end point of the last command @commands List of vector path commands closedVectorPath commands:vector = ClosedVectorPath; diff --git a/td/telegram/InlineQueriesManager.cpp b/td/telegram/InlineQueriesManager.cpp index 0de394c00..27f05ef2b 100644 --- a/td/telegram/InlineQueriesManager.cpp +++ b/td/telegram/InlineQueriesManager.cpp @@ -1169,6 +1169,8 @@ tl_object_ptr copy(const td_api::StickerType &obj) { return td_api::make_object(); case td_api::stickerTypeMask::ID: return td_api::make_object(); + case td_api::stickerTypeEmoji::ID: + return td_api::make_object(); default: UNREACHABLE(); } diff --git a/td/telegram/StickerType.cpp b/td/telegram/StickerType.cpp index 5b5e37b4f..913813b45 100644 --- a/td/telegram/StickerType.cpp +++ b/td/telegram/StickerType.cpp @@ -17,6 +17,8 @@ StickerType get_sticker_type(const td_api::object_ptr &type return StickerType::Regular; case td_api::stickerTypeMask::ID: return StickerType::Mask; + case td_api::stickerTypeEmoji::ID: + return StickerType::Emoji; default: UNREACHABLE(); return StickerType::Regular; @@ -29,6 +31,8 @@ td_api::object_ptr get_sticker_type_object(StickerType stic return td_api::make_object(); case StickerType::Mask: return td_api::make_object(); + case StickerType::Emoji: + return td_api::make_object(); default: UNREACHABLE(); return nullptr; @@ -41,6 +45,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, StickerType sticker_typ return string_builder << "Regular"; case StickerType::Mask: return string_builder << "Mask"; + case StickerType::Emoji: + return string_builder << "Emoji"; default: UNREACHABLE(); return string_builder; diff --git a/td/telegram/StickerType.h b/td/telegram/StickerType.h index d5be8f87f..324266052 100644 --- a/td/telegram/StickerType.h +++ b/td/telegram/StickerType.h @@ -14,9 +14,9 @@ namespace td { // update store_sticker/store_sticker_set when this type changes -enum class StickerType : int32 { Regular, Mask }; +enum class StickerType : int32 { Regular, Mask, Emoji }; -static constexpr int32 MAX_STICKER_TYPE = 2; +static constexpr int32 MAX_STICKER_TYPE = 3; StickerType get_sticker_type(const td_api::object_ptr &type); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 805082162..091bc1015 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -97,10 +97,15 @@ class GetAllStickersQuery final : public Td::ResultHandler { public: void send(StickerType sticker_type, int64 hash) { sticker_type_ = sticker_type; - if (sticker_type == StickerType::Mask) { - send_query(G()->net_query_creator().create(telegram_api::messages_getMaskStickers(hash))); - } else { - send_query(G()->net_query_creator().create(telegram_api::messages_getAllStickers(hash))); + switch (sticker_type) { + case StickerType::Regular: + return send_query(G()->net_query_creator().create(telegram_api::messages_getAllStickers(hash))); + case StickerType::Mask: + return send_query(G()->net_query_creator().create(telegram_api::messages_getMaskStickers(hash))); + case StickerType::Emoji: + return send_query(G()->net_query_creator().create(telegram_api::messages_getEmojiStickers(hash))); + default: + UNREACHABLE(); } } @@ -278,6 +283,9 @@ class GetArchivedStickerSetsQuery final : public Td::ResultHandler { if (sticker_type_ == StickerType::Mask) { flags |= telegram_api::messages_getArchivedStickers::MASKS_MASK; } + if (sticker_type_ == StickerType::Emoji) { + flags |= telegram_api::messages_getArchivedStickers::EMOJIS_MASK; + } send_query(G()->net_query_creator().create(telegram_api::messages_getArchivedStickers( flags, false /*ignored*/, false /*ignored*/, offset_sticker_set_id.get(), limit))); } @@ -649,6 +657,9 @@ class ReorderStickerSetsQuery final : public Td::ResultHandler { if (sticker_type == StickerType::Mask) { flags |= telegram_api::messages_reorderStickerSets::MASKS_MASK; } + if (sticker_type == StickerType::Emoji) { + flags |= telegram_api::messages_reorderStickerSets::EMOJIS_MASK; + } send_query(G()->net_query_creator().create(telegram_api::messages_reorderStickerSets( flags, false /*ignored*/, false /*ignored*/, StickersManager::convert_sticker_set_ids(sticker_set_ids)))); } @@ -1008,6 +1019,10 @@ class CreateNewStickerSetQuery final : public Td::ResultHandler { if (sticker_type == StickerType::Mask) { flags |= telegram_api::stickers_createStickerSet::MASKS_MASK; } + if (sticker_type == StickerType::Emoji) { + // flags |= telegram_api::stickers_createStickerSet::EMOJIS_MASK; + return on_error(Status::Error(400, "Can't create emoji sets")); + } if (sticker_format == StickerFormat::Tgs) { flags |= telegram_api::stickers_createStickerSet::ANIMATED_MASK; } @@ -2923,7 +2938,8 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptrofficial_; StickerFormat sticker_format = set->videos_ ? StickerFormat::Webm : (set->animated_ ? StickerFormat::Tgs : StickerFormat::Webp); - StickerType sticker_type = set->masks_ ? StickerType::Mask : StickerType::Regular; + StickerType sticker_type = + set->emojis_ ? StickerType::Emoji : (set->masks_ ? StickerType::Mask : StickerType::Regular); PhotoSize thumbnail; string minithumbnail; diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index b64b25ca3..4128d19ab 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -798,22 +798,22 @@ class StickersManager final : public Actor { vector recent_sticker_ids_[2]; vector favorite_sticker_ids_; - double next_installed_sticker_sets_load_time_[MAX_STICKER_TYPE] = {0, 0}; + double next_installed_sticker_sets_load_time_[MAX_STICKER_TYPE] = {0, 0, 0}; double next_featured_sticker_sets_load_time_ = 0; double next_recent_stickers_load_time_[2] = {0, 0}; double next_favorite_stickers_load_time_ = 0; - int64 installed_sticker_sets_hash_[MAX_STICKER_TYPE] = {0, 0}; + int64 installed_sticker_sets_hash_[MAX_STICKER_TYPE] = {0, 0, 0}; int64 featured_sticker_sets_hash_ = 0; int64 recent_stickers_hash_[2] = {0, 0}; int32 old_featured_sticker_set_count_ = -1; uint32 old_featured_sticker_set_generation_ = 1; - bool need_update_installed_sticker_sets_[MAX_STICKER_TYPE] = {false, false}; + bool need_update_installed_sticker_sets_[MAX_STICKER_TYPE] = {false, false, false}; bool need_update_featured_sticker_sets_ = false; - bool are_installed_sticker_sets_loaded_[MAX_STICKER_TYPE] = {false, false}; + bool are_installed_sticker_sets_loaded_[MAX_STICKER_TYPE] = {false, false, false}; bool are_featured_sticker_sets_loaded_ = false; bool are_recent_stickers_loaded_[2] = {false, false}; bool are_favorite_stickers_loaded_ = false; @@ -837,7 +837,7 @@ class StickersManager final : public Actor { FileSourceId app_config_file_source_id_; vector archived_sticker_set_ids_[MAX_STICKER_TYPE]; - int32 total_archived_sticker_set_count_[MAX_STICKER_TYPE] = {-1, -1}; + int32 total_archived_sticker_set_count_[MAX_STICKER_TYPE] = {-1, -1, -1}; FlatHashMap, FileIdHash> attached_sticker_sets_; diff --git a/td/telegram/StickersManager.hpp b/td/telegram/StickersManager.hpp index 0b67eb3d4..e68852f56 100644 --- a/td/telegram/StickersManager.hpp +++ b/td/telegram/StickersManager.hpp @@ -35,6 +35,7 @@ void StickersManager::store_sticker(FileId file_id, bool in_sticker_set, StorerT bool is_webm = sticker->format == StickerFormat::Webm; bool has_premium_animation = sticker->premium_animation_file_id.is_valid(); bool is_mask = sticker->type == StickerType::Mask; + bool is_emoji = sticker->type == StickerType::Emoji; BEGIN_STORE_FLAGS(); STORE_FLAG(is_mask); STORE_FLAG(has_sticker_set_access_hash); @@ -43,6 +44,7 @@ void StickersManager::store_sticker(FileId file_id, bool in_sticker_set, StorerT STORE_FLAG(has_minithumbnail); STORE_FLAG(is_webm); STORE_FLAG(has_premium_animation); + STORE_FLAG(is_emoji); END_STORE_FLAGS(); if (!in_sticker_set) { store(sticker->set_id.get(), storer); @@ -85,6 +87,7 @@ FileId StickersManager::parse_sticker(bool in_sticker_set, ParserT &parser) { bool is_webm; bool has_premium_animation; bool is_mask; + bool is_emoji; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_mask); PARSE_FLAG(has_sticker_set_access_hash); @@ -93,6 +96,7 @@ FileId StickersManager::parse_sticker(bool in_sticker_set, ParserT &parser) { PARSE_FLAG(has_minithumbnail); PARSE_FLAG(is_webm); PARSE_FLAG(has_premium_animation); + PARSE_FLAG(is_emoji); END_PARSE_FLAGS(); if (is_webm) { sticker->format = StickerFormat::Webm; @@ -101,7 +105,9 @@ FileId StickersManager::parse_sticker(bool in_sticker_set, ParserT &parser) { } else { sticker->format = StickerFormat::Webp; } - if (is_mask) { + if (is_emoji) { + sticker->type = StickerType::Emoji; + } else if (is_mask) { sticker->type = StickerType::Mask; } else { sticker->type = StickerType::Regular; @@ -169,6 +175,7 @@ void StickersManager::store_sticker_set(const StickerSet *sticker_set, bool with bool is_tgs = sticker_set->sticker_format == StickerFormat::Tgs; bool is_webm = sticker_set->sticker_format == StickerFormat::Webm; bool is_masks = sticker_set->sticker_type == StickerType::Mask; + bool is_emojis = sticker_set->sticker_type == StickerType::Emoji; BEGIN_STORE_FLAGS(); STORE_FLAG(sticker_set->is_inited); STORE_FLAG(was_loaded); @@ -185,6 +192,7 @@ void StickersManager::store_sticker_set(const StickerSet *sticker_set, bool with STORE_FLAG(sticker_set->are_legacy_sticker_thumbnails_reloaded); STORE_FLAG(has_minithumbnail); STORE_FLAG(is_webm); + STORE_FLAG(is_emojis); END_STORE_FLAGS(); store(sticker_set->id.get(), storer); store(sticker_set->access_hash, storer); @@ -235,6 +243,7 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser bool is_tgs; bool has_minithumbnail; bool is_webm; + bool is_emojis; BEGIN_PARSE_FLAGS(); PARSE_FLAG(sticker_set->is_inited); PARSE_FLAG(sticker_set->was_loaded); @@ -251,6 +260,7 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser PARSE_FLAG(sticker_set->are_legacy_sticker_thumbnails_reloaded); PARSE_FLAG(has_minithumbnail); PARSE_FLAG(is_webm); + PARSE_FLAG(is_emojis); END_PARSE_FLAGS(); int64 sticker_set_id; int64 access_hash; @@ -271,8 +281,10 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser sticker_format = StickerFormat::Webp; } StickerType sticker_type = StickerType::Regular; - if (is_masks) { - sticker_type = StickerType::Regular; + if (is_emojis) { + sticker_type = StickerType::Emoji; + } else if (is_masks) { + sticker_type = StickerType::Mask; } if (sticker_set->is_inited) { diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 763fb0e96..2f8080129 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1676,6 +1676,7 @@ void UpdatesManager::try_reload_data() { td_->stickers_manager_->reload_reactions(); td_->stickers_manager_->get_installed_sticker_sets(StickerType::Regular, Auto()); td_->stickers_manager_->get_installed_sticker_sets(StickerType::Mask, Auto()); + td_->stickers_manager_->get_installed_sticker_sets(StickerType::Emoji, Auto()); td_->stickers_manager_->get_featured_sticker_sets(0, 1000, Auto()); td_->stickers_manager_->get_recent_stickers(false, Auto()); td_->stickers_manager_->get_recent_stickers(true, Auto()); @@ -3315,7 +3316,9 @@ void UpdatesManager::on_update(tl_object_ptr up void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { StickerType sticker_type = StickerType::Regular; - if (update->masks_) { + if (update->emojis_) { + sticker_type = StickerType::Emoji; + } else if (update->masks_) { sticker_type = StickerType::Mask; } td_->stickers_manager_->on_update_sticker_sets_order(sticker_type, diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index b62fe1609..3cf33fa68 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -547,6 +547,9 @@ class CliClient final : public Actor { } static td_api::object_ptr as_sticker_type(string sticker_type) { + if (!sticker_type.empty() && sticker_type.back() == 'e') { + return td_api::make_object(); + } if (!sticker_type.empty() && sticker_type.back() == 'm') { return td_api::make_object(); } @@ -2619,9 +2622,9 @@ class CliClient final : public Actor { int64 sticker_set_id; get_args(args, sticker_set_id); send_request(td_api::make_object(sticker_set_id)); - } else if (op == "giss" || op == "gissm") { + } else if (op == "giss" || op == "gissm" || op == "gisse") { send_request(td_api::make_object(as_sticker_type(args))); - } else if (op == "gass" || op == "gassm") { + } else if (op == "gass" || op == "gassm" || op == "gasse") { int64 offset_sticker_set_id; string limit; get_args(args, offset_sticker_set_id, limit); @@ -2720,11 +2723,11 @@ class CliClient final : public Actor { } else if (op == "cssn") { const string &name = args; send_request(td_api::make_object(name)); - } else if (op == "usf" || op == "usfa" || op == "usfv" || op == "usfm") { + } else if (op == "usf" || op == "usfa" || op == "usfv" || op == "usfm" || op == "usfe") { send_request(td_api::make_object( -1, td_api::make_object(as_input_file(args), "😀", as_sticker_format(op), as_sticker_type(op), as_mask_position(op)))); - } else if (op == "cnss" || op == "cnssa" || op == "cnssv" || op == "cnssm") { + } else if (op == "cnss" || op == "cnssa" || op == "cnssv" || op == "cnssm" || op == "cnsse") { string title; string name; string stickers; @@ -2750,7 +2753,7 @@ class CliClient final : public Actor { send_request(td_api::make_object(set_id, is_installed, is_archived)); } else if (op == "vtss") { send_request(td_api::make_object(to_integers(args))); - } else if (op == "riss" || op == "rissm") { + } else if (op == "riss" || op == "rissm" || op == "risse") { string new_order; get_args(args, new_order); send_request(