Move on_view_dialog_active_stories to StoryManager.

This commit is contained in:
levlam 2024-03-06 14:46:52 +03:00
parent 0e8f076bab
commit 1c06f69a03
6 changed files with 132 additions and 149 deletions

View File

@ -2795,29 +2795,6 @@ class GetIsPremiumRequiredToContactQuery final : public Td::ResultHandler {
} }
}; };
class GetStoriesMaxIdsQuery final : public Td::ResultHandler {
vector<DialogId> dialog_ids_;
public:
void send(vector<DialogId> dialog_ids, vector<telegram_api::object_ptr<telegram_api::InputPeer>> &&input_peers) {
dialog_ids_ = std::move(dialog_ids);
send_query(G()->net_query_creator().create(telegram_api::stories_getPeerMaxIDs(std::move(input_peers))));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::stories_getPeerMaxIDs>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
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_dialog_max_active_story_ids(dialog_ids_, Auto());
}
};
class ContactsManager::UploadProfilePhotoCallback final : public FileManager::UploadCallback { class ContactsManager::UploadProfilePhotoCallback final : public FileManager::UploadCallback {
public: public:
void on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) final { void on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) final {
@ -5076,6 +5053,16 @@ bool ContactsManager::get_channel_stories_hidden(ChannelId channel_id) const {
return c->stories_hidden; return c->stories_hidden;
} }
bool ContactsManager::can_poll_user_active_stories(UserId user_id) const {
const User *u = get_user(user_id);
return need_poll_user_active_stories(u, user_id) && Time::now() >= u->max_active_story_id_next_reload_time;
}
bool ContactsManager::can_poll_channel_active_stories(ChannelId channel_id) const {
const Channel *c = get_channel(channel_id);
return need_poll_channel_active_stories(c, channel_id) && Time::now() >= c->max_active_story_id_next_reload_time;
}
string ContactsManager::get_user_private_forward_name(UserId user_id) { string ContactsManager::get_user_private_forward_name(UserId user_id) {
auto user_full = get_user_full_force(user_id, "get_user_private_forward_name"); auto user_full = get_user_full_force(user_id, "get_user_private_forward_name");
if (user_full != nullptr) { if (user_full != nullptr) {
@ -13760,114 +13747,6 @@ 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; !is_user_support(u) && !is_user_deleted(u) && u->was_online != 0;
} }
void ContactsManager::on_view_dialog_active_stories(vector<DialogId> dialog_ids) {
if (dialog_ids.empty() || td_->auth_manager_->is_bot()) {
return;
}
LOG(DEBUG) << "View active stories of " << dialog_ids;
const size_t MAX_SLICE_SIZE = 100; // server side limit
vector<DialogId> input_dialog_ids;
vector<telegram_api::object_ptr<telegram_api::InputPeer>> input_peers;
for (auto &dialog_id : dialog_ids) {
if (td::contains(input_dialog_ids, dialog_id)) {
continue;
}
auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read);
if (input_peer == nullptr) {
continue;
}
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<GetStoriesMaxIdsQuery>()->send(std::move(input_dialog_ids), std::move(input_peers));
input_dialog_ids.clear();
input_peers.clear();
}
}
if (!input_peers.empty()) {
td_->create_handler<GetStoriesMaxIdsQuery>()->send(std::move(input_dialog_ids), std::move(input_peers));
}
}
void ContactsManager::on_get_dialog_max_active_story_ids(const vector<DialogId> &dialog_ids,
const vector<int32> &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 (dialog_ids.size() != max_story_ids.size()) {
if (!max_story_ids.empty()) {
LOG(ERROR) << "Receive " << max_story_ids.size() << " max active story identifiers for " << dialog_ids;
}
return;
}
for (size_t i = 0; i < dialog_ids.size(); i++) {
auto max_story_id = StoryId(max_story_ids[i]);
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 " << dialog_id;
}
}
}
void ContactsManager::repair_chat_participants(ChatId chat_id) { void ContactsManager::repair_chat_participants(ChatId chat_id) {
send_get_chat_full_query(chat_id, Auto(), "repair_chat_participants"); send_get_chat_full_query(chat_id, Auto(), "repair_chat_participants");
} }
@ -15242,7 +15121,7 @@ void ContactsManager::load_user_full(UserId user_id, bool force, Promise<Unit> &
send_get_user_full_query(user_id, std::move(input_user), Auto(), "load expired user_full"); send_get_user_full_query(user_id, std::move(input_user), Auto(), "load expired user_full");
} }
on_view_dialog_active_stories({DialogId(user_id)}); td_->story_manager_->on_view_dialog_active_stories({DialogId(user_id)});
promise.set_value(Unit()); promise.set_value(Unit());
} }
@ -15670,7 +15549,7 @@ void ContactsManager::load_chat_full(ChatId chat_id, bool force, Promise<Unit> &
for (const auto &dialog_participant : chat_full->participants) { for (const auto &dialog_participant : chat_full->participants) {
participant_dialog_ids.push_back(dialog_participant.dialog_id_); participant_dialog_ids.push_back(dialog_participant.dialog_id_);
} }
on_view_dialog_active_stories(std::move(participant_dialog_ids)); td_->story_manager_->on_view_dialog_active_stories(std::move(participant_dialog_ids));
promise.set_value(Unit()); promise.set_value(Unit());
} }

