From eff767574987e41ee00d5e92572d1bfc2c80655e Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 26 Dec 2022 14:20:48 +0300 Subject: [PATCH] Support spoilers for messageAnimation. --- td/generate/scheme/td_api.tl | 19 ++++++++++++------- td/telegram/AnimationsManager.cpp | 17 ++++++++++++++--- td/telegram/AnimationsManager.h | 3 ++- td/telegram/MessageContent.cpp | 31 +++++++++++++++++++++---------- td/telegram/cli.cpp | 18 ++++++++++-------- 5 files changed, 59 insertions(+), 29 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 9da3dcf62..f31a7be04 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2241,8 +2241,12 @@ inputPassportElementError type:PassportElementType message:string source:InputPa //@description A text message @text Text of the message @web_page A preview of the web page that's mentioned in the text; may be null messageText text:formattedText web_page:webPage = MessageContent; -//@description An animation message (GIF-style). @animation The animation description @caption Animation caption @is_secret True, if the animation thumbnail must be blurred and the animation must be shown only while tapped -messageAnimation animation:animation caption:formattedText is_secret:Bool = MessageContent; +//@description An animation message (GIF-style). +//@animation The animation description +//@caption Animation caption +//@has_spoiler True, if the animation preview should be covered by a spoiler animation +//@is_secret True, if the animation thumbnail must be blurred and the animation must be shown only while tapped +messageAnimation animation:animation caption:formattedText has_spoiler:Bool is_secret:Bool = MessageContent; //@description An audio message @audio The audio description @caption Audio caption messageAudio audio:audio caption:formattedText = MessageContent; @@ -2253,7 +2257,7 @@ messageDocument document:document caption:formattedText = MessageContent; //@description A photo message //@photo The photo //@caption Photo caption -//@has_spoiler True, if the photo preview should be covered by spoiler animation +//@has_spoiler True, if the photo preview should be covered by a spoiler animation //@is_secret True, if the photo must be blurred and must be shown only while tapped messagePhoto photo:photo caption:formattedText has_spoiler:Bool is_secret:Bool = MessageContent; @@ -2266,7 +2270,7 @@ messageSticker sticker:sticker is_premium:Bool = MessageContent; //@description A video message //@video The video description //@caption Video caption -//@has_spoiler True, if the video preview should be covered by spoiler animation +//@has_spoiler True, if the video preview should be covered by a spoiler animation //@is_secret True, if the video thumbnail must be blurred and the video must be shown only while tapped messageVideo video:video caption:formattedText has_spoiler:Bool is_secret:Bool = MessageContent; @@ -2574,7 +2578,8 @@ inputMessageText text:formattedText disable_web_page_preview:Bool clear_draft:Bo //@width Width of the animation; may be replaced by the server //@height Height of the animation; may be replaced by the server //@caption Animation caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters -inputMessageAnimation animation:InputFile thumbnail:inputThumbnail added_sticker_file_ids:vector duration:int32 width:int32 height:int32 caption:formattedText = InputMessageContent; +//@has_spoiler True, if the animation preview should be covered by a spoiler animation; not supported in secret chats +inputMessageAnimation animation:InputFile thumbnail:inputThumbnail added_sticker_file_ids:vector duration:int32 width:int32 height:int32 caption:formattedText has_spoiler:Bool = InputMessageContent; //@description An audio message //@audio Audio file to be sent @@ -2600,7 +2605,7 @@ inputMessageDocument document:InputFile thumbnail:inputThumbnail disable_content //@height Photo height //@caption Photo caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters //@ttl Photo TTL (Time To Live), in seconds (0-60). A non-zero TTL can be specified only in private chats -//@has_spoiler True, if the photo preview should be covered by spoiler animation; not supported in secret chats +//@has_spoiler True, if the photo preview should be covered by a spoiler animation; not supported in secret chats inputMessagePhoto photo:InputFile thumbnail:inputThumbnail added_sticker_file_ids:vector width:int32 height:int32 caption:formattedText ttl:int32 has_spoiler:Bool = InputMessageContent; //@description A sticker message @@ -2621,7 +2626,7 @@ inputMessageSticker sticker:InputFile thumbnail:inputThumbnail width:int32 heigh //@supports_streaming True, if the video is supposed to be streamed //@caption Video caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters //@ttl Video TTL (Time To Live), in seconds (0-60). A non-zero TTL can be specified only in private chats -//@has_spoiler True, if the video preview should be covered by spoiler animation; not supported in secret chats +//@has_spoiler True, if the video preview should be covered by a spoiler animation; not supported in secret chats inputMessageVideo video:InputFile thumbnail:inputThumbnail added_sticker_file_ids:vector duration:int32 width:int32 height:int32 supports_streaming:Bool caption:formattedText ttl:int32 has_spoiler:Bool = InputMessageContent; //@description A video note message diff --git a/td/telegram/AnimationsManager.cpp b/td/telegram/AnimationsManager.cpp index 9b3e2d4d0..4ea5e5530 100644 --- a/td/telegram/AnimationsManager.cpp +++ b/td/telegram/AnimationsManager.cpp @@ -308,17 +308,25 @@ void AnimationsManager::create_animation(FileId file_id, string minithumbnail, P tl_object_ptr AnimationsManager::get_input_media( FileId file_id, tl_object_ptr input_file, - tl_object_ptr input_thumbnail) const { + tl_object_ptr input_thumbnail, bool has_spoiler) const { auto file_view = td_->file_manager_->get_file_view(file_id); if (file_view.is_encrypted()) { return nullptr; } if (file_view.has_remote_location() && !file_view.main_remote_location().is_web() && input_file == nullptr) { + int32 flags = 0; + if (has_spoiler) { + flags |= telegram_api::inputMediaDocument::SPOILER_MASK; + } return make_tl_object( - 0, false /*ignored*/, file_view.main_remote_location().as_input_document(), 0, string()); + flags, false /*ignored*/, file_view.main_remote_location().as_input_document(), 0, string()); } if (file_view.has_url()) { - return make_tl_object(0, false /*ignored*/, file_view.url(), 0); + int32 flags = 0; + if (has_spoiler) { + flags |= telegram_api::inputMediaDocumentExternal::SPOILER_MASK; + } + return make_tl_object(flags, false /*ignored*/, file_view.url(), 0); } if (input_file != nullptr) { @@ -350,6 +358,9 @@ tl_object_ptr AnimationsManager::get_input_media( if (input_thumbnail != nullptr) { flags |= telegram_api::inputMediaUploadedDocument::THUMB_MASK; } + if (has_spoiler) { + flags |= telegram_api::inputMediaUploadedDocument::SPOILER_MASK; + } return make_tl_object( flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_file), std::move(input_thumbnail), mime_type, std::move(attributes), std::move(added_stickers), 0); diff --git a/td/telegram/AnimationsManager.h b/td/telegram/AnimationsManager.h index 728f5e273..49db52143 100644 --- a/td/telegram/AnimationsManager.h +++ b/td/telegram/AnimationsManager.h @@ -45,7 +45,8 @@ class AnimationsManager final : public Actor { tl_object_ptr get_input_media(FileId file_id, tl_object_ptr input_file, - tl_object_ptr input_thumbnail) const; + tl_object_ptr input_thumbnail, + bool has_spoiler) const; SecretInputMedia get_secret_input_media(FileId animation_file_id, tl_object_ptr input_file, diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 0e8165b4c..6810958e8 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -123,9 +123,11 @@ class MessageAnimation final : public MessageContent { FileId file_id; FormattedText caption; + bool has_spoiler = false; MessageAnimation() = default; - MessageAnimation(FileId file_id, FormattedText &&caption) : file_id(file_id), caption(std::move(caption)) { + MessageAnimation(FileId file_id, FormattedText &&caption, bool has_spoiler) + : file_id(file_id), caption(std::move(caption)), has_spoiler(has_spoiler) { } MessageContentType get_type() const final { @@ -873,6 +875,9 @@ static void store(const MessageContent *content, StorerT &storer) { case MessageContentType::Animation: { const auto *m = static_cast(content); td->animations_manager_->store_animation(m->file_id, storer); + BEGIN_STORE_FLAGS(); + STORE_FLAG(m->has_spoiler); + END_STORE_FLAGS(); store(m->caption, storer); break; } @@ -1251,6 +1256,11 @@ static void parse(unique_ptr &content, ParserT &parser) { case MessageContentType::Animation: { auto m = make_unique(); m->file_id = td->animations_manager_->parse_animation(parser); + if (parser.version() >= static_cast(Version::AddMessageMediaSpoiler)) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(m->has_spoiler); + END_PARSE_FLAGS(); + } parse_caption(m->caption, parser); is_bad = !m->file_id.is_valid(); content = std::move(m); @@ -1809,7 +1819,7 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, get_message_text(td->contacts_manager_.get(), inline_message->message_, std::move(inline_message->entities_), true, false, 0, false, "create_inline_message_content"); if (allowed_media_content_id == td_api::inputMessageAnimation::ID) { - result.message_content = make_unique(file_id, std::move(caption)); + result.message_content = make_unique(file_id, std::move(caption), false); } else if (allowed_media_content_id == td_api::inputMessageAudio::ID) { result.message_content = make_unique(file_id, std::move(caption)); } else if (allowed_media_content_id == td_api::inputMessageDocument::ID) { @@ -1913,7 +1923,7 @@ static Result create_input_message_content( std::move(file_name), std::move(mime_type), input_animation->duration_, get_dimensions(input_animation->width_, input_animation->height_, nullptr), false); - content = make_unique(file_id, std::move(caption)); + content = make_unique(file_id, std::move(caption), input_animation->has_spoiler_ && !is_secret); break; } case td_api::inputMessageAudio::ID: { @@ -2480,7 +2490,8 @@ static tl_object_ptr get_input_media_impl( switch (content->get_type()) { case MessageContentType::Animation: { const auto *m = static_cast(content); - return td->animations_manager_->get_input_media(m->file_id, std::move(input_file), std::move(input_thumbnail)); + return td->animations_manager_->get_input_media(m->file_id, std::move(input_file), std::move(input_thumbnail), + m->has_spoiler); } case MessageContentType::Audio: { const auto *m = static_cast(content); @@ -3337,7 +3348,7 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo } need_update = true; } - if (old_->caption != new_->caption) { + if (old_->caption != new_->caption || old_->has_spoiler != new_->has_spoiler) { need_update = true; } break; @@ -3434,11 +3445,10 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo LOG(DEBUG) << "Photo date has changed from " << old_photo->date << " to " << new_photo->date; is_content_changed = true; } - if (old_photo->id.get() != new_photo->id.get() || old_->caption != new_->caption || - old_->has_spoiler != new_->has_spoiler) { + if (old_->caption != new_->caption || old_->has_spoiler != new_->has_spoiler) { need_update = true; } - if (old_photo->minithumbnail != new_photo->minithumbnail) { + if (old_photo->id.get() != new_photo->id.get() || old_photo->minithumbnail != new_photo->minithumbnail) { need_update = true; } if (old_photo->photos != new_photo->photos) { @@ -4316,7 +4326,7 @@ static unique_ptr get_document_message_content(Document &&parsed } switch (parsed_document.type) { case Document::Type::Animation: - return make_unique(file_id, std::move(caption)); + return make_unique(file_id, std::move(caption), has_spoiler); case Document::Type::Audio: return make_unique(file_id, std::move(caption)); case Document::Type::General: @@ -5321,7 +5331,8 @@ tl_object_ptr get_message_content_object(const MessageCo const auto *m = static_cast(content); return make_tl_object( td->animations_manager_->get_animation_object(m->file_id), - get_formatted_text_object(m->caption, skip_bot_commands, max_media_timestamp), is_content_secret); + get_formatted_text_object(m->caption, skip_bot_commands, max_media_timestamp), m->has_spoiler, + is_content_secret); } case MessageContentType::Audio: { const auto *m = static_cast(content); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 6f6764897..98a1be356 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3829,7 +3829,7 @@ class CliClient final : public Actor { send_request(td_api::make_object( chat_id, message_id, nullptr, td_api::make_object(as_input_file(animation), nullptr, vector(), 0, 0, - 0, as_caption("animation")))); + 0, as_caption("animation"), has_spoiler_))); } else if (op == "emc") { ChatId chat_id; MessageId message_id; @@ -4002,7 +4002,7 @@ class CliClient final : public Actor { get_args(args, chat_id, animation_path, width, height, caption); send_message(chat_id, td_api::make_object(as_input_file(animation_path), nullptr, vector(), 60, width, height, - as_caption(caption))); + as_caption(caption), has_spoiler_)); } else if (op == "sang") { ChatId chat_id; string animation_path; @@ -4010,25 +4010,27 @@ class CliClient final : public Actor { get_args(args, chat_id, animation_path, animation_conversion); send_message(chat_id, td_api::make_object( as_generated_file(animation_path, animation_conversion), nullptr, vector(), 60, - 0, 0, as_caption(""))); + 0, 0, as_caption(""), has_spoiler_)); } else if (op == "sanid") { ChatId chat_id; string file_id; get_args(args, chat_id, file_id); - send_message(chat_id, td_api::make_object( - as_input_file_id(file_id), nullptr, vector(), 0, 0, 0, as_caption(""))); + send_message(chat_id, + td_api::make_object( + as_input_file_id(file_id), nullptr, vector(), 0, 0, 0, as_caption(""), has_spoiler_)); } else if (op == "sanurl") { ChatId chat_id; string url; get_args(args, chat_id, url); - send_message(chat_id, td_api::make_object( - as_generated_file(url, "#url#"), nullptr, vector(), 0, 0, 0, as_caption(""))); + send_message(chat_id, td_api::make_object(as_generated_file(url, "#url#"), nullptr, + vector(), 0, 0, 0, as_caption(""), + has_spoiler_)); } else if (op == "sanurl2") { ChatId chat_id; string url; get_args(args, chat_id, url); send_message(chat_id, td_api::make_object( - as_remote_file(url), nullptr, vector(), 0, 0, 0, as_caption(""))); + as_remote_file(url), nullptr, vector(), 0, 0, 0, as_caption(""), has_spoiler_)); } else if (op == "sau") { ChatId chat_id; string audio_path;