diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 8d40923e1..100943726 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1435,6 +1435,7 @@ videoChat group_call_id:int32 has_participants:Bool default_participant_id:Messa //@notification_settings Notification settings for the chat //@available_reactions Types of reaction, available in the chat //@message_auto_delete_time Current message auto-delete or self-destruct timer setting for the chat, in seconds; 0 if disabled. Self-destruct timer in secret chats starts after the message or its content is viewed. Auto-delete timer in other chats starts from the send date +//@background Background set for the chat; may be null if none //@theme_name If non-empty, name of a theme, set for the chat //@action_bar Information about actions which must be possible to do through the chat action bar; may be null //@video_chat Information about video chat of the chat @@ -1442,7 +1443,7 @@ videoChat group_call_id:int32 has_participants:Bool default_participant_id:Messa //@reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat //@draft_message A draft of a message in the chat; may be null //@client_data Application-specific data associated with the chat. (For example, the chat scroll position or local chat notification settings can be stored here.) Persistent if the message database is used -chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector message_sender_id:MessageSender has_protected_content:Bool is_translatable:Bool is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 unread_reaction_count:int32 notification_settings:chatNotificationSettings available_reactions:ChatAvailableReactions message_auto_delete_time:int32 theme_name:string action_bar:ChatActionBar video_chat:videoChat pending_join_requests:chatJoinRequestsInfo reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; +chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector message_sender_id:MessageSender has_protected_content:Bool is_translatable:Bool is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 unread_reaction_count:int32 notification_settings:chatNotificationSettings available_reactions:ChatAvailableReactions message_auto_delete_time:int32 background:background theme_name:string action_bar:ChatActionBar video_chat:videoChat pending_join_requests:chatJoinRequestsInfo reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; //@description Represents a list of chats @total_count Approximate total number of chats found @chat_ids List of chat identifiers chats total_count:int32 chat_ids:vector = Chats; @@ -5373,6 +5374,9 @@ updateChatPendingJoinRequests chat_id:int53 pending_join_requests:chatJoinReques //@reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat updateChatReplyMarkup chat_id:int53 reply_markup_message_id:int53 = Update; +//@description The chat background was changed @chat_id Chat identifier @background The new chat background; may be null if background was reset to default +updateChatBackground chat_id:int53 background:background = Update; + //@description The chat theme was changed @chat_id Chat identifier @theme_name The new name of the chat theme; may be empty if theme was reset to default updateChatTheme chat_id:int53 theme_name:string = Update; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index a8ffa281b..d939737db 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -12350,6 +12350,8 @@ void ContactsManager::on_get_user_full(tl_object_ptr &&u td_->messages_manager_->on_update_dialog_notify_settings(DialogId(user_id), std::move(user->notify_settings_), "on_get_user_full"); + td_->messages_manager_->on_update_dialog_background(DialogId(user_id), std::move(user->wallpaper_)); + td_->messages_manager_->on_update_dialog_theme_name(DialogId(user_id), std::move(user->theme_emoticon_)); td_->messages_manager_->on_update_dialog_last_pinned_message_id(DialogId(user_id), diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 9bc5adc9d..35815ac26 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -11,7 +11,6 @@ #include "td/telegram/AudiosManager.h" #include "td/telegram/AudiosManager.hpp" #include "td/telegram/AuthManager.h" -#include "td/telegram/BackgroundInfo.h" #include "td/telegram/BackgroundInfo.hpp" #include "td/telegram/CallDiscardReason.h" #include "td/telegram/ChannelId.h" @@ -3240,6 +3239,15 @@ MessageId get_message_content_pinned_message_id(const MessageContent *content) { } } +BackgroundInfo get_message_content_background_info(const MessageContent *content) { + switch (content->get_type()) { + case MessageContentType::SetBackground: + return static_cast(content)->background_info; + default: + return BackgroundInfo(); + } +} + string get_message_content_theme_name(const MessageContent *content) { switch (content->get_type()) { case MessageContentType::ChatSetTheme: diff --git a/td/telegram/MessageContent.h b/td/telegram/MessageContent.h index 71e82fb02..176aef9ba 100644 --- a/td/telegram/MessageContent.h +++ b/td/telegram/MessageContent.h @@ -6,6 +6,7 @@ // #pragma once +#include "td/telegram/BackgroundInfo.h" #include "td/telegram/DialogId.h" #include "td/telegram/EncryptedFile.h" #include "td/telegram/files/FileId.h" @@ -135,6 +136,8 @@ StickerType get_message_content_sticker_type(const Td *td, const MessageContent MessageId get_message_content_pinned_message_id(const MessageContent *content); +BackgroundInfo get_message_content_background_info(const MessageContent *content); + string get_message_content_theme_name(const MessageContent *content); FullMessageId get_message_content_replied_message_id(DialogId dialog_id, const MessageContent *content); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index bad4d2708..074fe6ce3 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -7,6 +7,7 @@ #include "td/telegram/MessagesManager.h" #include "td/telegram/AuthManager.h" +#include "td/telegram/BackgroundInfo.hpp" #include "td/telegram/ChainId.h" #include "td/telegram/ChannelType.h" #include "td/telegram/ChatId.h" @@ -5349,6 +5350,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const { bool has_have_full_history_source = have_full_history && have_full_history_source != 0; bool has_available_reactions = !available_reactions.empty(); bool has_history_generation = history_generation != 0; + bool has_background = background_info.is_valid(); BEGIN_STORE_FLAGS(); STORE_FLAG(has_draft_message); STORE_FLAG(has_last_database_message); @@ -5434,6 +5436,8 @@ void MessagesManager::Dialog::store(StorerT &storer) const { STORE_FLAG(need_repair_unread_reaction_count); STORE_FLAG(is_translatable); STORE_FLAG(need_repair_unread_mention_count); + STORE_FLAG(is_background_inited); + STORE_FLAG(has_background); END_STORE_FLAGS(); } @@ -5549,6 +5553,9 @@ void MessagesManager::Dialog::store(StorerT &storer) const { if (has_history_generation) { store(history_generation, storer); } + if (has_background) { + store(background_info, storer); + } } // do not forget to resolve dialog dependencies including dependencies of last_message @@ -5599,6 +5606,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { bool has_have_full_history_source = false; bool has_available_reactions = false; bool has_history_generation = false; + bool has_background = false; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_draft_message); PARSE_FLAG(has_last_database_message); @@ -5699,10 +5707,13 @@ void MessagesManager::Dialog::parse(ParserT &parser) { PARSE_FLAG(need_repair_unread_reaction_count); PARSE_FLAG(is_translatable); PARSE_FLAG(need_repair_unread_mention_count); + PARSE_FLAG(is_background_inited); + PARSE_FLAG(has_background); END_PARSE_FLAGS(); } else { need_repair_action_bar = false; is_available_reactions_inited = false; + is_background_inited = false; } parse(last_new_message_id, parser); @@ -5855,6 +5866,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_history_generation) { parse(history_generation, parser); } + if (has_background) { + parse(background_info, parser); + } (void)legacy_know_can_report_spam; if (know_action_bar && !has_action_bar) { @@ -15722,6 +15736,10 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vectoris_background_inited && !td_->auth_manager_->is_bot()) { + // asynchronously get background from the server + // TODO add background to telegram_api::dialog + reload_dialog_info_full(dialog_id, "on_get_dialogs init background"); } else if (!d->is_theme_name_inited && !td_->auth_manager_->is_bot()) { // asynchronously get theme_name from the server // TODO add theme_name to telegram_api::dialog @@ -20590,6 +20608,21 @@ td_api::object_ptr MessagesManager::get_chat_action_bar_o return d->action_bar->get_chat_action_bar_object(dialog_type, false); } +td_api::object_ptr MessagesManager::get_dialog_background_object(const Dialog *d) const { + CHECK(d != nullptr); + if (d->dialog_id.get_type() == DialogType::SecretChat) { + auto user_id = td_->contacts_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); + if (!user_id.is_valid()) { + return nullptr; + } + d = get_dialog(DialogId(user_id)); + if (d == nullptr) { + return nullptr; + } + } + return d->background_info.get_background_object(td_); +} + string MessagesManager::get_dialog_theme_name(const Dialog *d) const { CHECK(d != nullptr); if (d->dialog_id.get_type() == DialogType::SecretChat) { @@ -20655,9 +20688,9 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * d->server_unread_count + d->local_unread_count, d->last_read_inbox_message_id.get(), d->last_read_outbox_message_id.get(), d->unread_mention_count, d->unread_reaction_count, get_chat_notification_settings_object(&d->notification_settings), std::move(available_reactions), - d->message_ttl.get_message_auto_delete_time_object(), get_dialog_theme_name(d), get_chat_action_bar_object(d), - get_video_chat_object(d), get_chat_join_requests_info_object(d), d->reply_markup_message_id.get(), - std::move(draft_message), d->client_data); + d->message_ttl.get_message_auto_delete_time_object(), get_dialog_background_object(d), get_dialog_theme_name(d), + get_chat_action_bar_object(d), get_video_chat_object(d), get_chat_join_requests_info_object(d), + d->reply_markup_message_id.get(), std::move(draft_message), d->client_data); } tl_object_ptr MessagesManager::get_chat_object(DialogId dialog_id) const { @@ -30243,6 +30276,7 @@ void MessagesManager::send_update_new_chat(Dialog *d) { d->is_update_new_chat_being_sent = true; auto chat_object = get_chat_object(d); bool has_action_bar = chat_object->action_bar_ != nullptr; + bool has_background = chat_object->background_ != nullptr; bool has_theme = !chat_object->theme_name_.empty(); d->last_sent_has_scheduled_messages = chat_object->has_scheduled_messages_; send_closure(G()->td(), &Td::send_update, make_tl_object(std::move(chat_object))); @@ -30252,6 +30286,9 @@ void MessagesManager::send_update_new_chat(Dialog *d) { if (has_action_bar) { send_update_secret_chats_with_user_action_bar(d); } + if (has_background) { + send_update_secret_chats_with_user_background(d); + } if (has_theme) { send_update_secret_chats_with_user_theme(d); } @@ -30541,6 +30578,42 @@ void MessagesManager::send_update_chat_available_reactions(const Dialog *d) { td_api::make_object(d->dialog_id.get(), std::move(available_reactions))); } +void MessagesManager::send_update_secret_chats_with_user_background(const Dialog *d) const { + if (td_->auth_manager_->is_bot()) { + return; + } + + if (d->dialog_id.get_type() != DialogType::User) { + return; + } + + td_->contacts_manager_->for_each_secret_chat_with_user( + d->dialog_id.get_user_id(), [this, user_d = d](SecretChatId secret_chat_id) { + DialogId dialog_id(secret_chat_id); + auto secret_chat_d = get_dialog(dialog_id); // must not create the dialog + if (secret_chat_d != nullptr && secret_chat_d->is_update_new_chat_sent) { + send_closure( + G()->td(), &Td::send_update, + td_api::make_object(dialog_id.get(), get_dialog_background_object(user_d))); + } + }); +} + +void MessagesManager::send_update_chat_background(const Dialog *d) { + if (td_->auth_manager_->is_bot()) { + return; + } + + CHECK(d != nullptr); + CHECK(d->dialog_id.get_type() != DialogType::SecretChat); + LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_background"; + on_dialog_updated(d->dialog_id, "send_update_chat_background"); + send_closure(G()->td(), &Td::send_update, + td_api::make_object(d->dialog_id.get(), get_dialog_background_object(d))); + + send_update_secret_chats_with_user_background(d); +} + void MessagesManager::send_update_secret_chats_with_user_theme(const Dialog *d) const { if (td_->auth_manager_->is_bot()) { return; @@ -31689,6 +31762,46 @@ void MessagesManager::drop_dialog_last_pinned_message_id(Dialog *d) { .release(); } +void MessagesManager::on_update_dialog_background(DialogId dialog_id, + telegram_api::object_ptr &&wallpaper) { + if (!dialog_id.is_valid()) { + LOG(ERROR) << "Receive background in invalid " << dialog_id; + return; + } + if (td_->auth_manager_->is_bot()) { + return; + } + + auto d = get_dialog_force(dialog_id, "on_update_dialog_background"); + if (d == nullptr) { + // nothing to do + return; + } + + set_dialog_background(d, BackgroundInfo(td_, std::move(wallpaper))); +} + +void MessagesManager::set_dialog_background(Dialog *d, BackgroundInfo &&background_info) { + CHECK(d != nullptr); + if (td_->auth_manager_->is_bot()) { + return; + } + + bool is_changed = d->background_info != background_info; + if (!is_changed && d->is_background_inited) { + return; + } + d->background_info = std::move(background_info); + d->is_background_inited = true; + + if (is_changed) { + LOG(INFO) << "Set " << d->dialog_id << " backgroud to " << d->background_info; + send_update_chat_background(d); + } else { + on_dialog_updated(d->dialog_id, "set_dialog_background"); + } +} + void MessagesManager::on_update_dialog_theme_name(DialogId dialog_id, string theme_name) { if (!dialog_id.is_valid()) { LOG(ERROR) << "Receive theme in invalid " << dialog_id; @@ -34916,6 +35029,9 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq set_dialog_last_pinned_message_id(d, pinned_message_id); } } + if (*need_update && m->message_id.is_server() && message_content_type == MessageContentType::SetBackground) { + set_dialog_background(d, get_message_content_background_info(m->content.get())); + } if (*need_update && m->message_id.is_server() && message_content_type == MessageContentType::ChatSetTheme) { set_dialog_theme_name(d, get_message_content_theme_name(m->content.get())); } @@ -36440,12 +36556,14 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di break; case DialogType::Chat: d->is_is_blocked_inited = true; + d->is_background_inited = true; break; case DialogType::Channel: { if (td_->contacts_manager_->is_broadcast_channel(dialog_id.get_channel_id())) { d->last_read_outbox_message_id = MessageId::max(); d->is_last_read_outbox_message_id_inited = true; } + d->is_background_inited = true; auto pts = load_channel_pts(dialog_id); if (pts > 0) { @@ -36472,6 +36590,7 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di d->is_last_read_inbox_message_id_inited = true; d->is_last_read_outbox_message_id_inited = true; d->is_last_pinned_message_id_inited = true; + d->is_background_inited = true; d->is_theme_name_inited = true; d->is_is_blocked_inited = true; if (!d->is_folder_id_inited && !td_->auth_manager_->is_bot()) { @@ -36622,6 +36741,9 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab } else if (being_added_dialog_id_ != dialog_id && !d->is_has_bots_inited && !td_->auth_manager_->is_bot()) { // asynchronously get has_bots from the server reload_dialog_info_full(dialog_id, "fix_new_dialog init has_bots"); + } else if (being_added_dialog_id_ != dialog_id && !d->is_background_inited && !td_->auth_manager_->is_bot()) { + // asynchronously get dialog background from the server + reload_dialog_info_full(dialog_id, "fix_new_dialog init background"); } else if (being_added_dialog_id_ != dialog_id && !d->is_theme_name_inited && !td_->auth_manager_->is_bot()) { // asynchronously get dialog theme identifier from the server reload_dialog_info_full(dialog_id, "fix_new_dialog init theme_name"); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 4ddcc1a6a..edb93855d 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -8,6 +8,7 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/AffectedHistory.h" +#include "td/telegram/BackgroundInfo.h" #include "td/telegram/ChannelId.h" #include "td/telegram/ChatReactions.h" #include "td/telegram/DialogAction.h" @@ -299,6 +300,8 @@ class MessagesManager final : public Actor { void on_update_dialog_last_pinned_message_id(DialogId dialog_id, MessageId last_pinned_message_id); + void on_update_dialog_background(DialogId dialog_id, telegram_api::object_ptr &&wallpaper); + void on_update_dialog_theme_name(DialogId dialog_id, string theme_name); void on_update_dialog_pending_join_requests(DialogId dialog_id, int32 pending_join_request_count, @@ -1331,6 +1334,7 @@ class MessagesManager final : public Actor { InputGroupCallId expected_active_group_call_id; DialogId default_join_group_call_as_dialog_id; DialogId default_send_message_as_dialog_id; + BackgroundInfo background_info; string theme_name; int32 pending_join_request_count = 0; vector pending_join_request_user_ids; @@ -1405,6 +1409,7 @@ class MessagesManager final : public Actor { bool has_expected_active_group_call_id = false; bool has_bots = false; bool is_has_bots_inited = false; + bool is_background_inited = false; bool is_theme_name_inited = false; bool is_available_reactions_inited = false; bool had_yet_unsent_message_id_overflow = false; @@ -2556,6 +2561,10 @@ class MessagesManager final : public Actor { void send_update_chat_available_reactions(const Dialog *d); + void send_update_secret_chats_with_user_background(const Dialog *d) const; + + void send_update_chat_background(const Dialog *d); + void send_update_secret_chats_with_user_theme(const Dialog *d) const; void send_update_chat_theme(const Dialog *d); @@ -2662,6 +2671,8 @@ class MessagesManager final : public Actor { void drop_dialog_last_pinned_message_id(Dialog *d); + void set_dialog_background(Dialog *d, BackgroundInfo &&background_info); + void set_dialog_theme_name(Dialog *d, string theme_name); void fix_pending_join_requests(DialogId dialog_id, int32 &pending_join_request_count, @@ -2778,6 +2789,8 @@ class MessagesManager final : public Actor { td_api::object_ptr get_chat_action_bar_object(const Dialog *d) const; + td_api::object_ptr get_dialog_background_object(const Dialog *d) const; + string get_dialog_theme_name(const Dialog *d) const; td_api::object_ptr get_chat_join_requests_info_object(const Dialog *d) const;