From 35a319db208783a923103599cd375fbf8441dba2 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 5 Sep 2023 17:41:33 +0300 Subject: [PATCH] Poll channel max active story identifiers. --- td/telegram/ContactsManager.cpp | 147 ++++++++++++++++++++------------ td/telegram/ContactsManager.h | 6 +- td/telegram/MessagesManager.cpp | 6 +- td/telegram/StoryManager.cpp | 3 +- 4 files changed, 102 insertions(+), 60 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 57ab922c3..0a46582c1 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -3794,11 +3794,11 @@ class GetSupportUserQuery final : public Td::ResultHandler { }; class GetStoriesMaxIdsQuery final : public Td::ResultHandler { - vector user_ids_; + vector dialog_ids_; public: - void send(vector user_ids, vector> &&input_peers) { - user_ids_ = std::move(user_ids); + void send(vector dialog_ids, vector> &&input_peers) { + dialog_ids_ = std::move(dialog_ids); send_query(G()->net_query_creator().create(telegram_api::stories_getPeerMaxIDs(std::move(input_peers)))); } @@ -3808,11 +3808,11 @@ class GetStoriesMaxIdsQuery final : public Td::ResultHandler { return on_error(result_ptr.move_as_error()); } - td_->contacts_manager_->on_get_user_max_active_story_ids(user_ids_, result_ptr.move_as_ok()); + td_->contacts_manager_->on_get_dialog_max_active_story_ids(dialog_ids_, result_ptr.move_as_ok()); } void on_error(Status status) final { - td_->contacts_manager_->on_get_user_max_active_story_ids(user_ids_, Auto()); + td_->contacts_manager_->on_get_dialog_max_active_story_ids(dialog_ids_, Auto()); } }; @@ -14840,13 +14840,11 @@ void ContactsManager::on_get_channel_participants( } } - vector participant_user_ids; + vector participant_dialog_ids; for (const auto &participant : result) { - if (participant.dialog_id_.get_type() == DialogType::User) { - participant_user_ids.push_back(participant.dialog_id_.get_user_id()); - } + participant_dialog_ids.push_back(participant.dialog_id_); } - on_view_user_active_stories(std::move(participant_user_ids)); + on_view_dialog_active_stories(std::move(participant_dialog_ids)); promise.set_value(DialogParticipants{total_count, std::move(result)}); } @@ -15616,64 +15614,110 @@ bool ContactsManager::need_poll_user_active_stories(const User *u, UserId user_i !is_user_support(u) && !is_user_deleted(u) && u->was_online != 0; } -void ContactsManager::on_view_user_active_stories(vector user_ids) { - if (user_ids.empty() || td_->auth_manager_->is_bot()) { +void ContactsManager::on_view_dialog_active_stories(vector dialog_ids) { + if (dialog_ids.empty() || td_->auth_manager_->is_bot()) { return; } - LOG(DEBUG) << "View active stories of " << user_ids; + LOG(DEBUG) << "View active stories of " << dialog_ids; const size_t MAX_SLICE_SIZE = 100; // server side limit - vector input_user_ids; + vector input_dialog_ids; vector> input_peers; - for (auto &user_id : user_ids) { - if (td::contains(input_user_ids, user_id)) { + for (auto &dialog_id : dialog_ids) { + if (td::contains(input_dialog_ids, dialog_id)) { continue; } - User *u = get_user(user_id); - if (!need_poll_user_active_stories(u, user_id) || Time::now() < u->max_active_story_id_next_reload_time || - u->is_max_active_story_id_being_reloaded) { - continue; - } - auto input_peer = td_->messages_manager_->get_input_peer(DialogId(user_id), AccessRights::Read); + auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { continue; } - u->is_max_active_story_id_being_reloaded = true; - input_user_ids.push_back(user_id); + + bool need_poll = false; + switch (dialog_id.get_type()) { + case DialogType::User: { + auto user_id = dialog_id.get_user_id(); + User *u = get_user(user_id); + if (need_poll_user_active_stories(u, user_id) && Time::now() >= u->max_active_story_id_next_reload_time && + !u->is_max_active_story_id_being_reloaded) { + u->is_max_active_story_id_being_reloaded = true; + need_poll = true; + } + break; + } + case DialogType::Channel: { + auto channel_id = dialog_id.get_channel_id(); + Channel *c = get_channel(channel_id); + if (need_poll_channel_active_stories(c, channel_id) && Time::now() >= c->max_active_story_id_next_reload_time && + !c->is_max_active_story_id_being_reloaded) { + c->is_max_active_story_id_being_reloaded = true; + need_poll = true; + } + break; + } + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + break; + } + if (!need_poll) { + continue; + } + input_dialog_ids.push_back(dialog_id); input_peers.push_back(std::move(input_peer)); if (input_peers.size() == MAX_SLICE_SIZE) { - td_->create_handler()->send(std::move(input_user_ids), std::move(input_peers)); - input_user_ids.clear(); + td_->create_handler()->send(std::move(input_dialog_ids), std::move(input_peers)); + input_dialog_ids.clear(); input_peers.clear(); } } if (!input_peers.empty()) { - td_->create_handler()->send(std::move(input_user_ids), std::move(input_peers)); + td_->create_handler()->send(std::move(input_dialog_ids), std::move(input_peers)); } } -void ContactsManager::on_get_user_max_active_story_ids(const vector &user_ids, - const vector &max_story_ids) { - for (auto &user_id : user_ids) { - User *u = get_user(user_id); - CHECK(u != nullptr); - CHECK(u->is_max_active_story_id_being_reloaded); - u->is_max_active_story_id_being_reloaded = false; +void ContactsManager::on_get_dialog_max_active_story_ids(const vector &dialog_ids, + const vector &max_story_ids) { + for (auto &dialog_id : dialog_ids) { + switch (dialog_id.get_type()) { + case DialogType::User: { + User *u = get_user(dialog_id.get_user_id()); + CHECK(u != nullptr); + CHECK(u->is_max_active_story_id_being_reloaded); + u->is_max_active_story_id_being_reloaded = false; + break; + } + case DialogType::Channel: { + Channel *c = get_channel(dialog_id.get_channel_id()); + CHECK(c != nullptr); + CHECK(c->is_max_active_story_id_being_reloaded); + c->is_max_active_story_id_being_reloaded = false; + break; + } + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + UNREACHABLE(); + } } - if (user_ids.size() != max_story_ids.size()) { + if (dialog_ids.size() != max_story_ids.size()) { if (!max_story_ids.empty()) { - LOG(ERROR) << "Receive " << max_story_ids.size() << " max active story identifiers for users " << user_ids; + LOG(ERROR) << "Receive " << max_story_ids.size() << " max active story identifiers for " << dialog_ids; } return; } - for (size_t i = 0; i < user_ids.size(); i++) { + for (size_t i = 0; i < dialog_ids.size(); i++) { auto max_story_id = StoryId(max_story_ids[i]); - if (max_story_id == StoryId()) { - on_update_user_story_ids(user_ids[i], StoryId(), StoryId()); - } else if (max_story_id.is_server()) { - on_update_user_story_ids(user_ids[i], max_story_id, StoryId()); + auto dialog_id = dialog_ids[i]; + if (max_story_id == StoryId() || max_story_id.is_server()) { + if (dialog_id.get_type() == DialogType::User) { + on_update_user_story_ids(dialog_id.get_user_id(), max_story_id, StoryId()); + } else { + on_update_channel_story_ids(dialog_id.get_channel_id(), max_story_id, StoryId()); + } } else { - LOG(ERROR) << "Receive " << max_story_id << " as maximum active story for " << user_ids[i]; + LOG(ERROR) << "Receive " << max_story_id << " as maximum active story for " << dialog_id; } } } @@ -17078,7 +17122,7 @@ void ContactsManager::load_user_full(UserId user_id, bool force, Promise & send_get_user_full_query(user_id, std::move(input_user), Auto(), "load expired user_full"); } - on_view_user_active_stories({user_id}); + on_view_dialog_active_stories({DialogId(user_id)}); promise.set_value(Unit()); } @@ -17470,13 +17514,11 @@ void ContactsManager::load_chat_full(ChatId chat_id, bool force, Promise & send_get_chat_full_query(chat_id, Auto(), source); } - vector participant_user_ids; + vector participant_dialog_ids; for (const auto &dialog_participant : chat_full->participants) { - if (dialog_participant.dialog_id_.get_type() == DialogType::User) { - participant_user_ids.push_back(dialog_participant.dialog_id_.get_user_id()); - } + participant_dialog_ids.push_back(dialog_participant.dialog_id_); } - on_view_user_active_stories(std::move(participant_user_ids)); + on_view_dialog_active_stories(std::move(participant_dialog_ids)); promise.set_value(Unit()); } @@ -18393,21 +18435,16 @@ void ContactsManager::do_search_chat_participants(ChatId chat_id, const string & return promise.set_error(Status::Error(500, "Can't find basic group full info")); } - vector participant_user_ids; vector dialog_ids; for (const auto &participant : chat_full->participants) { if (filter.is_dialog_participant_suitable(td_, participant)) { dialog_ids.push_back(participant.dialog_id_); - if (participant.dialog_id_.get_type() == DialogType::User) { - participant_user_ids.push_back(participant.dialog_id_.get_user_id()); - } } } - on_view_user_active_stories(std::move(participant_user_ids)); - int32 total_count; std::tie(total_count, dialog_ids) = search_among_dialogs(dialog_ids, query, limit); + on_view_dialog_active_stories(dialog_ids); promise.set_value(DialogParticipants{total_count, transform(dialog_ids, [chat_full](DialogId dialog_id) { return *ContactsManager::get_chat_full_participant(chat_full, dialog_id); })}); @@ -19526,7 +19563,7 @@ int64 ContactsManager::get_supergroup_id_object(ChannelId channel_id, const char } bool ContactsManager::need_poll_channel_active_stories(const Channel *c, ChannelId channel_id) const { - return c != nullptr && !get_channel_status(c).is_member() && + return c != nullptr && !c->is_megagroup && !get_channel_status(c).is_member() && have_input_peer_channel(c, channel_id, AccessRights::Read); } diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index ee9adc752..2739e5d25 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -716,9 +716,9 @@ class ContactsManager final : public Actor { void get_support_user(Promise> &&promise); - void on_view_user_active_stories(vector user_ids); + void on_view_dialog_active_stories(vector dialog_ids); - void on_get_user_max_active_story_ids(const vector &user_ids, const vector &max_story_ids); + void on_get_dialog_max_active_story_ids(const vector &dialog_ids, const vector &max_story_ids); void repair_chat_participants(ChatId chat_id); @@ -1002,6 +1002,8 @@ class ContactsManager final : public Actor { bool is_scam = false; bool is_fake = false; + bool is_max_active_story_id_being_reloaded = false; + bool is_title_changed = true; bool is_username_changed = true; bool is_photo_changed = true; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index ab8fd4359..ae342dced 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -19959,7 +19959,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess can_send_message(dialog_id).is_ok(); if (source == MessageSource::DialogList && dialog_type == DialogType::User) { - td_->contacts_manager_->on_view_user_active_stories({dialog_id.get_user_id()}); + td_->contacts_manager_->on_view_dialog_active_stories({dialog_id}); } // keep only valid message identifiers @@ -20507,7 +20507,7 @@ void MessagesManager::open_dialog(Dialog *d) { switch (dialog_id.get_type()) { case DialogType::User: - td_->contacts_manager_->on_view_user_active_stories({dialog_id.get_user_id()}); + td_->contacts_manager_->on_view_dialog_active_stories({dialog_id}); break; case DialogType::Chat: td_->contacts_manager_->repair_chat_participants(dialog_id.get_chat_id()); @@ -20523,6 +20523,8 @@ void MessagesManager::open_dialog(Dialog *d) { td_->contacts_manager_->get_channel_participants( channel_id, td_api::make_object(), string(), 0, 200, 200, Auto()); } + } else { + td_->contacts_manager_->on_view_dialog_active_stories({dialog_id}); } get_channel_difference(dialog_id, d->pts, 0, MessageId(), true, "open_dialog"); reget_dialog_action_bar(dialog_id, "open_dialog", false); diff --git a/td/telegram/StoryManager.cpp b/td/telegram/StoryManager.cpp index cef7bfb94..2ea8c43bf 100644 --- a/td/telegram/StoryManager.cpp +++ b/td/telegram/StoryManager.cpp @@ -2713,7 +2713,8 @@ void StoryManager::on_get_story_viewers( } } - td_->contacts_manager_->on_view_user_active_stories(story_viewers.get_user_ids()); + td_->contacts_manager_->on_view_dialog_active_stories( + transform(story_viewers.get_user_ids(), [](UserId user_id) { return DialogId(user_id); })); promise.set_value(story_viewers.get_story_viewers_object(td_->contacts_manager_.get())); }