tdesktop/Telegram/SourceFiles/info/profile/info_profile_values.cpp

350 lines
9.0 KiB
C++

/*
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 "info/profile/info_profile_values.h"
#include <rpl/filter.h>
#include <rpl/range.h>
#include <rpl/then.h>
#include <rpl/combine.h>
#include "observer_peer.h"
#include "core/application.h"
#include "auth_session.h"
#include "ui/wrap/slide_wrap.h"
#include "data/data_peer_values.h"
#include "data/data_shared_media.h"
#include "data/data_feed.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "boxes/peers/edit_peer_permissions_box.h"
namespace Info {
namespace Profile {
rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
return Notify::PeerUpdateValue(
peer,
Notify::PeerUpdate::Flag::NameChanged
) | rpl::map([=] {
return App::peerName(peer);
}) | WithEmptyEntities();
}
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
return Notify::PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::UserPhoneChanged
) | rpl::map([user] {
return App::formatPhone(user->phone());
}) | WithEmptyEntities();
}
auto PlainBioValue(not_null<UserData*> user) {
return Notify::PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::AboutChanged
) | rpl::map([user] { return user->about(); });
}
rpl::producer<TextWithEntities> BioValue(not_null<UserData*> user) {
return PlainBioValue(user)
| ToSingleLine()
| WithEmptyEntities();
}
auto PlainUsernameValue(not_null<PeerData*> peer) {
return Notify::PeerUpdateValue(
peer,
Notify::PeerUpdate::Flag::UsernameChanged
) | rpl::map([peer] {
return peer->userName();
});
}
rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
return PlainUsernameValue(
user
) | rpl::map([](QString &&username) {
return username.isEmpty()
? QString()
: ('@' + username);
}) | WithEmptyEntities();
}
rpl::producer<QString> PlainAboutValue(not_null<PeerData*> peer) {
if (const auto user = peer->asUser()) {
if (!user->botInfo) {
return rpl::single(QString());
}
}
return Notify::PeerUpdateValue(
peer,
Notify::PeerUpdate::Flag::AboutChanged
) | rpl::map([=] { return peer->about(); });
}
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
auto flags = TextParseLinks
| TextParseMentions
| TextParseHashtags;
if (peer->isUser()) {
flags |= TextParseBotCommands;
}
return PlainAboutValue(
peer
) | WithEmptyEntities(
) | rpl::map([=](TextWithEntities &&text) {
TextUtilities::ParseEntities(text, flags);
return std::move(text);
});
}
rpl::producer<QString> LinkValue(not_null<PeerData*> peer) {
return PlainUsernameValue(
peer
) | rpl::map([](QString &&username) {
return username.isEmpty()
? QString()
: Core::App().createInternalLinkFull(username);
});
}
rpl::producer<bool> NotificationsEnabledValue(not_null<PeerData*> peer) {
return rpl::merge(
Notify::PeerUpdateValue(
peer,
Notify::PeerUpdate::Flag::NotificationsEnabled
) | rpl::map([] { return rpl::empty_value(); }),
Auth().data().defaultNotifyUpdates(peer)
) | rpl::map([peer] {
return !Auth().data().notifyIsMuted(peer);
}) | rpl::distinct_until_changed();
}
rpl::producer<bool> IsContactValue(not_null<UserData*> user) {
return Notify::PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::UserIsContact
) | rpl::map([user] { return user->isContact(); });
}
rpl::producer<bool> CanInviteBotToGroupValue(not_null<UserData*> user) {
if (!user->botInfo) {
return rpl::single(false);
}
return Notify::PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::BotCanAddToGroups
) | rpl::map([user] {
return !user->botInfo->cantJoinGroups;
});
}
rpl::producer<bool> CanShareContactValue(not_null<UserData*> user) {
return Notify::PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::UserCanShareContact
) | rpl::map([user] {
return user->canShareThisContact();
});
}
rpl::producer<bool> CanAddContactValue(not_null<UserData*> user) {
using namespace rpl::mappers;
return rpl::combine(
IsContactValue(user),
CanShareContactValue(user),
!_1 && _2);
}
rpl::producer<bool> AmInChannelValue(not_null<ChannelData*> channel) {
return Notify::PeerUpdateValue(
channel,
Notify::PeerUpdate::Flag::ChannelAmIn
) | rpl::map([channel] { return channel->amIn(); });
}
rpl::producer<int> MembersCountValue(not_null<PeerData*> peer) {
using Flag = Notify::PeerUpdate::Flag;
if (const auto chat = peer->asChat()) {
return Notify::PeerUpdateValue(
peer,
Flag::MembersChanged
) | rpl::map([chat] {
return chat->amIn()
? std::max(chat->count, int(chat->participants.size()))
: 0;
});
} else if (const auto channel = peer->asChannel()) {
return Notify::PeerUpdateValue(
channel,
Flag::MembersChanged
) | rpl::map([channel] {
return channel->membersCount();
});
}
Unexpected("User in MembersCountViewer().");
}
rpl::producer<int> AdminsCountValue(not_null<PeerData*> peer) {
using Flag = Notify::PeerUpdate::Flag;
if (const auto chat = peer->asChat()) {
return Notify::PeerUpdateValue(
chat,
Flag::AdminsChanged | Flag::RightsChanged
) | rpl::map([=] {
return chat->participants.empty()
? 0
: int(chat->admins.size() + 1); // + creator
});
} else if (const auto channel = peer->asChannel()) {
return Notify::PeerUpdateValue(
channel,
Flag::AdminsChanged | Flag::RightsChanged
) | rpl::map([=] {
return channel->canViewAdmins()
? channel->adminsCount()
: 0;
});
}
Unexpected("User in AdminsCountValue().");
}
rpl::producer<int> RestrictionsCountValue(not_null<PeerData*> peer) {
const auto countOfRestrictions = [](ChatRestrictions restrictions) {
auto count = 0;
for (const auto f : Data::ListOfRestrictions()) {
if (restrictions & f) count++;
}
return int(Data::ListOfRestrictions().size()) - count;
};
using Flag = Notify::PeerUpdate::Flag;
if (const auto chat = peer->asChat()) {
return Notify::PeerUpdateValue(
chat,
Flag::RightsChanged
) | rpl::map([=] {
return countOfRestrictions(chat->defaultRestrictions());
});
} else if (const auto channel = peer->asChannel()) {
return Notify::PeerUpdateValue(
channel,
Flag::RightsChanged
) | rpl::map([=] {
return countOfRestrictions(channel->defaultRestrictions());
});
}
Unexpected("User in RestrictionsCountValue().");
}
rpl::producer<int> RestrictedCountValue(not_null<ChannelData*> channel) {
using Flag = Notify::PeerUpdate::Flag;
return Notify::PeerUpdateValue(
channel,
Flag::BannedUsersChanged | Flag::RightsChanged
) | rpl::map([=] {
return channel->canViewBanned()
? channel->restrictedCount()
: 0;
});
}
rpl::producer<int> KickedCountValue(not_null<ChannelData*> channel) {
using Flag = Notify::PeerUpdate::Flag;
return Notify::PeerUpdateValue(
channel,
Flag::BannedUsersChanged | Flag::RightsChanged
) | rpl::map([=] {
return channel->canViewBanned()
? channel->kickedCount()
: 0;
});
}
rpl::producer<int> SharedMediaCountValue(
not_null<PeerData*> peer,
PeerData *migrated,
Storage::SharedMediaType type) {
auto aroundId = 0;
auto limit = 0;
auto updated = SharedMediaMergedViewer(
SharedMediaMergedKey(
SparseIdsMergedSlice::Key(
peer->id,
migrated ? migrated->id : 0,
aroundId),
type),
limit,
limit
) | rpl::map([](const SparseIdsMergedSlice &slice) {
return slice.fullCount();
}) | rpl::filter_optional();
return rpl::single(0) | rpl::then(std::move(updated));
}
rpl::producer<int> CommonGroupsCountValue(not_null<UserData*> user) {
return Notify::PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::UserCommonChatsChanged
) | rpl::map([user] {
return user->commonChatsCount();
});
}
rpl::producer<bool> CanAddMemberValue(not_null<PeerData*> peer) {
if (auto chat = peer->asChat()) {
return Notify::PeerUpdateValue(
chat,
Notify::PeerUpdate::Flag::RightsChanged
) | rpl::map([=] {
return chat->canAddMembers();
});
} else if (auto channel = peer->asChannel()) {
return Notify::PeerUpdateValue(
channel,
Notify::PeerUpdate::Flag::RightsChanged
) | rpl::map([=] {
return channel->canAddMembers();
});
}
return rpl::single(false);
}
rpl::producer<bool> VerifiedValue(not_null<PeerData*> peer) {
if (auto user = peer->asUser()) {
return Data::PeerFlagValue(user, MTPDuser::Flag::f_verified);
} else if (auto channel = peer->asChannel()) {
return Data::PeerFlagValue(
channel,
MTPDchannel::Flag::f_verified);
}
return rpl::single(false);
}
rpl::producer<int> FeedChannelsCountValue(not_null<Data::Feed*> feed) {
using Flag = Data::FeedUpdateFlag;
return rpl::single(
Data::FeedUpdate{ feed, Flag::Channels }
) | rpl::then(
Auth().data().feedUpdated()
) | rpl::filter([=](const Data::FeedUpdate &update) {
return (update.feed == feed) && (update.flag == Flag::Channels);
}) | rpl::filter([=] {
return feed->channelsLoaded();
}) | rpl::map([=] {
return int(feed->channels().size());
}) | rpl::distinct_until_changed();
}
} // namespace Profile
} // namespace Info