Add sound to messageAnimatedEmoji.
This commit is contained in:
parent
9fb1f1438e
commit
038abf5466
@ -1711,8 +1711,8 @@ messageVenue venue:venue = MessageContent;
|
|||||||
//@description A message with a user contact @contact The contact description
|
//@description A message with a user contact @contact The contact description
|
||||||
messageContact contact:contact = MessageContent;
|
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
|
//@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 sticker:sticker color_replacements:vector<colorReplacement> emoji:string = MessageContent;
|
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
|
//@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
|
//@initial_state The animated stickers with the initial dice animation; may be null if unknown. updateMessageContent will be sent when the sticker became known
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "td/utils/buffer.h"
|
#include "td/utils/buffer.h"
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/crypto.h"
|
#include "td/utils/crypto.h"
|
||||||
|
#include "td/utils/emoji.h"
|
||||||
#include "td/utils/format.h"
|
#include "td/utils/format.h"
|
||||||
#include "td/utils/JsonBuilder.h"
|
#include "td/utils/JsonBuilder.h"
|
||||||
#include "td/utils/logging.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;
|
vector<string> dice_emojis;
|
||||||
std::unordered_map<string, size_t> dice_emoji_index;
|
std::unordered_map<string, size_t> dice_emoji_index;
|
||||||
std::unordered_map<string, string> dice_emoji_success_value;
|
std::unordered_map<string, string> dice_emoji_success_value;
|
||||||
|
vector<string> emoji_sounds;
|
||||||
string animation_search_provider;
|
string animation_search_provider;
|
||||||
string animation_search_emojis;
|
string animation_search_emojis;
|
||||||
vector<SuggestedAction> suggested_actions;
|
vector<SuggestedAction> suggested_actions;
|
||||||
@ -1563,6 +1565,46 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
|
|||||||
}
|
}
|
||||||
continue;
|
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") {
|
if (key == "gif_search_branding") {
|
||||||
animation_search_provider = get_json_value_string(std::move(key_value->value_), "gif_search_branding");
|
animation_search_provider = get_json_value_string(std::move(key_value->value_), "gif_search_branding");
|
||||||
continue;
|
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("dice_emojis", implode(dice_emojis, '\x01'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_config.set_option_string("emoji_sounds", implode(emoji_sounds, ','));
|
||||||
|
|
||||||
if (animation_search_provider.empty()) {
|
if (animation_search_provider.empty()) {
|
||||||
shared_config.set_option_empty("animation_search_provider");
|
shared_config.set_option_empty("animation_search_provider");
|
||||||
} else {
|
} else {
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "td/utils/format.h"
|
#include "td/utils/format.h"
|
||||||
#include "td/utils/JsonBuilder.h"
|
#include "td/utils/JsonBuilder.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/MimeType.h"
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
#include "td/utils/PathView.h"
|
#include "td/utils/PathView.h"
|
||||||
#include "td/utils/Random.h"
|
#include "td/utils/Random.h"
|
||||||
@ -1279,6 +1280,8 @@ void StickersManager::init() {
|
|||||||
|
|
||||||
on_update_dice_success_values();
|
on_update_dice_success_values();
|
||||||
|
|
||||||
|
on_update_emoji_sounds();
|
||||||
|
|
||||||
on_update_disable_animated_emojis();
|
on_update_disable_animated_emojis();
|
||||||
|
|
||||||
if (!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);
|
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(
|
vector<td_api::object_ptr<td_api::colorReplacement>> StickersManager::get_color_replacements_object(
|
||||||
int fitzpatrick_modifier) {
|
int fitzpatrick_modifier) {
|
||||||
vector<td_api::object_ptr<td_api::colorReplacement>> result;
|
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 =
|
auto animated_sticker =
|
||||||
it != emoji_messages_.end() ? it->second.animated_emoji_sticker : get_animated_emoji_sticker(emoji);
|
it != emoji_messages_.end() ? it->second.animated_emoji_sticker : get_animated_emoji_sticker(emoji);
|
||||||
if (animated_sticker.first.is_valid()) {
|
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>(
|
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>(
|
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>>()),
|
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() {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4100,8 +4147,11 @@ void StickersManager::try_update_animated_emoji_messages() {
|
|||||||
vector<FullMessageId> full_message_ids;
|
vector<FullMessageId> full_message_ids;
|
||||||
for (auto &it : emoji_messages_) {
|
for (auto &it : emoji_messages_) {
|
||||||
auto new_animated_sticker = get_animated_emoji_sticker(sticker_set, it.first);
|
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.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) {
|
for (auto full_message_id : it.second.full_message_ids) {
|
||||||
full_message_ids.push_back(full_message_id);
|
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];
|
auto &emoji_messages = emoji_messages_[emoji];
|
||||||
if (emoji_messages.full_message_ids.empty()) {
|
if (emoji_messages.full_message_ids.empty()) {
|
||||||
emoji_messages.animated_emoji_sticker = get_animated_emoji_sticker(emoji);
|
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;
|
bool is_inserted = emoji_messages.full_message_ids.insert(full_message_id).second;
|
||||||
LOG_CHECK(is_inserted) << source << ' ' << emoji << ' ' << full_message_id;
|
LOG_CHECK(is_inserted) << source << ' ' << emoji << ' ' << full_message_id;
|
||||||
|
@ -154,6 +154,8 @@ class StickersManager final : public Actor {
|
|||||||
|
|
||||||
void on_update_dice_success_values();
|
void on_update_dice_success_values();
|
||||||
|
|
||||||
|
void on_update_emoji_sounds();
|
||||||
|
|
||||||
void on_update_sticker_sets();
|
void on_update_sticker_sets();
|
||||||
|
|
||||||
void on_update_sticker_sets_order(bool is_masks, const vector<StickerSetId> &sticker_set_ids);
|
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);
|
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();
|
void try_update_animated_emoji_messages();
|
||||||
|
|
||||||
static int get_emoji_number(Slice emoji);
|
static int get_emoji_number(Slice emoji);
|
||||||
@ -817,6 +821,7 @@ class StickersManager final : public Actor {
|
|||||||
struct EmojiMessages {
|
struct EmojiMessages {
|
||||||
std::unordered_set<FullMessageId, FullMessageIdHash> full_message_ids;
|
std::unordered_set<FullMessageId, FullMessageIdHash> full_message_ids;
|
||||||
std::pair<FileId, int> animated_emoji_sticker;
|
std::pair<FileId, int> animated_emoji_sticker;
|
||||||
|
FileId sound_file_id;
|
||||||
};
|
};
|
||||||
std::unordered_map<string, EmojiMessages> emoji_messages_;
|
std::unordered_map<string, EmojiMessages> emoji_messages_;
|
||||||
|
|
||||||
@ -826,6 +831,9 @@ class StickersManager final : public Actor {
|
|||||||
string dice_success_values_str_;
|
string dice_success_values_str_;
|
||||||
vector<std::pair<int32, int32>> dice_success_values_;
|
vector<std::pair<int32, int32>> dice_success_values_;
|
||||||
|
|
||||||
|
string emoji_sounds_str_;
|
||||||
|
std::unordered_map<string, FileId> emoji_sounds_;
|
||||||
|
|
||||||
bool disable_animated_emojis_ = false;
|
bool disable_animated_emojis_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3275,7 +3275,7 @@ bool Td::is_internal_config_option(Slice name) {
|
|||||||
case 'd':
|
case 'd':
|
||||||
return name == "dc_txt_domain_name" || name == "dice_emojis" || name == "dice_success_values";
|
return name == "dc_txt_domain_name" || name == "dice_emojis" || name == "dice_success_values";
|
||||||
case 'e':
|
case 'e':
|
||||||
return name == "edit_time_limit";
|
return name == "edit_time_limit" || name == "emoji_sounds";
|
||||||
case 'i':
|
case 'i':
|
||||||
return name == "ignored_restriction_reasons";
|
return name == "ignored_restriction_reasons";
|
||||||
case 'l':
|
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);
|
return send_closure(stickers_manager_actor_, &StickersManager::on_update_dice_emojis);
|
||||||
} else if (name == "dice_success_values") {
|
} else if (name == "dice_success_values") {
|
||||||
return send_closure(stickers_manager_actor_, &StickersManager::on_update_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)) {
|
} else if (is_internal_config_option(name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -851,6 +851,13 @@ int get_fitzpatrick_modifier(Slice emoji) {
|
|||||||
return (c - 0xBB) + 2;
|
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) {
|
Slice remove_emoji_modifiers(Slice emoji) {
|
||||||
static const Slice modifiers[] = {u8"\uFE0E" /* variation selector-15 */,
|
static const Slice modifiers[] = {u8"\uFE0E" /* variation selector-15 */,
|
||||||
u8"\uFE0F" /* variation selector-16 */,
|
u8"\uFE0F" /* variation selector-16 */,
|
||||||
|
@ -17,6 +17,9 @@ bool is_emoji(Slice str);
|
|||||||
// checks whether emoji ends on a Fitzpatrick modifier and returns it's number or 0
|
// checks whether emoji ends on a Fitzpatrick modifier and returns it's number or 0
|
||||||
int get_fitzpatrick_modifier(Slice emoji);
|
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
|
// removes all emoji modifiers from the end of the string
|
||||||
Slice remove_emoji_modifiers(Slice emoji);
|
Slice remove_emoji_modifiers(Slice emoji);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user