1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include "mtproto/sender.h" 11 #include "data/stickers/data_stickers_set.h" 12 #include "settings.h" 13 14 class HistoryItem; 15 class DocumentData; 16 17 namespace Main { 18 class Session; 19 } // namespace Main 20 21 namespace Data { 22 23 class Session; 24 class DocumentMedia; 25 26 class Stickers final { 27 public: 28 explicit Stickers(not_null<Session*> owner); 29 30 [[nodiscard]] Session &owner() const; 31 [[nodiscard]] Main::Session &session() const; 32 33 // for backward compatibility 34 static constexpr auto DefaultSetId = 0; 35 static constexpr auto CustomSetId = 0xFFFFFFFFFFFFFFFFULL; 36 37 // For stickers panel, should not appear in Sets. 38 static constexpr auto RecentSetId = 0xFFFFFFFFFFFFFFFEULL; 39 static constexpr auto NoneSetId = 0xFFFFFFFFFFFFFFFDULL; 40 static constexpr auto FeaturedSetId = 0xFFFFFFFFFFFFFFFBULL; 41 42 // For cloud-stored recent stickers. 43 static constexpr auto CloudRecentSetId = 0xFFFFFFFFFFFFFFFCULL; 44 static constexpr auto CloudRecentAttachedSetId = 0xFFFFFFFFFFFFFFF9ULL; 45 46 // For cloud-stored faved stickers. 47 static constexpr auto FavedSetId = 0xFFFFFFFFFFFFFFFAULL; 48 49 // For setting up megagroup sticker set. 50 static constexpr auto MegagroupSetId = 0xFFFFFFFFFFFFFFEFULL; 51 52 enum Recent { 53 Regular, 54 Attached, 55 }; 56 57 void notifyUpdated(); 58 [[nodiscard]] rpl::producer<> updated() const; 59 void notifyRecentUpdated(Recent recent = Recent::Regular); 60 [[nodiscard]] rpl::producer<Recent> recentUpdated() const; 61 void notifySavedGifsUpdated(); 62 [[nodiscard]] rpl::producer<> savedGifsUpdated() const; 63 void notifyStickerSetInstalled(uint64 setId); 64 [[nodiscard]] rpl::producer<uint64> stickerSetInstalled() const; 65 66 void incrementSticker(not_null<DocumentData*> document); 67 updateNeeded(crl::time now)68 bool updateNeeded(crl::time now) const { 69 return updateNeeded(_lastUpdate, now); 70 } setLastUpdate(crl::time update)71 void setLastUpdate(crl::time update) { 72 _lastUpdate = update; 73 } recentUpdateNeeded(crl::time now)74 bool recentUpdateNeeded(crl::time now) const { 75 return updateNeeded(_lastRecentUpdate, now); 76 } setLastRecentUpdate(crl::time update)77 void setLastRecentUpdate(crl::time update) { 78 if (update) { 79 notifyRecentUpdated(); 80 } 81 _lastRecentUpdate = update; 82 } masksUpdateNeeded(crl::time now)83 bool masksUpdateNeeded(crl::time now) const { 84 return updateNeeded(_lastMasksUpdate, now); 85 } setLastMasksUpdate(crl::time update)86 void setLastMasksUpdate(crl::time update) { 87 _lastMasksUpdate = update; 88 } recentAttachedUpdateNeeded(crl::time now)89 bool recentAttachedUpdateNeeded(crl::time now) const { 90 return updateNeeded(_lastRecentAttachedUpdate, now); 91 } setLastRecentAttachedUpdate(crl::time update)92 void setLastRecentAttachedUpdate(crl::time update) { 93 if (update) { 94 notifyRecentUpdated(Recent::Attached); 95 } 96 _lastRecentAttachedUpdate = update; 97 } favedUpdateNeeded(crl::time now)98 bool favedUpdateNeeded(crl::time now) const { 99 return updateNeeded(_lastFavedUpdate, now); 100 } setLastFavedUpdate(crl::time update)101 void setLastFavedUpdate(crl::time update) { 102 _lastFavedUpdate = update; 103 } featuredUpdateNeeded(crl::time now)104 bool featuredUpdateNeeded(crl::time now) const { 105 return updateNeeded(_lastFeaturedUpdate, now); 106 } setLastFeaturedUpdate(crl::time update)107 void setLastFeaturedUpdate(crl::time update) { 108 _lastFeaturedUpdate = update; 109 } savedGifsUpdateNeeded(crl::time now)110 bool savedGifsUpdateNeeded(crl::time now) const { 111 return updateNeeded(_lastSavedGifsUpdate, now); 112 } setLastSavedGifsUpdate(crl::time update)113 void setLastSavedGifsUpdate(crl::time update) { 114 _lastSavedGifsUpdate = update; 115 } featuredSetsUnreadCount()116 int featuredSetsUnreadCount() const { 117 return _featuredSetsUnreadCount.current(); 118 } setFeaturedSetsUnreadCount(int count)119 void setFeaturedSetsUnreadCount(int count) { 120 _featuredSetsUnreadCount = count; 121 } featuredSetsUnreadCountValue()122 [[nodiscard]] rpl::producer<int> featuredSetsUnreadCountValue() const { 123 return _featuredSetsUnreadCount.value(); 124 } sets()125 const StickersSets &sets() const { 126 return _sets; 127 } setsRef()128 StickersSets &setsRef() { 129 return _sets; 130 } setsOrder()131 const StickersSetsOrder &setsOrder() const { 132 return _setsOrder; 133 } setsOrderRef()134 StickersSetsOrder &setsOrderRef() { 135 return _setsOrder; 136 } maskSetsOrder()137 const StickersSetsOrder &maskSetsOrder() const { 138 return _maskSetsOrder; 139 } maskSetsOrderRef()140 StickersSetsOrder &maskSetsOrderRef() { 141 return _maskSetsOrder; 142 } featuredSetsOrder()143 const StickersSetsOrder &featuredSetsOrder() const { 144 return _featuredSetsOrder; 145 } featuredSetsOrderRef()146 StickersSetsOrder &featuredSetsOrderRef() { 147 return _featuredSetsOrder; 148 } archivedSetsOrder()149 const StickersSetsOrder &archivedSetsOrder() const { 150 return _archivedSetsOrder; 151 } archivedSetsOrderRef()152 StickersSetsOrder &archivedSetsOrderRef() { 153 return _archivedSetsOrder; 154 } archivedMaskSetsOrder()155 const StickersSetsOrder &archivedMaskSetsOrder() const { 156 return _archivedMaskSetsOrder; 157 } archivedMaskSetsOrderRef()158 StickersSetsOrder &archivedMaskSetsOrderRef() { 159 return _archivedMaskSetsOrder; 160 } savedGifs()161 const SavedGifs &savedGifs() const { 162 return _savedGifs; 163 } savedGifsRef()164 SavedGifs &savedGifsRef() { 165 return _savedGifs; 166 } 167 void removeFromRecentSet(not_null<DocumentData*> document); 168 169 void addSavedGif(not_null<DocumentData*> document); 170 void checkSavedGif(not_null<HistoryItem*> item); 171 172 void applyArchivedResult( 173 const MTPDmessages_stickerSetInstallResultArchive &d); 174 void installLocally(uint64 setId); 175 void undoInstallLocally(uint64 setId); 176 bool isFaved(not_null<const DocumentData*> document); 177 void setFaved(not_null<DocumentData*> document, bool faved); 178 179 void setsReceived(const QVector<MTPStickerSet> &data, uint64 hash); 180 void masksReceived(const QVector<MTPStickerSet> &data, uint64 hash); 181 void specialSetReceived( 182 uint64 setId, 183 const QString &setTitle, 184 const QVector<MTPDocument> &items, 185 uint64 hash, 186 const QVector<MTPStickerPack> &packs = QVector<MTPStickerPack>(), 187 const QVector<MTPint> &usageDates = QVector<MTPint>()); 188 void featuredSetsReceived( 189 const QVector<MTPStickerSetCovered> &list, 190 const QVector<MTPlong> &unread, 191 uint64 hash); 192 void gifsReceived(const QVector<MTPDocument> &items, uint64 hash); 193 194 std::vector<not_null<DocumentData*>> getListByEmoji( 195 not_null<EmojiPtr> emoji, 196 uint64 seed); 197 std::optional<std::vector<not_null<EmojiPtr>>> getEmojiListFromSet( 198 not_null<DocumentData*> document); 199 200 StickersSet *feedSet(const MTPDstickerSet &data); 201 StickersSet *feedSetFull(const MTPmessages_StickerSet &data); 202 void newSetReceived(const MTPmessages_StickerSet &data); 203 204 QString getSetTitle(const MTPDstickerSet &s); 205 206 RecentStickerPack &getRecentPack() const; 207 208 private: updateNeeded(crl::time lastUpdate,crl::time now)209 bool updateNeeded(crl::time lastUpdate, crl::time now) const { 210 constexpr auto kUpdateTimeout = crl::time(3600'000); 211 return (lastUpdate == 0) 212 || (now >= lastUpdate + kUpdateTimeout); 213 } 214 void checkFavedLimit(StickersSet &set); 215 void setIsFaved( 216 not_null<DocumentData*> document, 217 std::optional<std::vector<not_null<EmojiPtr>>> emojiList 218 = std::nullopt); 219 void setIsNotFaved(not_null<DocumentData*> document); 220 void pushFavedToFront( 221 StickersSet &set, 222 not_null<DocumentData*> document, 223 const std::vector<not_null<EmojiPtr>> &emojiList); 224 void moveFavedToFront(StickersSet &set, int index); 225 void requestSetToPushFaved(not_null<DocumentData*> document); 226 void setPackAndEmoji( 227 StickersSet &set, 228 StickersPack &&pack, 229 const std::vector<TimeId> &&dates, 230 const QVector<MTPStickerPack> &packs); 231 void setsOrMasksReceived( 232 const QVector<MTPStickerSet> &data, 233 uint64 hash, 234 bool masks); 235 236 const not_null<Session*> _owner; 237 rpl::event_stream<> _updated; 238 rpl::event_stream<Recent> _recentUpdated; 239 rpl::event_stream<> _savedGifsUpdated; 240 rpl::event_stream<uint64> _stickerSetInstalled; 241 crl::time _lastUpdate = 0; 242 crl::time _lastRecentUpdate = 0; 243 crl::time _lastFavedUpdate = 0; 244 crl::time _lastFeaturedUpdate = 0; 245 crl::time _lastSavedGifsUpdate = 0; 246 crl::time _lastMasksUpdate = 0; 247 crl::time _lastRecentAttachedUpdate = 0; 248 rpl::variable<int> _featuredSetsUnreadCount = 0; 249 StickersSets _sets; 250 StickersSetsOrder _setsOrder; 251 StickersSetsOrder _maskSetsOrder; 252 StickersSetsOrder _featuredSetsOrder; 253 StickersSetsOrder _archivedSetsOrder; 254 StickersSetsOrder _archivedMaskSetsOrder; 255 SavedGifs _savedGifs; 256 257 }; 258 259 } // namespace Data 260