Reget users to restore their online status after removing them from privacy restrictions.

GitOrigin-RevId: e29832c5a056cdc5708c02ce31e77570ff335ced
This commit is contained in:
levlam 2020-04-19 12:53:07 +03:00
parent 38de2b016e
commit 822bc95d13
4 changed files with 50 additions and 10 deletions

View File

@ -11620,7 +11620,7 @@ ContactsManager::UserFull *ContactsManager::add_user_full(UserId user_id) {
void ContactsManager::reload_user(UserId user_id, Promise<Unit> &&promise) {
if (!user_id.is_valid()) {
return promise.set_error(Status::Error(6, "Invalid user id"));
return promise.set_error(Status::Error(6, "Invalid user ID"));
}
have_user_force(user_id);
@ -11854,7 +11854,7 @@ ContactsManager::Chat *ContactsManager::add_chat(ChatId chat_id) {
bool ContactsManager::get_chat(ChatId chat_id, int left_tries, Promise<Unit> &&promise) {
if (!chat_id.is_valid()) {
promise.set_error(Status::Error(6, "Invalid basic group id"));
promise.set_error(Status::Error(6, "Invalid basic group ID"));
return false;
}
@ -11880,7 +11880,7 @@ bool ContactsManager::get_chat(ChatId chat_id, int left_tries, Promise<Unit> &&p
void ContactsManager::reload_chat(ChatId chat_id, Promise<Unit> &&promise) {
if (!chat_id.is_valid()) {
return promise.set_error(Status::Error(6, "Invalid basic group id"));
return promise.set_error(Status::Error(6, "Invalid basic group ID"));
}
// there is no much reason to combine different requests into one request
@ -12173,7 +12173,7 @@ ContactsManager::Channel *ContactsManager::add_channel(ChannelId channel_id, con
bool ContactsManager::get_channel(ChannelId channel_id, int left_tries, Promise<Unit> &&promise) {
if (!channel_id.is_valid()) {
promise.set_error(Status::Error(6, "Invalid supergroup id"));
promise.set_error(Status::Error(6, "Invalid supergroup ID"));
return false;
}
@ -12199,7 +12199,7 @@ bool ContactsManager::get_channel(ChannelId channel_id, int left_tries, Promise<
void ContactsManager::reload_channel(ChannelId channel_id, Promise<Unit> &&promise) {
if (!channel_id.is_valid()) {
return promise.set_error(Status::Error(6, "Invalid supergroup id"));
return promise.set_error(Status::Error(6, "Invalid supergroup ID"));
}
have_channel_force(channel_id);
@ -12332,7 +12332,7 @@ ContactsManager::SecretChat *ContactsManager::get_secret_chat(SecretChatId secre
bool ContactsManager::get_secret_chat(SecretChatId secret_chat_id, bool force, Promise<Unit> &&promise) {
if (!secret_chat_id.is_valid()) {
promise.set_error(Status::Error(6, "Invalid secret chat id"));
promise.set_error(Status::Error(6, "Invalid secret chat ID"));
return false;
}

View File

@ -22,6 +22,9 @@
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include <algorithm>
#include <iterator>
namespace td {
Result<PrivacyManager::UserPrivacySetting> PrivacyManager::UserPrivacySetting::from_td_api(
@ -344,6 +347,13 @@ vector<int64> PrivacyManager::UserPrivacySettingRule::chat_ids_as_dialog_ids() c
return result;
}
vector<int32> PrivacyManager::UserPrivacySettingRule::get_restricted_user_ids() const {
if (type_ == Type::RestrictUsers) {
return user_ids_;
}
return {};
}
Result<PrivacyManager::UserPrivacySettingRules> PrivacyManager::UserPrivacySettingRules::from_telegram_api(
tl_object_ptr<telegram_api::account_privacyRules> rules) {
G()->td().get_actor_unsafe()->contacts_manager_->on_get_users(std::move(rules->users_), "on get privacy rules");
@ -393,6 +403,16 @@ vector<tl_object_ptr<telegram_api::InputPrivacyRule>> PrivacyManager::UserPrivac
return result;
}
vector<int32> PrivacyManager::UserPrivacySettingRules::get_restricted_user_ids() const {
vector<int32> result;
for (auto &rule : rules_) {
combine(result, rule.get_restricted_user_ids());
}
std::sort(result.begin(), result.end());
result.erase(std::unique(result.begin(), result.end()), result.end());
return result;
}
void PrivacyManager::get_privacy(tl_object_ptr<td_api::UserPrivacySetting> key,
Promise<tl_object_ptr<td_api::userPrivacySettingRules>> promise) {
auto r_user_privacy_setting = UserPrivacySetting::from_td_api(std::move(key));
@ -499,14 +519,27 @@ void PrivacyManager::do_update_privacy(UserPrivacySetting user_privacy_setting,
info.is_synchronized = true;
if (!(info.rules == privacy_rules)) {
if ((from_update || was_synchronized) && user_privacy_setting.type() == UserPrivacySetting::Type::UserStatus &&
!G()->close_flag()) {
send_closure_later(G()->contacts_manager(), &ContactsManager::on_update_online_status_privacy);
auto old_restricted = info.rules.get_restricted_user_ids();
auto new_restricted = privacy_rules.get_restricted_user_ids();
if (old_restricted != new_restricted) {
// if a user was unrestricted, it is not received from the server anymore
// we need to reget their online status manually
std::vector<int32> unrestricted;
std::set_difference(old_restricted.begin(), old_restricted.end(), new_restricted.begin(), new_restricted.end(),
std::back_inserter(unrestricted));
for (auto &user_id : unrestricted) {
send_closure_later(G()->contacts_manager(), &ContactsManager::reload_user, UserId(user_id), Promise<Unit>());
}
}
}
info.rules = std::move(privacy_rules);
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateUserPrivacySettingRules>(user_privacy_setting.as_td_api(),
info.rules.as_td_api()));
if ((from_update || was_synchronized) && user_privacy_setting.type() == UserPrivacySetting::Type::UserStatus) {
send_closure(G()->contacts_manager(), &ContactsManager::on_update_online_status_privacy);
}
}
}

View File

@ -76,6 +76,8 @@ class PrivacyManager : public NetQueryCallback {
return type_ == other.type_ && user_ids_ == other.user_ids_ && chat_ids_ == other.chat_ids_;
}
vector<int32> get_restricted_user_ids() const;
private:
enum class Type : int32 {
AllowContacts,
@ -113,6 +115,8 @@ class PrivacyManager : public NetQueryCallback {
return rules_ == other.rules_;
}
vector<int32> get_restricted_user_ids() const;
private:
vector<UserPrivacySettingRule> rules_;
};

View File

@ -167,6 +167,9 @@ void combine(vector<T> &destination, vector<T> &&source) {
if (destination.size() < source.size()) {
destination.swap(source);
}
if (source.empty()) {
return;
}
destination.reserve(destination.size() + source.size());
for (auto &elem : source) {
destination.push_back(std::move(elem));