Save and load lists of created public channels.

This commit is contained in:
levlam 2021-12-03 20:10:30 +03:00
parent a33027a9c1
commit fb9bb3cd69
5 changed files with 84 additions and 50 deletions

View File

@ -7633,12 +7633,55 @@ void ContactsManager::return_created_public_dialogs(Promise<td_api::object_ptr<t
}
void ContactsManager::get_created_public_dialogs(PublicDialogType type,
Promise<td_api::object_ptr<td_api::chats>> &&promise) {
Promise<td_api::object_ptr<td_api::chats>> &&promise,
bool from_binlog) {
auto index = static_cast<int32>(type);
if (created_public_channels_inited_[index]) {
return return_created_public_dialogs(std::move(promise), created_public_channels_[index]);
}
if (get_created_public_channels_queries_[index].empty() && G()->parameters().use_chat_info_db) {
auto pmc_key = PSTRING() << "public_channels" << index;
auto str = G()->td_db()->get_binlog_pmc()->get(pmc_key);
if (!str.empty()) {
auto r_channel_ids = transform(full_split(Slice(str), ','), [](Slice str) -> Result<ChannelId> {
TRY_RESULT(channel_id_int, to_integer_safe<int64>(str));
ChannelId channel_id(channel_id_int);
if (!channel_id.is_valid()) {
return Status::Error("Have invalid channel ID");
}
return channel_id;
});
if (std::any_of(r_channel_ids.begin(), r_channel_ids.end(),
[](auto &r_channel_id) { return r_channel_id.is_error(); })) {
LOG(ERROR) << "Can't parse " << str;
G()->td_db()->get_binlog_pmc()->erase(pmc_key);
} else {
Dependencies dependencies;
vector<ChannelId> channel_ids;
for (auto &r_channel_id : r_channel_ids) {
auto channel_id = r_channel_id.move_as_ok();
add_dialog_and_dependencies(dependencies, DialogId(channel_id));
channel_ids.push_back(channel_id);
}
if (!resolve_dependencies_force(td_, dependencies, "get_created_public_dialogs")) {
G()->td_db()->get_binlog_pmc()->erase(pmc_key);
} else {
created_public_channels_[index] = std::move(channel_ids);
created_public_channels_inited_[index] = true;
if (type == PublicDialogType::HasUsername) {
update_created_public_broadcasts();
}
if (from_binlog) {
return return_created_public_dialogs(std::move(promise), created_public_channels_[index]);
}
}
}
}
}
get_created_public_channels_queries_[index].push_back(std::move(promise));
if (get_created_public_channels_queries_[index].size() == 1) {
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), type](Result<Unit> &&result) {
@ -7684,6 +7727,8 @@ void ContactsManager::update_created_public_channels(Channel *c, ChannelId chann
update_created_public_broadcasts();
}
save_created_public_channels(PublicDialogType::HasUsername);
// TODO reload the list
}
}
@ -7698,6 +7743,8 @@ void ContactsManager::update_created_public_channels(Channel *c, ChannelId chann
}
}
if (was_changed) {
save_created_public_channels(PublicDialogType::IsLocationBased);
// TODO reload the list
}
}
@ -7719,6 +7766,20 @@ void ContactsManager::on_get_created_public_channels(PublicDialogType type,
if (type == PublicDialogType::HasUsername) {
update_created_public_broadcasts();
}
save_created_public_channels(type);
}
void ContactsManager::save_created_public_channels(PublicDialogType type) {
auto index = static_cast<int32>(type);
CHECK(created_public_channels_inited_[index]);
if (G()->parameters().use_chat_info_db) {
G()->td_db()->get_binlog_pmc()->set(
PSTRING() << "public_channels" << index,
implode(
transform(created_public_channels_[index], [](auto channel_id) { return PSTRING() << channel_id.get(); }),
','));
}
}
void ContactsManager::update_created_public_broadcasts() {
@ -16191,7 +16252,7 @@ void ContactsManager::after_get_difference() {
get_user(get_my_id(), 3, Promise<Unit>());
if (td_->is_online()) {
get_created_public_dialogs(PublicDialogType::HasUsername, Promise<td_api::object_ptr<td_api::chats>>());
get_created_public_dialogs(PublicDialogType::HasUsername, Promise<td_api::object_ptr<td_api::chats>>(), false);
}
}

View File

@ -417,7 +417,8 @@ class ContactsManager final : public Actor {
ChannelId migrate_chat_to_megagroup(ChatId chat_id, Promise<Unit> &promise);
void get_created_public_dialogs(PublicDialogType type, Promise<td_api::object_ptr<td_api::chats>> &&promise);
void get_created_public_dialogs(PublicDialogType type, Promise<td_api::object_ptr<td_api::chats>> &&promise,
bool from_binlog);
void check_created_public_dialogs_limit(PublicDialogType type, Promise<Unit> &&promise);
@ -1417,6 +1418,8 @@ class ContactsManager final : public Actor {
void update_created_public_channels(Channel *c, ChannelId channel_id);
void save_created_public_channels(PublicDialogType type);
void update_created_public_broadcasts();
void export_dialog_invite_link_impl(DialogId dialog_id, string title, int32 expire_date, int32 usage_limit,

View File

@ -2939,47 +2939,6 @@ class ReadMentionsQuery final : public Td::ResultHandler {
}
};
class GetSendAsQuery final : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::messageSenders>> promise_;
DialogId dialog_id_;
public:
explicit GetSendAsQuery(Promise<td_api::object_ptr<td_api::messageSenders>> &&promise)
: promise_(std::move(promise)) {
}
void send(DialogId dialog_id) {
dialog_id_ = dialog_id;
auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read);
if (input_peer == nullptr) {
return promise_.set_error(Status::Error(400, "Chat is not accessible"));
}
send_query(G()->net_query_creator().create(telegram_api::channels_getSendAs(std::move(input_peer))));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::channels_getSendAs>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for GetSendAsQuery: " << to_string(ptr);
td_->contacts_manager_->on_get_users(std::move(ptr->users_), "GetSendAsQuery");
td_->contacts_manager_->on_get_chats(std::move(ptr->chats_), "GetSendAsQuery");
promise_.set_value(convert_message_senders_object(td_, ptr->peers_));
}
void on_error(Status status) final {
td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReadMentionsQuery");
promise_.set_error(std::move(status));
}
};
class SaveDefaultSendAsActor final : public NetActorOnce {
Promise<Unit> promise_;
@ -24095,7 +24054,9 @@ void MessagesManager::add_message_dependencies(Dependencies &dependencies, const
}
void MessagesManager::get_dialog_send_message_as_dialog_ids(
DialogId dialog_id, Promise<td_api::object_ptr<td_api::messageSenders>> &&promise) {
DialogId dialog_id, Promise<td_api::object_ptr<td_api::messageSenders>> &&promise, bool is_recursive) {
TRY_STATUS_PROMISE(promise, G()->close_status());
const Dialog *d = get_dialog_force(dialog_id, "get_group_call_join_as");
if (d == nullptr) {
return promise.set_error(Status::Error(400, "Chat not found"));
@ -24127,9 +24088,17 @@ void MessagesManager::get_dialog_send_message_as_dialog_ids(
return promise.set_value(std::move(senders));
}
td_->contacts_manager_->get_created_public_dialogs(PublicDialogType::HasUsername,
Promise<td_api::object_ptr<td_api::chats>>());
td_->create_handler<GetSendAsQuery>(std::move(promise))->send(dialog_id);
CHECK(!is_recursive);
auto new_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, promise = std::move(promise)](
Result<td_api::object_ptr<td_api::chats>> &&result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
send_closure_later(actor_id, &MessagesManager::get_dialog_send_message_as_dialog_ids, dialog_id,
std::move(promise), true);
}
});
td_->contacts_manager_->get_created_public_dialogs(PublicDialogType::HasUsername, std::move(new_promise), true);
}
void MessagesManager::set_dialog_default_send_message_as_dialog_id(DialogId dialog_id,

View File

@ -394,7 +394,8 @@ class MessagesManager final : public Actor {
void reload_voice_chat_on_search(const string &username);
void get_dialog_send_message_as_dialog_ids(DialogId dialog_id,
Promise<td_api::object_ptr<td_api::messageSenders>> &&promise);
Promise<td_api::object_ptr<td_api::messageSenders>> &&promise,
bool is_recursive = false);
void set_dialog_default_send_message_as_dialog_id(DialogId dialog_id, DialogId message_sender_dialog_id,
Promise<Unit> &&promise);

View File

@ -5207,7 +5207,7 @@ void Td::on_request(uint64 id, td_api::checkChatUsername &request) {
void Td::on_request(uint64 id, const td_api::getCreatedPublicChats &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
contacts_manager_->get_created_public_dialogs(get_public_dialog_type(request.type_), std::move(promise));
contacts_manager_->get_created_public_dialogs(get_public_dialog_type(request.type_), std::move(promise), false);
}
void Td::on_request(uint64 id, const td_api::checkCreatedPublicChatsLimit &request) {