data_stickers.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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 "mtproto/sender.h"
  9. #include "data/stickers/data_stickers_set.h"
  10. #include "settings.h"
  11. class HistoryItem;
  12. class DocumentData;
  13. namespace Main {
  14. class Session;
  15. } // namespace Main
  16. namespace Window {
  17. class SessionController;
  18. } // namespace Window
  19. namespace ChatHelpers {
  20. class Show;
  21. } // namespace ChatHelpers
  22. namespace Data {
  23. class Session;
  24. class DocumentMedia;
  25. enum class StickersType : uchar {
  26. Stickers,
  27. Masks,
  28. Emoji,
  29. };
  30. [[nodiscard]] StickerType ThumbnailTypeFromPhotoSize(
  31. const MTPPhotoSize &size);
  32. class Stickers final {
  33. public:
  34. explicit Stickers(not_null<Session*> owner);
  35. [[nodiscard]] Session &owner() const;
  36. [[nodiscard]] Main::Session &session() const;
  37. // for backward compatibility
  38. static constexpr auto DefaultSetId = 0;
  39. static constexpr auto CustomSetId = 0xFFFFFFFFFFFFFFFFULL;
  40. // For stickers panel, should not appear in Sets.
  41. static constexpr auto RecentSetId = 0xFFFFFFFFFFFFFFFEULL;
  42. static constexpr auto NoneSetId = 0xFFFFFFFFFFFFFFFDULL;
  43. static constexpr auto FeaturedSetId = 0xFFFFFFFFFFFFFFFBULL;
  44. // For cloud-stored recent stickers.
  45. static constexpr auto CloudRecentSetId = 0xFFFFFFFFFFFFFFFCULL;
  46. static constexpr auto CloudRecentAttachedSetId = 0xFFFFFFFFFFFFFFF9ULL;
  47. // For cloud-stored faved stickers.
  48. static constexpr auto FavedSetId = 0xFFFFFFFFFFFFFFFAULL;
  49. // For setting up megagroup sticker set.
  50. static constexpr auto MegagroupSetId = 0xFFFFFFFFFFFFFFEFULL;
  51. // For collectible emoji statuses.
  52. static constexpr auto CollectibleSetId = 0xFFFFFFFFFFFFFFF8ULL;
  53. void notifyUpdated(StickersType type);
  54. [[nodiscard]] rpl::producer<StickersType> updated() const;
  55. [[nodiscard]] rpl::producer<> updated(StickersType type) const;
  56. void notifyRecentUpdated(StickersType type);
  57. [[nodiscard]] rpl::producer<StickersType> recentUpdated() const;
  58. [[nodiscard]] rpl::producer<> recentUpdated(StickersType type) const;
  59. void notifySavedGifsUpdated();
  60. [[nodiscard]] rpl::producer<> savedGifsUpdated() const;
  61. void notifyStickerSetInstalled(uint64 setId);
  62. [[nodiscard]] rpl::producer<uint64> stickerSetInstalled() const;
  63. void notifyEmojiSetInstalled(uint64 setId);
  64. [[nodiscard]] rpl::producer<uint64> emojiSetInstalled() const;
  65. void incrementSticker(not_null<DocumentData*> document);
  66. [[nodiscard]] bool updateNeeded(crl::time now) const {
  67. return updateNeeded(_lastUpdate, now);
  68. }
  69. void setLastUpdate(crl::time update) {
  70. _lastUpdate = update;
  71. }
  72. [[nodiscard]] bool recentUpdateNeeded(crl::time now) const {
  73. return updateNeeded(_lastRecentUpdate, now);
  74. }
  75. void setLastRecentUpdate(crl::time update) {
  76. if (update) {
  77. notifyRecentUpdated(StickersType::Stickers);
  78. }
  79. _lastRecentUpdate = update;
  80. }
  81. [[nodiscard]] bool masksUpdateNeeded(crl::time now) const {
  82. return updateNeeded(_lastMasksUpdate, now);
  83. }
  84. void setLastMasksUpdate(crl::time update) {
  85. _lastMasksUpdate = update;
  86. }
  87. [[nodiscard]] bool emojiUpdateNeeded(crl::time now) const {
  88. return updateNeeded(_lastEmojiUpdate, now);
  89. }
  90. void setLastEmojiUpdate(crl::time update) {
  91. _lastEmojiUpdate = update;
  92. }
  93. [[nodiscard]] bool recentAttachedUpdateNeeded(crl::time now) const {
  94. return updateNeeded(_lastRecentAttachedUpdate, now);
  95. }
  96. void setLastRecentAttachedUpdate(crl::time update) {
  97. if (update) {
  98. notifyRecentUpdated(StickersType::Masks);
  99. }
  100. _lastRecentAttachedUpdate = update;
  101. }
  102. [[nodiscard]] bool favedUpdateNeeded(crl::time now) const {
  103. return updateNeeded(_lastFavedUpdate, now);
  104. }
  105. void setLastFavedUpdate(crl::time update) {
  106. _lastFavedUpdate = update;
  107. }
  108. [[nodiscard]] bool featuredUpdateNeeded(crl::time now) const {
  109. return updateNeeded(_lastFeaturedUpdate, now);
  110. }
  111. void setLastFeaturedUpdate(crl::time update) {
  112. _lastFeaturedUpdate = update;
  113. }
  114. [[nodiscard]] bool featuredEmojiUpdateNeeded(crl::time now) const {
  115. return updateNeeded(_lastFeaturedEmojiUpdate, now);
  116. }
  117. void setLastFeaturedEmojiUpdate(crl::time update) {
  118. _lastFeaturedEmojiUpdate = update;
  119. }
  120. [[nodiscard]] bool savedGifsUpdateNeeded(crl::time now) const {
  121. return updateNeeded(_lastSavedGifsUpdate, now);
  122. }
  123. void setLastSavedGifsUpdate(crl::time update) {
  124. _lastSavedGifsUpdate = update;
  125. }
  126. [[nodiscard]] int featuredSetsUnreadCount() const {
  127. return _featuredSetsUnreadCount.current();
  128. }
  129. void setFeaturedSetsUnreadCount(int count) {
  130. _featuredSetsUnreadCount = count;
  131. }
  132. [[nodiscard]] rpl::producer<int> featuredSetsUnreadCountValue() const {
  133. return _featuredSetsUnreadCount.value();
  134. }
  135. [[nodiscard]] const StickersSets &sets() const {
  136. return _sets;
  137. }
  138. [[nodiscard]] StickersSets &setsRef() {
  139. return _sets;
  140. }
  141. [[nodiscard]] const StickersSetsOrder &setsOrder() const {
  142. return _setsOrder;
  143. }
  144. [[nodiscard]] StickersSetsOrder &setsOrderRef() {
  145. return _setsOrder;
  146. }
  147. [[nodiscard]] const StickersSetsOrder &maskSetsOrder() const {
  148. return _maskSetsOrder;
  149. }
  150. [[nodiscard]] StickersSetsOrder &maskSetsOrderRef() {
  151. return _maskSetsOrder;
  152. }
  153. [[nodiscard]] const StickersSetsOrder &emojiSetsOrder() const {
  154. return _emojiSetsOrder;
  155. }
  156. [[nodiscard]] StickersSetsOrder &emojiSetsOrderRef() {
  157. return _emojiSetsOrder;
  158. }
  159. [[nodiscard]] const StickersSetsOrder &featuredSetsOrder() const {
  160. return _featuredSetsOrder;
  161. }
  162. [[nodiscard]] StickersSetsOrder &featuredSetsOrderRef() {
  163. return _featuredSetsOrder;
  164. }
  165. [[nodiscard]] const StickersSetsOrder &featuredEmojiSetsOrder() const {
  166. return _featuredEmojiSetsOrder;
  167. }
  168. [[nodiscard]] StickersSetsOrder &featuredEmojiSetsOrderRef() {
  169. return _featuredEmojiSetsOrder;
  170. }
  171. [[nodiscard]] const StickersSetsOrder &archivedSetsOrder() const {
  172. return _archivedSetsOrder;
  173. }
  174. [[nodiscard]] StickersSetsOrder &archivedSetsOrderRef() {
  175. return _archivedSetsOrder;
  176. }
  177. [[nodiscard]] const StickersSetsOrder &archivedMaskSetsOrder() const {
  178. return _archivedMaskSetsOrder;
  179. }
  180. [[nodiscard]] StickersSetsOrder &archivedMaskSetsOrderRef() {
  181. return _archivedMaskSetsOrder;
  182. }
  183. [[nodiscard]] const SavedGifs &savedGifs() const {
  184. return _savedGifs;
  185. }
  186. [[nodiscard]] SavedGifs &savedGifsRef() {
  187. return _savedGifs;
  188. }
  189. void removeFromRecentSet(not_null<DocumentData*> document);
  190. void addSavedGif(
  191. std::shared_ptr<ChatHelpers::Show> show,
  192. not_null<DocumentData*> document);
  193. void checkSavedGif(not_null<HistoryItem*> item);
  194. void applyArchivedResult(
  195. const MTPDmessages_stickerSetInstallResultArchive &d);
  196. void installLocally(uint64 setId);
  197. void undoInstallLocally(uint64 setId);
  198. [[nodiscard]] bool isFaved(not_null<const DocumentData*> document) const;
  199. void setFaved(
  200. std::shared_ptr<ChatHelpers::Show> show,
  201. not_null<DocumentData*> document,
  202. bool faved);
  203. void setsReceived(const QVector<MTPStickerSet> &data, uint64 hash);
  204. void masksReceived(const QVector<MTPStickerSet> &data, uint64 hash);
  205. void emojiReceived(const QVector<MTPStickerSet> &data, uint64 hash);
  206. void specialSetReceived(
  207. uint64 setId,
  208. const QString &setTitle,
  209. const QVector<MTPDocument> &items,
  210. uint64 hash,
  211. const QVector<MTPStickerPack> &packs = QVector<MTPStickerPack>(),
  212. const QVector<MTPint> &usageDates = QVector<MTPint>());
  213. void featuredSetsReceived(const MTPmessages_FeaturedStickers &result);
  214. void featuredEmojiSetsReceived(
  215. const MTPmessages_FeaturedStickers &result);
  216. void gifsReceived(const QVector<MTPDocument> &items, uint64 hash);
  217. [[nodiscard]] std::vector<not_null<DocumentData*>> getPremiumList(
  218. uint64 seed);
  219. [[nodiscard]] std::vector<not_null<DocumentData*>> getListByEmoji(
  220. std::vector<EmojiPtr> emoji,
  221. uint64 seed,
  222. bool forceAllResults = false);
  223. [[nodiscard]] auto getEmojiListFromSet(not_null<DocumentData*> document)
  224. -> std::optional<std::vector<not_null<EmojiPtr>>>;
  225. [[nodiscard]] not_null<StickersSet*> collectibleSet();
  226. not_null<StickersSet*> feedSet(const MTPStickerSet &data);
  227. not_null<StickersSet*> feedSet(const MTPStickerSetCovered &data);
  228. not_null<StickersSet*> feedSetFull(const MTPDmessages_stickerSet &data);
  229. void feedSetStickers(
  230. not_null<StickersSet*> set,
  231. const QVector<MTPDocument> &documents,
  232. const QVector<MTPStickerPack> &packs);
  233. void feedSetCovers(
  234. not_null<StickersSet*> set,
  235. const QVector<MTPDocument> &documents);
  236. void newSetReceived(const MTPDmessages_stickerSet &set);
  237. [[nodiscard]] QString getSetTitle(const MTPDstickerSet &s);
  238. [[nodiscard]] RecentStickerPack &getRecentPack() const;
  239. private:
  240. [[nodiscard]] bool updateNeeded(crl::time last, crl::time now) const {
  241. constexpr auto kUpdateTimeout = crl::time(3600'000);
  242. return (last == 0) || (now >= last + kUpdateTimeout);
  243. }
  244. void checkFavedLimit(
  245. StickersSet &set,
  246. std::shared_ptr<ChatHelpers::Show> show);
  247. void setIsFaved(
  248. std::shared_ptr<ChatHelpers::Show> show,
  249. not_null<DocumentData*> document,
  250. std::optional<std::vector<not_null<EmojiPtr>>> emojiList
  251. = std::nullopt);
  252. void setIsNotFaved(not_null<DocumentData*> document);
  253. void pushFavedToFront(
  254. StickersSet &set,
  255. std::shared_ptr<ChatHelpers::Show> show,
  256. not_null<DocumentData*> document,
  257. const std::vector<not_null<EmojiPtr>> &emojiList);
  258. void moveFavedToFront(StickersSet &set, int index);
  259. void requestSetToPushFaved(
  260. std::shared_ptr<ChatHelpers::Show> show,
  261. not_null<DocumentData*> document);
  262. void setPackAndEmoji(
  263. StickersSet &set,
  264. StickersPack &&pack,
  265. const std::vector<TimeId> &&dates,
  266. const QVector<MTPStickerPack> &packs);
  267. void somethingReceived(
  268. const QVector<MTPStickerSet> &list,
  269. uint64 hash,
  270. StickersType type);
  271. void featuredReceived(
  272. const MTPDmessages_featuredStickers &data,
  273. StickersType type);
  274. const not_null<Session*> _owner;
  275. rpl::event_stream<StickersType> _updated;
  276. rpl::event_stream<StickersType> _recentUpdated;
  277. rpl::event_stream<> _savedGifsUpdated;
  278. rpl::event_stream<uint64> _stickerSetInstalled;
  279. rpl::event_stream<uint64> _emojiSetInstalled;
  280. crl::time _lastUpdate = 0;
  281. crl::time _lastRecentUpdate = 0;
  282. crl::time _lastFavedUpdate = 0;
  283. crl::time _lastFeaturedUpdate = 0;
  284. crl::time _lastSavedGifsUpdate = 0;
  285. crl::time _lastMasksUpdate = 0;
  286. crl::time _lastEmojiUpdate = 0;
  287. crl::time _lastFeaturedEmojiUpdate = 0;
  288. crl::time _lastRecentAttachedUpdate = 0;
  289. rpl::variable<int> _featuredSetsUnreadCount = 0;
  290. StickersSets _sets;
  291. StickersSetsOrder _setsOrder;
  292. StickersSetsOrder _maskSetsOrder;
  293. StickersSetsOrder _emojiSetsOrder;
  294. StickersSetsOrder _featuredSetsOrder;
  295. StickersSetsOrder _featuredEmojiSetsOrder;
  296. StickersSetsOrder _archivedSetsOrder;
  297. StickersSetsOrder _archivedMaskSetsOrder;
  298. SavedGifs _savedGifs;
  299. };
  300. } // namespace Data