Add updateChatOnlineMemberCount.

GitOrigin-RevId: 3c4a21b924acc4c5ff9af66a4d8c9d13b6effd26
This commit is contained in:
levlam 2019-02-26 03:24:33 +03:00
parent 5d8f7569b6
commit 8795d002de
6 changed files with 208 additions and 120 deletions

View File

@ -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;

Binary file not shown.

View File

@ -6723,6 +6723,12 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&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));
}

View File

@ -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;

View File

@ -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<telegram_api::Message> &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<Unit>());
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<Unit>());
}
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<int64> &&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<td_api::updateDeleteMessages>(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<td_api::updateDeleteMessages>(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<td_api::updateChatReadInbox>(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<td_api::updateChatReadInbox>(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<td_api::updateChatReadOutbox>(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<td_api::updateChatReadOutbox>(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<td_api::updateChatUnreadMentionCount>(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<td_api::updateChatUnreadMentionCount>(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<td_api::updateChatIsSponsored>(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<td_api::updateChatIsSponsored>(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<td_api::updateChatOnlineMemberCount>(dialog_id.get(), online_member_count));
}
void MessagesManager::on_send_message_get_quick_ack(int64 random_id) {

View File

@ -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<td_api::ChatAction> &&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<td_api::message> get_message_object(DialogId dialog_id, const Message *message) const;
static tl_object_ptr<td_api::messages> get_messages_object(int32 total_count,
@ -2340,6 +2346,14 @@ class MessagesManager : public Actor {
std::unordered_map<FullMessageId, FileSourceId, FullMessageIdHash> 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<DialogId, OnlineMemberCountInfo, DialogIdHash> dialog_online_member_counts_;
DialogId sponsored_dialog_id_;
DialogId being_added_dialog_id_;