diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 681be7a3c..d06eb5525 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -626,11 +626,12 @@ chatListArchive = ChatList; //@last_read_outbox_message_id Identifier of the last read outgoing message //@unread_mention_count Number of unread messages with a mention/reply in the chat //@notification_settings Notification settings for this chat +//@action_bar Describes actions which should be possible to do through a chat action bar //@pinned_message_id Identifier of the pinned message in the chat; 0 if none //@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 Contains client-specific data associated with the chat. (For example, the chat position or local chat notification settings can be stored here.) Persistent if a message database is used -chat id:int53 type:ChatType chat_list:ChatList title:string photo:chatPhoto permissions:chatPermissions last_message:message order:int64 is_pinned:Bool is_marked_as_unread:Bool is_sponsored: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 notification_settings:chatNotificationSettings pinned_message_id:int53 reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; +chat id:int53 type:ChatType chat_list:ChatList title:string photo:chatPhoto permissions:chatPermissions last_message:message order:int64 is_pinned:Bool is_marked_as_unread:Bool is_sponsored: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 notification_settings:chatNotificationSettings action_bar:ChatActionBar pinned_message_id:int53 reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; //@description Represents a list of chats @chat_ids List of chat identifiers chats chat_ids:vector = Chats; @@ -650,6 +651,24 @@ chatInviteLink invite_link:string = ChatInviteLink; chatInviteLinkInfo chat_id:int53 type:ChatType title:string photo:chatPhoto member_count:int32 member_user_ids:vector is_public:Bool = ChatInviteLinkInfo; +//@class ChatActionBar @description Describes actions which should be possible to do through a chat action bar + +//@description The chat can be reported as spam using the method reportChat with the reason chatReportReasonSpam +chatActionBarReportSpam = ChatActionBar; + +//@description The chat is a supergroup with a location, which can be reported as unrelated to the group using the method reportChat with the reason chatReportReasonUnrelatedLocation +chatActionBarReportUnrelatedLocation = ChatActionBar; + +//@description The chat is a private or a secret chat, which can be reported using the method reportChat, or the other user can be added to the contact list using the method addContact, or the other user can be blocked using the method blockUser +chatActionBarReportAddBlock = ChatActionBar; + +//@description The chat is a private or a secret chat and the other user can be added to the contact list using the method addContact +chatActionBarAddContact = ChatActionBar; + +//@description The chat is a private or a secret chat and the phone number can be shared with the other user using the method sharePhoneNumber +chatActionBarSharePhoneNumber = ChatActionBar; + + //@class KeyboardButtonType @description Describes a keyboard button type //@description A simple button, with text that should be sent when the button is pressed diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index c7de16c36..679791634 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index aeebb6a38..19269c214 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -8413,6 +8413,11 @@ bool ContactsManager::is_user_contact(const User *u, UserId user_id) const { return u != nullptr && u->is_contact && user_id != get_my_id(); } +bool ContactsManager::is_user_blocked(UserId user_id) { + const UserFull *user_full = get_user_full_force(user_id); + return user_full != nullptr && user_full->is_inited && user_full->is_blocked; +} + void ContactsManager::on_get_channel_participants_success( ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit, int64 random_id, int32 total_count, vector> &&participants) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 3e5bf9cde..b858c46b3 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -346,6 +346,8 @@ class ContactsManager : public Actor { bool is_user_contact(UserId user_id) const; + bool is_user_blocked(UserId user_id); + bool is_user_deleted(UserId user_id) const; bool is_user_bot(UserId user_id) const; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index d5af4106b..2c34e8c58 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -4117,6 +4117,11 @@ void MessagesManager::Dialog::store(StorerT &storer) const { STORE_FLAG(has_folder_id); STORE_FLAG(is_folder_id_inited); STORE_FLAG(has_pending_read_channel_inbox); + STORE_FLAG(know_action_bar); + STORE_FLAG(can_add_contact); + STORE_FLAG(can_block_user); + STORE_FLAG(can_share_phone_number); + STORE_FLAG(can_report_location); END_STORE_FLAGS(); } @@ -4270,7 +4275,19 @@ void MessagesManager::Dialog::parse(ParserT &parser) { PARSE_FLAG(has_folder_id); PARSE_FLAG(is_folder_id_inited); PARSE_FLAG(has_pending_read_channel_inbox); + PARSE_FLAG(know_action_bar); + PARSE_FLAG(can_add_contact); + PARSE_FLAG(can_block_user); + PARSE_FLAG(can_share_phone_number); + PARSE_FLAG(can_report_location); END_PARSE_FLAGS(); + } else { + is_folder_id_inited = false; + know_action_bar = false; + can_add_contact = false; + can_block_user = false; + can_share_phone_number = false; + can_report_location = false; } parse(last_new_message_id, parser); @@ -6612,14 +6629,116 @@ void MessagesManager::report_dialog(DialogId dialog_id, const tl_object_ptr &&peer_settings) { CHECK(peer_settings != nullptr); + if (dialog_id.get_type() == DialogType::User) { + // auto need_phone_number_privacy_exception = + // (peer_settings->flags_ & telegram_api::peerSettings::NEED_CONTACTS_EXCEPTION_MASK) != 0; + // TODO use need_phone_number_privacy_exception + } + Dialog *d = get_dialog_force(dialog_id); if (d == nullptr) { return; } + auto can_report_spam = (peer_settings->flags_ & telegram_api::peerSettings::REPORT_SPAM_MASK) != 0; + auto can_add_contact = (peer_settings->flags_ & telegram_api::peerSettings::ADD_CONTACT_MASK) != 0; + auto can_block_user = (peer_settings->flags_ & telegram_api::peerSettings::BLOCK_CONTACT_MASK) != 0; + auto can_share_phone_number = (peer_settings->flags_ & telegram_api::peerSettings::SHARE_CONTACT_MASK) != 0; + auto can_report_location = (peer_settings->flags_ & telegram_api::peerSettings::REPORT_GEO_MASK) != 0; + if (d->can_report_spam == can_report_spam && d->can_add_contact == can_add_contact && + d->can_block_user == can_block_user && d->can_share_phone_number == can_share_phone_number && + d->can_report_location == can_report_location) { + return; + } + d->know_can_report_spam = true; - d->can_report_spam = (peer_settings->flags_ & telegram_api::peerSettings::REPORT_SPAM_MASK) != 0; - on_dialog_updated(dialog_id, "can_report_spam"); + d->know_action_bar = true; + d->can_report_spam = can_report_spam; + d->can_add_contact = can_add_contact; + d->can_block_user = can_block_user; + d->can_share_phone_number = can_share_phone_number; + d->can_report_location = can_report_location; + + fix_dialog_action_bar(d); + + on_dialog_updated(dialog_id, "on_get_peer_settings"); +} + +void MessagesManager::fix_dialog_action_bar(Dialog *d) { + CHECK(d != nullptr); + if (!d->know_action_bar) { + return; + } + + if (d->can_report_location) { + if (d->dialog_id.get_type() != DialogType::Channel) { + LOG(ERROR) << "Receive can_report_location in " << d->dialog_id; + d->can_report_location = false; + } else if (d->can_report_spam || d->can_add_contact || d->can_block_user || d->can_share_phone_number) { + LOG(ERROR) << "Receive action bar " << d->can_report_spam << "/" << d->can_add_contact << "/" << d->can_block_user + << "/" << d->can_share_phone_number << "/" << d->can_report_location; + d->can_report_spam = false; + d->can_add_contact = false; + d->can_block_user = false; + d->can_share_phone_number = false; + } + } + if (d->dialog_id.get_type() == DialogType::User) { + auto user_id = d->dialog_id.get_user_id(); + bool is_me = user_id == td_->contacts_manager_->get_my_id(); + bool is_contact = td_->contacts_manager_->is_user_contact(user_id); + bool is_blocked = td_->contacts_manager_->is_user_blocked(user_id); + bool is_deleted = td_->contacts_manager_->is_user_deleted(user_id); + if (is_me || is_blocked) { + d->can_report_spam = false; + } + if (is_me || is_blocked || is_deleted) { + d->can_share_phone_number = false; + } + if (is_me || is_blocked || is_deleted || is_contact) { + d->can_block_user = false; + d->can_add_contact = false; + } + } + if (d->can_share_phone_number) { + CHECK(!d->can_report_location); + if (d->dialog_id.get_type() != DialogType::User) { + LOG(ERROR) << "Receive can_share_phone_number in " << d->dialog_id; + d->can_share_phone_number = false; + } else if (d->can_report_spam || d->can_add_contact || d->can_block_user) { + LOG(ERROR) << "Receive action bar " << d->can_report_spam << "/" << d->can_add_contact << "/" << d->can_block_user + << "/" << d->can_share_phone_number; + d->can_report_spam = false; + d->can_add_contact = false; + d->can_block_user = false; + } + } + if (d->can_block_user) { + CHECK(!d->can_report_location); + CHECK(!d->can_share_phone_number); + if (d->dialog_id.get_type() != DialogType::User) { + LOG(ERROR) << "Receive can_block_user in " << d->dialog_id; + d->can_block_user = false; + } else if (!d->can_report_spam || !d->can_add_contact) { + LOG(ERROR) << "Receive action bar " << d->can_report_spam << "/" << d->can_add_contact << "/" + << d->can_block_user; + d->can_report_spam = true; + d->can_add_contact = true; + } + } + if (d->can_add_contact) { + CHECK(!d->can_report_location); + CHECK(!d->can_share_phone_number); + if (d->dialog_id.get_type() != DialogType::User) { + LOG(ERROR) << "Receive can_add_contact in " << d->dialog_id; + d->can_add_contact = false; + } else if (d->can_report_spam != d->can_block_user) { + LOG(ERROR) << "Receive action bar " << d->can_report_spam << "/" << d->can_add_contact << "/" + << d->can_block_user; + d->can_report_spam = false; + d->can_block_user = false; + } + } } void MessagesManager::get_dialog_statistics_url(DialogId dialog_id, const string ¶meters, bool is_dark, @@ -14211,6 +14330,40 @@ td_api::object_ptr MessagesManager::get_chat_list_object(Folde return td_api::make_object(); } +td_api::object_ptr MessagesManager::get_chat_action_bar_object(const Dialog *d) { + if (!d->know_action_bar) { + if (d->know_can_report_spam && d->dialog_id.get_type() != DialogType::SecretChat && d->can_report_spam) { + return td_api::make_object(); + } + return nullptr; + } + + if (d->can_report_location) { + CHECK(d->dialog_id.get_type() == DialogType::Channel); + CHECK(!d->can_share_phone_number && !d->can_block_user && !d->can_add_contact && !d->can_report_spam); + return td_api::make_object(); + } + if (d->can_share_phone_number) { + CHECK(d->dialog_id.get_type() == DialogType::User); + CHECK(!d->can_block_user && !d->can_add_contact && !d->can_report_spam); + return td_api::make_object(); + } + if (d->can_block_user) { + CHECK(d->dialog_id.get_type() == DialogType::User); + CHECK(d->can_report_spam && d->can_add_contact); + return td_api::make_object(); + } + if (d->can_add_contact) { + CHECK(d->dialog_id.get_type() == DialogType::User); + CHECK(!d->can_report_spam); + return td_api::make_object(); + } + if (d->can_report_spam) { + return td_api::make_object(); + } + return nullptr; +} + td_api::object_ptr MessagesManager::get_chat_object(const Dialog *d) const { CHECK(d != nullptr); @@ -14264,8 +14417,9 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * can_delete_for_all_users, can_report_dialog(d->dialog_id), d->notification_settings.silent_send_message, 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, - get_chat_notification_settings_object(&d->notification_settings), d->pinned_message_id.get(), - d->reply_markup_message_id.get(), get_draft_message_object(d->draft_message), d->client_data); + get_chat_notification_settings_object(&d->notification_settings), get_chat_action_bar_object(d), + d->pinned_message_id.get(), d->reply_markup_message_id.get(), get_draft_message_object(d->draft_message), + d->client_data); } tl_object_ptr MessagesManager::get_chat_object(DialogId dialog_id) const { @@ -25526,13 +25680,8 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&d, d->need_restore_reply_markup = false; d->is_last_read_inbox_message_id_inited = true; d->is_last_read_outbox_message_id_inited = true; - d->know_can_report_spam = true; d->is_pinned_message_id_inited = true; d->is_folder_id_inited = true; - if (!is_loaded_from_database) { - d->can_report_spam = - td_->contacts_manager_->default_can_report_spam_in_secret_chat(dialog_id.get_secret_chat_id()); - } break; case DialogType::None: default: diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 760cb9f52..b926e6558 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1042,6 +1042,11 @@ class MessagesManager : public Actor { bool know_can_report_spam = false; bool can_report_spam = false; + bool know_action_bar = false; + bool can_add_contact = false; + bool can_block_user = false; + bool can_share_phone_number = false; + bool can_report_location = false; bool is_opened = false; @@ -1913,12 +1918,16 @@ class MessagesManager : public Actor { void add_dialog_last_database_message(Dialog *d, unique_ptr &&last_database_message); + void fix_dialog_action_bar(Dialog *d); + td_api::object_ptr get_chat_type_object(DialogId dialog_id) const; static td_api::object_ptr get_chat_list_object(const Dialog *d); static td_api::object_ptr get_chat_list_object(FolderId folder_id); + static td_api::object_ptr get_chat_action_bar_object(const Dialog *d); + td_api::object_ptr get_chat_object(const Dialog *d) const; bool have_dialog_info(DialogId dialog_id) const;