mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-30 22:25:12 +00:00
Moved user privacy from ApiWrap to Api::UserPrivacy.
This commit is contained in:
@@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_sensitive_content.h"
|
||||
#include "api/api_global_privacy.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "api/api_user_privacy.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_changes.h"
|
||||
@@ -120,49 +121,6 @@ using UpdatedFileReferences = Data::UpdatedFileReferences;
|
||||
|
||||
} // namespace
|
||||
|
||||
MTPInputPrivacyKey ApiWrap::Privacy::Input(Key key) {
|
||||
switch (key) {
|
||||
case Privacy::Key::Calls: return MTP_inputPrivacyKeyPhoneCall();
|
||||
case Privacy::Key::Invites: return MTP_inputPrivacyKeyChatInvite();
|
||||
case Privacy::Key::PhoneNumber: return MTP_inputPrivacyKeyPhoneNumber();
|
||||
case Privacy::Key::AddedByPhone:
|
||||
return MTP_inputPrivacyKeyAddedByPhone();
|
||||
case Privacy::Key::LastSeen:
|
||||
return MTP_inputPrivacyKeyStatusTimestamp();
|
||||
case Privacy::Key::CallsPeer2Peer:
|
||||
return MTP_inputPrivacyKeyPhoneP2P();
|
||||
case Privacy::Key::Forwards:
|
||||
return MTP_inputPrivacyKeyForwards();
|
||||
case Privacy::Key::ProfilePhoto:
|
||||
return MTP_inputPrivacyKeyProfilePhoto();
|
||||
}
|
||||
Unexpected("Key in ApiWrap::Privacy::Input.");
|
||||
}
|
||||
|
||||
std::optional<ApiWrap::Privacy::Key> ApiWrap::Privacy::KeyFromMTP(
|
||||
mtpTypeId type) {
|
||||
using Key = Privacy::Key;
|
||||
switch (type) {
|
||||
case mtpc_privacyKeyPhoneNumber:
|
||||
case mtpc_inputPrivacyKeyPhoneNumber: return Key::PhoneNumber;
|
||||
case mtpc_privacyKeyAddedByPhone:
|
||||
case mtpc_inputPrivacyKeyAddedByPhone: return Key::AddedByPhone;
|
||||
case mtpc_privacyKeyStatusTimestamp:
|
||||
case mtpc_inputPrivacyKeyStatusTimestamp: return Key::LastSeen;
|
||||
case mtpc_privacyKeyChatInvite:
|
||||
case mtpc_inputPrivacyKeyChatInvite: return Key::Invites;
|
||||
case mtpc_privacyKeyPhoneCall:
|
||||
case mtpc_inputPrivacyKeyPhoneCall: return Key::Calls;
|
||||
case mtpc_privacyKeyPhoneP2P:
|
||||
case mtpc_inputPrivacyKeyPhoneP2P: return Key::CallsPeer2Peer;
|
||||
case mtpc_privacyKeyForwards:
|
||||
case mtpc_inputPrivacyKeyForwards: return Key::Forwards;
|
||||
case mtpc_privacyKeyProfilePhoto:
|
||||
case mtpc_inputPrivacyKeyProfilePhoto: return Key::ProfilePhoto;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool ApiWrap::BlockedPeersSlice::Item::operator==(const Item &other) const {
|
||||
return (peer == other.peer) && (date == other.date);
|
||||
}
|
||||
@@ -195,6 +153,7 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
|
||||
, _selfDestruct(std::make_unique<Api::SelfDestruct>(this))
|
||||
, _sensitiveContent(std::make_unique<Api::SensitiveContent>(this))
|
||||
, _globalPrivacy(std::make_unique<Api::GlobalPrivacy>(this))
|
||||
, _userPrivacy(std::make_unique<Api::UserPrivacy>(this))
|
||||
, _inviteLinks(std::make_unique<Api::InviteLinks>(this)) {
|
||||
crl::on_main(session, [=] {
|
||||
// You can't use _session->lifetime() in the constructor,
|
||||
@@ -2309,45 +2268,7 @@ void ApiWrap::saveDraftToCloudDelayed(not_null<History*> history) {
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::savePrivacy(
|
||||
const MTPInputPrivacyKey &key,
|
||||
QVector<MTPInputPrivacyRule> &&rules) {
|
||||
const auto keyTypeId = key.type();
|
||||
const auto it = _privacySaveRequests.find(keyTypeId);
|
||||
if (it != _privacySaveRequests.cend()) {
|
||||
request(it->second).cancel();
|
||||
_privacySaveRequests.erase(it);
|
||||
}
|
||||
|
||||
const auto requestId = request(MTPaccount_SetPrivacy(
|
||||
key,
|
||||
MTP_vector<MTPInputPrivacyRule>(std::move(rules))
|
||||
)).done([=](const MTPaccount_PrivacyRules &result) {
|
||||
result.match([&](const MTPDaccount_privacyRules &data) {
|
||||
_session->data().processUsers(data.vusers());
|
||||
_session->data().processChats(data.vchats());
|
||||
_privacySaveRequests.remove(keyTypeId);
|
||||
if (const auto key = Privacy::KeyFromMTP(keyTypeId)) {
|
||||
handlePrivacyChange(*key, data.vrules());
|
||||
}
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_privacySaveRequests.remove(keyTypeId);
|
||||
}).send();
|
||||
|
||||
_privacySaveRequests.emplace(keyTypeId, requestId);
|
||||
}
|
||||
|
||||
void ApiWrap::handlePrivacyChange(
|
||||
Privacy::Key key,
|
||||
const MTPVector<MTPPrivacyRule> &rules) {
|
||||
pushPrivacy(key, rules.v);
|
||||
if (key == Privacy::Key::LastSeen) {
|
||||
updatePrivacyLastSeens(rules.v);
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::updatePrivacyLastSeens(const QVector<MTPPrivacyRule> &rules) {
|
||||
void ApiWrap::updatePrivacyLastSeens() {
|
||||
const auto now = base::unixtime::now();
|
||||
_session->data().enumerateUsers([&](UserData *user) {
|
||||
if (user->isSelf() || !user->isFullLoaded()) {
|
||||
@@ -4878,125 +4799,6 @@ void ApiWrap::saveSelfBio(const QString &text, FnMut<void()> done) {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::reloadPrivacy(Privacy::Key key) {
|
||||
if (_privacyRequestIds.contains(key)) {
|
||||
return;
|
||||
}
|
||||
const auto requestId = request(MTPaccount_GetPrivacy(
|
||||
Privacy::Input(key)
|
||||
)).done([=](const MTPaccount_PrivacyRules &result) {
|
||||
_privacyRequestIds.erase(key);
|
||||
result.match([&](const MTPDaccount_privacyRules &data) {
|
||||
_session->data().processUsers(data.vusers());
|
||||
_session->data().processChats(data.vchats());
|
||||
pushPrivacy(key, data.vrules().v);
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_privacyRequestIds.erase(key);
|
||||
}).send();
|
||||
_privacyRequestIds.emplace(key, requestId);
|
||||
}
|
||||
|
||||
auto ApiWrap::parsePrivacy(const QVector<MTPPrivacyRule> &rules)
|
||||
-> Privacy {
|
||||
using Option = Privacy::Option;
|
||||
|
||||
// This is simplified version of privacy rules interpretation.
|
||||
// But it should be fine for all the apps
|
||||
// that use the same subset of features.
|
||||
auto result = Privacy();
|
||||
auto optionSet = false;
|
||||
const auto SetOption = [&](Option option) {
|
||||
if (optionSet) return;
|
||||
optionSet = true;
|
||||
result.option = option;
|
||||
};
|
||||
auto &always = result.always;
|
||||
auto &never = result.never;
|
||||
const auto Feed = [&](const MTPPrivacyRule &rule) {
|
||||
rule.match([&](const MTPDprivacyValueAllowAll &) {
|
||||
SetOption(Option::Everyone);
|
||||
}, [&](const MTPDprivacyValueAllowContacts &) {
|
||||
SetOption(Option::Contacts);
|
||||
}, [&](const MTPDprivacyValueAllowUsers &data) {
|
||||
const auto &users = data.vusers().v;
|
||||
always.reserve(always.size() + users.size());
|
||||
for (const auto userId : users) {
|
||||
const auto user = _session->data().user(UserId(userId.v));
|
||||
if (!base::contains(never, user)
|
||||
&& !base::contains(always, user)) {
|
||||
always.emplace_back(user);
|
||||
}
|
||||
}
|
||||
}, [&](const MTPDprivacyValueAllowChatParticipants &data) {
|
||||
const auto &chats = data.vchats().v;
|
||||
always.reserve(always.size() + chats.size());
|
||||
for (const auto &chatId : chats) {
|
||||
const auto chat = _session->data().chatLoaded(chatId);
|
||||
const auto peer = chat
|
||||
? static_cast<PeerData*>(chat)
|
||||
: _session->data().channelLoaded(chatId);
|
||||
if (peer
|
||||
&& !base::contains(never, peer)
|
||||
&& !base::contains(always, peer)) {
|
||||
always.emplace_back(peer);
|
||||
}
|
||||
}
|
||||
}, [&](const MTPDprivacyValueDisallowContacts &) {
|
||||
// not supported
|
||||
}, [&](const MTPDprivacyValueDisallowAll &) {
|
||||
SetOption(Option::Nobody);
|
||||
}, [&](const MTPDprivacyValueDisallowUsers &data) {
|
||||
const auto &users = data.vusers().v;
|
||||
never.reserve(never.size() + users.size());
|
||||
for (const auto userId : users) {
|
||||
const auto user = _session->data().user(UserId(userId.v));
|
||||
if (!base::contains(always, user)
|
||||
&& !base::contains(never, user)) {
|
||||
never.emplace_back(user);
|
||||
}
|
||||
}
|
||||
}, [&](const MTPDprivacyValueDisallowChatParticipants &data) {
|
||||
const auto &chats = data.vchats().v;
|
||||
never.reserve(never.size() + chats.size());
|
||||
for (const auto &chatId : chats) {
|
||||
const auto chat = _session->data().chatLoaded(chatId);
|
||||
const auto peer = chat
|
||||
? static_cast<PeerData*>(chat)
|
||||
: _session->data().channelLoaded(chatId);
|
||||
if (peer
|
||||
&& !base::contains(always, peer)
|
||||
&& !base::contains(never, peer)) {
|
||||
never.emplace_back(peer);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
for (const auto &rule : rules) {
|
||||
Feed(rule);
|
||||
}
|
||||
Feed(MTP_privacyValueDisallowAll()); // disallow by default.
|
||||
return result;
|
||||
}
|
||||
|
||||
void ApiWrap::pushPrivacy(
|
||||
Privacy::Key key,
|
||||
const QVector<MTPPrivacyRule> &rules) {
|
||||
const auto &saved = (_privacyValues[key] = parsePrivacy(rules));
|
||||
const auto i = _privacyChanges.find(key);
|
||||
if (i != end(_privacyChanges)) {
|
||||
i->second.fire_copy(saved);
|
||||
}
|
||||
}
|
||||
|
||||
auto ApiWrap::privacyValue(Privacy::Key key) -> rpl::producer<Privacy> {
|
||||
if (const auto i = _privacyValues.find(key); i != end(_privacyValues)) {
|
||||
return _privacyChanges[key].events_starting_with_copy(i->second);
|
||||
} else {
|
||||
return _privacyChanges[key].events();
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::reloadBlockedPeers() {
|
||||
if (_blockedPeersRequestId) {
|
||||
return;
|
||||
@@ -5068,6 +4870,10 @@ Api::GlobalPrivacy &ApiWrap::globalPrivacy() {
|
||||
return *_globalPrivacy;
|
||||
}
|
||||
|
||||
Api::UserPrivacy &ApiWrap::userPrivacy() {
|
||||
return *_userPrivacy;
|
||||
}
|
||||
|
||||
Api::InviteLinks &ApiWrap::inviteLinks() {
|
||||
return *_inviteLinks;
|
||||
}
|
||||
|
Reference in New Issue
Block a user