Add sound to messageAnimatedEmoji.

This commit is contained in:
levlam 2021-10-05 23:20:49 +03:00
parent 9fb1f1438e
commit 038abf5466
7 changed files with 121 additions and 6 deletions

View File

@ -1711,8 +1711,8 @@ messageVenue venue:venue = MessageContent;
//@description A message with a user contact @contact The contact description
messageContact contact:contact = MessageContent;
//@description A message with an animated emoji @sticker The animated sticker with the emoji animation @color_replacements The list of colors to be replaced while the sticker is rendered @emoji The corresponding emoji
messageAnimatedEmoji sticker:sticker color_replacements:vector<colorReplacement> emoji:string = MessageContent;
//@description A message with an animated emoji @emoji The corresponding emoji @sticker Animated sticker with the emoji animation @color_replacements List of colors to be replaced while the sticker is rendered @sound File containing the sound to be played when the animated emoji is clicked if any; may be null
messageAnimatedEmoji emoji:string sticker:sticker color_replacements:vector<colorReplacement> sound:file = MessageContent;
//@description A dice message. The dice value is randomly generated by the server
//@initial_state The animated stickers with the initial dice animation; may be null if unknown. updateMessageContent will be sent when the sticker became known

View File

@ -47,6 +47,7 @@
#include "td/utils/buffer.h"
#include "td/utils/common.h"
#include "td/utils/crypto.h"
#include "td/utils/emoji.h"
#include "td/utils/format.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/logging.h"
@ -1478,6 +1479,7 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
vector<string> dice_emojis;
std::unordered_map<string, size_t> dice_emoji_index;
std::unordered_map<string, string> dice_emoji_success_value;
vector<string> emoji_sounds;
string animation_search_provider;
string animation_search_emojis;
vector<SuggestedAction> suggested_actions;
@ -1563,6 +1565,46 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
}
continue;
}
if (key == "emojies_sounds") {
if (value->get_id() == telegram_api::jsonObject::ID) {
auto sounds = std::move(static_cast<telegram_api::jsonObject *>(value)->value_);
for (auto &sound : sounds) {
CHECK(sound != nullptr);
if (sound->value_->get_id() == telegram_api::jsonObject::ID) {
string id;
string access_hash;
string file_reference_base64;
for (auto &sound_key_value : static_cast<telegram_api::jsonObject *>(sound->value_.get())->value_) {
if (sound_key_value->value_->get_id() != telegram_api::jsonString::ID) {
continue;
}
auto current_value = get_json_value_string(std::move(sound_key_value->value_), Slice());
if (sound_key_value->key_ == "id") {
id = std::move(current_value);
}
if (sound_key_value->key_ == "access_hash") {
access_hash = std::move(current_value);
}
if (sound_key_value->key_ == "file_reference_base64") {
file_reference_base64 = std::move(current_value);
}
}
if (to_integer_safe<int64>(id).is_error() || to_integer_safe<int64>(access_hash).is_error() ||
!is_base64url(file_reference_base64) || !is_emoji(sound->key_)) {
LOG(ERROR) << "Receive unexpected sound value " << to_string(sound);
} else {
emoji_sounds.push_back(sound->key_);
emoji_sounds.push_back(PSTRING() << id << ':' << access_hash << ':' << file_reference_base64);
}
} else {
LOG(ERROR) << "Receive unexpected emoji sound " << to_string(sound);
}
}
} else {
LOG(ERROR) << "Receive unexpected emojies_sounds " << to_string(*value);
}
continue;
}
if (key == "gif_search_branding") {
animation_search_provider = get_json_value_string(std::move(key_value->value_), "gif_search_branding");
continue;
@ -1722,6 +1764,8 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
shared_config.set_option_string("dice_emojis", implode(dice_emojis, '\x01'));
}
shared_config.set_option_string("emoji_sounds", implode(emoji_sounds, ','));
if (animation_search_provider.empty()) {
shared_config.set_option_empty("animation_search_provider");
} else {

View File

@ -46,6 +46,7 @@
#include "td/utils/format.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/logging.h"
#include "td/utils/MimeType.h"
#include "td/utils/misc.h"
#include "td/utils/PathView.h"
#include "td/utils/Random.h"
@ -1279,6 +1280,8 @@ void StickersManager::init() {
on_update_dice_success_values();
on_update_emoji_sounds();
on_update_disable_animated_emojis();
if (!disable_animated_emojis_) {
@ -1963,6 +1966,14 @@ std::pair<FileId, int> StickersManager::get_animated_emoji_sticker(const string
return get_animated_emoji_sticker(get_animated_emoji_sticker_set(), emoji);
}
FileId StickersManager::get_animated_emoji_sound_file_id(const string &emoji) const {
auto it = emoji_sounds_.find(remove_fitzpatrick_modifier(emoji).str());
if (it == emoji_sounds_.end()) {
return {};
}
return it->second;
}
vector<td_api::object_ptr<td_api::colorReplacement>> StickersManager::get_color_replacements_object(
int fitzpatrick_modifier) {
vector<td_api::object_ptr<td_api::colorReplacement>> result;
@ -1996,8 +2007,11 @@ td_api::object_ptr<td_api::MessageContent> StickersManager::get_message_content_
auto animated_sticker =
it != emoji_messages_.end() ? it->second.animated_emoji_sticker : get_animated_emoji_sticker(emoji);
if (animated_sticker.first.is_valid()) {
auto sound_file_id =
it != emoji_messages_.end() ? it->second.sound_file_id : get_animated_emoji_sound_file_id(emoji);
return td_api::make_object<td_api::messageAnimatedEmoji>(
get_sticker_object(animated_sticker.first), get_color_replacements_object(animated_sticker.second), emoji);
emoji, get_sticker_object(animated_sticker.first), get_color_replacements_object(animated_sticker.second),
sound_file_id.is_valid() ? td_->file_manager_->get_file_object(sound_file_id) : nullptr);
}
return td_api::make_object<td_api::messageText>(
td_api::make_object<td_api::formattedText>(emoji, std::vector<td_api::object_ptr<td_api::textEntity>>()),
@ -4068,8 +4082,41 @@ void StickersManager::on_update_dice_success_values() {
});
}
void StickersManager::on_update_emoji_sounds() {
if (G()->close_flag() || !is_inited_ || td_->auth_manager_->is_bot()) {
return;
}
auto emoji_sounds_str = G()->shared_config().get_option_string("emoji_sounds");
if (emoji_sounds_str == emoji_sounds_str_) {
return;
}
LOG(INFO) << "Change emoji sounds to " << emoji_sounds_str;
emoji_sounds_str_ = std::move(emoji_sounds_str);
emoji_sounds_.clear();
auto sounds = full_split(Slice(emoji_sounds_str_), ',');
CHECK(sounds.size() % 2 == 0);
for (size_t i = 0; i < sounds.size(); i += 2) {
vector<Slice> parts = full_split(sounds[i + 1], ':');
CHECK(parts.size() == 3);
auto id = to_integer<int64>(parts[0]);
auto access_hash = to_integer<int64>(parts[1]);
auto file_reference = base64url_decode(parts[2]).move_as_ok();
auto suggested_file_name = PSTRING() << static_cast<uint64>(id) << '.'
<< MimeType::to_extension("audio/ogg", "oga");
auto file_id = td_->file_manager_->register_remote(
FullRemoteFileLocation(FileType::VoiceNote, id, access_hash, DcId::internal(2), std::move(file_reference)),
FileLocationSource::FromServer, DialogId(), 0, 0, std::move(suggested_file_name));
CHECK(file_id.is_valid());
emoji_sounds_.emplace(remove_fitzpatrick_modifier(sounds[i]).str(), file_id);
}
try_update_animated_emoji_messages();
}
void StickersManager::on_update_disable_animated_emojis() {
if (G()->close_flag() || td_->auth_manager_->is_bot() || !is_inited_) {
if (G()->close_flag() || !is_inited_ || td_->auth_manager_->is_bot()) {
return;
}
@ -4100,8 +4147,11 @@ void StickersManager::try_update_animated_emoji_messages() {
vector<FullMessageId> full_message_ids;
for (auto &it : emoji_messages_) {
auto new_animated_sticker = get_animated_emoji_sticker(sticker_set, it.first);
if (new_animated_sticker != it.second.animated_emoji_sticker) {
auto new_sound_file_id = get_animated_emoji_sound_file_id(it.first);
if (new_animated_sticker != it.second.animated_emoji_sticker ||
(new_animated_sticker.first.is_valid() && new_sound_file_id != it.second.sound_file_id)) {
it.second.animated_emoji_sticker = new_animated_sticker;
it.second.sound_file_id = new_sound_file_id;
for (auto full_message_id : it.second.full_message_ids) {
full_message_ids.push_back(full_message_id);
}
@ -4180,6 +4230,7 @@ void StickersManager::register_emoji(const string &emoji, FullMessageId full_mes
auto &emoji_messages = emoji_messages_[emoji];
if (emoji_messages.full_message_ids.empty()) {
emoji_messages.animated_emoji_sticker = get_animated_emoji_sticker(emoji);
emoji_messages.sound_file_id = get_animated_emoji_sound_file_id(emoji);
}
bool is_inserted = emoji_messages.full_message_ids.insert(full_message_id).second;
LOG_CHECK(is_inserted) << source << ' ' << emoji << ' ' << full_message_id;

View File

@ -154,6 +154,8 @@ class StickersManager final : public Actor {
void on_update_dice_success_values();
void on_update_emoji_sounds();
void on_update_sticker_sets();
void on_update_sticker_sets_order(bool is_masks, const vector<StickerSetId> &sticker_set_ids);
@ -611,6 +613,8 @@ class StickersManager final : public Actor {
std::pair<FileId, int> get_animated_emoji_sticker(const string &emoji);
FileId get_animated_emoji_sound_file_id(const string &emoji) const;
void try_update_animated_emoji_messages();
static int get_emoji_number(Slice emoji);
@ -817,6 +821,7 @@ class StickersManager final : public Actor {
struct EmojiMessages {
std::unordered_set<FullMessageId, FullMessageIdHash> full_message_ids;
std::pair<FileId, int> animated_emoji_sticker;
FileId sound_file_id;
};
std::unordered_map<string, EmojiMessages> emoji_messages_;
@ -826,6 +831,9 @@ class StickersManager final : public Actor {
string dice_success_values_str_;
vector<std::pair<int32, int32>> dice_success_values_;
string emoji_sounds_str_;
std::unordered_map<string, FileId> emoji_sounds_;
bool disable_animated_emojis_ = false;
};

View File

@ -3275,7 +3275,7 @@ bool Td::is_internal_config_option(Slice name) {
case 'd':
return name == "dc_txt_domain_name" || name == "dice_emojis" || name == "dice_success_values";
case 'e':
return name == "edit_time_limit";
return name == "edit_time_limit" || name == "emoji_sounds";
case 'i':
return name == "ignored_restriction_reasons";
case 'l':
@ -3377,6 +3377,8 @@ void Td::on_config_option_updated(const string &name) {
return send_closure(stickers_manager_actor_, &StickersManager::on_update_dice_emojis);
} else if (name == "dice_success_values") {
return send_closure(stickers_manager_actor_, &StickersManager::on_update_dice_success_values);
} else if (name == "emoji_sounds") {
return send_closure(stickers_manager_actor_, &StickersManager::on_update_emoji_sounds);
} else if (is_internal_config_option(name)) {
return;
}

View File

@ -851,6 +851,13 @@ int get_fitzpatrick_modifier(Slice emoji) {
return (c - 0xBB) + 2;
}
Slice remove_fitzpatrick_modifier(Slice emoji) {
while (get_fitzpatrick_modifier(emoji) != 0) {
emoji.remove_suffix(4);
}
return emoji;
}
Slice remove_emoji_modifiers(Slice emoji) {
static const Slice modifiers[] = {u8"\uFE0E" /* variation selector-15 */,
u8"\uFE0F" /* variation selector-16 */,

View File

@ -17,6 +17,9 @@ bool is_emoji(Slice str);
// checks whether emoji ends on a Fitzpatrick modifier and returns it's number or 0
int get_fitzpatrick_modifier(Slice emoji);
// removes all Fitzpatrick modifier from the end of the string
Slice remove_fitzpatrick_modifier(Slice emoji);
// removes all emoji modifiers from the end of the string
Slice remove_emoji_modifiers(Slice emoji);