data_peer.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "data/data_types.h"
  9. #include "data/data_flags.h"
  10. #include "data/notify/data_peer_notify_settings.h"
  11. #include "data/data_cloud_file.h"
  12. #include "ui/userpic_view.h"
  13. struct BotInfo;
  14. class PeerData;
  15. class UserData;
  16. class ChatData;
  17. class ChannelData;
  18. enum class ChatRestriction;
  19. namespace Ui {
  20. class EmptyUserpic;
  21. struct BotVerifyDetails;
  22. } // namespace Ui
  23. namespace Main {
  24. class Account;
  25. class Session;
  26. } // namespace Main
  27. namespace Data {
  28. class Forum;
  29. class ForumTopic;
  30. class Session;
  31. class GroupCall;
  32. struct ReactionId;
  33. class WallPaper;
  34. [[nodiscard]] uint8 DecideColorIndex(PeerId peerId);
  35. // Must be used only for PeerColor-s.
  36. [[nodiscard]] PeerId FakePeerIdForJustName(const QString &name);
  37. class RestrictionCheckResult {
  38. public:
  39. [[nodiscard]] static RestrictionCheckResult Allowed() {
  40. return { 0 };
  41. }
  42. [[nodiscard]] static RestrictionCheckResult WithEveryone() {
  43. return { 1 };
  44. }
  45. [[nodiscard]] static RestrictionCheckResult Explicit() {
  46. return { 2 };
  47. }
  48. explicit operator bool() const {
  49. return (_value != 0);
  50. }
  51. bool operator==(const RestrictionCheckResult &other) const {
  52. return (_value == other._value);
  53. }
  54. bool operator!=(const RestrictionCheckResult &other) const {
  55. return !(*this == other);
  56. }
  57. [[nodiscard]] bool isAllowed() const {
  58. return (*this == Allowed());
  59. }
  60. [[nodiscard]] bool isWithEveryone() const {
  61. return (*this == WithEveryone());
  62. }
  63. [[nodiscard]] bool isExplicit() const {
  64. return (*this == Explicit());
  65. }
  66. private:
  67. RestrictionCheckResult(int value) : _value(value) {
  68. }
  69. int _value = 0;
  70. };
  71. struct UnavailableReason {
  72. QString reason;
  73. QString text;
  74. friend inline bool operator==(
  75. const UnavailableReason &,
  76. const UnavailableReason &) = default;
  77. [[nodiscard]] bool sensitive() const;
  78. [[nodiscard]] static UnavailableReason Sensitive();
  79. [[nodiscard]] static QString Compute(
  80. not_null<Main::Session*> session,
  81. const std::vector<UnavailableReason> &list);
  82. [[nodiscard]] static bool IgnoreSensitiveMark(
  83. not_null<Main::Session*> session);
  84. [[nodiscard]] static std::vector<UnavailableReason> Extract(
  85. const MTPvector<MTPRestrictionReason> *list);
  86. };
  87. bool ApplyBotMenuButton(
  88. not_null<BotInfo*> info,
  89. const MTPBotMenuButton *button);
  90. enum class AllowedReactionsType : uchar {
  91. All,
  92. Default,
  93. Some,
  94. };
  95. struct AllowedReactions {
  96. std::vector<ReactionId> some;
  97. int maxCount = 0;
  98. AllowedReactionsType type = AllowedReactionsType::Some;
  99. bool paidEnabled = false;
  100. friend inline bool operator==(
  101. const AllowedReactions &,
  102. const AllowedReactions &) = default;
  103. };
  104. [[nodiscard]] AllowedReactions Parse(
  105. const MTPChatReactions &value,
  106. int maxCount,
  107. bool paidEnabled);
  108. [[nodiscard]] PeerData *PeerFromInputMTP(
  109. not_null<Session*> owner,
  110. const MTPInputPeer &input);
  111. [[nodiscard]] UserData *UserFromInputMTP(
  112. not_null<Session*> owner,
  113. const MTPInputUser &input);
  114. } // namespace Data
  115. class PeerClickHandler : public ClickHandler {
  116. public:
  117. PeerClickHandler(not_null<PeerData*> peer);
  118. void onClick(ClickContext context) const override;
  119. not_null<PeerData*> peer() const {
  120. return _peer;
  121. }
  122. private:
  123. not_null<PeerData*> _peer;
  124. };
  125. enum class PeerBarSetting {
  126. ReportSpam = (1 << 0),
  127. AddContact = (1 << 1),
  128. BlockContact = (1 << 2),
  129. ShareContact = (1 << 3),
  130. NeedContactsException = (1 << 4),
  131. AutoArchived = (1 << 5),
  132. RequestChat = (1 << 6),
  133. RequestChatIsBroadcast = (1 << 7),
  134. HasBusinessBot = (1 << 8),
  135. BusinessBotPaused = (1 << 9),
  136. BusinessBotCanReply = (1 << 10),
  137. Unknown = (1 << 11),
  138. };
  139. inline constexpr bool is_flag_type(PeerBarSetting) { return true; };
  140. using PeerBarSettings = base::flags<PeerBarSetting>;
  141. struct PeerBarDetails {
  142. QString phoneCountryCode;
  143. int registrationDate = 0; // YYYYMM or 0, YYYY > 2012, MM > 0.
  144. TimeId nameChangeDate = 0;
  145. TimeId photoChangeDate = 0;
  146. QString requestChatTitle;
  147. TimeId requestChatDate;
  148. UserData *businessBot = nullptr;
  149. QString businessBotManageUrl;
  150. int paysPerMessage = 0;
  151. };
  152. class PeerData {
  153. protected:
  154. PeerData(not_null<Data::Session*> owner, PeerId id);
  155. PeerData(const PeerData &other) = delete;
  156. PeerData &operator=(const PeerData &other) = delete;
  157. public:
  158. using BarSettings = Data::Flags<PeerBarSettings>;
  159. virtual ~PeerData();
  160. static constexpr auto kServiceNotificationsId = peerFromUser(777000);
  161. static constexpr auto kSavedHiddenAuthorId = peerFromUser(2666000);
  162. [[nodiscard]] Data::Session &owner() const;
  163. [[nodiscard]] Main::Session &session() const;
  164. [[nodiscard]] Main::Account &account() const;
  165. [[nodiscard]] uint8 colorIndex() const {
  166. return _colorIndex;
  167. }
  168. bool changeColorIndex(uint8 index);
  169. bool clearColorIndex();
  170. [[nodiscard]] DocumentId backgroundEmojiId() const;
  171. bool changeBackgroundEmojiId(DocumentId id);
  172. void setEmojiStatus(const MTPEmojiStatus &status);
  173. void setEmojiStatus(EmojiStatusId emojiStatusId, TimeId until = 0);
  174. [[nodiscard]] EmojiStatusId emojiStatusId() const;
  175. [[nodiscard]] bool isUser() const {
  176. return peerIsUser(id);
  177. }
  178. [[nodiscard]] bool isChat() const {
  179. return peerIsChat(id);
  180. }
  181. [[nodiscard]] bool isChannel() const {
  182. return peerIsChannel(id);
  183. }
  184. [[nodiscard]] bool isBot() const;
  185. [[nodiscard]] bool isSelf() const;
  186. [[nodiscard]] bool isVerified() const;
  187. [[nodiscard]] bool isPremium() const;
  188. [[nodiscard]] bool isScam() const;
  189. [[nodiscard]] bool isFake() const;
  190. [[nodiscard]] bool isMegagroup() const;
  191. [[nodiscard]] bool isBroadcast() const;
  192. [[nodiscard]] bool isForum() const;
  193. [[nodiscard]] bool isGigagroup() const;
  194. [[nodiscard]] bool isRepliesChat() const;
  195. [[nodiscard]] bool isVerifyCodes() const;
  196. [[nodiscard]] bool sharedMediaInfo() const;
  197. [[nodiscard]] bool savedSublistsInfo() const;
  198. [[nodiscard]] bool hasStoriesHidden() const;
  199. void setStoriesHidden(bool hidden);
  200. [[nodiscard]] Ui::BotVerifyDetails *botVerifyDetails() const;
  201. [[nodiscard]] bool isNotificationsUser() const {
  202. return (id == peerFromUser(333000))
  203. || (id == kServiceNotificationsId);
  204. }
  205. [[nodiscard]] bool isServiceUser() const {
  206. return isUser() && !(id.value % 1000);
  207. }
  208. [[nodiscard]] bool isSavedHiddenAuthor() const {
  209. return (id == kSavedHiddenAuthorId);
  210. }
  211. [[nodiscard]] Data::Forum *forum() const;
  212. [[nodiscard]] Data::ForumTopic *forumTopicFor(MsgId rootId) const;
  213. [[nodiscard]] Data::PeerNotifySettings &notify() {
  214. return _notify;
  215. }
  216. [[nodiscard]] const Data::PeerNotifySettings &notify() const {
  217. return _notify;
  218. }
  219. [[nodiscard]] bool allowsForwarding() const;
  220. [[nodiscard]] Data::RestrictionCheckResult amRestricted(
  221. ChatRestriction right) const;
  222. [[nodiscard]] bool amAnonymous() const;
  223. [[nodiscard]] bool canRevokeFullHistory() const;
  224. [[nodiscard]] bool slowmodeApplied() const;
  225. [[nodiscard]] rpl::producer<bool> slowmodeAppliedValue() const;
  226. [[nodiscard]] int slowmodeSecondsLeft() const;
  227. [[nodiscard]] bool canManageGroupCall() const;
  228. [[nodiscard]] int starsPerMessage() const;
  229. [[nodiscard]] int starsPerMessageChecked() const;
  230. [[nodiscard]] UserData *asBot();
  231. [[nodiscard]] const UserData *asBot() const;
  232. [[nodiscard]] UserData *asUser();
  233. [[nodiscard]] const UserData *asUser() const;
  234. [[nodiscard]] ChatData *asChat();
  235. [[nodiscard]] const ChatData *asChat() const;
  236. [[nodiscard]] ChannelData *asChannel();
  237. [[nodiscard]] const ChannelData *asChannel() const;
  238. [[nodiscard]] ChannelData *asMegagroup();
  239. [[nodiscard]] const ChannelData *asMegagroup() const;
  240. [[nodiscard]] ChannelData *asBroadcast();
  241. [[nodiscard]] const ChannelData *asBroadcast() const;
  242. [[nodiscard]] ChatData *asChatNotMigrated();
  243. [[nodiscard]] const ChatData *asChatNotMigrated() const;
  244. [[nodiscard]] ChannelData *asChannelOrMigrated();
  245. [[nodiscard]] const ChannelData *asChannelOrMigrated() const;
  246. [[nodiscard]] ChatData *migrateFrom() const;
  247. [[nodiscard]] ChannelData *migrateTo() const;
  248. [[nodiscard]] not_null<PeerData*> migrateToOrMe();
  249. [[nodiscard]] not_null<const PeerData*> migrateToOrMe() const;
  250. void updateFull();
  251. void updateFullForced();
  252. void fullUpdated();
  253. [[nodiscard]] bool wasFullUpdated() const {
  254. return (_lastFullUpdate != 0);
  255. }
  256. [[nodiscard]] int nameVersion() const;
  257. [[nodiscard]] const QString &name() const;
  258. [[nodiscard]] const QString &shortName() const;
  259. [[nodiscard]] const QString &topBarNameText() const;
  260. [[nodiscard]] QString username() const;
  261. [[nodiscard]] QString editableUsername() const;
  262. [[nodiscard]] const std::vector<QString> &usernames() const;
  263. [[nodiscard]] bool isUsernameEditable(QString username) const;
  264. [[nodiscard]] const base::flat_set<QString> &nameWords() const {
  265. return _nameWords;
  266. }
  267. [[nodiscard]] const base::flat_set<QChar> &nameFirstLetters() const {
  268. return _nameFirstLetters;
  269. }
  270. void setUserpic(
  271. PhotoId photoId,
  272. const ImageLocation &location,
  273. bool hasVideo);
  274. void setUserpicPhoto(const MTPPhoto &data);
  275. void paintUserpic(
  276. Painter &p,
  277. Ui::PeerUserpicView &view,
  278. int x,
  279. int y,
  280. int size,
  281. bool forceCircle = false) const;
  282. void paintUserpicLeft(
  283. Painter &p,
  284. Ui::PeerUserpicView &view,
  285. int x,
  286. int y,
  287. int w,
  288. int size,
  289. bool forceCircle = false) const {
  290. paintUserpic(
  291. p,
  292. view,
  293. rtl() ? (w - x - size) : x,
  294. y,
  295. size,
  296. forceCircle);
  297. }
  298. void loadUserpic();
  299. [[nodiscard]] bool hasUserpic() const;
  300. [[nodiscard]] Ui::PeerUserpicView activeUserpicView();
  301. [[nodiscard]] Ui::PeerUserpicView createUserpicView();
  302. [[nodiscard]] bool useEmptyUserpic(Ui::PeerUserpicView &view) const;
  303. [[nodiscard]] InMemoryKey userpicUniqueKey(Ui::PeerUserpicView &view) const;
  304. [[nodiscard]] static QImage GenerateUserpicImage(
  305. not_null<PeerData*> peer,
  306. Ui::PeerUserpicView &view,
  307. int size,
  308. std::optional<int> radius = {});
  309. [[nodiscard]] ImageLocation userpicLocation() const;
  310. static constexpr auto kUnknownPhotoId = PhotoId(0xFFFFFFFFFFFFFFFFULL);
  311. [[nodiscard]] bool userpicPhotoUnknown() const;
  312. [[nodiscard]] PhotoId userpicPhotoId() const;
  313. [[nodiscard]] bool userpicHasVideo() const;
  314. [[nodiscard]] Data::FileOrigin userpicOrigin() const;
  315. [[nodiscard]] Data::FileOrigin userpicPhotoOrigin() const;
  316. // If this string is not empty we must not allow to open the
  317. // conversation and we must show this string instead.
  318. [[nodiscard]] QString computeUnavailableReason() const;
  319. [[nodiscard]] bool hasSensitiveContent() const;
  320. void setUnavailableReasons(
  321. std::vector<Data::UnavailableReason> &&reason);
  322. [[nodiscard]] ClickHandlerPtr createOpenLink();
  323. [[nodiscard]] const ClickHandlerPtr &openLink() {
  324. if (!_openLink) {
  325. _openLink = createOpenLink();
  326. }
  327. return _openLink;
  328. }
  329. [[nodiscard]] QImage *userpicCloudImage(Ui::PeerUserpicView &view) const;
  330. [[nodiscard]] bool canPinMessages() const;
  331. [[nodiscard]] bool canEditMessagesIndefinitely() const;
  332. [[nodiscard]] bool canCreatePolls() const;
  333. [[nodiscard]] bool canCreateTopics() const;
  334. [[nodiscard]] bool canManageTopics() const;
  335. [[nodiscard]] bool canManageGifts() const;
  336. [[nodiscard]] bool canTransferGifts() const;
  337. [[nodiscard]] bool canExportChatHistory() const;
  338. // Returns true if about text was changed.
  339. bool setAbout(const QString &newAbout);
  340. [[nodiscard]] const QString &about() const {
  341. return _about;
  342. }
  343. void checkFolder(FolderId folderId);
  344. void setBarSettings(PeerBarSettings which) {
  345. _barSettings.set(which);
  346. }
  347. [[nodiscard]] auto barSettings() const {
  348. return (_barSettings.current() & PeerBarSetting::Unknown)
  349. ? std::nullopt
  350. : std::make_optional(_barSettings.current());
  351. }
  352. [[nodiscard]] auto barSettingsValue() const {
  353. return (_barSettings.current() & PeerBarSetting::Unknown)
  354. ? _barSettings.changes()
  355. : (_barSettings.value() | rpl::type_erased());
  356. }
  357. [[nodiscard]] int paysPerMessage() const;
  358. void clearPaysPerMessage();
  359. [[nodiscard]] QString requestChatTitle() const;
  360. [[nodiscard]] TimeId requestChatDate() const;
  361. [[nodiscard]] UserData *businessBot() const;
  362. [[nodiscard]] QString businessBotManageUrl() const;
  363. void clearBusinessBot();
  364. [[nodiscard]] QString phoneCountryCode() const;
  365. [[nodiscard]] int registrationMonth() const;
  366. [[nodiscard]] int registrationYear() const;
  367. [[nodiscard]] TimeId nameChangeDate() const;
  368. [[nodiscard]] TimeId photoChangeDate() const;
  369. enum class TranslationFlag : uchar {
  370. Unknown,
  371. Disabled,
  372. Enabled,
  373. };
  374. void setTranslationDisabled(bool disabled);
  375. [[nodiscard]] TranslationFlag translationFlag() const;
  376. void saveTranslationDisabled(bool disabled);
  377. void setBarSettings(const MTPPeerSettings &data);
  378. bool changeColorIndex(const tl::conditional<MTPint> &cloudColorIndex);
  379. bool changeBackgroundEmojiId(
  380. const tl::conditional<MTPlong> &cloudBackgroundEmoji);
  381. bool changeColor(const tl::conditional<MTPPeerColor> &cloudColor);
  382. enum class BlockStatus : char {
  383. Unknown,
  384. Blocked,
  385. NotBlocked,
  386. };
  387. [[nodiscard]] BlockStatus blockStatus() const {
  388. return _blockStatus;
  389. }
  390. [[nodiscard]] bool isBlocked() const {
  391. return (blockStatus() == BlockStatus::Blocked);
  392. }
  393. void setIsBlocked(bool is);
  394. enum class LoadedStatus : char {
  395. Not,
  396. Minimal,
  397. Normal,
  398. Full,
  399. };
  400. [[nodiscard]] LoadedStatus loadedStatus() const {
  401. return _loadedStatus;
  402. }
  403. [[nodiscard]] bool isMinimalLoaded() const {
  404. return (loadedStatus() != LoadedStatus::Not);
  405. }
  406. [[nodiscard]] bool isLoaded() const {
  407. return (loadedStatus() == LoadedStatus::Normal) || isFullLoaded();
  408. }
  409. [[nodiscard]] bool isFullLoaded() const {
  410. return (loadedStatus() == LoadedStatus::Full);
  411. }
  412. void setLoadedStatus(LoadedStatus status);
  413. [[nodiscard]] TimeId messagesTTL() const;
  414. void setMessagesTTL(TimeId period);
  415. [[nodiscard]] Data::GroupCall *groupCall() const;
  416. [[nodiscard]] PeerId groupCallDefaultJoinAs() const;
  417. void setThemeEmoji(const QString &emoticon);
  418. [[nodiscard]] const QString &themeEmoji() const;
  419. void setWallPaper(
  420. std::optional<Data::WallPaper> paper,
  421. bool overriden = false);
  422. [[nodiscard]] bool wallPaperOverriden() const;
  423. [[nodiscard]] const Data::WallPaper *wallPaper() const;
  424. enum class StoriesState {
  425. Unknown,
  426. None,
  427. HasRead,
  428. HasUnread,
  429. };
  430. [[nodiscard]] bool hasActiveStories() const;
  431. [[nodiscard]] bool hasUnreadStories() const;
  432. void setStoriesState(StoriesState state);
  433. [[nodiscard]] int peerGiftsCount() const;
  434. const PeerId id;
  435. MTPinputPeer input = MTP_inputPeerEmpty();
  436. protected:
  437. void updateNameDelayed(
  438. const QString &newName,
  439. const QString &newNameOrPhone,
  440. const QString &newUsername);
  441. void updateUserpic(PhotoId photoId, MTP::DcId dcId, bool hasVideo);
  442. void clearUserpic();
  443. void invalidateEmptyUserpic();
  444. void checkTrustedPayForMessage();
  445. private:
  446. void fillNames();
  447. [[nodiscard]] not_null<Ui::EmptyUserpic*> ensureEmptyUserpic() const;
  448. [[nodiscard]] virtual auto unavailableReasons() const
  449. -> const std::vector<Data::UnavailableReason> &;
  450. void setUserpicChecked(
  451. PhotoId photoId,
  452. const ImageLocation &location,
  453. bool hasVideo);
  454. virtual void setUnavailableReasonsList(
  455. std::vector<Data::UnavailableReason> &&reasons);
  456. void setHasSensitiveContent(bool has);
  457. const not_null<Data::Session*> _owner;
  458. mutable Data::CloudImage _userpic;
  459. PhotoId _userpicPhotoId = kUnknownPhotoId;
  460. mutable std::unique_ptr<Ui::EmptyUserpic> _userpicEmpty;
  461. Data::PeerNotifySettings _notify;
  462. ClickHandlerPtr _openLink;
  463. base::flat_set<QString> _nameWords; // for filtering
  464. base::flat_set<QChar> _nameFirstLetters;
  465. EmojiStatusId _emojiStatusId;
  466. DocumentId _backgroundEmojiId = 0;
  467. crl::time _lastFullUpdate = 0;
  468. QString _name;
  469. uint32 _nameVersion : 29 = 1;
  470. uint32 _sensitiveContent : 1 = 0;
  471. uint32 _wallPaperOverriden : 1 = 0;
  472. uint32 _checkedTrustedPayForMessage : 1 = 0;
  473. TimeId _ttlPeriod = 0;
  474. BarSettings _barSettings = PeerBarSettings(PeerBarSetting::Unknown);
  475. std::unique_ptr<PeerBarDetails> _barDetails;
  476. BlockStatus _blockStatus = BlockStatus::Unknown;
  477. LoadedStatus _loadedStatus = LoadedStatus::Not;
  478. TranslationFlag _translationFlag = TranslationFlag::Unknown;
  479. uint8 _colorIndex : 6 = 0;
  480. uint8 _colorIndexCloud : 1 = 0;
  481. uint8 _userpicHasVideo : 1 = 0;
  482. QString _about;
  483. QString _themeEmoticon;
  484. std::unique_ptr<Data::WallPaper> _wallPaper;
  485. };
  486. namespace Data {
  487. void SetTopPinnedMessageId(
  488. not_null<PeerData*> peer,
  489. MsgId messageId);
  490. [[nodiscard]] FullMsgId ResolveTopPinnedId(
  491. not_null<PeerData*> peer,
  492. MsgId topicRootId,
  493. PeerData *migrated = nullptr);
  494. [[nodiscard]] FullMsgId ResolveMinPinnedId(
  495. not_null<PeerData*> peer,
  496. MsgId topicRootId,
  497. PeerData *migrated = nullptr);
  498. } // namespace Data