2017-09-25 09:02:55 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
2018-01-03 10:23:14 +00:00
|
|
|
the official desktop application for the Telegram messaging service.
|
2017-09-25 09:02:55 +00:00
|
|
|
|
2018-01-03 10:23:14 +00:00
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
2017-09-25 09:02:55 +00:00
|
|
|
*/
|
|
|
|
#include "info/profile/info_profile_values.h"
|
|
|
|
|
2019-01-21 13:42:21 +00:00
|
|
|
#include "core/application.h"
|
2020-11-02 06:34:54 +00:00
|
|
|
#include "core/click_handler_types.h"
|
2022-04-17 12:55:44 +00:00
|
|
|
#include "countries/countries_instance.h"
|
2019-07-24 11:45:24 +00:00
|
|
|
#include "main/main_session.h"
|
2017-09-25 09:02:55 +00:00
|
|
|
#include "ui/wrap/slide_wrap.h"
|
2021-07-26 06:32:16 +00:00
|
|
|
#include "ui/text/format_values.h" // Ui::FormatPhone
|
2019-06-18 12:16:43 +00:00
|
|
|
#include "ui/text/text_utilities.h"
|
2019-07-04 10:07:32 +00:00
|
|
|
#include "lang/lang_keys.h"
|
2022-04-01 10:18:07 +00:00
|
|
|
#include "data/notify/data_notify_settings.h"
|
2017-10-22 17:06:57 +00:00
|
|
|
#include "data/data_peer_values.h"
|
2017-11-06 07:31:18 +00:00
|
|
|
#include "data/data_shared_media.h"
|
2021-12-13 11:26:19 +00:00
|
|
|
#include "data/data_message_reactions.h"
|
2019-04-15 11:54:03 +00:00
|
|
|
#include "data/data_folder.h"
|
2020-06-12 12:12:34 +00:00
|
|
|
#include "data/data_changes.h"
|
2019-01-04 11:09:48 +00:00
|
|
|
#include "data/data_channel.h"
|
|
|
|
#include "data/data_chat.h"
|
|
|
|
#include "data/data_user.h"
|
2018-02-07 12:40:37 +00:00
|
|
|
#include "data/data_session.h"
|
2019-03-15 08:20:12 +00:00
|
|
|
#include "boxes/peers/edit_peer_permissions_box.h"
|
2022-05-30 14:30:51 +00:00
|
|
|
#include "boxes/premium_limits_box.h"
|
2022-03-15 11:12:49 +00:00
|
|
|
#include "base/unixtime.h"
|
2019-03-15 08:20:12 +00:00
|
|
|
|
2017-09-25 09:02:55 +00:00
|
|
|
namespace Info {
|
|
|
|
namespace Profile {
|
2019-07-04 10:07:32 +00:00
|
|
|
namespace {
|
|
|
|
|
2020-06-12 12:12:34 +00:00
|
|
|
using UpdateFlag = Data::PeerUpdate::Flag;
|
|
|
|
|
2020-10-29 16:53:07 +00:00
|
|
|
auto PlainAboutValue(not_null<PeerData*> peer) {
|
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::About
|
|
|
|
) | rpl::map([=] {
|
2020-10-29 16:53:07 +00:00
|
|
|
return peer->about();
|
2020-06-12 12:12:34 +00:00
|
|
|
});
|
2019-07-04 10:07:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto PlainUsernameValue(not_null<PeerData*> peer) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
2019-07-04 10:07:32 +00:00
|
|
|
peer,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::Username
|
2019-07-04 10:07:32 +00:00
|
|
|
) | rpl::map([=] {
|
|
|
|
return peer->userName();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-10-29 16:53:07 +00:00
|
|
|
void StripExternalLinks(TextWithEntities &text) {
|
|
|
|
const auto local = [](const QString &url) {
|
2020-11-02 06:34:54 +00:00
|
|
|
return !UrlRequiresConfirmation(QUrl::fromUserInput(url));
|
2020-10-29 16:53:07 +00:00
|
|
|
};
|
|
|
|
const auto notLocal = [&](const EntityInText &entity) {
|
|
|
|
if (entity.type() == EntityType::CustomUrl) {
|
|
|
|
return !local(entity.data());
|
|
|
|
} else if (entity.type() == EntityType::Url) {
|
|
|
|
return !local(text.text.mid(entity.offset(), entity.length()));
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
text.entities.erase(
|
|
|
|
ranges::remove_if(text.entities, notLocal),
|
|
|
|
text.entities.end());
|
|
|
|
}
|
|
|
|
|
2019-07-04 10:07:32 +00:00
|
|
|
} // namespace
|
2017-09-25 09:02:55 +00:00
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
2018-09-09 17:38:08 +00:00
|
|
|
peer,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::Name
|
2018-09-09 17:38:08 +00:00
|
|
|
) | rpl::map([=] {
|
2019-09-13 06:06:02 +00:00
|
|
|
return peer->name;
|
2021-10-18 13:21:49 +00:00
|
|
|
}) | Ui::Text::ToWithEntities();
|
2018-09-09 17:38:08 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
|
2022-04-17 12:55:44 +00:00
|
|
|
return rpl::merge(
|
|
|
|
Countries::Instance().updated(),
|
|
|
|
user->session().changes().peerFlagsValue(
|
|
|
|
user,
|
|
|
|
UpdateFlag::PhoneNumber) | rpl::to_empty
|
2020-06-12 12:12:34 +00:00
|
|
|
) | rpl::map([=] {
|
2021-07-26 06:32:16 +00:00
|
|
|
return Ui::FormatPhone(user->phone());
|
2019-06-18 12:16:43 +00:00
|
|
|
}) | Ui::Text::ToWithEntities();
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2019-07-04 10:07:32 +00:00
|
|
|
rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user) {
|
|
|
|
return rpl::combine(
|
|
|
|
PhoneValue(user),
|
|
|
|
PlainUsernameValue(user),
|
2020-10-29 16:53:07 +00:00
|
|
|
PlainAboutValue(user),
|
2019-07-04 10:07:32 +00:00
|
|
|
tr::lng_info_mobile_hidden()
|
|
|
|
) | rpl::map([](
|
|
|
|
const TextWithEntities &phone,
|
|
|
|
const QString &username,
|
2020-10-29 16:53:07 +00:00
|
|
|
const QString &about,
|
2019-07-04 10:07:32 +00:00
|
|
|
const QString &hidden) {
|
2020-10-29 16:53:07 +00:00
|
|
|
return (phone.text.isEmpty() && username.isEmpty() && about.isEmpty())
|
2019-07-04 10:07:32 +00:00
|
|
|
? Ui::Text::WithEntities(hidden)
|
|
|
|
: phone;
|
|
|
|
});
|
2017-11-07 07:21:48 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
|
2017-12-22 07:05:20 +00:00
|
|
|
return PlainUsernameValue(
|
|
|
|
user
|
|
|
|
) | rpl::map([](QString &&username) {
|
|
|
|
return username.isEmpty()
|
|
|
|
? QString()
|
|
|
|
: ('@' + username);
|
2019-06-18 12:16:43 +00:00
|
|
|
}) | Ui::Text::ToWithEntities();
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-18 13:21:49 +00:00
|
|
|
TextWithEntities AboutWithEntities(
|
|
|
|
not_null<PeerData*> peer,
|
|
|
|
const QString &value) {
|
2020-10-29 16:53:07 +00:00
|
|
|
auto flags = TextParseLinks | TextParseMentions;
|
|
|
|
const auto user = peer->asUser();
|
|
|
|
const auto isBot = user && user->isBot();
|
2022-05-30 14:30:51 +00:00
|
|
|
const auto isPremium = user && user->isPremium();
|
2020-10-29 16:53:07 +00:00
|
|
|
if (!user) {
|
|
|
|
flags |= TextParseHashtags;
|
|
|
|
} else if (isBot) {
|
|
|
|
flags |= TextParseHashtags | TextParseBotCommands;
|
2017-11-17 07:42:53 +00:00
|
|
|
}
|
2020-10-29 16:53:07 +00:00
|
|
|
const auto stripExternal = peer->isChat()
|
|
|
|
|| peer->isMegagroup()
|
2022-05-30 14:30:51 +00:00
|
|
|
|| (user && !isBot && !isPremium);
|
|
|
|
const auto limit = AppConfigLimit(
|
|
|
|
&peer->session(),
|
|
|
|
"about_length_limit_default",
|
|
|
|
70);
|
|
|
|
const auto used = (!user || isPremium || value.size() <= limit)
|
|
|
|
? value
|
|
|
|
: value.mid(0, limit) + "...";
|
2021-10-18 13:21:49 +00:00
|
|
|
auto result = TextWithEntities{ value };
|
|
|
|
TextUtilities::ParseEntities(result, flags);
|
|
|
|
if (stripExternal) {
|
|
|
|
StripExternalLinks(result);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
|
2017-12-22 07:05:20 +00:00
|
|
|
return PlainAboutValue(
|
|
|
|
peer
|
2021-10-18 13:21:49 +00:00
|
|
|
) | rpl::map([peer](const QString &value) {
|
|
|
|
return AboutWithEntities(peer, value);
|
2017-12-22 07:05:20 +00:00
|
|
|
});
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<QString> LinkValue(not_null<PeerData*> peer) {
|
2017-12-22 07:05:20 +00:00
|
|
|
return PlainUsernameValue(
|
|
|
|
peer
|
2020-06-17 09:36:25 +00:00
|
|
|
) | rpl::map([=](QString &&username) {
|
2017-12-22 07:05:20 +00:00
|
|
|
return username.isEmpty()
|
|
|
|
? QString()
|
2020-06-17 09:36:25 +00:00
|
|
|
: peer->session().createInternalLinkFull(username);
|
2017-12-22 07:05:20 +00:00
|
|
|
});
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2019-06-21 12:27:46 +00:00
|
|
|
rpl::producer<const ChannelLocation*> LocationValue(
|
|
|
|
not_null<ChannelData*> channel) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return channel->session().changes().peerFlagsValue(
|
2019-06-21 12:27:46 +00:00
|
|
|
channel,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::ChannelLocation
|
2019-06-21 12:27:46 +00:00
|
|
|
) | rpl::map([=] {
|
|
|
|
return channel->getLocation();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<bool> NotificationsEnabledValue(not_null<PeerData*> peer) {
|
2018-04-09 17:48:29 +00:00
|
|
|
return rpl::merge(
|
2020-06-12 12:12:34 +00:00
|
|
|
peer->session().changes().peerFlagsValue(
|
2017-09-25 09:02:55 +00:00
|
|
|
peer,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::Notifications
|
2020-06-21 16:25:29 +00:00
|
|
|
) | rpl::to_empty,
|
2022-04-06 15:23:41 +00:00
|
|
|
peer->owner().notifySettings().defaultUpdates(peer)
|
2020-06-08 09:06:50 +00:00
|
|
|
) | rpl::map([=] {
|
2022-04-01 10:36:33 +00:00
|
|
|
return !peer->owner().notifySettings().isMuted(peer);
|
2017-12-22 07:05:20 +00:00
|
|
|
}) | rpl::distinct_until_changed();
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<bool> IsContactValue(not_null<UserData*> user) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return user->session().changes().peerFlagsValue(
|
|
|
|
user,
|
|
|
|
UpdateFlag::IsContact
|
|
|
|
) | rpl::map([=] {
|
|
|
|
return user->isContact();
|
|
|
|
});
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2022-03-23 10:15:52 +00:00
|
|
|
[[nodiscard]] rpl::producer<QString> InviteToChatButton(
|
|
|
|
not_null<UserData*> user) {
|
|
|
|
if (!user->isBot() || user->isRepliesChat() || user->isSupport()) {
|
|
|
|
return rpl::single(QString());
|
|
|
|
}
|
|
|
|
using Flag = Data::PeerUpdate::Flag;
|
|
|
|
return user->session().changes().peerFlagsValue(
|
|
|
|
user,
|
|
|
|
Flag::BotCanBeInvited | Flag::Rights
|
|
|
|
) | rpl::map([=] {
|
|
|
|
const auto info = user->botInfo.get();
|
|
|
|
return info->cantJoinGroups
|
|
|
|
? (info->channelAdminRights
|
|
|
|
? tr::lng_profile_invite_to_channel(tr::now)
|
|
|
|
: QString())
|
|
|
|
: (info->channelAdminRights
|
|
|
|
? tr::lng_profile_add_bot_as_admin(tr::now)
|
|
|
|
: tr::lng_profile_invite_to_group(tr::now));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]] rpl::producer<QString> InviteToChatAbout(
|
|
|
|
not_null<UserData*> user) {
|
|
|
|
if (!user->isBot() || user->isRepliesChat() || user->isSupport()) {
|
|
|
|
return rpl::single(QString());
|
2017-11-07 11:53:05 +00:00
|
|
|
}
|
2022-03-23 10:15:52 +00:00
|
|
|
using Flag = Data::PeerUpdate::Flag;
|
2020-06-12 12:12:34 +00:00
|
|
|
return user->session().changes().peerFlagsValue(
|
|
|
|
user,
|
2022-03-23 10:15:52 +00:00
|
|
|
Flag::BotCanBeInvited | Flag::Rights
|
2020-06-12 12:12:34 +00:00
|
|
|
) | rpl::map([=] {
|
2022-03-23 10:15:52 +00:00
|
|
|
const auto info = user->botInfo.get();
|
|
|
|
return (info->cantJoinGroups || !info->groupAdminRights)
|
|
|
|
? (info->channelAdminRights
|
|
|
|
? tr::lng_profile_invite_to_channel_about(tr::now)
|
|
|
|
: QString())
|
|
|
|
: (info->channelAdminRights
|
|
|
|
? tr::lng_profile_add_bot_as_admin_about(tr::now)
|
|
|
|
: tr::lng_profile_invite_to_group_about(tr::now));
|
2017-12-22 07:05:20 +00:00
|
|
|
});
|
2017-11-07 11:53:05 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<bool> CanShareContactValue(not_null<UserData*> user) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return user->session().changes().peerFlagsValue(
|
|
|
|
user,
|
|
|
|
UpdateFlag::CanShareContact
|
|
|
|
) | rpl::map([=] {
|
2017-12-22 07:05:20 +00:00
|
|
|
return user->canShareThisContact();
|
|
|
|
});
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<bool> CanAddContactValue(not_null<UserData*> user) {
|
2017-09-25 09:02:55 +00:00
|
|
|
using namespace rpl::mappers;
|
2019-06-10 14:58:45 +00:00
|
|
|
if (user->isBot() || user->isSelf()) {
|
|
|
|
return rpl::single(false);
|
|
|
|
}
|
|
|
|
return IsContactValue(
|
|
|
|
user
|
|
|
|
) | rpl::map(!_1);
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<bool> AmInChannelValue(not_null<ChannelData*> channel) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return channel->session().changes().peerFlagsValue(
|
2017-11-07 11:53:05 +00:00
|
|
|
channel,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::ChannelAmIn
|
|
|
|
) | rpl::map([=] {
|
|
|
|
return channel->amIn();
|
|
|
|
});
|
2017-11-07 11:53:05 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<int> MembersCountValue(not_null<PeerData*> peer) {
|
|
|
|
if (const auto chat = peer->asChat()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
2017-11-07 11:53:05 +00:00
|
|
|
peer,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::Members
|
|
|
|
) | rpl::map([=] {
|
2017-12-22 07:05:20 +00:00
|
|
|
return chat->amIn()
|
|
|
|
? std::max(chat->count, int(chat->participants.size()))
|
|
|
|
: 0;
|
|
|
|
});
|
2019-01-07 12:55:49 +00:00
|
|
|
} else if (const auto channel = peer->asChannel()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Members
|
|
|
|
) | rpl::map([=] {
|
2017-12-22 07:05:20 +00:00
|
|
|
return channel->membersCount();
|
|
|
|
});
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
Unexpected("User in MembersCountViewer().");
|
|
|
|
}
|
|
|
|
|
2021-10-12 08:39:07 +00:00
|
|
|
rpl::producer<int> PendingRequestsCountValue(not_null<PeerData*> peer) {
|
|
|
|
if (const auto chat = peer->asChat()) {
|
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::PendingRequests
|
|
|
|
) | rpl::map([=] {
|
|
|
|
return chat->pendingRequestsCount();
|
|
|
|
});
|
|
|
|
} else if (const auto channel = peer->asChannel()) {
|
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::PendingRequests
|
|
|
|
) | rpl::map([=] {
|
|
|
|
return channel->pendingRequestsCount();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
Unexpected("User in MembersCountViewer().");
|
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<int> AdminsCountValue(not_null<PeerData*> peer) {
|
|
|
|
if (const auto chat = peer->asChat()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Admins | UpdateFlag::Rights
|
2019-01-07 12:55:49 +00:00
|
|
|
) | rpl::map([=] {
|
2019-01-10 12:38:57 +00:00
|
|
|
return chat->participants.empty()
|
|
|
|
? 0
|
2020-12-30 09:28:35 +00:00
|
|
|
: int(chat->admins.size() + (chat->creator ? 1 : 0));
|
2019-01-07 12:55:49 +00:00
|
|
|
});
|
|
|
|
} else if (const auto channel = peer->asChannel()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Admins | UpdateFlag::Rights
|
2019-01-07 12:55:49 +00:00
|
|
|
) | rpl::map([=] {
|
|
|
|
return channel->canViewAdmins()
|
|
|
|
? channel->adminsCount()
|
|
|
|
: 0;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
Unexpected("User in AdminsCountValue().");
|
2017-11-08 16:45:30 +00:00
|
|
|
}
|
|
|
|
|
2019-03-15 08:20:12 +00:00
|
|
|
|
|
|
|
rpl::producer<int> RestrictionsCountValue(not_null<PeerData*> peer) {
|
|
|
|
const auto countOfRestrictions = [](ChatRestrictions restrictions) {
|
|
|
|
auto count = 0;
|
2021-09-08 10:53:54 +00:00
|
|
|
for (const auto &f : Data::ListOfRestrictions()) {
|
2019-03-15 08:20:12 +00:00
|
|
|
if (restrictions & f) count++;
|
|
|
|
}
|
|
|
|
return int(Data::ListOfRestrictions().size()) - count;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (const auto chat = peer->asChat()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Rights
|
2019-03-15 08:20:12 +00:00
|
|
|
) | rpl::map([=] {
|
|
|
|
return countOfRestrictions(chat->defaultRestrictions());
|
|
|
|
});
|
|
|
|
} else if (const auto channel = peer->asChannel()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Rights
|
2019-03-15 08:20:12 +00:00
|
|
|
) | rpl::map([=] {
|
|
|
|
return countOfRestrictions(channel->defaultRestrictions());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
Unexpected("User in RestrictionsCountValue().");
|
|
|
|
}
|
|
|
|
|
2019-07-16 12:54:38 +00:00
|
|
|
rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
|
|
|
|
not_null<PeerData*> peer) {
|
|
|
|
if (const auto chat = peer->asChat()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Migration
|
2019-07-16 12:54:38 +00:00
|
|
|
) | rpl::map([=] {
|
|
|
|
return chat->migrateToOrMe();
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return rpl::single(peer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<int> RestrictedCountValue(not_null<ChannelData*> channel) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return channel->session().changes().peerFlagsValue(
|
2017-11-08 16:45:30 +00:00
|
|
|
channel,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::BannedUsers | UpdateFlag::Rights
|
2019-01-05 10:50:04 +00:00
|
|
|
) | rpl::map([=] {
|
2017-12-22 07:05:20 +00:00
|
|
|
return channel->canViewBanned()
|
|
|
|
? channel->restrictedCount()
|
|
|
|
: 0;
|
|
|
|
});
|
2017-11-08 16:45:30 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<int> KickedCountValue(not_null<ChannelData*> channel) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return channel->session().changes().peerFlagsValue(
|
2017-11-08 16:45:30 +00:00
|
|
|
channel,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::BannedUsers | UpdateFlag::Rights
|
2019-01-05 10:50:04 +00:00
|
|
|
) | rpl::map([=] {
|
2017-12-22 07:05:20 +00:00
|
|
|
return channel->canViewBanned()
|
|
|
|
? channel->kickedCount()
|
|
|
|
: 0;
|
|
|
|
});
|
2017-11-08 16:45:30 +00:00
|
|
|
}
|
|
|
|
|
2017-09-25 09:02:55 +00:00
|
|
|
rpl::producer<int> SharedMediaCountValue(
|
|
|
|
not_null<PeerData*> peer,
|
2017-10-31 18:25:22 +00:00
|
|
|
PeerData *migrated,
|
2017-09-25 09:02:55 +00:00
|
|
|
Storage::SharedMediaType type) {
|
|
|
|
auto aroundId = 0;
|
|
|
|
auto limit = 0;
|
|
|
|
auto updated = SharedMediaMergedViewer(
|
2020-06-08 09:06:50 +00:00
|
|
|
&peer->session(),
|
2017-10-29 15:32:01 +00:00
|
|
|
SharedMediaMergedKey(
|
|
|
|
SparseIdsMergedSlice::Key(
|
2017-10-31 18:25:22 +00:00
|
|
|
peer->id,
|
2017-10-29 15:32:01 +00:00
|
|
|
migrated ? migrated->id : 0,
|
|
|
|
aroundId),
|
|
|
|
type),
|
2017-09-25 09:02:55 +00:00
|
|
|
limit,
|
2017-12-22 07:05:20 +00:00
|
|
|
limit
|
|
|
|
) | rpl::map([](const SparseIdsMergedSlice &slice) {
|
|
|
|
return slice.fullCount();
|
|
|
|
}) | rpl::filter_optional();
|
2017-09-25 09:02:55 +00:00
|
|
|
return rpl::single(0) | rpl::then(std::move(updated));
|
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<int> CommonGroupsCountValue(not_null<UserData*> user) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return user->session().changes().peerFlagsValue(
|
2017-09-25 09:02:55 +00:00
|
|
|
user,
|
2020-06-12 12:12:34 +00:00
|
|
|
UpdateFlag::CommonChats
|
|
|
|
) | rpl::map([=] {
|
2017-12-22 07:05:20 +00:00
|
|
|
return user->commonChatsCount();
|
|
|
|
});
|
2017-09-25 09:02:55 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 12:55:49 +00:00
|
|
|
rpl::producer<bool> CanAddMemberValue(not_null<PeerData*> peer) {
|
2019-06-23 12:18:33 +00:00
|
|
|
if (const auto chat = peer->asChat()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Rights
|
2019-01-05 10:50:04 +00:00
|
|
|
) | rpl::map([=] {
|
|
|
|
return chat->canAddMembers();
|
2017-12-22 07:05:20 +00:00
|
|
|
});
|
2019-06-23 12:18:33 +00:00
|
|
|
} else if (const auto channel = peer->asChannel()) {
|
2020-06-12 12:12:34 +00:00
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Rights
|
2019-01-05 10:50:04 +00:00
|
|
|
) | rpl::map([=] {
|
2017-12-22 07:05:20 +00:00
|
|
|
return channel->canAddMembers();
|
|
|
|
});
|
2017-09-25 16:06:53 +00:00
|
|
|
}
|
|
|
|
return rpl::single(false);
|
|
|
|
}
|
|
|
|
|
2021-12-13 11:26:19 +00:00
|
|
|
rpl::producer<int> FullReactionsCountValue(
|
|
|
|
not_null<Main::Session*> session) {
|
|
|
|
const auto reactions = &session->data().reactions();
|
2022-03-11 05:55:21 +00:00
|
|
|
return rpl::single(rpl::empty) | rpl::then(
|
2021-12-13 11:26:19 +00:00
|
|
|
reactions->updates()
|
|
|
|
) | rpl::map([=] {
|
2022-05-18 13:37:24 +00:00
|
|
|
return int(reactions->list(Data::Reactions::Type::Active).size());
|
2021-12-13 11:26:19 +00:00
|
|
|
}) | rpl::distinct_until_changed();
|
|
|
|
}
|
|
|
|
|
|
|
|
rpl::producer<int> AllowedReactionsCountValue(not_null<PeerData*> peer) {
|
|
|
|
if (peer->isUser()) {
|
|
|
|
return FullReactionsCountValue(&peer->session());
|
|
|
|
}
|
|
|
|
return peer->session().changes().peerFlagsValue(
|
|
|
|
peer,
|
|
|
|
UpdateFlag::Reactions
|
|
|
|
) | rpl::map([=] {
|
|
|
|
if (const auto chat = peer->asChat()) {
|
|
|
|
return int(chat->allowedReactions().size());
|
|
|
|
} else if (const auto channel = peer->asChannel()) {
|
|
|
|
return int(channel->allowedReactions().size());
|
|
|
|
}
|
|
|
|
Unexpected("Peer type in AllowedReactionsCountValue.");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-01-21 12:39:40 +00:00
|
|
|
template <typename Flag, typename Peer>
|
|
|
|
rpl::producer<Badge> BadgeValueFromFlags(Peer peer) {
|
2022-05-20 15:28:50 +00:00
|
|
|
return rpl::combine(
|
|
|
|
Data::PeerFlagsValue(
|
|
|
|
peer,
|
|
|
|
Flag::Verified | Flag::Scam | Flag::Fake),
|
|
|
|
Data::PeerPremiumValue(peer)
|
|
|
|
) | rpl::map([=](base::flags<Flag> value, bool premium) {
|
2021-07-08 13:11:09 +00:00
|
|
|
return (value & Flag::Verified)
|
2021-01-21 12:39:40 +00:00
|
|
|
? Badge::Verified
|
2022-05-20 15:28:50 +00:00
|
|
|
: premium
|
|
|
|
? Badge::Premium
|
2021-07-08 13:11:09 +00:00
|
|
|
: (value & Flag::Scam)
|
2021-01-21 12:39:40 +00:00
|
|
|
? Badge::Scam
|
2021-07-08 13:11:09 +00:00
|
|
|
: (value & Flag::Fake)
|
2021-01-21 12:39:40 +00:00
|
|
|
? Badge::Fake
|
|
|
|
: Badge::None;
|
|
|
|
});
|
2017-11-06 14:13:56 +00:00
|
|
|
}
|
2019-06-23 12:18:33 +00:00
|
|
|
|
2021-01-21 12:39:40 +00:00
|
|
|
rpl::producer<Badge> BadgeValue(not_null<PeerData*> peer) {
|
2019-06-23 12:18:33 +00:00
|
|
|
if (const auto user = peer->asUser()) {
|
2021-07-08 13:11:09 +00:00
|
|
|
return BadgeValueFromFlags<UserDataFlag>(user);
|
2019-06-23 12:18:33 +00:00
|
|
|
} else if (const auto channel = peer->asChannel()) {
|
2021-07-08 13:11:09 +00:00
|
|
|
return BadgeValueFromFlags<ChannelDataFlag>(channel);
|
2019-06-23 12:18:33 +00:00
|
|
|
}
|
2021-01-21 12:39:40 +00:00
|
|
|
return rpl::single(Badge::None);
|
2019-06-23 12:18:33 +00:00
|
|
|
}
|
2021-01-21 12:39:40 +00:00
|
|
|
|
2017-09-25 09:02:55 +00:00
|
|
|
} // namespace Profile
|
|
|
|
} // namespace Info
|