2019-01-04 11:09:48 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
|
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
|
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
|
|
*/
|
|
|
|
#include "data/data_user.h"
|
|
|
|
|
|
|
|
#include "storage/localstorage.h"
|
2020-06-18 12:47:09 +00:00
|
|
|
#include "main/main_session.h"
|
2019-01-04 11:09:48 +00:00
|
|
|
#include "data/data_session.h"
|
2020-06-12 12:12:34 +00:00
|
|
|
#include "data/data_changes.h"
|
2022-05-14 20:50:02 +00:00
|
|
|
#include "data/data_peer_bot_command.h"
|
2022-09-01 05:58:04 +00:00
|
|
|
#include "data/data_emoji_statuses.h"
|
2022-10-09 11:25:47 +00:00
|
|
|
#include "data/data_user_names.h"
|
2022-10-13 17:34:04 +00:00
|
|
|
#include "data/notify/data_notify_settings.h"
|
2020-10-10 09:15:37 +00:00
|
|
|
#include "ui/text/text_options.h"
|
2019-01-04 11:09:48 +00:00
|
|
|
#include "lang/lang_keys.h"
|
2022-09-30 07:25:02 +00:00
|
|
|
#include "styles/style_chat.h"
|
2019-01-04 11:09:48 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2019-03-15 12:09:05 +00:00
|
|
|
// User with hidden last seen stays online in UI for such amount of seconds.
|
|
|
|
constexpr auto kSetOnlineAfterActivity = TimeId(30);
|
|
|
|
|
2020-06-12 12:12:34 +00:00
|
|
|
using UpdateFlag = Data::PeerUpdate::Flag;
|
2019-01-04 11:09:48 +00:00
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2022-09-30 07:25:02 +00:00
|
|
|
BotInfo::BotInfo() : text(st::msgMinWidth) {
|
|
|
|
}
|
|
|
|
|
2019-01-04 11:09:48 +00:00
|
|
|
UserData::UserData(not_null<Data::Session*> owner, PeerId id)
|
2021-12-01 14:51:18 +00:00
|
|
|
: PeerData(owner, id)
|
|
|
|
, _flags((id == owner->session().userPeerId()) ? Flag::Self : Flag(0)) {
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::canShareThisContact() const {
|
|
|
|
return canShareThisContactFast()
|
|
|
|
|| !owner().findContactPhone(peerToUser(id)).isEmpty();
|
|
|
|
}
|
|
|
|
|
2019-06-06 16:48:42 +00:00
|
|
|
void UserData::setIsContact(bool is) {
|
2019-06-07 11:32:58 +00:00
|
|
|
const auto status = is
|
|
|
|
? ContactStatus::Contact
|
|
|
|
: ContactStatus::NotContact;
|
|
|
|
if (_contactStatus != status) {
|
|
|
|
_contactStatus = status;
|
2020-06-12 12:12:34 +00:00
|
|
|
session().changes().peerUpdated(this, UpdateFlag::IsContact);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-09 16:57:05 +00:00
|
|
|
// see Serialize::readPeer as well
|
2019-01-04 11:09:48 +00:00
|
|
|
void UserData::setPhoto(const MTPUserProfilePhoto &photo) {
|
2020-05-28 13:51:18 +00:00
|
|
|
photo.match([&](const MTPDuserProfilePhoto &data) {
|
2022-05-16 11:38:35 +00:00
|
|
|
updateUserpic(
|
|
|
|
data.vphoto_id().v,
|
|
|
|
data.vdc_id().v,
|
|
|
|
data.is_has_video());
|
2020-05-28 13:51:18 +00:00
|
|
|
}, [&](const MTPDuserProfilePhotoEmpty &) {
|
2019-01-04 11:09:48 +00:00
|
|
|
clearUserpic();
|
2020-05-28 13:51:18 +00:00
|
|
|
});
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
|
2022-08-19 12:38:11 +00:00
|
|
|
void UserData::setEmojiStatus(const MTPEmojiStatus &status) {
|
2022-09-01 05:58:04 +00:00
|
|
|
const auto parsed = Data::ParseEmojiStatus(status);
|
|
|
|
setEmojiStatus(parsed.id, parsed.until);
|
2022-08-19 12:38:11 +00:00
|
|
|
}
|
|
|
|
|
2022-09-01 05:58:04 +00:00
|
|
|
void UserData::setEmojiStatus(DocumentId emojiStatusId, TimeId until) {
|
2022-08-09 15:53:40 +00:00
|
|
|
if (_emojiStatusId != emojiStatusId) {
|
|
|
|
_emojiStatusId = emojiStatusId;
|
|
|
|
session().changes().peerUpdated(this, UpdateFlag::EmojiStatus);
|
|
|
|
}
|
2022-09-01 05:58:04 +00:00
|
|
|
owner().emojiStatuses().registerAutomaticClear(this, until);
|
2022-08-09 15:53:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DocumentId UserData::emojiStatusId() const {
|
|
|
|
return _emojiStatusId;
|
|
|
|
}
|
|
|
|
|
2019-12-09 13:57:33 +00:00
|
|
|
auto UserData::unavailableReasons() const
|
|
|
|
-> const std::vector<Data::UnavailableReason> & {
|
|
|
|
return _unavailableReasons;
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
|
2019-12-09 13:57:33 +00:00
|
|
|
void UserData::setUnavailableReasons(
|
|
|
|
std::vector<Data::UnavailableReason> &&reasons) {
|
|
|
|
if (_unavailableReasons != reasons) {
|
|
|
|
_unavailableReasons = std::move(reasons);
|
2020-06-12 12:12:34 +00:00
|
|
|
session().changes().peerUpdated(
|
2019-01-04 11:09:48 +00:00
|
|
|
this,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::UnavailableReason);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::setCommonChatsCount(int count) {
|
|
|
|
if (_commonChatsCount != count) {
|
|
|
|
_commonChatsCount = count;
|
2020-06-12 12:12:34 +00:00
|
|
|
session().changes().peerUpdated(this, UpdateFlag::CommonChats);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::setName(const QString &newFirstName, const QString &newLastName, const QString &newPhoneName, const QString &newUsername) {
|
|
|
|
bool changeName = !newFirstName.isEmpty() || !newLastName.isEmpty();
|
|
|
|
|
|
|
|
QString newFullName;
|
|
|
|
if (changeName && newFirstName.trimmed().isEmpty()) {
|
|
|
|
firstName = newLastName;
|
|
|
|
lastName = QString();
|
|
|
|
newFullName = firstName;
|
|
|
|
} else {
|
|
|
|
if (changeName) {
|
|
|
|
firstName = newFirstName;
|
|
|
|
lastName = newLastName;
|
|
|
|
}
|
2019-06-19 16:39:25 +00:00
|
|
|
newFullName = lastName.isEmpty() ? firstName : tr::lng_full_name(tr::now, lt_first_name, firstName, lt_last_name, lastName);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
updateNameDelayed(newFullName, newPhoneName, newUsername);
|
|
|
|
}
|
|
|
|
|
2022-10-14 15:49:40 +00:00
|
|
|
void UserData::setUsernames(const Data::Usernames &newUsernames) {
|
|
|
|
const auto wasUsername = username();
|
|
|
|
const auto wasUsernames = usernames();
|
|
|
|
_username.setUsernames(newUsernames);
|
|
|
|
const auto nowUsername = username();
|
|
|
|
const auto nowUsernames = usernames();
|
|
|
|
session().changes().peerUpdated(
|
|
|
|
this,
|
|
|
|
UpdateFlag()
|
|
|
|
| ((wasUsername != nowUsername)
|
|
|
|
? UpdateFlag::Username
|
|
|
|
: UpdateFlag())
|
|
|
|
| (!ranges::equal(wasUsernames, nowUsernames)
|
|
|
|
? UpdateFlag::Usernames
|
|
|
|
: UpdateFlag()));
|
2022-10-09 11:25:47 +00:00
|
|
|
}
|
|
|
|
|
2022-10-05 11:32:16 +00:00
|
|
|
void UserData::setUsername(const QString &username) {
|
2022-10-14 15:49:40 +00:00
|
|
|
_username.setUsername(username);
|
2022-10-05 11:32:16 +00:00
|
|
|
}
|
|
|
|
|
2019-01-04 11:09:48 +00:00
|
|
|
void UserData::setPhone(const QString &newPhone) {
|
|
|
|
if (_phone != newPhone) {
|
|
|
|
_phone = newPhone;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::setBotInfoVersion(int version) {
|
|
|
|
if (version < 0) {
|
2020-06-10 18:08:17 +00:00
|
|
|
// We don't support bots becoming non-bots.
|
2022-06-15 19:25:51 +00:00
|
|
|
if (botInfo) {
|
|
|
|
botInfo->version = -1;
|
|
|
|
}
|
2019-01-04 11:09:48 +00:00
|
|
|
} else if (!botInfo) {
|
|
|
|
botInfo = std::make_unique<BotInfo>();
|
|
|
|
botInfo->version = version;
|
2020-06-10 18:08:17 +00:00
|
|
|
owner().userIsBotChanged(this);
|
2019-01-04 11:09:48 +00:00
|
|
|
} else if (botInfo->version < version) {
|
2021-07-01 09:49:37 +00:00
|
|
|
if (!botInfo->commands.empty()) {
|
2019-01-04 11:09:48 +00:00
|
|
|
botInfo->commands.clear();
|
2020-06-10 18:08:17 +00:00
|
|
|
owner().botCommandsChanged(this);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
botInfo->description.clear();
|
|
|
|
botInfo->version = version;
|
|
|
|
botInfo->inited = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::setBotInfo(const MTPBotInfo &info) {
|
|
|
|
switch (info.type()) {
|
|
|
|
case mtpc_botInfo: {
|
2019-07-18 08:51:11 +00:00
|
|
|
const auto &d = info.c_botInfo();
|
2022-04-15 13:32:34 +00:00
|
|
|
if (!isBot()) {
|
|
|
|
return;
|
|
|
|
} else if (d.vuser_id() && peerFromUser(*d.vuser_id()) != id) {
|
2019-07-18 08:51:11 +00:00
|
|
|
return;
|
|
|
|
}
|
2019-01-04 11:09:48 +00:00
|
|
|
|
2022-04-15 13:32:34 +00:00
|
|
|
QString desc = qs(d.vdescription().value_or_empty());
|
2019-01-04 11:09:48 +00:00
|
|
|
if (botInfo->description != desc) {
|
|
|
|
botInfo->description = desc;
|
2019-06-12 13:26:04 +00:00
|
|
|
botInfo->text = Ui::Text::String(st::msgMinWidth);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
2022-05-14 21:27:21 +00:00
|
|
|
|
2022-06-14 15:16:18 +00:00
|
|
|
auto commands = d.vcommands()
|
|
|
|
? ranges::views::all(
|
|
|
|
d.vcommands()->v
|
|
|
|
) | ranges::views::transform(
|
|
|
|
Data::BotCommandFromTL
|
|
|
|
) | ranges::to_vector
|
|
|
|
: std::vector<Data::BotCommand>();
|
2022-05-14 21:27:21 +00:00
|
|
|
const auto changedCommands = !ranges::equal(
|
2021-07-01 11:05:15 +00:00
|
|
|
botInfo->commands,
|
2022-05-14 21:27:21 +00:00
|
|
|
commands);
|
|
|
|
botInfo->commands = std::move(commands);
|
|
|
|
|
2022-04-11 08:16:34 +00:00
|
|
|
const auto changedButton = Data::ApplyBotMenuButton(
|
|
|
|
botInfo.get(),
|
|
|
|
d.vmenu_button());
|
2019-01-04 11:09:48 +00:00
|
|
|
botInfo->inited = true;
|
|
|
|
|
2022-04-07 12:16:43 +00:00
|
|
|
if (changedCommands || changedButton) {
|
2020-06-10 18:08:17 +00:00
|
|
|
owner().botCommandsChanged(this);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::setNameOrPhone(const QString &newNameOrPhone) {
|
2022-08-09 11:12:19 +00:00
|
|
|
nameOrPhone = newNameOrPhone;
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::madeAction(TimeId when) {
|
2019-03-12 10:36:33 +00:00
|
|
|
if (isBot() || isServiceUser() || when <= 0) {
|
|
|
|
return;
|
|
|
|
} else if (onlineTill <= 0 && -onlineTill < when) {
|
2019-03-15 12:09:05 +00:00
|
|
|
onlineTill = -when - kSetOnlineAfterActivity;
|
2020-06-12 12:12:34 +00:00
|
|
|
session().changes().peerUpdated(this, UpdateFlag::OnlineStatus);
|
2019-01-04 11:09:48 +00:00
|
|
|
} else if (onlineTill > 0 && onlineTill < when + 1) {
|
2019-03-15 12:09:05 +00:00
|
|
|
onlineTill = when + kSetOnlineAfterActivity;
|
2020-06-12 12:12:34 +00:00
|
|
|
session().changes().peerUpdated(this, UpdateFlag::OnlineStatus);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::setAccessHash(uint64 accessHash) {
|
|
|
|
if (accessHash == kInaccessibleAccessHashOld) {
|
|
|
|
_accessHash = 0;
|
2021-07-08 11:19:12 +00:00
|
|
|
_flags.add(Flag::Deleted);
|
2019-01-04 11:09:48 +00:00
|
|
|
} else {
|
|
|
|
_accessHash = accessHash;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-01 14:51:18 +00:00
|
|
|
void UserData::setFlags(UserDataFlags which) {
|
|
|
|
_flags.set((flags() & UserDataFlag::Self)
|
|
|
|
| (which & ~UserDataFlag::Self));
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::addFlags(UserDataFlags which) {
|
|
|
|
_flags.add(which & ~UserDataFlag::Self);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserData::removeFlags(UserDataFlags which) {
|
|
|
|
_flags.remove(which & ~UserDataFlag::Self);
|
|
|
|
}
|
|
|
|
|
2022-05-16 11:38:35 +00:00
|
|
|
bool UserData::isVerified() const {
|
|
|
|
return flags() & UserDataFlag::Verified;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::isScam() const {
|
|
|
|
return flags() & UserDataFlag::Scam;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::isFake() const {
|
|
|
|
return flags() & UserDataFlag::Fake;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::isPremium() const {
|
|
|
|
return flags() & UserDataFlag::Premium;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::isBotInlineGeo() const {
|
|
|
|
return flags() & UserDataFlag::BotInlineGeo;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::isBot() const {
|
|
|
|
return botInfo != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::isSupport() const {
|
|
|
|
return flags() & UserDataFlag::Support;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::isInaccessible() const {
|
|
|
|
return flags() & UserDataFlag::Deleted;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::canWrite() const {
|
|
|
|
// Duplicated in Data::CanWriteValue().
|
|
|
|
return !isInaccessible() && !isRepliesChat();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::applyMinPhoto() const {
|
|
|
|
return !(flags() & UserDataFlag::DiscardMinPhoto);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::canAddContact() const {
|
|
|
|
return canShareThisContact() && !isContact();
|
|
|
|
}
|
|
|
|
|
2022-07-03 14:56:12 +00:00
|
|
|
bool UserData::canReceiveGifts() const {
|
|
|
|
return flags() & UserDataFlag::CanReceiveGifts;
|
|
|
|
}
|
|
|
|
|
2022-07-14 19:25:04 +00:00
|
|
|
bool UserData::canReceiveVoices() const {
|
2022-07-31 06:46:33 +00:00
|
|
|
return !(flags() & UserDataFlag::VoiceMessagesForbidden);
|
2022-07-14 19:25:04 +00:00
|
|
|
}
|
|
|
|
|
2022-05-16 11:38:35 +00:00
|
|
|
bool UserData::canShareThisContactFast() const {
|
|
|
|
return !_phone.isEmpty();
|
|
|
|
}
|
|
|
|
|
2022-10-14 15:49:40 +00:00
|
|
|
QString UserData::username() const {
|
|
|
|
return _username.username();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString UserData::editableUsername() const {
|
|
|
|
return _username.editableUsername();;
|
2022-10-05 11:32:16 +00:00
|
|
|
}
|
|
|
|
|
2022-10-09 11:25:47 +00:00
|
|
|
const std::vector<QString> &UserData::usernames() const {
|
2022-10-14 15:49:40 +00:00
|
|
|
return _username.usernames();
|
2022-10-09 11:25:47 +00:00
|
|
|
}
|
|
|
|
|
2022-05-16 11:38:35 +00:00
|
|
|
const QString &UserData::phone() const {
|
|
|
|
return _phone;
|
|
|
|
}
|
|
|
|
|
|
|
|
UserData::ContactStatus UserData::contactStatus() const {
|
|
|
|
return _contactStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::isContact() const {
|
|
|
|
return (contactStatus() == ContactStatus::Contact);
|
|
|
|
}
|
|
|
|
|
|
|
|
UserData::CallsStatus UserData::callsStatus() const {
|
|
|
|
return _callsStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
int UserData::commonChatsCount() const {
|
|
|
|
return _commonChatsCount;
|
|
|
|
}
|
|
|
|
|
2019-01-04 11:09:48 +00:00
|
|
|
void UserData::setCallsStatus(CallsStatus callsStatus) {
|
|
|
|
if (callsStatus != _callsStatus) {
|
|
|
|
_callsStatus = callsStatus;
|
2020-06-12 12:12:34 +00:00
|
|
|
session().changes().peerUpdated(this, UpdateFlag::HasCalls);
|
2019-01-04 11:09:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UserData::hasCalls() const {
|
|
|
|
return (callsStatus() != CallsStatus::Disabled)
|
|
|
|
&& (callsStatus() != CallsStatus::Unknown);
|
|
|
|
}
|
2019-04-23 09:40:14 +00:00
|
|
|
|
|
|
|
namespace Data {
|
|
|
|
|
|
|
|
void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
|
2019-07-05 13:38:38 +00:00
|
|
|
if (const auto photo = update.vprofile_photo()) {
|
|
|
|
user->owner().processPhoto(*photo);
|
2019-04-23 09:40:14 +00:00
|
|
|
}
|
2021-07-08 14:30:27 +00:00
|
|
|
user->setSettings(update.vsettings());
|
2022-10-13 17:34:04 +00:00
|
|
|
user->owner().notifySettings().apply(user, update.vnotify_settings());
|
2019-04-23 09:40:14 +00:00
|
|
|
|
2021-02-15 10:31:04 +00:00
|
|
|
user->setMessagesTTL(update.vttl_period().value_or_empty());
|
2019-07-05 13:38:38 +00:00
|
|
|
if (const auto info = update.vbot_info()) {
|
|
|
|
user->setBotInfo(*info);
|
2019-04-23 09:40:14 +00:00
|
|
|
} else {
|
|
|
|
user->setBotInfoVersion(-1);
|
|
|
|
}
|
2019-07-05 13:38:38 +00:00
|
|
|
if (const auto pinned = update.vpinned_msg_id()) {
|
2022-10-28 05:19:27 +00:00
|
|
|
SetTopPinnedMessageId(user, pinned->v);
|
2019-04-23 09:40:14 +00:00
|
|
|
}
|
2022-07-03 14:56:12 +00:00
|
|
|
const auto canReceiveGifts = (update.vflags().v
|
|
|
|
& MTPDuserFull::Flag::f_premium_gifts)
|
|
|
|
&& update.vpremium_gifts();
|
2021-07-08 11:19:12 +00:00
|
|
|
using Flag = UserDataFlag;
|
|
|
|
const auto mask = Flag::Blocked
|
|
|
|
| Flag::HasPhoneCalls
|
|
|
|
| Flag::PhoneCallsPrivate
|
2022-07-03 14:56:12 +00:00
|
|
|
| Flag::CanReceiveGifts
|
2022-08-06 10:16:36 +00:00
|
|
|
| Flag::CanPinMessages
|
|
|
|
| Flag::VoiceMessagesForbidden;
|
2021-07-08 11:19:12 +00:00
|
|
|
user->setFlags((user->flags() & ~mask)
|
|
|
|
| (update.is_phone_calls_private() ? Flag::PhoneCallsPrivate : Flag())
|
|
|
|
| (update.is_phone_calls_available() ? Flag::HasPhoneCalls : Flag())
|
2022-07-03 14:56:12 +00:00
|
|
|
| (canReceiveGifts ? Flag::CanReceiveGifts : Flag())
|
2021-07-08 11:19:12 +00:00
|
|
|
| (update.is_can_pin_message() ? Flag::CanPinMessages : Flag())
|
2022-07-14 19:25:04 +00:00
|
|
|
| (update.is_blocked() ? Flag::Blocked : Flag())
|
2022-07-31 06:46:33 +00:00
|
|
|
| (update.is_voice_messages_forbidden()
|
|
|
|
? Flag::VoiceMessagesForbidden
|
2022-07-14 19:25:04 +00:00
|
|
|
: Flag()));
|
2019-06-07 11:32:58 +00:00
|
|
|
user->setIsBlocked(update.is_blocked());
|
2019-04-23 09:40:14 +00:00
|
|
|
user->setCallsStatus(update.is_phone_calls_private()
|
|
|
|
? UserData::CallsStatus::Private
|
|
|
|
: update.is_phone_calls_available()
|
|
|
|
? UserData::CallsStatus::Enabled
|
|
|
|
: UserData::CallsStatus::Disabled);
|
2019-07-05 13:38:38 +00:00
|
|
|
user->setAbout(qs(update.vabout().value_or_empty()));
|
|
|
|
user->setCommonChatsCount(update.vcommon_chats_count().v);
|
|
|
|
user->checkFolder(update.vfolder_id().value_or_empty());
|
2021-08-25 16:16:50 +00:00
|
|
|
user->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
|
2022-03-23 10:15:52 +00:00
|
|
|
|
|
|
|
if (const auto info = user->botInfo.get()) {
|
|
|
|
const auto group = update.vbot_group_admin_rights()
|
|
|
|
? ChatAdminRightsInfo(*update.vbot_group_admin_rights()).flags
|
|
|
|
: ChatAdminRights();
|
|
|
|
const auto channel = update.vbot_broadcast_admin_rights()
|
|
|
|
? ChatAdminRightsInfo(
|
|
|
|
*update.vbot_broadcast_admin_rights()).flags
|
|
|
|
: ChatAdminRights();
|
|
|
|
if (info->groupAdminRights != group
|
|
|
|
|| info->channelAdminRights != channel) {
|
|
|
|
info->groupAdminRights = group;
|
|
|
|
info->channelAdminRights = channel;
|
|
|
|
user->session().changes().peerUpdated(
|
|
|
|
user,
|
|
|
|
Data::PeerUpdate::Flag::Rights);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-23 09:40:14 +00:00
|
|
|
user->fullUpdated();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Data
|