diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 5aa071d2a..d593d3bc2 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -611,6 +611,9 @@ chatJoinRequest user_id:int53 request_date:int32 bio:string = ChatJoinRequest; //@description Contains a list of chat join requests @total_count Approximate total count of requests found @requests List of the requests chatJoinRequests total_count:int32 requests:vector = ChatJoinRequests; +//@description Contains information about pending chat join requests @total_count Number of pending join requests, which wait administrator approval @user_ids List of identifiers, of users with newest pending requests +chatJoinRequestsInfo total_count:int32 user_ids:vector = ChatJoinRequestsInfo; + //@description Represents a basic group of 0-200 users (must be upgraded to a supergroup to accommodate more than 200 users) //@id Group identifier @@ -965,12 +968,12 @@ videoChat group_call_id:int32 has_participants:Bool default_participant_id:Messa //@message_ttl_setting Current message Time To Live setting (self-destruct timer) for the chat; 0 if not defined. TTL is counted from the time message or its content is viewed in secret chats and from the send date in other chats //@theme_name If non-empty, name of a theme, set for the chat //@action_bar Describes actions which must be possible to do through a chat action bar; may be null -//@video_chat Contains information about video chat of the chat -//@pending_join_request_count Number of pending join requests, waiting administrator's approval +//@video_chat Information about video chat of the chat +//@pending_join_requests Information about pending join requests; may be null //@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 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 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 notification_settings:chatNotificationSettings message_ttl_setting:int32 theme_name:string action_bar:ChatActionBar video_chat:videoChat pending_join_request_count:int53 reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; +//@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 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 notification_settings:chatNotificationSettings message_ttl_setting: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; //@description Represents a list of chats @total_count Approximate total count of chats found @chat_ids List of chat identifiers chats total_count:int32 chat_ids:vector = Chats; @@ -3719,8 +3722,8 @@ updateChatActionBar chat_id:int53 action_bar:ChatActionBar = 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; -//@description The number of chat pending join requests was changed @chat_id Chat identifier @pending_join_request_count The new number of pending join requests -updateChatPendingJoinRequestCount chat_id:int53 pending_join_request_count:int32 = Update; +//@description The chat pending join requests were changed @chat_id Chat identifier @pending_join_requests The new data about pending join requests; may be null +updateChatPendingJoinRequests chat_id:int53 pending_join_requests:chatJoinRequestsInfo = Update; //@description The default chat reply markup was changed. Can occur because new messages with reply markup were received or because an old reply markup was hidden by the user //@chat_id Chat identifier @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 diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 01cdad0cb..eb4f6f766 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -9976,7 +9976,7 @@ void ContactsManager::update_chat(Chat *c, ChatId chat_id, bool from_binlog, boo } if (c->is_status_changed) { if (!c->status.can_manage_invite_links()) { - td_->messages_manager_->drop_dialog_pending_join_request_count(DialogId(chat_id)); + td_->messages_manager_->drop_dialog_pending_join_requests(DialogId(chat_id)); } c->is_status_changed = false; } @@ -10042,7 +10042,7 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from remove_inactive_channel(channel_id); } if (!c->status.can_manage_invite_links()) { - td_->messages_manager_->drop_dialog_pending_join_request_count(DialogId(channel_id)); + td_->messages_manager_->drop_dialog_pending_join_requests(DialogId(channel_id)); } c->is_status_changed = false; } @@ -10652,7 +10652,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c td_->messages_manager_->on_update_dialog_theme_name(DialogId(chat_id), std::move(chat->theme_emoticon_)); - td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(chat_id), chat->requests_pending_); + td_->messages_manager_->on_update_dialog_pending_join_requests(DialogId(chat_id), chat->requests_pending_, + std::move(chat->recent_requesters_)); auto bot_commands = get_bot_commands(std::move(chat->bot_info_), &chat_full->participants); if (chat_full->bot_commands != bot_commands) { @@ -10697,8 +10698,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c td_->messages_manager_->on_update_dialog_theme_name(DialogId(channel_id), std::move(channel->theme_emoticon_)); - td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(channel_id), - channel->requests_pending_); + td_->messages_manager_->on_update_dialog_pending_join_requests(DialogId(channel_id), channel->requests_pending_, + std::move(channel->recent_requesters_)); { MessageTtlSetting message_ttl_setting; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index e74d1c282..5f9200c59 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -5359,7 +5359,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const { bool store_has_bots = dialog_type == DialogType::Chat || dialog_type == DialogType::Channel; bool has_theme_name = !theme_name.empty(); bool has_flags3 = true; - bool has_pending_join_request_count = pending_join_request_count != 0; + bool has_pending_join_requests = pending_join_request_count != 0; BEGIN_STORE_FLAGS(); STORE_FLAG(has_draft_message); STORE_FLAG(has_last_database_message); @@ -5431,7 +5431,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const { } if (has_flags3) { BEGIN_STORE_FLAGS(); - STORE_FLAG(has_pending_join_request_count); + STORE_FLAG(has_pending_join_requests); END_STORE_FLAGS(); } @@ -5528,8 +5528,9 @@ void MessagesManager::Dialog::store(StorerT &storer) const { if (has_theme_name) { store(theme_name, storer); } - if (has_pending_join_request_count) { + if (has_pending_join_requests) { store(pending_join_request_count, storer); + store(pending_join_request_user_ids, storer); } } @@ -5565,7 +5566,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { bool has_default_join_group_call_as_dialog_id = false; bool has_theme_name = false; bool has_flags3 = false; - bool has_pending_join_request_count = false; + bool has_pending_join_requests = false; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_draft_message); PARSE_FLAG(has_last_database_message); @@ -5659,7 +5660,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { } if (has_flags3) { BEGIN_PARSE_FLAGS(); - PARSE_FLAG(has_pending_join_request_count); + PARSE_FLAG(has_pending_join_requests); END_PARSE_FLAGS(); } @@ -5789,8 +5790,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_theme_name) { parse(theme_name, parser); } - if (has_pending_join_request_count) { + if (has_pending_join_requests) { parse(pending_join_request_count, parser); + parse(pending_join_request_user_ids, parser); } } @@ -20300,6 +20302,16 @@ string MessagesManager::get_dialog_theme_name(const Dialog *d) const { return d->theme_name; } +td_api::object_ptr MessagesManager::get_chat_join_requests_info_object( + const Dialog *d) const { + if (d->pending_join_request_count == 0) { + return nullptr; + } + return td_api::make_object( + d->pending_join_request_count, td_->contacts_manager_->get_user_ids_object(d->pending_join_request_user_ids, + "get_chat_join_requests_info_object")); +} + td_api::object_ptr MessagesManager::get_video_chat_object(const Dialog *d) const { auto active_group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, d->dialog_id); auto default_participant_alias = @@ -20381,7 +20393,7 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * 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->message_ttl_setting.get_message_ttl_setting_object(), get_dialog_theme_name(d), get_chat_action_bar_object(d), - get_video_chat_object(d), d->pending_join_request_count, d->reply_markup_message_id.get(), + 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); } @@ -29147,18 +29159,17 @@ void MessagesManager::send_update_chat_theme(const Dialog *d) { send_update_secret_chats_with_user_theme(d); } -void MessagesManager::send_update_chat_pending_join_request_count(const Dialog *d) { +void MessagesManager::send_update_chat_pending_join_requests(const Dialog *d) { if (td_->auth_manager_->is_bot()) { return; } CHECK(d != nullptr); - LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id - << " in send_update_chat_pending_join_request_count"; - on_dialog_updated(d->dialog_id, "send_update_chat_pending_join_request_count"); + LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_pending_join_requests"; + on_dialog_updated(d->dialog_id, "send_update_chat_pending_join_requests"); send_closure(G()->td(), &Td::send_update, - td_api::make_object(d->dialog_id.get(), - d->pending_join_request_count)); + td_api::make_object(d->dialog_id.get(), + get_chat_join_requests_info_object(d))); } void MessagesManager::send_update_chat_video_chat(const Dialog *d) { @@ -30184,16 +30195,16 @@ void MessagesManager::set_dialog_theme_name(Dialog *d, string theme_name) { } } -void MessagesManager::drop_dialog_pending_join_request_count(DialogId dialog_id) { +void MessagesManager::drop_dialog_pending_join_requests(DialogId dialog_id) { CHECK(dialog_id.is_valid()); auto d = get_dialog(dialog_id); // called from update_chat/channel, must not create the dialog if (d != nullptr && d->is_update_new_chat_sent) { - set_dialog_pending_join_request_count(d, 0); + set_dialog_pending_join_requests(d, 0, {}); } } -void MessagesManager::on_update_dialog_pending_join_request_count(DialogId dialog_id, - int32 pending_join_request_count) { +void MessagesManager::on_update_dialog_pending_join_requests(DialogId dialog_id, int32 pending_join_request_count, + vector pending_requesters) { if (!dialog_id.is_valid()) { LOG(ERROR) << "Receive pending join request count in invalid " << dialog_id; return; @@ -30205,46 +30216,64 @@ void MessagesManager::on_update_dialog_pending_join_request_count(DialogId dialo return; } - set_dialog_pending_join_request_count(d, pending_join_request_count); + auto pending_join_request_user_ids = UserId::get_user_ids(pending_requesters); + td::remove_if(pending_join_request_user_ids, [](UserId user_id) { return !user_id.is_valid(); }); + set_dialog_pending_join_requests(d, pending_join_request_count, std::move(pending_join_request_user_ids)); } -void MessagesManager::fix_pending_join_request_count(DialogId dialog_id, int32 &pending_join_request_count) const { - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::SecretChat: - pending_join_request_count = 0; - return; - case DialogType::Chat: { - auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_status(chat_id); - if (!status.can_manage_invite_links()) { - pending_join_request_count = 0; - } - return; +void MessagesManager::fix_pending_join_requests(DialogId dialog_id, int32 &pending_join_request_count, + vector &pending_join_request_user_ids) const { + bool need_drop_pending_join_requests = [&] { + if (pending_join_request_count < 0) { + return true; } - case DialogType::Channel: { - auto channel_id = dialog_id.get_channel_id(); - auto status = td_->contacts_manager_->get_channel_permissions(channel_id); - if (!status.can_manage_invite_links()) { - pending_join_request_count = 0; + switch (dialog_id.get_type()) { + case DialogType::User: + case DialogType::SecretChat: + return true; + case DialogType::Chat: { + auto chat_id = dialog_id.get_chat_id(); + auto status = td_->contacts_manager_->get_chat_status(chat_id); + if (!status.can_manage_invite_links()) { + return true; + } + break; } - return; + case DialogType::Channel: { + auto channel_id = dialog_id.get_channel_id(); + auto status = td_->contacts_manager_->get_channel_permissions(channel_id); + if (!status.can_manage_invite_links()) { + return true; + } + break; + } + case DialogType::None: + default: + UNREACHABLE(); } - case DialogType::None: - default: - UNREACHABLE(); + return false; + }(); + if (need_drop_pending_join_requests) { + pending_join_request_count = 0; + pending_join_request_user_ids.clear(); + } else if (static_cast(pending_join_request_count) < pending_join_request_user_ids.size()) { + LOG(ERROR) << "Fix pending join request count from " << pending_join_request_count << " to " + << pending_join_request_user_ids.size(); + pending_join_request_count = narrow_cast(pending_join_request_user_ids.size()); } } -void MessagesManager::set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count) { +void MessagesManager::set_dialog_pending_join_requests(Dialog *d, int32 pending_join_request_count, + vector pending_join_request_user_ids) { CHECK(d != nullptr); - fix_pending_join_request_count(d->dialog_id, pending_join_request_count); - bool is_changed = d->pending_join_request_count != pending_join_request_count; - if (!is_changed) { + fix_pending_join_requests(d->dialog_id, pending_join_request_count, pending_join_request_user_ids); + if (d->pending_join_request_count == pending_join_request_count && + d->pending_join_request_user_ids == pending_join_request_user_ids) { return; } d->pending_join_request_count = pending_join_request_count; - send_update_chat_pending_join_request_count(d); + d->pending_join_request_user_ids = std::move(pending_join_request_user_ids); + send_update_chat_pending_join_requests(d); } void MessagesManager::repair_dialog_scheduled_messages(Dialog *d) { @@ -34789,7 +34818,7 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&d, on_dialog_updated(dialog_id, "pending update_dialog_group_call"); } } - fix_pending_join_request_count(dialog_id, d->pending_join_request_count); + fix_pending_join_requests(dialog_id, d->pending_join_request_count, d->pending_join_request_user_ids); if (!is_loaded_from_database) { CHECK(order == DEFAULT_ORDER); @@ -35852,6 +35881,9 @@ unique_ptr MessagesManager::parse_dialog(DialogId dialo if (d->draft_message != nullptr) { add_formatted_text_dependencies(dependencies, &d->draft_message->input_message_text.text); } + for (auto user_id : d->pending_join_request_user_ids) { + dependencies.user_ids.insert(user_id); + } if (!resolve_dependencies_force(td_, dependencies, source)) { send_get_dialog_query(dialog_id, Auto(), 0, source); } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index d00f50b42..199f1fd8d 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -293,7 +293,8 @@ class MessagesManager final : public Actor { void on_update_dialog_theme_name(DialogId dialog_id, string theme_name); - void on_update_dialog_pending_join_request_count(DialogId dialog_id, int32 pending_join_request_count); + void on_update_dialog_pending_join_requests(DialogId dialog_id, int32 pending_join_request_count, + vector pending_requesters); void on_update_dialog_has_scheduled_server_messages(DialogId dialog_id, bool has_scheduled_server_messages); @@ -791,7 +792,7 @@ class MessagesManager final : public Actor { void on_dialog_linked_channel_updated(DialogId dialog_id, ChannelId old_linked_channel_id, ChannelId new_linked_channel_id) const; - void drop_dialog_pending_join_request_count(DialogId dialog_id); + void drop_dialog_pending_join_requests(DialogId dialog_id); void on_resolved_username(const string &username, DialogId dialog_id); void drop_username(const string &username); @@ -1195,6 +1196,7 @@ class MessagesManager final : public Actor { DialogId default_join_group_call_as_dialog_id; string theme_name; int32 pending_join_request_count = 0; + vector pending_join_request_user_ids; FolderId folder_id; vector dialog_list_ids; // TODO replace with mask @@ -2360,7 +2362,7 @@ class MessagesManager final : public Actor { void send_update_chat_theme(const Dialog *d); - void send_update_chat_pending_join_request_count(const Dialog *d); + void send_update_chat_pending_join_requests(const Dialog *d); void send_update_chat_video_chat(const Dialog *d); @@ -2461,9 +2463,11 @@ class MessagesManager final : public Actor { void set_dialog_theme_name(Dialog *d, string theme_name); - void fix_pending_join_request_count(DialogId dialog_id, int32 &pending_join_request_count) const; + void fix_pending_join_requests(DialogId dialog_id, int32 &pending_join_request_count, + vector &pending_join_request_user_ids) const; - void set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count); + void set_dialog_pending_join_requests(Dialog *d, int32 pending_join_request_count, + vector pending_join_request_user_ids); void repair_dialog_scheduled_messages(Dialog *d); @@ -2557,6 +2561,8 @@ class MessagesManager final : public Actor { string get_dialog_theme_name(const Dialog *d) const; + td_api::object_ptr get_chat_join_requests_info_object(const Dialog *d) const; + td_api::object_ptr get_video_chat_object(const Dialog *d) const; td_api::object_ptr get_chat_object(const Dialog *d) const; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index be9a2c172..31dbf68f0 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -3213,8 +3213,8 @@ void UpdatesManager::on_update(tl_object_ptr update, } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(update->peer_), - update->requests_pending_); + td_->messages_manager_->on_update_dialog_pending_join_requests(DialogId(update->peer_), update->requests_pending_, + std::move(update->recent_requesters_)); promise.set_value(Unit()); }