| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852 |
- /*
- 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 "api/api_credits.h"
- #include "api/api_sensitive_content.h"
- #include "api/api_statistics.h"
- #include "storage/localstorage.h"
- #include "storage/storage_account.h"
- #include "storage/storage_user_photos.h"
- #include "main/main_session.h"
- #include "data/business/data_business_common.h"
- #include "data/business/data_business_info.h"
- #include "data/components/credits.h"
- #include "data/data_session.h"
- #include "data/data_changes.h"
- #include "data/data_peer_bot_command.h"
- #include "data/data_photo.h"
- #include "data/data_stories.h"
- #include "data/data_wall_paper.h"
- #include "data/notify/data_notify_settings.h"
- #include "history/history.h"
- #include "api/api_peer_photo.h"
- #include "apiwrap.h"
- #include "lang/lang_keys.h"
- #include "styles/style_chat.h"
- namespace {
- // User with hidden last seen stays online in UI for such amount of seconds.
- constexpr auto kSetOnlineAfterActivity = TimeId(30);
- using UpdateFlag = Data::PeerUpdate::Flag;
- bool ApplyBotVerifierSettings(
- not_null<BotInfo*> info,
- const MTPBotVerifierSettings *settings) {
- if (!settings) {
- const auto taken = base::take(info->verifierSettings);
- return taken != nullptr;
- }
- const auto &data = settings->data();
- const auto parsed = BotVerifierSettings{
- .iconId = DocumentId(data.vicon().v),
- .company = qs(data.vcompany()),
- .customDescription = qs(data.vcustom_description().value_or_empty()),
- .canModifyDescription = data.is_can_modify_custom_description(),
- };
- if (!info->verifierSettings) {
- info->verifierSettings = std::make_unique<BotVerifierSettings>(
- parsed);
- return true;
- } else if (*info->verifierSettings != parsed) {
- *info->verifierSettings = parsed;
- return true;
- }
- return false;
- }
- } // namespace
- BotInfo::BotInfo() = default;
- Data::LastseenStatus LastseenFromMTP(
- const MTPUserStatus &status,
- Data::LastseenStatus currentStatus) {
- return status.match([](const MTPDuserStatusEmpty &data) {
- return Data::LastseenStatus::LongAgo();
- }, [&](const MTPDuserStatusRecently &data) {
- return currentStatus.isLocalOnlineValue()
- ? Data::LastseenStatus::OnlineTill(
- currentStatus.onlineTill(),
- true,
- data.is_by_me())
- : Data::LastseenStatus::Recently(data.is_by_me());
- }, [](const MTPDuserStatusLastWeek &data) {
- return Data::LastseenStatus::WithinWeek(data.is_by_me());
- }, [](const MTPDuserStatusLastMonth &data) {
- return Data::LastseenStatus::WithinMonth(data.is_by_me());
- }, [](const MTPDuserStatusOnline& data) {
- return Data::LastseenStatus::OnlineTill(data.vexpires().v);
- }, [](const MTPDuserStatusOffline &data) {
- return Data::LastseenStatus::OnlineTill(data.vwas_online().v);
- });
- }
- UserData::UserData(not_null<Data::Session*> owner, PeerId id)
- : PeerData(owner, id)
- , _flags((id == owner->session().userPeerId()) ? Flag::Self : Flag(0)) {
- }
- UserData::~UserData() = default;
- bool UserData::canShareThisContact() const {
- return canShareThisContactFast()
- || !owner().findContactPhone(peerToUser(id)).isEmpty();
- }
- void UserData::setIsContact(bool is) {
- const auto status = is
- ? ContactStatus::Contact
- : ContactStatus::NotContact;
- if (_contactStatus != status) {
- _contactStatus = status;
- session().changes().peerUpdated(this, UpdateFlag::IsContact);
- }
- }
- Data::LastseenStatus UserData::lastseen() const {
- return _lastseen;
- }
- bool UserData::updateLastseen(Data::LastseenStatus value) {
- if (_lastseen == value) {
- return false;
- }
- _lastseen = value;
- owner().maybeStopWatchForOffline(this);
- return true;
- }
- // see Serialize::readPeer as well
- void UserData::setPhoto(const MTPUserProfilePhoto &photo) {
- photo.match([&](const MTPDuserProfilePhoto &data) {
- if (data.is_personal()) {
- addFlags(UserDataFlag::PersonalPhoto);
- } else {
- removeFlags(UserDataFlag::PersonalPhoto);
- }
- updateUserpic(
- data.vphoto_id().v,
- data.vdc_id().v,
- data.is_has_video());
- }, [&](const MTPDuserProfilePhotoEmpty &) {
- removeFlags(UserDataFlag::PersonalPhoto);
- clearUserpic();
- });
- }
- auto UserData::unavailableReasons() const
- -> const std::vector<Data::UnavailableReason> & {
- return _unavailableReasons;
- }
- void UserData::setUnavailableReasonsList(
- std::vector<Data::UnavailableReason> &&reasons) {
- _unavailableReasons = std::move(reasons);
- }
- void UserData::setCommonChatsCount(int count) {
- if (_commonChatsCount != count) {
- _commonChatsCount = count;
- session().changes().peerUpdated(this, UpdateFlag::CommonChats);
- }
- }
- int UserData::peerGiftsCount() const {
- return _peerGiftsCount;
- }
- void UserData::setPeerGiftsCount(int count) {
- if (_peerGiftsCount != count) {
- _peerGiftsCount = count;
- session().changes().peerUpdated(this, UpdateFlag::PeerGifts);
- }
- }
- bool UserData::hasPrivateForwardName() const {
- return !_privateForwardName.isEmpty();
- }
- QString UserData::privateForwardName() const {
- return _privateForwardName;
- }
- void UserData::setPrivateForwardName(const QString &name) {
- _privateForwardName = name;
- }
- bool UserData::hasActiveStories() const {
- return flags() & Flag::HasActiveStories;
- }
- bool UserData::hasUnreadStories() const {
- return flags() & Flag::HasUnreadStories;
- }
- void UserData::setStoriesState(StoriesState state) {
- Expects(state != StoriesState::Unknown);
- const auto was = flags();
- switch (state) {
- case StoriesState::None:
- _flags.remove(Flag::HasActiveStories | Flag::HasUnreadStories);
- break;
- case StoriesState::HasRead:
- _flags.set(
- (flags() & ~Flag::HasUnreadStories) | Flag::HasActiveStories);
- break;
- case StoriesState::HasUnread:
- _flags.add(Flag::HasActiveStories | Flag::HasUnreadStories);
- break;
- }
- if (flags() != was) {
- if (const auto history = owner().historyLoaded(this)) {
- history->updateChatListEntryPostponed();
- }
- session().changes().peerUpdated(this, UpdateFlag::StoriesState);
- }
- }
- const Data::BusinessDetails &UserData::businessDetails() const {
- static const auto empty = Data::BusinessDetails();
- return _businessDetails ? *_businessDetails : empty;
- }
- void UserData::setBusinessDetails(Data::BusinessDetails details) {
- details.hours = details.hours.normalized();
- if ((!details && !_businessDetails)
- || (details && _businessDetails && details == *_businessDetails)) {
- return;
- }
- _businessDetails = details
- ? std::make_unique<Data::BusinessDetails>(std::move(details))
- : nullptr;
- session().changes().peerUpdated(this, UpdateFlag::BusinessDetails);
- }
- void UserData::setStarRefProgram(StarRefProgram program) {
- const auto info = botInfo.get();
- if (info && info->starRefProgram != program) {
- info->starRefProgram = program;
- session().changes().peerUpdated(
- this,
- Data::PeerUpdate::Flag::StarRefProgram);
- }
- }
- ChannelId UserData::personalChannelId() const {
- return _personalChannelId;
- }
- MsgId UserData::personalChannelMessageId() const {
- return _personalChannelMessageId;
- }
- void UserData::setPersonalChannel(ChannelId channelId, MsgId messageId) {
- if (_personalChannelId != channelId
- || _personalChannelMessageId != messageId) {
- _personalChannelId = channelId;
- _personalChannelMessageId = messageId;
- session().changes().peerUpdated(this, UpdateFlag::PersonalChannel);
- }
- }
- 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;
- }
- newFullName = lastName.isEmpty()
- ? firstName
- : tr::lng_full_name(
- tr::now,
- lt_first_name,
- firstName,
- lt_last_name,
- lastName);
- }
- updateNameDelayed(newFullName, newPhoneName, newUsername);
- }
- 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()));
- }
- void UserData::setUsername(const QString &username) {
- _username.setUsername(username);
- }
- void UserData::setPhone(const QString &newPhone) {
- if (_phone != newPhone) {
- _phone = newPhone;
- }
- }
- void UserData::setBotInfoVersion(int version) {
- if (version < 0) {
- // We don't support bots becoming non-bots.
- if (botInfo) {
- botInfo->version = -1;
- }
- } else if (!botInfo) {
- botInfo = std::make_unique<BotInfo>();
- botInfo->version = version;
- owner().userIsBotChanged(this);
- } else if (botInfo->version < version) {
- if (!botInfo->commands.empty()) {
- botInfo->commands.clear();
- owner().botCommandsChanged(this);
- }
- botInfo->description.clear();
- botInfo->version = version;
- botInfo->inited = false;
- }
- }
- void UserData::setBotInfo(const MTPBotInfo &info) {
- switch (info.type()) {
- case mtpc_botInfo: {
- const auto &d = info.c_botInfo();
- if (!isBot()) {
- return;
- } else if (d.vuser_id() && peerFromUser(*d.vuser_id()) != id) {
- return;
- }
- const auto description = qs(d.vdescription().value_or_empty());
- if (botInfo->description != description) {
- botInfo->description = description;
- ++botInfo->descriptionVersion;
- }
- if (const auto photo = d.vdescription_photo()) {
- const auto parsed = owner().processPhoto(*photo);
- if (botInfo->photo != parsed) {
- botInfo->photo = parsed;
- ++botInfo->descriptionVersion;
- }
- } else if (botInfo->photo) {
- botInfo->photo = nullptr;
- ++botInfo->descriptionVersion;
- }
- if (const auto document = d.vdescription_document()) {
- const auto parsed = owner().processDocument(*document);
- if (botInfo->document != parsed) {
- botInfo->document = parsed;
- ++botInfo->descriptionVersion;
- }
- } else if (botInfo->document) {
- botInfo->document = nullptr;
- ++botInfo->descriptionVersion;
- }
- auto commands = d.vcommands()
- ? ranges::views::all(
- d.vcommands()->v
- ) | ranges::views::transform(
- Data::BotCommandFromTL
- ) | ranges::to_vector
- : std::vector<Data::BotCommand>();
- const auto changedCommands = !ranges::equal(
- botInfo->commands,
- commands);
- botInfo->commands = std::move(commands);
- const auto changedButton = Data::ApplyBotMenuButton(
- botInfo.get(),
- d.vmenu_button());
- botInfo->inited = true;
- const auto privacy = qs(d.vprivacy_policy_url().value_or_empty());
- const auto privacyChanged = (botInfo->privacyPolicyUrl != privacy);
- botInfo->privacyPolicyUrl = privacy;
- if (const auto settings = d.vapp_settings()) {
- const auto &data = settings->data();
- botInfo->botAppColorTitleDay = Ui::MaybeColorFromSerialized(
- data.vheader_color()).value_or(QColor(0, 0, 0, 0));
- botInfo->botAppColorTitleNight = Ui::MaybeColorFromSerialized(
- data.vheader_dark_color()).value_or(QColor(0, 0, 0, 0));
- botInfo->botAppColorBodyDay = Ui::MaybeColorFromSerialized(
- data.vbackground_color()).value_or(QColor(0, 0, 0, 0));
- botInfo->botAppColorBodyNight = Ui::MaybeColorFromSerialized(
- data.vbackground_dark_color()).value_or(QColor(0, 0, 0, 0));
- } else {
- botInfo->botAppColorTitleDay
- = botInfo->botAppColorTitleNight
- = botInfo->botAppColorBodyDay
- = botInfo->botAppColorBodyNight
- = QColor(0, 0, 0, 0);
- }
- const auto changedVerifierSettings = ApplyBotVerifierSettings(
- botInfo.get(),
- d.vverifier_settings());
- if (changedCommands
- || changedButton
- || privacyChanged
- || changedVerifierSettings) {
- owner().botCommandsChanged(this);
- }
- } break;
- }
- }
- void UserData::setNameOrPhone(const QString &newNameOrPhone) {
- nameOrPhone = newNameOrPhone;
- }
- void UserData::madeAction(TimeId when) {
- if (isBot() || isServiceUser() || when <= 0) {
- return;
- }
- const auto till = lastseen().onlineTill();
- if (till < when + 1
- && updateLastseen(
- Data::LastseenStatus::OnlineTill(
- when + kSetOnlineAfterActivity,
- !till || lastseen().isLocalOnlineValue(),
- lastseen().isHiddenByMe()))) {
- session().changes().peerUpdated(this, UpdateFlag::OnlineStatus);
- }
- }
- void UserData::setAccessHash(uint64 accessHash) {
- if (accessHash == kInaccessibleAccessHashOld) {
- _accessHash = 0;
- _flags.add(Flag::Deleted);
- invalidateEmptyUserpic();
- } else {
- _accessHash = accessHash;
- }
- }
- void UserData::setFlags(UserDataFlags which) {
- if ((which & UserDataFlag::Deleted)
- != (flags() & UserDataFlag::Deleted)) {
- invalidateEmptyUserpic();
- }
- _flags.set((flags() & UserDataFlag::Self)
- | (which & ~UserDataFlag::Self));
- }
- void UserData::addFlags(UserDataFlags which) {
- setFlags(flags() | which);
- }
- void UserData::removeFlags(UserDataFlags which) {
- setFlags(flags() & ~which);
- }
- 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::applyMinPhoto() const {
- return !(flags() & UserDataFlag::DiscardMinPhoto);
- }
- bool UserData::hasPersonalPhoto() const {
- return (flags() & UserDataFlag::PersonalPhoto);
- }
- bool UserData::hasStoriesHidden() const {
- return (flags() & UserDataFlag::StoriesHidden);
- }
- bool UserData::hasRequirePremiumToWrite() const {
- return (flags() & UserDataFlag::HasRequirePremiumToWrite);
- }
- bool UserData::hasStarsPerMessage() const {
- return (flags() & UserDataFlag::HasStarsPerMessage);
- }
- bool UserData::requiresPremiumToWrite() const {
- return !isSelf() && (flags() & UserDataFlag::RequiresPremiumToWrite);
- }
- bool UserData::messageMoneyRestrictionsKnown() const {
- return (flags() & UserDataFlag::MessageMoneyRestrictionsKnown);
- }
- bool UserData::canSendIgnoreMoneyRestrictions() const {
- return !isInaccessible() && !isRepliesChat() && !isVerifyCodes();
- }
- bool UserData::readDatesPrivate() const {
- return (flags() & UserDataFlag::ReadDatesPrivate);
- }
- int UserData::starsPerMessage() const {
- return _starsPerMessage;
- }
- void UserData::setStarsPerMessage(int stars) {
- if (_starsPerMessage != stars) {
- _starsPerMessage = stars;
- session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
- }
- checkTrustedPayForMessage();
- }
- bool UserData::canAddContact() const {
- return canShareThisContact() && !isContact();
- }
- bool UserData::canShareThisContactFast() const {
- return !_phone.isEmpty();
- }
- QString UserData::username() const {
- return _username.username();
- }
- QString UserData::editableUsername() const {
- return _username.editableUsername();
- }
- const std::vector<QString> &UserData::usernames() const {
- return _username.usernames();
- }
- bool UserData::isUsernameEditable(QString username) const {
- return _username.isEditable(username);
- }
- void UserData::setBotVerifyDetails(Ui::BotVerifyDetails details) {
- if (!details) {
- if (_botVerifyDetails) {
- _botVerifyDetails = nullptr;
- session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
- }
- } else if (!_botVerifyDetails) {
- _botVerifyDetails = std::make_unique<Ui::BotVerifyDetails>(details);
- session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
- } else if (*_botVerifyDetails != details) {
- *_botVerifyDetails = details;
- session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
- }
- }
- void UserData::setBotVerifyDetailsIcon(DocumentId iconId) {
- if (!iconId) {
- setBotVerifyDetails({});
- } else {
- auto info = _botVerifyDetails
- ? *_botVerifyDetails
- : Ui::BotVerifyDetails();
- info.iconId = iconId;
- setBotVerifyDetails(info);
- }
- }
- 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;
- }
- void UserData::setCallsStatus(CallsStatus callsStatus) {
- if (callsStatus != _callsStatus) {
- _callsStatus = callsStatus;
- session().changes().peerUpdated(this, UpdateFlag::HasCalls);
- }
- }
- Data::Birthday UserData::birthday() const {
- return _birthday;
- }
- void UserData::setBirthday(Data::Birthday value) {
- if (_birthday != value) {
- _birthday = value;
- session().changes().peerUpdated(this, UpdateFlag::Birthday);
- if (isSelf()) {
- session().api().sensitiveContent().reload(true);
- }
- }
- }
- void UserData::setBirthday(const tl::conditional<MTPBirthday> &value) {
- if (!value) {
- setBirthday(Data::Birthday());
- } else {
- const auto &data = value->data();
- setBirthday(Data::Birthday(
- data.vday().v,
- data.vmonth().v,
- data.vyear().value_or_empty()));
- }
- }
- bool UserData::hasCalls() const {
- return (callsStatus() != CallsStatus::Disabled)
- && (callsStatus() != CallsStatus::Unknown);
- }
- namespace Data {
- void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
- const auto profilePhoto = update.vprofile_photo()
- ? user->owner().processPhoto(*update.vprofile_photo()).get()
- : nullptr;
- const auto personalPhoto = update.vpersonal_photo()
- ? user->owner().processPhoto(*update.vpersonal_photo()).get()
- : nullptr;
- if (personalPhoto && profilePhoto) {
- user->session().api().peerPhoto().registerNonPersonalPhoto(
- user,
- profilePhoto);
- } else {
- user->session().api().peerPhoto().unregisterNonPersonalPhoto(user);
- }
- if (const auto photo = update.vfallback_photo()) {
- const auto data = user->owner().processPhoto(*photo);
- if (!data->isNull()) { // Sometimes there is photoEmpty :shrug:
- user->session().storage().add(Storage::UserPhotosSetBack(
- peerToUser(user->id),
- data->id
- ));
- }
- }
- user->setBarSettings(update.vsettings());
- user->owner().notifySettings().apply(user, update.vnotify_settings());
- user->setMessagesTTL(update.vttl_period().value_or_empty());
- if (const auto info = update.vbot_info()) {
- user->setBotInfo(*info);
- } else {
- user->setBotInfoVersion(-1);
- }
- if (const auto info = user->botInfo.get()) {
- info->canManageEmojiStatus = update.is_bot_can_manage_emoji_status();
- user->setStarRefProgram(
- Data::ParseStarRefProgram(update.vstarref_program()));
- }
- if (const auto pinned = update.vpinned_msg_id()) {
- SetTopPinnedMessageId(user, pinned->v);
- }
- user->setStarsPerMessage(
- update.vsend_paid_messages_stars().value_or_empty());
- using Flag = UserDataFlag;
- const auto mask = Flag::Blocked
- | Flag::HasPhoneCalls
- | Flag::PhoneCallsPrivate
- | Flag::CanPinMessages
- | Flag::VoiceMessagesForbidden
- | Flag::ReadDatesPrivate
- | Flag::MessageMoneyRestrictionsKnown
- | Flag::RequiresPremiumToWrite;
- user->setFlags((user->flags() & ~mask)
- | (update.is_phone_calls_private()
- ? Flag::PhoneCallsPrivate
- : Flag())
- | (update.is_phone_calls_available() ? Flag::HasPhoneCalls : Flag())
- | (update.is_can_pin_message() ? Flag::CanPinMessages : Flag())
- | (update.is_blocked() ? Flag::Blocked : Flag())
- | (update.is_voice_messages_forbidden()
- ? Flag::VoiceMessagesForbidden
- : Flag())
- | (update.is_read_dates_private() ? Flag::ReadDatesPrivate : Flag())
- | Flag::MessageMoneyRestrictionsKnown
- | (update.is_contact_require_premium()
- ? Flag::RequiresPremiumToWrite
- : Flag()));
- user->setIsBlocked(update.is_blocked());
- user->setCallsStatus(update.is_phone_calls_private()
- ? UserData::CallsStatus::Private
- : update.is_phone_calls_available()
- ? UserData::CallsStatus::Enabled
- : UserData::CallsStatus::Disabled);
- user->setAbout(qs(update.vabout().value_or_empty()));
- user->setCommonChatsCount(update.vcommon_chats_count().v);
- user->setPeerGiftsCount(update.vstargifts_count().value_or_empty());
- user->checkFolder(update.vfolder_id().value_or_empty());
- user->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
- user->setTranslationDisabled(update.is_translations_disabled());
- user->setPrivateForwardName(
- update.vprivate_forward_name().value_or_empty());
- 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);
- }
- if (info->canEditInformation) {
- const auto id = user->id;
- const auto weak = base::make_weak(&user->session());
- const auto creditsLoadLifetime
- = std::make_shared<rpl::lifetime>();
- const auto creditsLoad
- = creditsLoadLifetime->make_state<Api::CreditsStatus>(user);
- creditsLoad->request({}, [=](Data::CreditsStatusSlice slice) {
- if (const auto strong = weak.get()) {
- strong->credits().apply(id, slice.balance);
- creditsLoadLifetime->destroy();
- }
- });
- const auto currencyLoadLifetime
- = std::make_shared<rpl::lifetime>();
- const auto currencyLoad
- = currencyLoadLifetime->make_state<Api::EarnStatistics>(user);
- currencyLoad->request(
- ) | rpl::start_with_error_done([=](const QString &error) {
- currencyLoadLifetime->destroy();
- }, [=] {
- if (const auto strong = weak.get()) {
- strong->credits().applyCurrency(
- id,
- currencyLoad->data().currentBalance);
- currencyLoadLifetime->destroy();
- }
- }, *currencyLoadLifetime);
- }
- }
- if (const auto paper = update.vwallpaper()) {
- user->setWallPaper(
- Data::WallPaper::Create(&user->session(), *paper),
- update.is_wallpaper_overridden());
- } else {
- user->setWallPaper({});
- }
- user->setBusinessDetails(FromMTP(
- &user->owner(),
- update.vbusiness_work_hours(),
- update.vbusiness_location(),
- update.vbusiness_intro()));
- user->setBirthday(update.vbirthday());
- user->setPersonalChannel(
- update.vpersonal_channel_id().value_or_empty(),
- update.vpersonal_channel_message().value_or_empty());
- if (user->isSelf()) {
- user->owner().businessInfo().applyAwaySettings(
- FromMTP(&user->owner(), update.vbusiness_away_message()));
- user->owner().businessInfo().applyGreetingSettings(
- FromMTP(&user->owner(), update.vbusiness_greeting_message()));
- }
- user->setBotVerifyDetails(
- ParseBotVerifyDetails(update.vbot_verification()));
- user->owner().stories().apply(user, update.vstories());
- user->fullUpdated();
- }
- StarRefProgram ParseStarRefProgram(const MTPStarRefProgram *program) {
- if (!program) {
- return {};
- }
- auto result = StarRefProgram();
- const auto &data = program->data();
- result.commission = data.vcommission_permille().v;
- result.durationMonths = data.vduration_months().value_or_empty();
- result.revenuePerUser = data.vdaily_revenue_per_user()
- ? Data::FromTL(*data.vdaily_revenue_per_user())
- : StarsAmount();
- result.endDate = data.vend_date().value_or_empty();
- return result;
- }
- Ui::BotVerifyDetails ParseBotVerifyDetails(const MTPBotVerification *info) {
- if (!info) {
- return {};
- }
- const auto &data = info->data();
- const auto description = qs(data.vdescription());
- const auto flags = TextParseLinks;
- return {
- .botId = UserId(data.vbot_id().v),
- .iconId = DocumentId(data.vicon().v),
- .description = TextUtilities::ParseEntities(description, flags),
- };
- }
- } // namespace Data
|