diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 9b4bf18f3..722c779a4 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2380,6 +2380,9 @@ updateChatReplyMarkup chat_id:int53 reply_markup_message_id:int53 = Update; //@description A chat draft has changed. Be aware that the update may come in the currently opened chat but with old content of the draft. If the user has changed the content of the draft, this update shouldn't be applied @chat_id Chat identifier @draft_message The new draft message; may be null @order New value of the chat order updateChatDraftMessage chat_id:int53 draft_message:draftMessage order:int64 = Update; +//@description The number of online group members has changed. This update is sent only for currently open chats. There is no guarantee that it will be sent just after the count has changed @chat_id Identifier of the chat @online_member_count New number of online members in the chat +updateChatOnlineMemberCount chat_id:int53 online_member_count:int32 = Update; + //@description A notification was changed @notification_group_id Unique notification group identifier @notification Changed notification updateNotification notification_group_id:int32 notification:notification = Update; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index fd2f6cde2..df7cba028 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 c21734412..f118c6e66 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -6723,6 +6723,12 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c } td_->messages_manager_->on_update_dialog_pinned_message_id(DialogId(channel_id), pinned_message_id); + int32 online_member_count = 0; + if ((channel_full->flags_ & CHANNEL_FULL_FLAG_HAS_ONLINE_MEMBER_COUNT) != 0) { + online_member_count = channel_full->online_count_; + } + td_->messages_manager_->on_update_channel_online_member_count(channel_id, online_member_count); + for (auto &bot_info : channel_full->bot_info_) { on_update_bot_info(std::move(bot_info)); } diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 7a1dd59aa..c1f1597da 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -764,6 +764,8 @@ class ContactsManager : public Actor { static constexpr int32 CHANNEL_FULL_FLAG_HAS_STICKER_SET = 1 << 8; static constexpr int32 CHANNEL_FULL_FLAG_HAS_AVAILABLE_MIN_MESSAGE_ID = 1 << 9; static constexpr int32 CHANNEL_FULL_FLAG_IS_ALL_HISTORY_HIDDEN = 1 << 10; + static constexpr int32 CHANNEL_FULL_FLAG_CAN_VIEW_STATISTICS = 1 << 12; + static constexpr int32 CHANNEL_FULL_FLAG_HAS_ONLINE_MEMBER_COUNT = 1 << 13; static constexpr int32 CHAT_INVITE_FLAG_IS_CHANNEL = 1 << 0; static constexpr int32 CHAT_INVITE_FLAG_IS_BROADCAST = 1 << 1; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index e40e201ba..7af01043f 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -5096,6 +5096,21 @@ void MessagesManager::on_update_channel_max_unavailable_message_id(ChannelId cha "on_update_channel_max_unavailable_message_id"); } +void MessagesManager::on_update_channel_online_member_count(ChannelId channel_id, int32 online_member_count) { + if (!channel_id.is_valid()) { + LOG(ERROR) << "Receive online member count in invalid " << channel_id; + return; + } + + DialogId dialog_id(channel_id); + if (is_broadcast_channel(dialog_id)) { + LOG_IF(ERROR, online_member_count != 0) << "Receive online member count in broadcast " << channel_id; + return; + } + + set_dialog_online_member_count(dialog_id, online_member_count, "on_update_channel_online_member_count"); +} + void MessagesManager::on_update_include_sponsored_dialog_to_unread_count() { if (td_->auth_manager_->is_bot()) { // just in case @@ -8448,6 +8463,28 @@ void MessagesManager::set_dialog_max_unavailable_message_id(DialogId dialog_id, } } +void MessagesManager::set_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, + const char *source) { + if (td_->auth_manager_->is_bot()) { + return; + } + + Dialog *d = get_dialog(dialog_id); + if (d == nullptr) { + return; + } + + auto &info = dialog_online_member_counts_[dialog_id]; + bool need_update = d->is_opened && (!info.is_update_sent || info.online_member_count != online_member_count); + info.online_member_count = online_member_count; + info.updated_time = Time::now(); + + if (need_update) { + info.is_update_sent = true; + send_update_chat_online_member_count(dialog_id, online_member_count); + } +} + MessageId MessagesManager::get_message_id(const tl_object_ptr &message_ptr) { int32 constructor_id = message_ptr->get_id(); switch (constructor_id) { @@ -18663,24 +18700,26 @@ void MessagesManager::remove_all_dialog_notifications(DialogId dialog_id, Notifi void MessagesManager::remove_all_dialog_notifications(Dialog *d, MessageId max_message_id, NotificationGroupInfo &group_info, const char *source) { // removes up to max_message_id - if (group_info.group_id.is_valid()) { - VLOG(notifications) << "Remove all dialog notifications in " << group_info.group_id << '/' << d->dialog_id - << " up to " << max_message_id << " from " << source; - - auto max_notification_message_id = max_message_id; - if (d->last_message_id.is_valid() && max_notification_message_id.get() >= d->last_message_id.get()) { - max_notification_message_id = d->last_message_id; - set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(), "remove_all_dialog_notifications 1"); - } else if (max_notification_message_id == MessageId::max()) { - max_notification_message_id = get_next_local_message_id(d); - set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(), "remove_all_dialog_notifications 2"); - } else { - LOG(FATAL) << "TODO support deleting up to " << max_message_id << " if ever will be needed"; - } - - send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification_group, - group_info.group_id, NotificationId(), max_notification_message_id, 0, Promise()); + if (!group_info.group_id.is_valid()) { + return; } + + VLOG(notifications) << "Remove all dialog notifications in " << group_info.group_id << '/' << d->dialog_id + << " up to " << max_message_id << " from " << source; + + auto max_notification_message_id = max_message_id; + if (d->last_message_id.is_valid() && max_notification_message_id.get() >= d->last_message_id.get()) { + max_notification_message_id = d->last_message_id; + set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(), "remove_all_dialog_notifications 1"); + } else if (max_notification_message_id == MessageId::max()) { + max_notification_message_id = get_next_local_message_id(d); + set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(), "remove_all_dialog_notifications 2"); + } else { + LOG(FATAL) << "TODO support deleting up to " << max_message_id << " if ever will be needed"; + } + + send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification_group, group_info.group_id, + NotificationId(), max_notification_message_id, 0, Promise()); } void MessagesManager::send_update_message_send_succeeded(Dialog *d, MessageId old_message_id, const Message *m) const { @@ -18713,12 +18752,14 @@ void MessagesManager::send_update_message_edited(DialogId dialog_id, const Messa void MessagesManager::send_update_delete_messages(DialogId dialog_id, vector &&message_ids, bool is_permanent, bool from_cache) const { - if (!message_ids.empty()) { - LOG_CHECK(have_dialog(dialog_id)) << "Wrong " << dialog_id << " in send_update_delete_messages"; - send_closure(G()->td(), &Td::send_update, - make_tl_object(dialog_id.get(), std::move(message_ids), is_permanent, - from_cache)); + if (message_ids.empty()) { + return; } + + LOG_CHECK(have_dialog(dialog_id)) << "Wrong " << dialog_id << " in send_update_delete_messages"; + send_closure( + G()->td(), &Td::send_update, + make_tl_object(dialog_id.get(), std::move(message_ids), is_permanent, from_cache)); } void MessagesManager::send_update_new_chat(Dialog *d) { @@ -18755,131 +18796,153 @@ void MessagesManager::send_update_chat_last_message_impl(const Dialog *d, const } void MessagesManager::send_update_unread_message_count(DialogId dialog_id, bool force, const char *source) { - if (!td_->auth_manager_->is_bot() && G()->parameters().use_message_db) { - CHECK(is_message_unread_count_inited_); - if (unread_message_muted_count_ < 0 || unread_message_muted_count_ > unread_message_total_count_) { - LOG(ERROR) << "Unread message count became invalid: " << unread_message_total_count_ << '/' - << unread_message_total_count_ - unread_message_muted_count_ << " from " << source << " and " - << dialog_id; - if (unread_message_muted_count_ < 0) { - unread_message_muted_count_ = 0; - } - if (unread_message_muted_count_ > unread_message_total_count_) { - unread_message_total_count_ = unread_message_muted_count_; - } + if (td_->auth_manager_->is_bot() || !G()->parameters().use_message_db) { + return; + } + + CHECK(is_message_unread_count_inited_); + if (unread_message_muted_count_ < 0 || unread_message_muted_count_ > unread_message_total_count_) { + LOG(ERROR) << "Unread message count became invalid: " << unread_message_total_count_ << '/' + << unread_message_total_count_ - unread_message_muted_count_ << " from " << source << " and " + << dialog_id; + if (unread_message_muted_count_ < 0) { + unread_message_muted_count_ = 0; } - G()->td_db()->get_binlog_pmc()->set("unread_message_count", - PSTRING() << unread_message_total_count_ << ' ' << unread_message_muted_count_); - int32 unread_unmuted_count = unread_message_total_count_ - unread_message_muted_count_; - if (!force && running_get_difference_) { - LOG(INFO) << "Postpone updateUnreadMessageCount to " << unread_message_total_count_ << '/' << unread_unmuted_count - << " from " << source << " and " << dialog_id; - have_postponed_unread_message_count_update_ = true; - } else { - have_postponed_unread_message_count_update_ = false; - LOG(INFO) << "Send updateUnreadMessageCount to " << unread_message_total_count_ << '/' << unread_unmuted_count - << " from " << source << " and " << dialog_id; - send_closure(G()->td(), &Td::send_update, get_update_unread_message_count_object()); + if (unread_message_muted_count_ > unread_message_total_count_) { + unread_message_total_count_ = unread_message_muted_count_; } } + G()->td_db()->get_binlog_pmc()->set("unread_message_count", + PSTRING() << unread_message_total_count_ << ' ' << unread_message_muted_count_); + int32 unread_unmuted_count = unread_message_total_count_ - unread_message_muted_count_; + if (!force && running_get_difference_) { + LOG(INFO) << "Postpone updateUnreadMessageCount to " << unread_message_total_count_ << '/' << unread_unmuted_count + << " from " << source << " and " << dialog_id; + have_postponed_unread_message_count_update_ = true; + } else { + have_postponed_unread_message_count_update_ = false; + LOG(INFO) << "Send updateUnreadMessageCount to " << unread_message_total_count_ << '/' << unread_unmuted_count + << " from " << source << " and " << dialog_id; + send_closure(G()->td(), &Td::send_update, get_update_unread_message_count_object()); + } } void MessagesManager::send_update_unread_chat_count(DialogId dialog_id, bool force, const char *source) { - if (!td_->auth_manager_->is_bot() && G()->parameters().use_message_db) { - CHECK(is_dialog_unread_count_inited_); - if (unread_dialog_muted_marked_count_ < 0 || unread_dialog_marked_count_ < unread_dialog_muted_marked_count_ || - unread_dialog_muted_count_ < unread_dialog_muted_marked_count_ || - unread_dialog_total_count_ + unread_dialog_muted_marked_count_ < - unread_dialog_muted_count_ + unread_dialog_marked_count_) { - LOG(ERROR) << "Unread chat count became invalid: " << unread_dialog_total_count_ << '/' - << unread_dialog_total_count_ - unread_dialog_muted_count_ << '/' << unread_dialog_marked_count_ << '/' - << unread_dialog_marked_count_ - unread_dialog_muted_marked_count_ << " from " << source << " and " - << dialog_id; - if (unread_dialog_muted_marked_count_ < 0) { - unread_dialog_muted_marked_count_ = 0; - } - if (unread_dialog_marked_count_ < unread_dialog_muted_marked_count_) { - unread_dialog_marked_count_ = unread_dialog_muted_marked_count_; - } - if (unread_dialog_muted_count_ < unread_dialog_muted_marked_count_) { - unread_dialog_muted_count_ = unread_dialog_muted_marked_count_; - } - if (unread_dialog_total_count_ + unread_dialog_muted_marked_count_ < + if (td_->auth_manager_->is_bot() || !G()->parameters().use_message_db) { + return; + } + + CHECK(is_dialog_unread_count_inited_); + if (unread_dialog_muted_marked_count_ < 0 || unread_dialog_marked_count_ < unread_dialog_muted_marked_count_ || + unread_dialog_muted_count_ < unread_dialog_muted_marked_count_ || + unread_dialog_total_count_ + unread_dialog_muted_marked_count_ < unread_dialog_muted_count_ + unread_dialog_marked_count_) { - unread_dialog_total_count_ = - unread_dialog_muted_count_ + unread_dialog_marked_count_ - unread_dialog_muted_marked_count_; - } + LOG(ERROR) << "Unread chat count became invalid: " << unread_dialog_total_count_ << '/' + << unread_dialog_total_count_ - unread_dialog_muted_count_ << '/' << unread_dialog_marked_count_ << '/' + << unread_dialog_marked_count_ - unread_dialog_muted_marked_count_ << " from " << source << " and " + << dialog_id; + if (unread_dialog_muted_marked_count_ < 0) { + unread_dialog_muted_marked_count_ = 0; } - G()->td_db()->get_binlog_pmc()->set( - "unread_dialog_count", PSTRING() << unread_dialog_total_count_ << ' ' << unread_dialog_muted_count_ << ' ' - << unread_dialog_marked_count_ << ' ' << unread_dialog_muted_marked_count_); - bool need_postpone = !force && running_get_difference_; - int32 unread_unmuted_count = unread_dialog_total_count_ - unread_dialog_muted_count_; - int32 unread_unmuted_marked_count = unread_dialog_marked_count_ - unread_dialog_muted_marked_count_; - LOG(INFO) << (need_postpone ? "Postpone" : "Send") << " updateUnreadChatCount to " << unread_dialog_total_count_ - << '/' << unread_unmuted_count << '/' << unread_dialog_marked_count_ << '/' << unread_unmuted_marked_count - << " from " << source << " and " << dialog_id; - if (need_postpone) { - have_postponed_unread_chat_count_update_ = true; - } else { - have_postponed_unread_chat_count_update_ = false; - send_closure(G()->td(), &Td::send_update, get_update_unread_chat_count_object()); + if (unread_dialog_marked_count_ < unread_dialog_muted_marked_count_) { + unread_dialog_marked_count_ = unread_dialog_muted_marked_count_; } + if (unread_dialog_muted_count_ < unread_dialog_muted_marked_count_) { + unread_dialog_muted_count_ = unread_dialog_muted_marked_count_; + } + if (unread_dialog_total_count_ + unread_dialog_muted_marked_count_ < + unread_dialog_muted_count_ + unread_dialog_marked_count_) { + unread_dialog_total_count_ = + unread_dialog_muted_count_ + unread_dialog_marked_count_ - unread_dialog_muted_marked_count_; + } + } + G()->td_db()->get_binlog_pmc()->set( + "unread_dialog_count", PSTRING() << unread_dialog_total_count_ << ' ' << unread_dialog_muted_count_ << ' ' + << unread_dialog_marked_count_ << ' ' << unread_dialog_muted_marked_count_); + bool need_postpone = !force && running_get_difference_; + int32 unread_unmuted_count = unread_dialog_total_count_ - unread_dialog_muted_count_; + int32 unread_unmuted_marked_count = unread_dialog_marked_count_ - unread_dialog_muted_marked_count_; + LOG(INFO) << (need_postpone ? "Postpone" : "Send") << " updateUnreadChatCount to " << unread_dialog_total_count_ + << '/' << unread_unmuted_count << '/' << unread_dialog_marked_count_ << '/' << unread_unmuted_marked_count + << " from " << source << " and " << dialog_id; + if (need_postpone) { + have_postponed_unread_chat_count_update_ = true; + } else { + have_postponed_unread_chat_count_update_ = false; + send_closure(G()->td(), &Td::send_update, get_update_unread_chat_count_object()); } } void MessagesManager::send_update_chat_read_inbox(const Dialog *d, bool force, const char *source) { + if (td_->auth_manager_->is_bot()) { + return; + } + CHECK(d != nullptr); - if (!td_->auth_manager_->is_bot()) { - LOG_CHECK(d->is_update_new_chat_sent) - << "Wrong " << d->dialog_id << " in send_update_chat_read_inbox from " << source; - on_dialog_updated(d->dialog_id, source); - if (!force && (running_get_difference_ || running_get_channel_difference(d->dialog_id) || - get_channel_difference_to_logevent_id_.count(d->dialog_id) != 0)) { - LOG(INFO) << "Postpone updateChatReadInbox in " << d->dialog_id << "(" << get_dialog_title(d->dialog_id) - << ") to " << d->server_unread_count << " + " << d->local_unread_count << " from " << source; - postponed_chat_read_inbox_updates_.insert(d->dialog_id); - } else { - postponed_chat_read_inbox_updates_.erase(d->dialog_id); - LOG(INFO) << "Send updateChatReadInbox in " << d->dialog_id << "(" << get_dialog_title(d->dialog_id) << ") to " - << d->server_unread_count << " + " << d->local_unread_count << " from " << source; - send_closure(G()->td(), &Td::send_update, - make_tl_object(d->dialog_id.get(), d->last_read_inbox_message_id.get(), - d->server_unread_count + d->local_unread_count)); - } + LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_read_inbox from " + << source; + on_dialog_updated(d->dialog_id, source); + if (!force && (running_get_difference_ || running_get_channel_difference(d->dialog_id) || + get_channel_difference_to_logevent_id_.count(d->dialog_id) != 0)) { + LOG(INFO) << "Postpone updateChatReadInbox in " << d->dialog_id << "(" << get_dialog_title(d->dialog_id) << ") to " + << d->server_unread_count << " + " << d->local_unread_count << " from " << source; + postponed_chat_read_inbox_updates_.insert(d->dialog_id); + } else { + postponed_chat_read_inbox_updates_.erase(d->dialog_id); + LOG(INFO) << "Send updateChatReadInbox in " << d->dialog_id << "(" << get_dialog_title(d->dialog_id) << ") to " + << d->server_unread_count << " + " << d->local_unread_count << " from " << source; + send_closure(G()->td(), &Td::send_update, + make_tl_object(d->dialog_id.get(), d->last_read_inbox_message_id.get(), + d->server_unread_count + d->local_unread_count)); } } void MessagesManager::send_update_chat_read_outbox(const Dialog *d) { - CHECK(d != nullptr); - if (!td_->auth_manager_->is_bot()) { - LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_read_outbox"; - on_dialog_updated(d->dialog_id, "send_update_chat_read_outbox"); - send_closure( - G()->td(), &Td::send_update, - make_tl_object(d->dialog_id.get(), d->last_read_outbox_message_id.get())); + 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_read_outbox"; + on_dialog_updated(d->dialog_id, "send_update_chat_read_outbox"); + send_closure(G()->td(), &Td::send_update, + make_tl_object(d->dialog_id.get(), d->last_read_outbox_message_id.get())); } void MessagesManager::send_update_chat_unread_mention_count(const Dialog *d) { - CHECK(d != nullptr); - if (!td_->auth_manager_->is_bot()) { - LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_unread_mention_count"; - LOG(INFO) << "Update unread mention message count in " << d->dialog_id << " to " << d->unread_mention_count; - on_dialog_updated(d->dialog_id, "send_update_chat_unread_mention_count"); - send_closure(G()->td(), &Td::send_update, - make_tl_object(d->dialog_id.get(), d->unread_mention_count)); + 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_unread_mention_count"; + LOG(INFO) << "Update unread mention message count in " << d->dialog_id << " to " << d->unread_mention_count; + on_dialog_updated(d->dialog_id, "send_update_chat_unread_mention_count"); + send_closure(G()->td(), &Td::send_update, + make_tl_object(d->dialog_id.get(), d->unread_mention_count)); } void MessagesManager::send_update_chat_is_sponsored(const Dialog *d) const { - if (!td_->auth_manager_->is_bot()) { - bool is_sponsored = d->order == SPONSORED_DIALOG_ORDER; - LOG(INFO) << "Update chat is sponsored for " << d->dialog_id; - auto order = DialogDate(d->order, d->dialog_id) <= last_dialog_date_ ? d->order : 0; - send_closure(G()->td(), &Td::send_update, - make_tl_object(d->dialog_id.get(), is_sponsored, order)); + 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_is_sponsored"; + bool is_sponsored = d->order == SPONSORED_DIALOG_ORDER; + LOG(INFO) << "Update chat is sponsored for " << d->dialog_id; + auto order = DialogDate(d->order, d->dialog_id) <= last_dialog_date_ ? d->order : 0; + send_closure(G()->td(), &Td::send_update, + make_tl_object(d->dialog_id.get(), is_sponsored, order)); +} + +void MessagesManager::send_update_chat_online_member_count(DialogId dialog_id, int32 online_member_count) const { + if (td_->auth_manager_->is_bot()) { + return; + } + + send_closure(G()->td(), &Td::send_update, + make_tl_object(dialog_id.get(), online_member_count)); } void MessagesManager::on_send_message_get_quick_ack(int64 random_id) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 5b153fb5e..512f06f7c 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -303,6 +303,8 @@ class MessagesManager : public Actor { void on_update_channel_max_unavailable_message_id(ChannelId channel_id, MessageId max_unavailable_message_id); + void on_update_channel_online_member_count(ChannelId channel_id, int32 online_member_count); + void on_update_include_sponsored_dialog_to_unread_count(); void on_user_dialog_action(DialogId dialog_id, UserId user_id, tl_object_ptr &&action, @@ -1454,6 +1456,8 @@ class MessagesManager : public Actor { void set_dialog_max_unavailable_message_id(DialogId dialog_id, MessageId max_unavailable_message_id, bool from_update, const char *source); + void set_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, const char *source); + void preload_newer_messages(const Dialog *d, MessageId max_message_id); void preload_older_messages(const Dialog *d, MessageId min_message_id); @@ -1635,6 +1639,8 @@ class MessagesManager : public Actor { void send_update_chat_is_sponsored(const Dialog *d) const; + void send_update_chat_online_member_count(DialogId dialog_id, int32 online_member_count) const; + tl_object_ptr get_message_object(DialogId dialog_id, const Message *message) const; static tl_object_ptr get_messages_object(int32 total_count, @@ -2340,6 +2346,14 @@ class MessagesManager : public Actor { std::unordered_map full_message_id_to_file_source_id_; + struct OnlineMemberCountInfo { + int32 online_member_count = 0; + double updated_time = 0; + bool is_update_sent = false; + }; + + std::unordered_map dialog_online_member_counts_; + DialogId sponsored_dialog_id_; DialogId being_added_dialog_id_;