View File

@ -167,6 +167,9 @@ class ContactsManager final : public Actor {
bool get_user_stories_hidden(UserId user_id) const; bool get_user_stories_hidden(UserId user_id) const;
bool get_channel_stories_hidden(ChannelId channel_id) const; bool get_channel_stories_hidden(ChannelId channel_id) const;
bool can_poll_user_active_stories(UserId user_id) const;
bool can_poll_channel_active_stories(ChannelId channel_id) const;
string get_user_private_forward_name(UserId user_id); string get_user_private_forward_name(UserId user_id);
bool get_user_voice_messages_forbidden(UserId user_id) const; bool get_user_voice_messages_forbidden(UserId user_id) const;
@ -698,10 +701,6 @@ class ContactsManager final : public Actor {
void get_support_user(Promise<td_api::object_ptr<td_api::user>> &&promise); void get_support_user(Promise<td_api::object_ptr<td_api::user>> &&promise);
void on_view_dialog_active_stories(vector<DialogId> dialog_ids);
void on_get_dialog_max_active_story_ids(const vector<DialogId> &dialog_ids, const vector<int32> &max_story_ids);
void repair_chat_participants(ChatId chat_id); void repair_chat_participants(ChatId chat_id);
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const; void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
@ -768,8 +767,6 @@ class ContactsManager final : public Actor {
bool is_repaired = false; // whether cached value is rechecked bool is_repaired = false; // whether cached value is rechecked
bool is_max_active_story_id_being_reloaded = false;
bool is_name_changed = true; bool is_name_changed = true;
bool is_username_changed = true; bool is_username_changed = true;
bool is_photo_changed = true; bool is_photo_changed = true;
@ -981,8 +978,6 @@ class ContactsManager final : public Actor {
bool is_scam = false; bool is_scam = false;
bool is_fake = false; bool is_fake = false;
bool is_max_active_story_id_being_reloaded = false;
bool is_title_changed = true; bool is_title_changed = true;
bool is_username_changed = true; bool is_username_changed = true;
bool is_photo_changed = true; bool is_photo_changed = true;

View File

@ -18,6 +18,7 @@
#include "td/telegram/MessagesManager.h" #include "td/telegram/MessagesManager.h"
#include "td/telegram/misc.h" #include "td/telegram/misc.h"
#include "td/telegram/PasswordManager.h" #include "td/telegram/PasswordManager.h"
#include "td/telegram/StoryManager.h"
#include "td/telegram/Td.h" #include "td/telegram/Td.h"
#include "td/telegram/TdDb.h" #include "td/telegram/TdDb.h"
#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.h"
@ -1754,7 +1755,7 @@ void DialogParticipantManager::do_search_chat_participants(ChatId chat_id, const
int32 total_count; int32 total_count;
std::tie(total_count, dialog_ids) = search_among_dialogs(dialog_ids, query, limit); std::tie(total_count, dialog_ids) = search_among_dialogs(dialog_ids, query, limit);
td_->contacts_manager_->on_view_dialog_active_stories(dialog_ids); td_->story_manager_->on_view_dialog_active_stories(dialog_ids);
vector<DialogParticipant> dialog_participants; vector<DialogParticipant> dialog_participants;
for (auto dialog_id : dialog_ids) { for (auto dialog_id : dialog_ids) {
for (const auto &participant : *participants) { for (const auto &participant : *participants) {
@ -1950,7 +1951,7 @@ void DialogParticipantManager::on_get_channel_participants(
for (const auto &participant : result) { for (const auto &participant : result) {
participant_dialog_ids.push_back(participant.dialog_id_); participant_dialog_ids.push_back(participant.dialog_id_);
} }
td_->contacts_manager_->on_view_dialog_active_stories(std::move(participant_dialog_ids)); td_->story_manager_->on_view_dialog_active_stories(std::move(participant_dialog_ids));
promise.set_value(DialogParticipants{total_count, std::move(result)}); promise.set_value(DialogParticipants{total_count, std::move(result)});
} }

View File

@ -18376,7 +18376,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector<MessageId> mess
can_send_message(dialog_id).is_ok(); can_send_message(dialog_id).is_ok();
if (source == MessageSource::DialogList && dialog_type == DialogType::User) { if (source == MessageSource::DialogList && dialog_type == DialogType::User) {
td_->contacts_manager_->on_view_dialog_active_stories({dialog_id}); td_->story_manager_->on_view_dialog_active_stories({dialog_id});
} }
// keep only valid message identifiers // keep only valid message identifiers
@ -18927,7 +18927,7 @@ void MessagesManager::open_dialog(Dialog *d) {
switch (dialog_id.get_type()) { switch (dialog_id.get_type()) {
case DialogType::User: case DialogType::User:
td_->contacts_manager_->on_view_dialog_active_stories({dialog_id}); td_->story_manager_->on_view_dialog_active_stories({dialog_id});
break; break;
case DialogType::Chat: case DialogType::Chat:
td_->contacts_manager_->repair_chat_participants(dialog_id.get_chat_id()); td_->contacts_manager_->repair_chat_participants(dialog_id.get_chat_id());
@ -18944,7 +18944,7 @@ void MessagesManager::open_dialog(Dialog *d) {
channel_id, td_api::make_object<td_api::supergroupMembersFilterRecent>(), string(), 0, 200, 200, Auto()); channel_id, td_api::make_object<td_api::supergroupMembersFilterRecent>(), string(), 0, 200, 200, Auto());
} }
} else { } else {
td_->contacts_manager_->on_view_dialog_active_stories({dialog_id}); td_->story_manager_->on_view_dialog_active_stories({dialog_id});
} }
get_channel_difference(dialog_id, d->pts, 0, MessageId(), true, "open_dialog"); get_channel_difference(dialog_id, d->pts, 0, MessageId(), true, "open_dialog");
reget_dialog_action_bar(dialog_id, "open_dialog", false); reget_dialog_action_bar(dialog_id, "open_dialog", false);

View File

@ -772,6 +772,29 @@ class ReportStoryQuery final : public Td::ResultHandler {
} }
}; };
class GetStoriesMaxIdsQuery final : public Td::ResultHandler {
vector<DialogId> dialog_ids_;
public:
void send(vector<DialogId> dialog_ids, vector<telegram_api::object_ptr<telegram_api::InputPeer>> &&input_peers) {
dialog_ids_ = std::move(dialog_ids);
send_query(G()->net_query_creator().create(telegram_api::stories_getPeerMaxIDs(std::move(input_peers))));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::stories_getPeerMaxIDs>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
td_->story_manager_->on_get_dialog_max_active_story_ids(dialog_ids_, result_ptr.move_as_ok());
}
void on_error(Status status) final {
td_->story_manager_->on_get_dialog_max_active_story_ids(dialog_ids_, Auto());
}
};
class ActivateStealthModeQuery final : public Td::ResultHandler { class ActivateStealthModeQuery final : public Td::ResultHandler {
Promise<Unit> promise_; Promise<Unit> promise_;
@ -2968,7 +2991,7 @@ void StoryManager::on_get_story_interactions(
} }
} }
td_->contacts_manager_->on_view_dialog_active_stories(story_viewers.get_actor_dialog_ids()); on_view_dialog_active_stories(story_viewers.get_actor_dialog_ids());
promise.set_value(story_viewers.get_story_interactions_object(td_)); promise.set_value(story_viewers.get_story_interactions_object(td_));
} }
@ -3048,7 +3071,7 @@ void StoryManager::on_get_dialog_story_interactions(
StoryViewers story_viewers(td_, total_count, std::move(reaction_list->reactions_), StoryViewers story_viewers(td_, total_count, std::move(reaction_list->reactions_),
std::move(reaction_list->next_offset_)); std::move(reaction_list->next_offset_));
td_->contacts_manager_->on_view_dialog_active_stories(story_viewers.get_actor_dialog_ids()); on_view_dialog_active_stories(story_viewers.get_actor_dialog_ids());
promise.set_value(story_viewers.get_story_interactions_object(td_)); promise.set_value(story_viewers.get_story_interactions_object(td_));
} }
@ -4437,6 +4460,84 @@ void StoryManager::on_get_story_views(DialogId owner_dialog_id, const vector<Sto
} }
} }
void StoryManager::on_view_dialog_active_stories(vector<DialogId> dialog_ids) {
if (dialog_ids.empty() || td_->auth_manager_->is_bot()) {
return;
}
LOG(DEBUG) << "View active stories of " << dialog_ids;
const size_t MAX_SLICE_SIZE = 100; // server side limit
vector<DialogId> input_dialog_ids;
vector<telegram_api::object_ptr<telegram_api::InputPeer>> input_peers;
for (auto &dialog_id : dialog_ids) {
if (td::contains(input_dialog_ids, dialog_id)) {
continue;
}
auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read);
if (input_peer == nullptr) {
continue;
}
bool need_poll = [&] {
switch (dialog_id.get_type()) {
case DialogType::User:
return td_->contacts_manager_->can_poll_user_active_stories(dialog_id.get_user_id());
case DialogType::Channel:
return td_->contacts_manager_->can_poll_channel_active_stories(dialog_id.get_channel_id());
case DialogType::Chat:
case DialogType::SecretChat:
case DialogType::None:
default:
return false;
}
}();
if (!need_poll) {
continue;
}
if (!being_reloaded_active_stories_dialog_ids_.insert(dialog_id).second) {
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<GetStoriesMaxIdsQuery>()->send(std::move(input_dialog_ids), std::move(input_peers));
input_dialog_ids.clear();
input_peers.clear();
}
}
if (!input_peers.empty()) {
td_->create_handler<GetStoriesMaxIdsQuery>()->send(std::move(input_dialog_ids), std::move(input_peers));
}
}
void StoryManager::on_get_dialog_max_active_story_ids(const vector<DialogId> &dialog_ids,
const vector<int32> &max_story_ids) {
for (auto &dialog_id : dialog_ids) {
auto is_deleted = being_reloaded_active_stories_dialog_ids_.erase(dialog_id) > 0;
CHECK(is_deleted);
}
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 " << dialog_ids;
}
return;
}
for (size_t i = 0; i < dialog_ids.size(); i++) {
auto max_story_id = StoryId(max_story_ids[i]);
auto dialog_id = dialog_ids[i];
if (max_story_id == StoryId() || max_story_id.is_server()) {
if (dialog_id.get_type() == DialogType::User) {
td_->contacts_manager_->on_update_user_story_ids(dialog_id.get_user_id(), max_story_id, StoryId());
} else {
td_->contacts_manager_->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 " << dialog_id;
}
}
}
FileSourceId StoryManager::get_story_file_source_id(StoryFullId story_full_id) { FileSourceId StoryManager::get_story_file_source_id(StoryFullId story_full_id) {
if (td_->auth_manager_->is_bot()) { if (td_->auth_manager_->is_bot()) {
return FileSourceId(); return FileSourceId();
@ -4768,7 +4869,8 @@ void StoryManager::send_story(DialogId dialog_id, td_api::object_ptr<td_api::Inp
if (dialog_id.get_type() == DialogType::Channel && if (dialog_id.get_type() == DialogType::Channel &&
td_->contacts_manager_->is_megagroup_channel(dialog_id.get_channel_id())) { td_->contacts_manager_->is_megagroup_channel(dialog_id.get_channel_id())) {
story->sender_dialog_id_ = td_->messages_manager_->get_dialog_default_send_message_as_dialog_id(dialog_id); story->sender_dialog_id_ = td_->messages_manager_->get_dialog_default_send_message_as_dialog_id(dialog_id);
if (story->sender_dialog_id_ == DialogId() && !td_->dialog_manager_->is_anonymous_administrator(dialog_id, nullptr)) { if (story->sender_dialog_id_ == DialogId() &&
!td_->dialog_manager_->is_anonymous_administrator(dialog_id, nullptr)) {
story->sender_dialog_id_ = td_->dialog_manager_->get_my_dialog_id(); story->sender_dialog_id_ = td_->dialog_manager_->get_my_dialog_id();
} }
} }

View File

@ -315,6 +315,10 @@ class StoryManager final : public Actor {
void on_get_story_views(DialogId owner_dialog_id, const vector<StoryId> &story_ids, void on_get_story_views(DialogId owner_dialog_id, const vector<StoryId> &story_ids,
telegram_api::object_ptr<telegram_api::stories_storyViews> &&story_views); telegram_api::object_ptr<telegram_api::stories_storyViews> &&story_views);
void on_view_dialog_active_stories(vector<DialogId> dialog_ids);
void on_get_dialog_max_active_story_ids(const vector<DialogId> &dialog_ids, const vector<int32> &max_story_ids);
bool have_story(StoryFullId story_full_id) const; bool have_story(StoryFullId story_full_id) const;
bool have_story_force(StoryFullId story_full_id); bool have_story_force(StoryFullId story_full_id);
@ -686,6 +690,8 @@ class StoryManager final : public Actor {
FlatHashMap<uint32, unique_ptr<ReadyToSendStory>> ready_to_send_stories_; FlatHashMap<uint32, unique_ptr<ReadyToSendStory>> ready_to_send_stories_;
FlatHashSet<DialogId, DialogIdHash> being_reloaded_active_stories_dialog_ids_;
bool channels_to_send_stories_inited_ = false; bool channels_to_send_stories_inited_ = false;
vector<ChannelId> channels_to_send_stories_; vector<ChannelId> channels_to_send_stories_;
vector<Promise<td_api::object_ptr<td_api::chats>>> get_dialogs_to_send_stories_queries_; vector<Promise<td_api::object_ptr<td_api::chats>>> get_dialogs_to_send_stories_queries_;