Add td_api::clickAnimatedEmojiMessage.

This commit is contained in:
levlam 2021-09-16 00:41:40 +03:00
parent a3fefcd18b
commit 5fd11e4b7a
10 changed files with 168 additions and 11 deletions

View File

@ -4515,6 +4515,9 @@ viewMessages chat_id:int53 message_thread_id:int53 message_ids:vector<int53> for
//@description Informs TDLib that the message content has been opened (e.g., the user has opened a photo, video, document, location or venue, or has listened to an audio file or voice note message). An updateMessageContentOpened update will be generated if something has changed @chat_id Chat identifier of the message @message_id Identifier of the message with the opened content
openMessageContent chat_id:int53 message_id:int53 = Ok;
//@description Informs TDLib that a message with an animated emoji was clicked by the user. Returns a big animated sticker to be played or a 404 error if usual animation needs to be played @chat_id Chat identifier of the message @message_id Identifier of the clicked message
clickAnimatedEmojiMessage chat_id:int53 message_id:int53 = Sticker;
//@description Returns information about the type of an internal link. Returns a 404 error if the link is not internal. Can be called before authorization @link The link
getInternalLinkType link:string = InternalLinkType;

View File

@ -5300,6 +5300,20 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte
}
}
void get_message_content_animated_emoji_click_sticker(const MessageContent *content, FullMessageId full_message_id,
Td *td, Promise<td_api::object_ptr<td_api::sticker>> &&promise) {
if (content->get_type() != MessageContentType::Text) {
return promise.set_error(Status::Error(400, "Message is not an animated emoji message"));
}
auto &text = static_cast<const MessageText *>(content)->text;
if (!text.entities.empty()) {
// TODO enable the error
// return promise.set_error(Status::Error(400, "Message is not an animated emoji message"));
}
td->stickers_manager_->get_animated_emoji_click_sticker(text.text, full_message_id, std::move(promise));
}
bool need_reget_message_content(const MessageContent *content) {
CHECK(content != nullptr);
switch (content->get_type()) {

View File

@ -225,6 +225,9 @@ vector<FileId> get_message_content_file_ids(const MessageContent *content, const
string get_message_content_search_text(const Td *td, const MessageContent *content);
void get_message_content_animated_emoji_click_sticker(const MessageContent *content, FullMessageId full_message_id,
Td *td, Promise<td_api::object_ptr<td_api::sticker>> &&promise);
bool need_reget_message_content(const MessageContent *content);
bool need_delay_message_content_notification(const MessageContent *content, UserId my_user_id);

View File

@ -19703,6 +19703,27 @@ void MessagesManager::read_message_contents_on_server(DialogId dialog_id, vector
}
}
void MessagesManager::click_animated_emoji_message(FullMessageId full_message_id,
Promise<td_api::object_ptr<td_api::sticker>> &&promise) {
auto dialog_id = full_message_id.get_dialog_id();
Dialog *d = get_dialog_force(dialog_id, "click_animated_emoji_message");
if (d == nullptr) {
return promise.set_error(Status::Error(400, "Chat not found"));
}
auto message_id = get_persistent_message_id(d, full_message_id.get_message_id());
auto *m = get_message_force(d, message_id, "click_animated_emoji_message");
if (m == nullptr) {
return promise.set_error(Status::Error(400, "Message not found"));
}
if (m->message_id.is_scheduled() || dialog_id.get_type() != DialogType::User || !m->message_id.is_server()) {
return promise.set_value(nullptr);
}
get_message_content_animated_emoji_click_sticker(m->content.get(), full_message_id, td_, std::move(promise));
}
void MessagesManager::open_dialog(Dialog *d) {
DialogId dialog_id = d->dialog_id;
if (!have_input_peer(dialog_id, AccessRights::Read)) {

View File

@ -647,6 +647,9 @@ class MessagesManager final : public Actor {
Status open_message_content(FullMessageId full_message_id) TD_WARN_UNUSED_RESULT;
void click_animated_emoji_message(FullMessageId full_message_id,
Promise<td_api::object_ptr<td_api::sticker>> &&promise);
td_api::object_ptr<td_api::updateScopeNotificationSettings> get_update_scope_notification_settings_object(
NotificationSettingsScope scope) const;

View File

@ -1224,9 +1224,7 @@ void StickersManager::init() {
if (!G()->is_test_dc()) {
// add animated emoji click sticker set
auto &sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji_click());
init_special_sticker_set(sticker_set, 1258816259751996, 1, "EmojiAnimations");
load_special_sticker_set_info_from_binlog(sticker_set);
G()->shared_config().set_option_string(PSLICE() << sticker_set.type_.type_ << "_name", sticker_set.short_name_);
}
dice_emojis_str_ =
@ -1357,14 +1355,25 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t
special_sticker_set.is_being_loaded_ = false;
auto emoji = type.get_dice_emoji();
CHECK(!emoji.empty());
CHECK(special_sticker_set.id_.is_valid());
auto sticker_set = get_sticker_set(special_sticker_set.id_);
CHECK(sticker_set != nullptr);
CHECK(sticker_set->was_loaded);
if (type.type_ == SpecialStickerSetType::animated_emoji_click()) {
auto pending_requests = std::move(pending_get_animated_emoji_click_stickers_);
reset_to_empty(pending_get_animated_emoji_click_stickers_);
for (auto &pending_request : pending_requests) {
choose_animated_emoji_click_sticker(sticker_set, std::move(pending_request.message_text_),
pending_request.full_message_id_, pending_request.start_time_,
std::move(pending_request.promise_));
}
return;
}
auto emoji = type.get_dice_emoji();
CHECK(!emoji.empty());
auto it = dice_messages_.find(emoji);
if (it == dice_messages_.end()) {
return;
@ -1770,12 +1779,12 @@ tl_object_ptr<td_api::stickerSet> StickersManager::get_sticker_set_object(Sticke
for (auto sticker_id : sticker_set->sticker_ids) {
stickers.push_back(get_sticker_object(sticker_id));
vector<string> sticker_emojis;
auto it = sticker_set->sticker_emojis_map_.find(sticker_id);
if (it == sticker_set->sticker_emojis_map_.end()) {
emojis.push_back(Auto());
} else {
emojis.push_back(make_tl_object<td_api::emojis>(vector<string>(it->second)));
if (it != sticker_set->sticker_emojis_map_.end()) {
sticker_emojis = it->second;
}
emojis.push_back(make_tl_object<td_api::emojis>(std::move(sticker_emojis)));
}
auto thumbnail = get_thumbnail_object(td_->file_manager_.get(), sticker_set->thumbnail,
sticker_set->is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp);
@ -2826,8 +2835,6 @@ void StickersManager::on_get_special_sticker_set(const SpecialStickerSetType &ty
<< ' ' << sticker_set.short_name_);
if (type.type_ == SpecialStickerSetType::animated_emoji()) {
G()->shared_config().set_option_string(PSLICE() << type.type_ << "_name", sticker_set.short_name_);
} else if (type.type_ == SpecialStickerSetType::animated_emoji_click()) {
G()->shared_config().set_option_string(PSLICE() << type.type_ << "_name", sticker_set.short_name_);
} else if (!type.get_dice_emoji().empty()) {
sticker_set.is_being_loaded_ = true;
}
@ -3973,6 +3980,79 @@ void StickersManager::unregister_dice(const string &emoji, int32 value, FullMess
}
}
void StickersManager::get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id,
Promise<td_api::object_ptr<td_api::sticker>> &&promise) {
auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji_click());
if (!special_sticker_set.id_.is_valid()) {
// don't wait for the first load of the sticker set from the server
if (!special_sticker_set.is_being_loaded_) {
load_special_sticker_set(special_sticker_set);
}
return promise.set_value(nullptr);
}
auto sticker_set = get_sticker_set(special_sticker_set.id_);
CHECK(sticker_set != nullptr);
if (sticker_set->was_loaded) {
return choose_animated_emoji_click_sticker(sticker_set, message_text, full_message_id, Time::now(),
std::move(promise));
}
LOG(INFO) << "Waiting for an emoji click sticker set needed in " << full_message_id;
if (!special_sticker_set.is_being_loaded_) {
load_special_sticker_set(special_sticker_set);
}
PendingGetAnimatedEmojiClickSticker pending_request;
pending_request.message_text_ = message_text;
pending_request.full_message_id_ = full_message_id;
pending_request.start_time_ = Time::now();
pending_request.promise_ = std::move(promise);
pending_get_animated_emoji_click_stickers_.push_back(std::move(pending_request));
}
int StickersManager::get_emoji_number(Slice emoji) {
// '0'-'9' + U+20E3
auto data = emoji.ubegin();
if (emoji.size() != 4 || emoji[0] < '0' || emoji[0] > '9' || data[1] != 0xE2 || data[2] != 0x83 || data[3] != 0xA3) {
return -1;
}
return emoji[0] - '0';
}
void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *sticker_set, string message_text,
FullMessageId full_message_id, double start_time,
Promise<td_api::object_ptr<td_api::sticker>> &&promise) {
CHECK(sticker_set->was_loaded);
message_text = remove_emoji_modifiers(message_text);
if (message_text.empty()) {
return promise.set_error(Status::Error(400, "Message is not an animated emoji message"));
}
vector<std::pair<int, FileId>> found_stickers;
for (auto sticker_id : sticker_set->sticker_ids) {
auto s = get_sticker(sticker_id);
CHECK(s != nullptr);
if (s->alt == message_text) {
auto it = sticker_set->sticker_emojis_map_.find(sticker_id);
if (it != sticker_set->sticker_emojis_map_.end()) {
for (auto &emoji : it->second) {
auto number = get_emoji_number(emoji);
if (number > 0) {
found_stickers.emplace_back(number, sticker_id);
}
}
}
}
}
if (found_stickers.empty()) {
return promise.set_value(nullptr);
}
auto result = found_stickers[Random::fast(0, narrow_cast<int>(found_stickers.size()) - 1)];
promise.set_value(get_sticker_object(result.second));
}
void StickersManager::view_featured_sticker_sets(const vector<StickerSetId> &sticker_set_ids) {
for (auto sticker_set_id : sticker_set_ids) {
auto set = get_sticker_set(sticker_set_id);

View File

@ -69,6 +69,9 @@ class StickersManager final : public Actor {
void unregister_dice(const string &emoji, int32 value, FullMessageId full_message_id, const char *source);
void get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id,
Promise<td_api::object_ptr<td_api::sticker>> &&promise);
void create_sticker(FileId file_id, string minithumbnail, PhotoSize thumbnail, Dimensions dimensions,
tl_object_ptr<telegram_api::documentAttributeSticker> sticker, bool is_animated,
MultiPromiseActor *load_data_multipromise_ptr);
@ -389,6 +392,13 @@ class StickersManager final : public Actor {
Promise<> promise;
};
struct PendingGetAnimatedEmojiClickSticker {
string message_text_;
FullMessageId full_message_id_;
double start_time_ = 0;
Promise<td_api::object_ptr<td_api::sticker>> promise_;
};
struct SpecialStickerSet {
StickerSetId id_;
int64 access_hash_ = 0;
@ -572,6 +582,12 @@ class StickersManager final : public Actor {
bool update_sticker_set_cache(const StickerSet *sticker_set, Promise<Unit> &promise);
static int get_emoji_number(Slice emoji);
void choose_animated_emoji_click_sticker(const StickerSet *sticker_set, string message_text,
FullMessageId full_message_id, double start_time,
Promise<td_api::object_ptr<td_api::sticker>> &&promise);
td_api::object_ptr<td_api::updateDiceEmojis> get_update_dice_emojis_object() const;
void start_up() final;
@ -722,6 +738,8 @@ class StickersManager final : public Actor {
std::unordered_map<int64, unique_ptr<PendingSetStickerSetThumbnail>> pending_set_sticker_set_thumbnails_;
vector<PendingGetAnimatedEmojiClickSticker> pending_get_animated_emoji_click_stickers_;
std::shared_ptr<UploadStickerFileCallback> upload_sticker_file_callback_;
std::unordered_map<FileId, std::pair<UserId, Promise<Unit>>, FileIdHash> being_uploaded_files_;

View File

@ -5398,6 +5398,13 @@ void Td::on_request(uint64 id, const td_api::openMessageContent &request) {
id, messages_manager_->open_message_content({DialogId(request.chat_id_), MessageId(request.message_id_)}));
}
void Td::on_request(uint64 id, const td_api::clickAnimatedEmojiMessage &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
messages_manager_->click_animated_emoji_message({DialogId(request.chat_id_), MessageId(request.message_id_)},
std::move(promise));
}
void Td::on_request(uint64 id, const td_api::getInternalLinkType &request) {
auto type = link_manager_->parse_internal_link(request.link_);
send_closure(actor_id(this), &Td::send_result, id, type == nullptr ? nullptr : type->get_internal_link_type_object());

View File

@ -600,6 +600,8 @@ class Td final : public Actor {
void on_request(uint64 id, const td_api::openMessageContent &request);
void on_request(uint64 id, const td_api::clickAnimatedEmojiMessage &request);
void on_request(uint64 id, const td_api::getInternalLinkType &request);
void on_request(uint64 id, td_api::getExternalLinkInfo &request);

View File

@ -4099,6 +4099,12 @@ class CliClient final : public Actor {
string message_id;
get_args(args, chat_id, message_id);
send_request(td_api::make_object<td_api::openMessageContent>(as_chat_id(chat_id), as_message_id(message_id)));
} else if (op == "caem") {
string chat_id;
string message_id;
get_args(args, chat_id, message_id);
send_request(
td_api::make_object<td_api::clickAnimatedEmojiMessage>(as_chat_id(chat_id), as_message_id(message_id)));
} else if (op == "gilt") {
string link = args;
send_request(td_api::make_object<td_api::getInternalLinkType>(link));