tdesktop/Telegram/SourceFiles/data/data_peer.h

479 lines
13 KiB
C
Raw Normal View History

/*
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
*/
#pragma once
#include "data/data_types.h"
#include "data/data_flags.h"
2017-12-04 17:46:03 +00:00
#include "data/data_notify_settings.h"
2020-05-28 14:32:10 +00:00
#include "data/data_cloud_file.h"
class PeerData;
class UserData;
class ChatData;
class ChannelData;
enum class ChatRestriction;
2021-02-02 16:38:30 +00:00
struct BotCommand {
QString command;
QString description;
};
2019-07-24 11:45:24 +00:00
namespace Ui {
class EmptyUserpic;
} // namespace Ui
2019-06-06 11:59:00 +00:00
namespace Main {
class Account;
2019-07-24 11:45:24 +00:00
class Session;
2019-06-06 11:59:00 +00:00
} // namespace Main
namespace Data {
2019-01-03 12:36:01 +00:00
class Session;
class GroupCall;
2021-02-02 16:38:30 +00:00
class CloudImageView;
2018-01-04 09:40:58 +00:00
int PeerColorIndex(PeerId peerId);
int PeerColorIndex(BareId bareId);
style::color PeerUserpicColor(PeerId peerId);
// Must be used only for PeerColor-s.
PeerId FakePeerIdForJustName(const QString &name);
class RestrictionCheckResult {
public:
[[nodiscard]] static RestrictionCheckResult Allowed() {
return { 0 };
}
[[nodiscard]] static RestrictionCheckResult WithEveryone() {
return { 1 };
}
[[nodiscard]] static RestrictionCheckResult Explicit() {
return { 2 };
}
explicit operator bool() const {
return (_value != 0);
}
bool operator==(const RestrictionCheckResult &other) const {
return (_value == other._value);
}
bool operator!=(const RestrictionCheckResult &other) const {
return !(*this == other);
}
[[nodiscard]] bool isAllowed() const {
return (*this == Allowed());
}
[[nodiscard]] bool isWithEveryone() const {
return (*this == WithEveryone());
}
[[nodiscard]] bool isExplicit() const {
return (*this == Explicit());
}
private:
RestrictionCheckResult(int value) : _value(value) {
}
int _value = 0;
};
struct UnavailableReason {
QString reason;
QString text;
bool operator==(const UnavailableReason &other) const {
return (reason == other.reason) && (text == other.text);
}
bool operator!=(const UnavailableReason &other) const {
return !(*this == other);
}
};
bool UpdateBotCommands(
std::vector<BotCommand> &commands,
const MTPVector<MTPBotCommand> &data);
2021-07-05 17:59:06 +00:00
bool UpdateBotCommands(
base::flat_map<UserId, std::vector<BotCommand>> &commands,
UserId botId,
const MTPVector<MTPBotCommand> &data);
bool UpdateBotCommands(
base::flat_map<UserId, std::vector<BotCommand>> &commands,
const MTPVector<MTPBotInfo> &data);
} // namespace Data
class PeerClickHandler : public ClickHandler {
public:
PeerClickHandler(not_null<PeerData*> peer);
void onClick(ClickContext context) const override;
not_null<PeerData*> peer() const {
return _peer;
}
private:
not_null<PeerData*> _peer;
};
2021-07-08 14:30:27 +00:00
enum class PeerSetting {
ReportSpam = (1 << 0),
AddContact = (1 << 1),
BlockContact = (1 << 2),
ShareContact = (1 << 3),
NeedContactsException = (1 << 4),
AutoArchived = (1 << 5),
RequestChat = (1 << 6),
RequestChatIsBroadcast = (1 << 7),
Unknown = (1 << 8),
2021-07-08 14:30:27 +00:00
};
inline constexpr bool is_flag_type(PeerSetting) { return true; };
using PeerSettings = base::flags<PeerSetting>;
2021-07-08 14:30:27 +00:00
class PeerData {
protected:
2019-01-03 12:36:01 +00:00
PeerData(not_null<Data::Session*> owner, PeerId id);
PeerData(const PeerData &other) = delete;
PeerData &operator=(const PeerData &other) = delete;
public:
2021-07-08 14:30:27 +00:00
using Settings = Data::Flags<PeerSettings>;
2017-12-04 17:46:03 +00:00
virtual ~PeerData();
2019-03-12 10:36:33 +00:00
static constexpr auto kServiceNotificationsId = peerFromUser(777000);
[[nodiscard]] Data::Session &owner() const;
2019-07-24 11:45:24 +00:00
[[nodiscard]] Main::Session &session() const;
2019-06-06 11:59:00 +00:00
[[nodiscard]] Main::Account &account() const;
2019-01-03 12:36:01 +00:00
[[nodiscard]] bool isUser() const {
return peerIsUser(id);
}
[[nodiscard]] bool isChat() const {
return peerIsChat(id);
}
[[nodiscard]] bool isChannel() const {
return peerIsChannel(id);
}
2021-12-01 14:51:18 +00:00
[[nodiscard]] bool isSelf() const;
[[nodiscard]] bool isVerified() const;
2019-06-23 12:18:33 +00:00
[[nodiscard]] bool isScam() const;
2021-01-21 12:39:40 +00:00
[[nodiscard]] bool isFake() const;
[[nodiscard]] bool isMegagroup() const;
[[nodiscard]] bool isBroadcast() const;
2021-02-12 15:07:41 +00:00
[[nodiscard]] bool isGigagroup() const;
2020-09-11 15:33:26 +00:00
[[nodiscard]] bool isRepliesChat() const;
[[nodiscard]] bool sharedMediaInfo() const {
return isSelf() || isRepliesChat();
}
2017-12-04 17:46:03 +00:00
2019-03-12 10:36:33 +00:00
[[nodiscard]] bool isNotificationsUser() const {
return (id == peerFromUser(333000))
|| (id == kServiceNotificationsId);
}
[[nodiscard]] bool isServiceUser() const {
return isUser() && !(id.value % 1000);
2019-03-12 10:36:33 +00:00
}
[[nodiscard]] std::optional<TimeId> notifyMuteUntil() const {
return _notify.muteUntil();
2017-12-04 17:46:03 +00:00
}
bool notifyChange(const MTPPeerNotifySettings &settings) {
return _notify.change(settings);
}
bool notifyChange(
2018-09-21 16:28:46 +00:00
std::optional<int> muteForSeconds,
std::optional<bool> silentPosts) {
return _notify.change(muteForSeconds, silentPosts);
2017-12-04 17:46:03 +00:00
}
[[nodiscard]] bool notifySettingsUnknown() const {
2017-12-04 17:46:03 +00:00
return _notify.settingsUnknown();
}
[[nodiscard]] std::optional<bool> notifySilentPosts() const {
2017-12-04 17:46:03 +00:00
return _notify.silentPosts();
}
[[nodiscard]] MTPinputPeerNotifySettings notifySerialize() const {
2017-12-04 17:46:03 +00:00
return _notify.serialize();
}
[[nodiscard]] bool canWrite() const;
[[nodiscard]] bool allowsForwarding() const;
[[nodiscard]] Data::RestrictionCheckResult amRestricted(
ChatRestriction right) const;
2020-09-10 11:19:48 +00:00
[[nodiscard]] bool amAnonymous() const;
2019-03-21 13:48:40 +00:00
[[nodiscard]] bool canRevokeFullHistory() const;
2019-07-17 10:37:42 +00:00
[[nodiscard]] bool slowmodeApplied() const;
[[nodiscard]] rpl::producer<bool> slowmodeAppliedValue() const;
2019-07-17 10:37:42 +00:00
[[nodiscard]] int slowmodeSecondsLeft() const;
[[nodiscard]] bool canSendPolls() const;
[[nodiscard]] bool canManageGroupCall() const;
[[nodiscard]] UserData *asUser();
[[nodiscard]] const UserData *asUser() const;
[[nodiscard]] ChatData *asChat();
[[nodiscard]] const ChatData *asChat() const;
[[nodiscard]] ChannelData *asChannel();
[[nodiscard]] const ChannelData *asChannel() const;
[[nodiscard]] ChannelData *asMegagroup();
[[nodiscard]] const ChannelData *asMegagroup() const;
[[nodiscard]] ChannelData *asBroadcast();
[[nodiscard]] const ChannelData *asBroadcast() const;
2019-01-13 13:28:05 +00:00
[[nodiscard]] ChatData *asChatNotMigrated();
[[nodiscard]] const ChatData *asChatNotMigrated() const;
[[nodiscard]] ChannelData *asChannelOrMigrated();
[[nodiscard]] const ChannelData *asChannelOrMigrated() const;
[[nodiscard]] ChatData *migrateFrom() const;
[[nodiscard]] ChannelData *migrateTo() const;
[[nodiscard]] not_null<PeerData*> migrateToOrMe();
[[nodiscard]] not_null<const PeerData*> migrateToOrMe() const;
void updateFull();
void updateFullForced();
void fullUpdated();
[[nodiscard]] bool wasFullUpdated() const {
return (_lastFullUpdate != 0);
}
2019-06-12 13:26:04 +00:00
[[nodiscard]] const Ui::Text::String &nameText() const;
[[nodiscard]] const QString &shortName() const;
2019-06-12 13:26:04 +00:00
[[nodiscard]] const Ui::Text::String &topBarNameText() const;
[[nodiscard]] QString userName() const;
[[nodiscard]] const base::flat_set<QString> &nameWords() const {
return _nameWords;
}
[[nodiscard]] const base::flat_set<QChar> &nameFirstLetters() const {
return _nameFirstLetters;
}
2020-05-28 14:32:10 +00:00
void setUserpic(PhotoId photoId, const ImageLocation &location);
void setUserpicPhoto(const MTPPhoto &data);
void paintUserpic(
Painter &p,
2020-05-28 14:32:10 +00:00
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const;
void paintUserpicLeft(
Painter &p,
2020-05-28 14:32:10 +00:00
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int w,
int size) const {
2020-05-28 14:32:10 +00:00
paintUserpic(p, view, rtl() ? (w - x - size) : x, y, size);
}
void loadUserpic();
2020-05-28 14:32:10 +00:00
[[nodiscard]] bool hasUserpic() const;
[[nodiscard]] std::shared_ptr<Data::CloudImageView> activeUserpicView();
[[nodiscard]] std::shared_ptr<Data::CloudImageView> createUserpicView();
[[nodiscard]] bool useEmptyUserpic(
std::shared_ptr<Data::CloudImageView> &view) const;
[[nodiscard]] InMemoryKey userpicUniqueKey(
std::shared_ptr<Data::CloudImageView> &view) const;
void saveUserpic(
std::shared_ptr<Data::CloudImageView> &view,
const QString &path,
int size) const;
void saveUserpicRounded(
std::shared_ptr<Data::CloudImageView> &view,
const QString &path,
int size) const;
[[nodiscard]] QPixmap genUserpic(
std::shared_ptr<Data::CloudImageView> &view,
int size) const;
[[nodiscard]] QImage generateUserpicImage(
2020-05-28 14:32:10 +00:00
std::shared_ptr<Data::CloudImageView> &view,
int size) const;
[[nodiscard]] QImage generateUserpicImage(
std::shared_ptr<Data::CloudImageView> &view,
int size,
ImageRoundRadius radius) const;
2020-05-28 14:32:10 +00:00
[[nodiscard]] ImageLocation userpicLocation() const {
return _userpic.location();
2017-11-20 19:54:05 +00:00
}
static constexpr auto kUnknownPhotoId = PhotoId(0xFFFFFFFFFFFFFFFFULL);
[[nodiscard]] bool userpicPhotoUnknown() const {
return (_userpicPhotoId == kUnknownPhotoId);
}
[[nodiscard]] PhotoId userpicPhotoId() const {
return userpicPhotoUnknown() ? 0 : _userpicPhotoId;
}
[[nodiscard]] Data::FileOrigin userpicOrigin() const;
[[nodiscard]] Data::FileOrigin userpicPhotoOrigin() const;
// If this string is not empty we must not allow to open the
// conversation and we must show this string instead.
[[nodiscard]] QString computeUnavailableReason() const;
[[nodiscard]] ClickHandlerPtr createOpenLink();
[[nodiscard]] const ClickHandlerPtr &openLink() {
if (!_openLink) {
_openLink = createOpenLink();
}
return _openLink;
}
2020-05-28 14:32:10 +00:00
[[nodiscard]] Image *currentUserpic(
std::shared_ptr<Data::CloudImageView> &view) const;
[[nodiscard]] bool canPinMessages() const;
[[nodiscard]] bool canEditMessagesIndefinitely() const;
[[nodiscard]] bool canExportChatHistory() const;
// Returns true if about text was changed.
bool setAbout(const QString &newAbout);
[[nodiscard]] const QString &about() const {
return _about;
}
void checkFolder(FolderId folderId);
2021-07-08 14:30:27 +00:00
void setSettings(PeerSettings which) {
_settings.set(which);
}
[[nodiscard]] auto settings() const {
2021-07-08 14:30:27 +00:00
return (_settings.current() & PeerSetting::Unknown)
? std::nullopt
: std::make_optional(_settings.current());
}
[[nodiscard]] auto settingsValue() const {
2021-07-08 14:30:27 +00:00
return (_settings.current() & PeerSetting::Unknown)
? _settings.changes()
: (_settings.value() | rpl::type_erased());
}
[[nodiscard]] QString requestChatTitle() const {
return _requestChatTitle;
}
[[nodiscard]] TimeId requestChatDate() const {
return _requestChatDate;
}
2021-07-08 14:30:27 +00:00
void setSettings(const MTPPeerSettings &data);
enum class BlockStatus : char {
Unknown,
Blocked,
NotBlocked,
};
[[nodiscard]] BlockStatus blockStatus() const {
return _blockStatus;
}
[[nodiscard]] bool isBlocked() const {
return (blockStatus() == BlockStatus::Blocked);
}
void setIsBlocked(bool is);
enum class LoadedStatus : char {
Not,
Minimal,
2021-10-12 12:50:18 +00:00
Normal,
Full,
};
[[nodiscard]] LoadedStatus loadedStatus() const {
return _loadedStatus;
}
[[nodiscard]] bool isMinimalLoaded() const {
return (loadedStatus() != LoadedStatus::Not);
}
2021-10-12 12:50:18 +00:00
[[nodiscard]] bool isLoaded() const {
return (loadedStatus() == LoadedStatus::Normal) || isFullLoaded();
}
[[nodiscard]] bool isFullLoaded() const {
return (loadedStatus() == LoadedStatus::Full);
}
void setLoadedStatus(LoadedStatus status);
2021-02-02 16:38:30 +00:00
[[nodiscard]] TimeId messagesTTL() const;
void setMessagesTTL(TimeId period);
2021-02-02 16:38:30 +00:00
[[nodiscard]] Data::GroupCall *groupCall() const;
[[nodiscard]] PeerId groupCallDefaultJoinAs() const;
2021-09-24 15:10:25 +00:00
void setThemeEmoji(const QString &emoticon);
2021-08-25 16:16:50 +00:00
[[nodiscard]] const QString &themeEmoji() const;
const PeerId id;
QString name;
MTPinputPeer input = MTP_inputPeerEmpty();
int nameVersion = 1;
protected:
void updateNameDelayed(
const QString &newName,
const QString &newNameOrPhone,
const QString &newUsername);
2021-03-30 08:16:05 +00:00
void updateUserpic(PhotoId photoId, MTP::DcId dcId);
void clearUserpic();
private:
void fillNames();
2020-05-28 14:32:10 +00:00
[[nodiscard]] not_null<Ui::EmptyUserpic*> ensureEmptyUserpic() const;
[[nodiscard]] virtual auto unavailableReasons() const
-> const std::vector<Data::UnavailableReason> &;
2020-05-28 14:32:10 +00:00
void setUserpicChecked(PhotoId photoId, const ImageLocation &location);
2020-01-09 17:24:54 +00:00
const not_null<Data::Session*> _owner;
2019-01-03 12:36:01 +00:00
2020-05-28 14:32:10 +00:00
mutable Data::CloudImage _userpic;
PhotoId _userpicPhotoId = kUnknownPhotoId;
mutable std::unique_ptr<Ui::EmptyUserpic> _userpicEmpty;
2019-06-12 13:26:04 +00:00
Ui::Text::String _nameText;
2017-12-04 17:46:03 +00:00
Data::NotifySettings _notify;
ClickHandlerPtr _openLink;
base::flat_set<QString> _nameWords; // for filtering
base::flat_set<QChar> _nameFirstLetters;
crl::time _lastFullUpdate = 0;
2021-02-02 16:38:30 +00:00
TimeId _ttlPeriod = 0;
2021-07-08 14:30:27 +00:00
Settings _settings = PeerSettings(PeerSetting::Unknown);
BlockStatus _blockStatus = BlockStatus::Unknown;
LoadedStatus _loadedStatus = LoadedStatus::Not;
QString _requestChatTitle;
TimeId _requestChatDate = 0;
QString _about;
2021-09-24 15:10:25 +00:00
QString _themeEmoticon;
};
namespace Data {
2019-06-19 15:09:03 +00:00
std::optional<QString> RestrictionError(
not_null<PeerData*> peer,
ChatRestriction restriction);
void SetTopPinnedMessageId(not_null<PeerData*> peer, MsgId messageId);
[[nodiscard]] FullMsgId ResolveTopPinnedId(
not_null<PeerData*> peer,
PeerData *migrated);
2020-10-26 11:46:08 +00:00
[[nodiscard]] FullMsgId ResolveMinPinnedId(
not_null<PeerData*> peer,
PeerData *migrated);
[[nodiscard]] std::optional<int> ResolvePinnedCount(
not_null<PeerData*> peer,
PeerData *migrated);
} // namespace Data