diff --git a/Telegram/Resources/scheme.tl b/Telegram/Resources/scheme.tl index 11323f5423..aab00c1123 100644 --- a/Telegram/Resources/scheme.tl +++ b/Telegram/Resources/scheme.tl @@ -463,7 +463,7 @@ upload.fileCdnRedirect#ea52fe5a dc_id:int file_token:bytes encryption_key:bytes dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int = DcOption; -config#9c840964 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int disabled_features:Vector = Config; +config#9c840964 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured:flags.4?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int disabled_features:Vector = Config; nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc; @@ -607,7 +607,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet; inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet; inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet; -stickerSet#cd303b41 flags:# installed:flags.0?true archived:flags.1?true official:flags.2?true masks:flags.3?true id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet; +stickerSet#5585a139 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet; messages.stickerSet#b60a24a6 set:StickerSet packs:Vector documents:Vector = messages.StickerSet; @@ -754,7 +754,7 @@ messages.featuredStickersNotModified#4ede3cf = messages.FeaturedStickers; messages.featuredStickers#f89d88e5 hash:int sets:Vector unread:Vector = messages.FeaturedStickers; messages.recentStickersNotModified#b17f890 = messages.RecentStickers; -messages.recentStickers#5ce20970 hash:int stickers:Vector = messages.RecentStickers; +messages.recentStickers#22f3afb3 hash:int packs:Vector stickers:Vector dates:Vector = messages.RecentStickers; messages.archivedStickers#4fcba9c8 count:int sets:Vector = messages.ArchivedStickers; @@ -956,6 +956,10 @@ inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer; dialogPeerFeed#da429411 feed_id:int = DialogPeer; dialogPeer#e56dbf05 peer:Peer = DialogPeer; +webAuthorization#cac943f2 hash:long bot_id:int domain:string browser:string platform:string date_created:int date_active:int ip:string region:string = WebAuthorization; + +account.webAuthorizations#ed56c9fc authorizations:Vector users:Vector = account.WebAuthorizations; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1009,6 +1013,9 @@ account.updatePasswordSettings#fa7c4b86 current_password_hash:bytes new_settings account.sendConfirmPhoneCode#1516d7bd flags:# allow_flashcall:flags.0?true hash:string current_number:flags.0?Bool = auth.SentCode; account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool; account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPassword; +account.getWebAuthorizations#182e6d6f = account.WebAuthorizations; +account.resetWebAuthorization#2d01b9ef hash:long = Bool; +account.resetWebAuthorizations#682d2594 = Bool; users.getUsers#d91a548 id:Vector = Vector; users.getFullUser#ca30a5b1 id:InputUser = UserFull; @@ -1063,6 +1070,7 @@ messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long da messages.receivedQueue#55a5bb66 max_qts:int = Vector; messages.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool; messages.readMessageContents#36a73f77 id:Vector = messages.AffectedMessages; +messages.getStickers#85cb5182 flags:# exclude_featured:flags.0?true emoticon:string hash:string = messages.Stickers; messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers; messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector = MessageMedia; messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 0410e5335b..1b7de76569 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -512,9 +512,13 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt auto stickersChanged = (canEditStickers != channel->canEditStickers()); auto stickerSet = (f.has_stickerset() ? &f.vstickerset.c_stickerSet() : nullptr); auto newSetId = (stickerSet ? stickerSet->vid.v : 0); - auto oldSetId = (channel->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) ? channel->mgInfo->stickerSet.c_inputStickerSetID().vid.v : 0; + auto oldSetId = (channel->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) + ? channel->mgInfo->stickerSet.c_inputStickerSetID().vid.v + : 0; if (oldSetId != newSetId) { - channel->mgInfo->stickerSet = stickerSet ? MTP_inputStickerSetID(stickerSet->vid, stickerSet->vaccess_hash) : MTP_inputStickerSetEmpty(); + channel->mgInfo->stickerSet = stickerSet + ? MTP_inputStickerSetID(stickerSet->vid, stickerSet->vaccess_hash) + : MTP_inputStickerSetEmpty(); stickersChanged = true; } if (stickersChanged) { @@ -1131,7 +1135,9 @@ void ApiWrap::requestStickerSets() { } } -void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers::Order &localRemoved) { +void ApiWrap::saveStickerSets( + const Stickers::Order &localOrder, + const Stickers::Order &localRemoved) { for (auto requestId : base::take(_stickerSetDisenableRequests)) { request(requestId).cancel(); } @@ -1187,13 +1193,15 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers: int removeIndex = _session->data().stickerSetsOrder().indexOf(it->id); if (removeIndex >= 0) _session->data().stickerSetsOrderRef().removeAt(removeIndex); - if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured) && !(it->flags & MTPDstickerSet_ClientFlag::f_special)) { + if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured) + && !(it->flags & MTPDstickerSet_ClientFlag::f_special)) { sets.erase(it); } else { if (it->flags & MTPDstickerSet::Flag::f_archived) { writeArchived = true; } - it->flags &= ~(MTPDstickerSet::Flag::f_installed | MTPDstickerSet::Flag::f_archived); + it->flags &= ~(MTPDstickerSet::Flag::f_installed_date | MTPDstickerSet::Flag::f_archived); + it->installDate = TimeId(0); } } } @@ -1202,7 +1210,7 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers: // Clear all installed flags, set only for sets from order. for (auto &set : sets) { if (!(set.flags & MTPDstickerSet::Flag::f_archived)) { - set.flags &= ~MTPDstickerSet::Flag::f_installed; + set.flags &= ~MTPDstickerSet::Flag::f_installed_date; } } @@ -1226,12 +1234,15 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers: writeArchived = true; } order.push_back(setId); - it->flags |= MTPDstickerSet::Flag::f_installed; + it->flags |= MTPDstickerSet::Flag::f_installed_date; + if (!it->installDate) { + it->installDate = unixtime(); + } } } for (auto it = sets.begin(); it != sets.cend();) { if ((it->flags & MTPDstickerSet_ClientFlag::f_featured) - || (it->flags & MTPDstickerSet::Flag::f_installed) + || (it->flags & MTPDstickerSet::Flag::f_installed_date) || (it->flags & MTPDstickerSet::Flag::f_archived) || (it->flags & MTPDstickerSet_ClientFlag::f_special)) { ++it; @@ -1892,7 +1903,10 @@ void ApiWrap::requestRecentStickers(TimeId now) { || _recentStickersUpdateRequest) { return; } - auto onDone = [this](const MTPmessages_RecentStickers &result) { + _recentStickersUpdateRequest = request(MTPmessages_GetRecentStickers( + MTP_flags(0), + MTP_int(Local::countRecentStickersHash()) + )).done([=](const MTPmessages_RecentStickers &result) { _session->data().setLastRecentStickersUpdate(getms(true)); _recentStickersUpdateRequest = 0; @@ -1900,14 +1914,20 @@ void ApiWrap::requestRecentStickers(TimeId now) { case mtpc_messages_recentStickersNotModified: return; case mtpc_messages_recentStickers: { auto &d = result.c_messages_recentStickers(); - Stickers::SpecialSetReceived(Stickers::CloudRecentSetId, lang(lng_recent_stickers), d.vstickers.v, d.vhash.v); + Stickers::SpecialSetReceived( + Stickers::CloudRecentSetId, + lang(lng_recent_stickers), + d.vstickers.v, + d.vhash.v, + d.vpacks.v); } return; default: Unexpected("Type in ApiWrap::recentStickersDone()"); } - }; - _recentStickersUpdateRequest = request(MTPmessages_GetRecentStickers(MTP_flags(0), MTP_int(Local::countRecentStickersHash()))).done(onDone).fail([this, onDone](const RPCError &error) { + }).fail([=](const RPCError &error) { + _session->data().setLastRecentStickersUpdate(getms(true)); + _recentStickersUpdateRequest = 0; + LOG(("App Fail: Failed to get recent stickers!")); - onDone(MTP_messages_recentStickersNotModified()); }).send(); } @@ -1916,7 +1936,9 @@ void ApiWrap::requestFavedStickers(TimeId now) { || _favedStickersUpdateRequest) { return; } - auto onDone = [this](const MTPmessages_FavedStickers &result) { + _favedStickersUpdateRequest = request(MTPmessages_GetFavedStickers( + MTP_int(Local::countFavedStickersHash()) + )).done([=](const MTPmessages_FavedStickers &result) { _session->data().setLastFavedStickersUpdate(getms(true)); _favedStickersUpdateRequest = 0; @@ -1924,14 +1946,20 @@ void ApiWrap::requestFavedStickers(TimeId now) { case mtpc_messages_favedStickersNotModified: return; case mtpc_messages_favedStickers: { auto &d = result.c_messages_favedStickers(); - Stickers::SpecialSetReceived(Stickers::FavedSetId, Lang::Hard::FavedSetTitle(), d.vstickers.v, d.vhash.v, d.vpacks.v); + Stickers::SpecialSetReceived( + Stickers::FavedSetId, + Lang::Hard::FavedSetTitle(), + d.vstickers.v, + d.vhash.v, + d.vpacks.v); } return; default: Unexpected("Type in ApiWrap::favedStickersDone()"); } - }; - _favedStickersUpdateRequest = request(MTPmessages_GetFavedStickers(MTP_int(Local::countFavedStickersHash()))).done(onDone).fail([this, onDone](const RPCError &error) { + }).fail([=](const RPCError &error) { + _session->data().setLastFavedStickersUpdate(getms(true)); + _favedStickersUpdateRequest = 0; + LOG(("App Fail: Failed to get faved stickers!")); - onDone(MTP_messages_favedStickersNotModified()); }).send(); } @@ -1940,7 +1968,9 @@ void ApiWrap::requestFeaturedStickers(TimeId now) { || _featuredStickersUpdateRequest) { return; } - auto onDone = [this](const MTPmessages_FeaturedStickers &result) { + _featuredStickersUpdateRequest = request(MTPmessages_GetFeaturedStickers( + MTP_int(Local::countFeaturedStickersHash()) + )).done([=](const MTPmessages_FeaturedStickers &result) { _session->data().setLastFeaturedStickersUpdate(getms(true)); _featuredStickersUpdateRequest = 0; @@ -1952,10 +1982,11 @@ void ApiWrap::requestFeaturedStickers(TimeId now) { } return; default: Unexpected("Type in ApiWrap::featuredStickersDone()"); } - }; - _featuredStickersUpdateRequest = request(MTPmessages_GetFeaturedStickers(MTP_int(Local::countFeaturedStickersHash()))).done(onDone).fail([this, onDone](const RPCError &error) { + }).fail([=](const RPCError &error) { + _session->data().setLastFeaturedStickersUpdate(getms(true)); + _featuredStickersUpdateRequest = 0; + LOG(("App Fail: Failed to get featured stickers!")); - onDone(MTP_messages_featuredStickersNotModified()); }).send(); } @@ -1964,7 +1995,9 @@ void ApiWrap::requestSavedGifs(TimeId now) { || _savedGifsUpdateRequest) { return; } - auto onDone = [this](const MTPmessages_SavedGifs &result) { + _savedGifsUpdateRequest = request(MTPmessages_GetSavedGifs( + MTP_int(Local::countSavedGifsHash()) + )).done([=](const MTPmessages_SavedGifs &result) { _session->data().setLastSavedGifsUpdate(getms(true)); _savedGifsUpdateRequest = 0; @@ -1976,10 +2009,11 @@ void ApiWrap::requestSavedGifs(TimeId now) { } return; default: Unexpected("Type in ApiWrap::savedGifsDone()"); } - }; - _savedGifsUpdateRequest = request(MTPmessages_GetSavedGifs(MTP_int(Local::countSavedGifsHash()))).done(onDone).fail([this, onDone](const RPCError &error) { + }).fail([=](const RPCError &error) { + _session->data().setLastSavedGifsUpdate(getms(true)); + _savedGifsUpdateRequest = 0; + LOG(("App Fail: Failed to get saved gifs!")); - onDone(MTP_messages_savedGifsNotModified()); }).send(); } diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index c099e92940..03a3d2de82 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -156,12 +156,16 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) { _setCount = s.vcount.v; _setHash = s.vhash.v; _setFlags = s.vflags.v; + _setInstallDate = s.has_installed_date() + ? s.vinstalled_date.v + : TimeId(0); auto &sets = Auth().data().stickerSetsRef(); auto it = sets.find(_setId); if (it != sets.cend()) { auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded | MTPDstickerSet_ClientFlag::f_unread | MTPDstickerSet_ClientFlag::f_special); _setFlags |= clientFlags; it->flags = _setFlags; + it->installDate = _setInstallDate; it->stickers = _pack; it->emoji = _emoji; } @@ -201,13 +205,25 @@ void StickerSetBox::Inner::installDone(const MTPmessages_StickerSetInstallResult Auth().data().archivedStickerSetsOrderRef().removeAt(index); } } + _setInstallDate = unixtime(); _setFlags &= ~MTPDstickerSet::Flag::f_archived; - _setFlags |= MTPDstickerSet::Flag::f_installed; + _setFlags |= MTPDstickerSet::Flag::f_installed_date; auto it = sets.find(_setId); if (it == sets.cend()) { - it = sets.insert(_setId, Stickers::Set(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags)); + it = sets.insert( + _setId, + Stickers::Set( + _setId, + _setAccess, + _setTitle, + _setShortName, + _setCount, + _setHash, + _setFlags, + _setInstallDate)); } else { it->flags = _setFlags; + it->installDate = _setInstallDate; } it->stickers = _pack; it->emoji = _emoji; @@ -396,11 +412,17 @@ bool StickerSetBox::Inner::loaded() const { return _loaded && !_pack.isEmpty(); } -int32 StickerSetBox::Inner::notInstalled() const { - if (!_loaded) return 0; - auto it = Auth().data().stickerSets().constFind(_setId); - if (it == Auth().data().stickerSets().cend() || !(it->flags & MTPDstickerSet::Flag::f_installed) || (it->flags & MTPDstickerSet::Flag::f_archived)) return _pack.size(); - return 0; +bool StickerSetBox::Inner::notInstalled() const { + if (!_loaded) { + return false; + } + const auto it = Auth().data().stickerSets().constFind(_setId); + if ((it == Auth().data().stickerSets().cend()) + || !(it->flags & MTPDstickerSet::Flag::f_installed_date) + || (it->flags & MTPDstickerSet::Flag::f_archived)) { + return _pack.size() > 0; + } + return false; } bool StickerSetBox::Inner::official() const { diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.h b/Telegram/SourceFiles/boxes/sticker_set_box.h index 733bf1efe4..2917cbe6b3 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.h +++ b/Telegram/SourceFiles/boxes/sticker_set_box.h @@ -50,7 +50,7 @@ public: Inner(QWidget *parent, const MTPInputStickerSet &set); bool loaded() const; - int32 notInstalled() const; + bool notInstalled() const; bool official() const; base::lambda title() const; QString shortName() const; @@ -98,9 +98,10 @@ private: uint64 _setId = 0; uint64 _setAccess = 0; QString _setTitle, _setShortName; - int32 _setCount = 0; + int _setCount = 0; int32 _setHash = 0; MTPDstickerSet::Flags _setFlags = 0; + TimeId _setInstallDate = TimeId(0); MTPInputStickerSet _input; diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index f7b765544a..9d943a5846 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -446,8 +446,14 @@ void StickersBox::installSet(uint64 setId) { if (_featured.widget()) _featured.widget()->setRemovedSets(_localRemoved); _archived.widget()->setRemovedSets(_localRemoved); } - if (!(it->flags & MTPDstickerSet::Flag::f_installed) || (it->flags & MTPDstickerSet::Flag::f_archived)) { - MTP::send(MTPmessages_InstallStickerSet(Stickers::inputSetId(*it), MTP_boolFalse()), rpcDone(&StickersBox::installDone), rpcFail(&StickersBox::installFail, setId)); + if (!(it->flags & MTPDstickerSet::Flag::f_installed_date) + || (it->flags & MTPDstickerSet::Flag::f_archived)) { + MTP::send( + MTPmessages_InstallStickerSet( + Stickers::inputSetId(*it), + MTP_boolFalse()), + rpcDone(&StickersBox::installDone), + rpcFail(&StickersBox::installFail, setId)); Stickers::InstallLocally(setId); } @@ -455,7 +461,8 @@ void StickersBox::installSet(uint64 setId) { void StickersBox::installDone(const MTPmessages_StickerSetInstallResult &result) { if (result.type() == mtpc_messages_stickerSetInstallResultArchive) { - Stickers::ApplyArchivedResult(result.c_messages_stickerSetInstallResultArchive()); + Stickers::ApplyArchivedResult( + result.c_messages_stickerSetInstallResultArchive()); } } @@ -1564,8 +1571,13 @@ QString StickersBox::Inner::fillSetTitle(const Stickers::Set &set, int maxNameWi return result; } -void StickersBox::Inner::fillSetFlags(const Stickers::Set &set, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outArchived) { - *outInstalled = (set.flags & MTPDstickerSet::Flag::f_installed); +void StickersBox::Inner::fillSetFlags( + const Stickers::Set &set, + bool *outInstalled, + bool *outOfficial, + bool *outUnread, + bool *outArchived) { + *outInstalled = (set.flags & MTPDstickerSet::Flag::f_installed_date); *outOfficial = (set.flags & MTPDstickerSet::Flag::f_official); *outArchived = (set.flags & MTPDstickerSet::Flag::f_archived); if (_section == Section::Featured) { diff --git a/Telegram/SourceFiles/chat_helpers/stickers.cpp b/Telegram/SourceFiles/chat_helpers/stickers.cpp index b5608f32bd..70acbadd3b 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers.cpp @@ -79,15 +79,29 @@ void ApplyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) { bool ApplyArchivedResultFake() { auto sets = QVector(); for (auto &set : Auth().data().stickerSetsRef()) { - if ((set.flags & MTPDstickerSet::Flag::f_installed) && !(set.flags & MTPDstickerSet_ClientFlag::f_special)) { + if ((set.flags & MTPDstickerSet::Flag::f_installed_date) + && !(set.flags & MTPDstickerSet_ClientFlag::f_special)) { if (rand_value() % 128 < 64) { - auto data = MTP_stickerSet(MTP_flags(set.flags | MTPDstickerSet::Flag::f_archived), MTP_long(set.id), MTP_long(set.access), MTP_string(set.title), MTP_string(set.shortName), MTP_int(set.count), MTP_int(set.hash)); - sets.push_back(MTP_stickerSetCovered(data, MTP_documentEmpty(MTP_long(0)))); + auto data = MTP_stickerSet( + MTP_flags(set.flags | MTPDstickerSet::Flag::f_archived), + MTP_int(set.installDate), + MTP_long(set.id), + MTP_long(set.access), + MTP_string(set.title), + MTP_string(set.shortName), + MTP_int(set.count), + MTP_int(set.hash)); + sets.push_back(MTP_stickerSetCovered( + data, + MTP_documentEmpty(MTP_long(0)))); } } } - if (sets.size() > 3) sets = sets.mid(0, 3); - auto fakeResult = MTP_messages_stickerSetInstallResultArchive(MTP_vector(sets)); + if (sets.size() > 3) { + sets = sets.mid(0, 3); + } + auto fakeResult = MTP_messages_stickerSetInstallResultArchive( + MTP_vector(sets)); ApplyArchivedResult(fakeResult.c_messages_stickerSetInstallResultArchive()); return true; } @@ -101,7 +115,8 @@ void InstallLocally(uint64 setId) { auto flags = it->flags; it->flags &= ~(MTPDstickerSet::Flag::f_archived | MTPDstickerSet_ClientFlag::f_unread); - it->flags |= MTPDstickerSet::Flag::f_installed; + it->flags |= MTPDstickerSet::Flag::f_installed_date; + it->installDate = unixtime(); auto changedFlags = flags ^ it->flags; auto &order = Auth().data().stickerSetsOrderRef(); @@ -124,7 +139,9 @@ void InstallLocally(uint64 setId) { } } Local::writeInstalledStickers(); - if (changedFlags & MTPDstickerSet_ClientFlag::f_unread) Local::writeFeaturedStickers(); + if (changedFlags & MTPDstickerSet_ClientFlag::f_unread) { + Local::writeFeaturedStickers(); + } if (changedFlags & MTPDstickerSet::Flag::f_archived) { auto index = Auth().data().archivedStickerSetsOrderRef().indexOf(setId); if (index >= 0) { @@ -142,7 +159,8 @@ void UndoInstallLocally(uint64 setId) { return; } - it->flags &= ~MTPDstickerSet::Flag::f_installed; + it->flags &= ~MTPDstickerSet::Flag::f_installed_date; + it->installDate = TimeId(0); auto &order = Auth().data().stickerSetsOrderRef(); int currentIndex = order.indexOf(setId); @@ -217,7 +235,15 @@ void SetIsFaved(not_null document, base::optionalstickers.indexOf(document); if (index == 0) { @@ -321,7 +347,9 @@ void SetsReceived(const QVector &data, int32 hash) { QMap setsToRequest; for (auto &set : sets) { if (!(set.flags & MTPDstickerSet::Flag::f_archived)) { - set.flags &= ~MTPDstickerSet::Flag::f_installed; // mark for removing + // Mark for removing. + set.flags &= ~MTPDstickerSet::Flag::f_installed_date; + set.installDate = 0; } } for_const (auto &setData, data) { @@ -338,7 +366,7 @@ void SetsReceived(const QVector &data, int32 hash) { auto writeRecent = false; auto &recent = GetRecentPack(); for (auto it = sets.begin(), e = sets.end(); it != e;) { - bool installed = (it->flags & MTPDstickerSet::Flag::f_installed); + bool installed = (it->flags & MTPDstickerSet::Flag::f_installed_date); bool featured = (it->flags & MTPDstickerSet_ClientFlag::f_featured); bool special = (it->flags & MTPDstickerSet_ClientFlag::f_special); bool archived = (it->flags & MTPDstickerSet::Flag::f_archived); @@ -400,7 +428,12 @@ void SetPackAndEmoji(Set &set, Pack &&pack, const QVector &packs } } -void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVector &items, int32 hash, const QVector &packs) { +void SpecialSetReceived( + uint64 setId, + const QString &setTitle, + const QVector &items, + int32 hash, + const QVector &packs) { auto &sets = Auth().data().stickerSetsRef(); auto it = sets.find(setId); @@ -411,7 +444,15 @@ void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVectortitle = setTitle; } @@ -512,13 +553,24 @@ void FeaturedSetsReceived(const QVector &data, const QVect if (set) { auto it = sets.find(set->vid.v); - auto title = GetSetTitle(*set); + const auto title = GetSetTitle(*set); + const auto installDate = set->has_installed_date() + ? set->vinstalled_date.v + : TimeId(0); if (it == sets.cend()) { auto setClientFlags = MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded; if (unreadMap.contains(set->vid.v)) { setClientFlags |= MTPDstickerSet_ClientFlag::f_unread; } - it = sets.insert(set->vid.v, Set(set->vid.v, set->vaccess_hash.v, title, qs(set->vshort_name), set->vcount.v, set->vhash.v, set->vflags.v | setClientFlags)); + it = sets.insert(set->vid.v, Set( + set->vid.v, + set->vaccess_hash.v, + title, + qs(set->vshort_name), + set->vcount.v, + set->vhash.v, + set->vflags.v | setClientFlags, + installDate)); } else { it->access = set->vaccess_hash.v; it->title = title; @@ -526,6 +578,7 @@ void FeaturedSetsReceived(const QVector &data, const QVect auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_unread | MTPDstickerSet_ClientFlag::f_not_loaded | MTPDstickerSet_ClientFlag::f_special); it->flags = set->vflags.v | clientFlags; it->flags |= MTPDstickerSet_ClientFlag::f_featured; + it->installDate = installDate; if (unreadMap.contains(it->id)) { it->flags |= MTPDstickerSet_ClientFlag::f_unread; } else { @@ -546,7 +599,7 @@ void FeaturedSetsReceived(const QVector &data, const QVect auto unreadCount = 0; for (auto it = sets.begin(), e = sets.end(); it != e;) { - bool installed = (it->flags & MTPDstickerSet::Flag::f_installed); + bool installed = (it->flags & MTPDstickerSet::Flag::f_installed_date); bool featured = (it->flags & MTPDstickerSet_ClientFlag::f_featured); bool special = (it->flags & MTPDstickerSet_ClientFlag::f_special); bool archived = (it->flags & MTPDstickerSet::Flag::f_archived); @@ -677,7 +730,15 @@ Set *FeedSet(const MTPDstickerSet &set) { auto title = GetSetTitle(set); auto flags = MTPDstickerSet::Flags(0); if (it == sets.cend()) { - it = sets.insert(set.vid.v, Stickers::Set(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | MTPDstickerSet_ClientFlag::f_not_loaded)); + it = sets.insert(set.vid.v, Stickers::Set( + set.vid.v, + set.vaccess_hash.v, + title, + qs(set.vshort_name), + set.vcount.v, + set.vhash.v, + set.vflags.v | MTPDstickerSet_ClientFlag::f_not_loaded, + set.has_installed_date() ? set.vinstalled_date.v : TimeId(0))); } else { it->access = set.vaccess_hash.v; it->title = title; @@ -685,7 +746,12 @@ Set *FeedSet(const MTPDstickerSet &set) { flags = it->flags; auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_unread | MTPDstickerSet_ClientFlag::f_not_loaded | MTPDstickerSet_ClientFlag::f_special); it->flags = set.vflags.v | clientFlags; - if (it->count != set.vcount.v || it->hash != set.vhash.v || it->emoji.isEmpty()) { + it->installDate = set.has_installed_date() + ? set.vinstalled_date.v + : TimeId(0); + if (it->count != set.vcount.v + || it->hash != set.vhash.v + || it->emoji.isEmpty()) { it->count = set.vcount.v; it->hash = set.vhash.v; it->flags |= MTPDstickerSet_ClientFlag::f_not_loaded; // need to request this set @@ -782,7 +848,7 @@ Set *FeedSetFull(const MTPmessages_StickerSet &data) { } if (set) { - if (set->flags & MTPDstickerSet::Flag::f_installed) { + if (set->flags & MTPDstickerSet::Flag::f_installed_date) { if (!(set->flags & MTPDstickerSet::Flag::f_archived)) { Local::writeInstalledStickers(); } diff --git a/Telegram/SourceFiles/chat_helpers/stickers.h b/Telegram/SourceFiles/chat_helpers/stickers.h index f3f4bff2e7..89ce9a6a5f 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers.h +++ b/Telegram/SourceFiles/chat_helpers/stickers.h @@ -26,19 +26,31 @@ using Pack = QVector; using ByEmojiMap = QMap; struct Set { - Set(uint64 id, uint64 access, const QString &title, const QString &shortName, int32 count, int32 hash, MTPDstickerSet::Flags flags) - : id(id) - , access(access) - , title(title) - , shortName(shortName) - , count(count) - , hash(hash) - , flags(flags) { + Set( + uint64 id, + uint64 access, + const QString &title, + const QString &shortName, + int count, + int32 hash, + MTPDstickerSet::Flags flags, + TimeId installDate) + : id(id) + , access(access) + , title(title) + , shortName(shortName) + , count(count) + , hash(hash) + , flags(flags) + , installDate(installDate) { } - uint64 id, access; + uint64 id = 0; + uint64 access = 0; QString title, shortName; - int32 count, hash; + int count = 0; + int32 hash = 0; MTPDstickerSet::Flags flags; + TimeId installDate = 0; Pack stickers; ByEmojiMap emoji; }; @@ -59,8 +71,16 @@ bool IsFaved(not_null document); void SetFaved(not_null document, bool faved); void SetsReceived(const QVector &data, int32 hash); -void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVector &items, int32 hash, const QVector &packs = QVector()); -void FeaturedSetsReceived(const QVector &data, const QVector &unread, int32 hash); +void SpecialSetReceived( + uint64 setId, + const QString &setTitle, + const QVector &items, + int32 hash, + const QVector &packs = QVector()); +void FeaturedSetsReceived( + const QVector &data, + const QVector &unread, + int32 hash); void GifsReceived(const QVector &items, int32 hash); Pack GetListByEmoji(not_null emoji); diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index ec912821cd..dc915302ba 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -914,7 +914,8 @@ bool StickersListWidget::featuredHasAddButton(int index) const { return false; } auto flags = _featuredSets[index].flags; - return !(flags & MTPDstickerSet::Flag::f_installed) || (flags & MTPDstickerSet::Flag::f_archived); + return !(flags & MTPDstickerSet::Flag::f_installed_date) + || (flags & MTPDstickerSet::Flag::f_archived); } QRect StickersListWidget::featuredAddRect(int index) const { @@ -1295,15 +1296,27 @@ void StickersListWidget::appendSet( AppendSkip skip) { auto &sets = Auth().data().stickerSets(); auto it = sets.constFind(setId); - if (it == sets.cend() || it->stickers.isEmpty()) return; - if ((skip == AppendSkip::Archived) && (it->flags & MTPDstickerSet::Flag::f_archived)) return; - if ((skip == AppendSkip::Installed) && (it->flags & MTPDstickerSet::Flag::f_installed) && !(it->flags & MTPDstickerSet::Flag::f_archived)) { + if (it == sets.cend() || it->stickers.isEmpty()) { + return; + } + if ((skip == AppendSkip::Archived) + && (it->flags & MTPDstickerSet::Flag::f_archived)) { + return; + } + if ((skip == AppendSkip::Installed) + && (it->flags & MTPDstickerSet::Flag::f_installed_date) + && !(it->flags & MTPDstickerSet::Flag::f_archived)) { if (!_installedLocallySets.contains(setId)) { return; } } - to.push_back(Set(it->id, it->flags, it->title, it->stickers.size() + 1, it->stickers)); + to.push_back(Set( + it->id, + it->flags, + it->title, + it->stickers.size() + 1, + it->stickers)); } void StickersListWidget::refreshRecent() { @@ -1417,7 +1430,7 @@ void StickersListWidget::refreshMegagroupStickers(GroupStickersPlace place) { auto &sets = Auth().data().stickerSets(); auto it = sets.constFind(set.vid.v); if (it != sets.cend()) { - auto isInstalled = (it->flags & MTPDstickerSet::Flag::f_installed) + auto isInstalled = (it->flags & MTPDstickerSet::Flag::f_installed_date) && !(it->flags & MTPDstickerSet::Flag::f_archived); if (isInstalled && !canEdit) { removeHiddenForGroup(); @@ -1800,8 +1813,10 @@ void StickersListWidget::removeSet(uint64 setId) { ++i; } } - it->flags &= ~MTPDstickerSet::Flag::f_installed; - if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured) && !(it->flags & MTPDstickerSet_ClientFlag::f_special)) { + it->flags &= ~MTPDstickerSet::Flag::f_installed_date; + it->installDate = TimeId(0); + if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured) + && !(it->flags & MTPDstickerSet_ClientFlag::f_special)) { sets.erase(it); } int removeIndex = Auth().data().stickerSetsOrder().indexOf(_removingSetId); diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 999bf5961b..3afdd21e2d 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -155,14 +155,18 @@ QString saveFileName(const QString &title, const QString &filter, const QString bool StickerData::setInstalled() const { switch (set.type()) { case mtpc_inputStickerSetID: { - auto it = Auth().data().stickerSets().constFind(set.c_inputStickerSetID().vid.v); - return (it != Auth().data().stickerSets().cend()) && !(it->flags & MTPDstickerSet::Flag::f_archived) && (it->flags & MTPDstickerSet::Flag::f_installed); + auto it = Auth().data().stickerSets().constFind( + set.c_inputStickerSetID().vid.v); + return (it != Auth().data().stickerSets().cend()) + && !(it->flags & MTPDstickerSet::Flag::f_archived) + && (it->flags & MTPDstickerSet::Flag::f_installed_date); } break; case mtpc_inputStickerSetShortName: { auto name = qs(set.c_inputStickerSetShortName().vshort_name).toLower(); for (auto it = Auth().data().stickerSets().cbegin(), e = Auth().data().stickerSets().cend(); it != e; ++it) { if (it->shortName.toLower() == name) { - return !(it->flags & MTPDstickerSet::Flag::f_archived) && (it->flags & MTPDstickerSet::Flag::f_installed); + return !(it->flags & MTPDstickerSet::Flag::f_archived) + && (it->flags & MTPDstickerSet::Flag::f_installed_date); } } } break; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 4d33a20e57..3b3436f3cb 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -4241,7 +4241,15 @@ void MainWidget::incrementSticker(DocumentData *sticker) { auto it = sets.find(Stickers::CloudRecentSetId); if (it == sets.cend()) { if (it == sets.cend()) { - it = sets.insert(Stickers::CloudRecentSetId, Stickers::Set(Stickers::CloudRecentSetId, 0, lang(lng_recent_stickers), QString(), 0, 0, MTPDstickerSet_ClientFlag::f_special | 0)); + it = sets.insert(Stickers::CloudRecentSetId, Stickers::Set( + Stickers::CloudRecentSetId, + uint64(0), + lang(lng_recent_stickers), + QString(), + 0, // count + 0, // hash + MTPDstickerSet_ClientFlag::f_special | 0, + TimeId(0))); } else { it->title = lang(lng_recent_stickers); } @@ -5270,13 +5278,28 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { auto &set = d.vstickerset.c_messages_stickerSet(); if (set.vset.type() == mtpc_stickerSet) { auto &s = set.vset.c_stickerSet(); + if (!s.has_installed_date()) { + LOG(("API Error: " + "updateNewStickerSet without install_date flag.")); + } if (!s.is_masks()) { auto &sets = Auth().data().stickerSetsRef(); auto it = sets.find(s.vid.v); if (it == sets.cend()) { - it = sets.insert(s.vid.v, Stickers::Set(s.vid.v, s.vaccess_hash.v, Stickers::GetSetTitle(s), qs(s.vshort_name), s.vcount.v, s.vhash.v, s.vflags.v | MTPDstickerSet::Flag::f_installed)); + it = sets.insert(s.vid.v, Stickers::Set( + s.vid.v, + s.vaccess_hash.v, + Stickers::GetSetTitle(s), + qs(s.vshort_name), + s.vcount.v, + s.vhash.v, + s.vflags.v | MTPDstickerSet::Flag::f_installed_date, + s.has_installed_date() ? s.vinstalled_date.v : unixtime())); } else { - it->flags |= MTPDstickerSet::Flag::f_installed; + it->flags |= MTPDstickerSet::Flag::f_installed_date; + if (!it->installDate) { + it->installDate = unixtime(); + } if (it->flags & MTPDstickerSet::Flag::f_archived) { it->flags &= ~MTPDstickerSet::Flag::f_archived; writeArchived = true; diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index d8d67db182..f4d85d8b9f 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -36,6 +36,7 @@ namespace { constexpr auto kThemeFileSizeLimit = 5 * 1024 * 1024; constexpr auto kFileLoaderQueueStopTimeout = TimeMs(5000); +constexpr auto kDefaultStickerInstallDate = TimeId(1); using FileKey = quint64; @@ -3185,13 +3186,33 @@ void cancelTask(TaskId id) { void _writeStickerSet(QDataStream &stream, const Stickers::Set &set) { bool notLoaded = (set.flags & MTPDstickerSet_ClientFlag::f_not_loaded); if (notLoaded) { - stream << quint64(set.id) << quint64(set.access) << set.title << set.shortName << qint32(-set.count) << qint32(set.hash) << qint32(set.flags); + stream + << quint64(set.id) + << quint64(set.access) + << set.title + << set.shortName + << qint32(-set.count) + << qint32(set.hash) + << qint32(set.flags); + if (AppVersion > 1002008) { + stream << qint32(set.installDate); + } return; } else { if (set.stickers.isEmpty()) return; } - stream << quint64(set.id) << quint64(set.access) << set.title << set.shortName << qint32(set.stickers.size()) << qint32(set.hash) << qint32(set.flags); + stream + << quint64(set.id) + << quint64(set.access) + << set.title + << set.shortName + << qint32(set.stickers.size()) + << qint32(set.hash) + << qint32(set.flags); + if (AppVersion > 1002008) { + stream << qint32(set.installDate); + } for (auto j = set.stickers.cbegin(), e = set.stickers.cend(); j != e; ++j) { Serialize::Document::writeToStream(stream, *j); } @@ -3241,8 +3262,8 @@ void _writeStickerSets(FileKey &stickersKey, CheckSet checkSet, const Stickers:: continue; } - // id + access + title + shortName + stickersCount + hash + flags - size += sizeof(quint64) * 2 + Serialize::stringSize(set.title) + Serialize::stringSize(set.shortName) + sizeof(quint32) + sizeof(qint32) * 2; + // id + access + title + shortName + stickersCount + hash + flags + installDate + size += sizeof(quint64) * 2 + Serialize::stringSize(set.title) + Serialize::stringSize(set.shortName) + sizeof(quint32) + sizeof(qint32) * 3; for_const (auto &sticker, set.stickers) { size += Serialize::Document::sizeInStream(sticker); } @@ -3296,7 +3317,7 @@ void _readStickerSets(FileKey &stickersKey, Stickers::Order *outOrder = nullptr, return; } - bool readingInstalled = (readingFlags == MTPDstickerSet::Flag::f_installed); + bool readingInstalled = (readingFlags == MTPDstickerSet::Flag::f_installed_date); auto &sets = Auth().data().stickerSetsRef(); if (outOrder) outOrder->clear(); @@ -3311,7 +3332,14 @@ void _readStickerSets(FileKey &stickersKey, Stickers::Order *outOrder = nullptr, quint64 setId = 0, setAccess = 0; QString setTitle, setShortName; qint32 scnt = 0; - stickers.stream >> setId >> setAccess >> setTitle >> setShortName >> scnt; + auto setInstallDate = qint32(0); + + stickers.stream + >> setId + >> setAccess + >> setTitle + >> setShortName + >> scnt; qint32 setHash = 0; MTPDstickerSet::Flags setFlags = 0; @@ -3324,8 +3352,11 @@ void _readStickerSets(FileKey &stickersKey, Stickers::Order *outOrder = nullptr, setFlags |= MTPDstickerSet_ClientFlag::f_not_loaded; } } + if (stickers.version > 1002008) { + stickers.stream >> setInstallDate; + } if (readingInstalled && stickers.version < 9061) { - setFlags |= MTPDstickerSet::Flag::f_installed; + setFlags |= MTPDstickerSet::Flag::f_installed_date; } if (setId == Stickers::DefaultSetId) { @@ -3354,8 +3385,16 @@ void _readStickerSets(FileKey &stickersKey, Stickers::Order *outOrder = nullptr, auto it = sets.find(setId); if (it == sets.cend()) { // We will set this flags from order lists when reading those stickers. - setFlags &= ~(MTPDstickerSet::Flag::f_installed | MTPDstickerSet_ClientFlag::f_featured); - it = sets.insert(setId, Stickers::Set(setId, setAccess, setTitle, setShortName, 0, setHash, MTPDstickerSet::Flags(setFlags))); + setFlags &= ~(MTPDstickerSet::Flag::f_installed_date | MTPDstickerSet_ClientFlag::f_featured); + it = sets.insert(setId, Stickers::Set( + setId, + setAccess, + setTitle, + setShortName, + 0, + setHash, + MTPDstickerSet::Flags(setFlags), + setInstallDate)); } auto &set = it.value(); auto inputSet = MTP_inputStickerSetID(MTP_long(set.id), MTP_long(set.access)); @@ -3431,6 +3470,9 @@ void _readStickerSets(FileKey &stickersKey, Stickers::Order *outOrder = nullptr, auto it = sets.find(setId); if (it != sets.cend()) { it->flags |= readingFlags; + if (readingInstalled && !it->installDate) { + it->installDate = kDefaultStickerInstallDate; + } } } } @@ -3446,7 +3488,7 @@ void writeInstalledStickers() { if (set.stickers.isEmpty()) { // all other special are "installed" return StickerSetCheckResult::Skip; } - } else if (!(set.flags & MTPDstickerSet::Flag::f_installed) || (set.flags & MTPDstickerSet::Flag::f_archived)) { + } else if (!(set.flags & MTPDstickerSet::Flag::f_installed_date) || (set.flags & MTPDstickerSet::Flag::f_archived)) { return StickerSetCheckResult::Skip; } else if (set.flags & MTPDstickerSet_ClientFlag::f_not_loaded) { // waiting to receive return StickerSetCheckResult::Abort; @@ -3529,8 +3571,27 @@ void importOldRecentStickers() { auto &recent = cRefRecentStickers(); recent.clear(); - auto &def = sets.insert(Stickers::DefaultSetId, Stickers::Set(Stickers::DefaultSetId, 0, lang(lng_stickers_default_set), QString(), 0, 0, MTPDstickerSet::Flag::f_official | MTPDstickerSet::Flag::f_installed | MTPDstickerSet_ClientFlag::f_special)).value(); - auto &custom = sets.insert(Stickers::CustomSetId, Stickers::Set(Stickers::CustomSetId, 0, qsl("Custom stickers"), QString(), 0, 0, MTPDstickerSet::Flag::f_installed | MTPDstickerSet_ClientFlag::f_special)).value(); + auto &def = sets.insert(Stickers::DefaultSetId, Stickers::Set( + Stickers::DefaultSetId, + uint64(0), + lang(lng_stickers_default_set), + QString(), + 0, // count + 0, // hash + (MTPDstickerSet::Flag::f_official + | MTPDstickerSet::Flag::f_installed_date + | MTPDstickerSet_ClientFlag::f_special), + kDefaultStickerInstallDate)).value(); + auto &custom = sets.insert(Stickers::CustomSetId, Stickers::Set( + Stickers::CustomSetId, + uint64(0), + qsl("Custom stickers"), + QString(), + 0, // count + 0, // hash + (MTPDstickerSet::Flag::f_installed_date + | MTPDstickerSet_ClientFlag::f_special), + kDefaultStickerInstallDate)).value(); QMap read; while (!stickers.stream.atEnd()) { @@ -3601,11 +3662,17 @@ void readInstalledStickers() { } Auth().data().stickerSetsRef().clear(); - _readStickerSets(_installedStickersKey, &Auth().data().stickerSetsOrderRef(), MTPDstickerSet::Flag::f_installed); + _readStickerSets( + _installedStickersKey, + &Auth().data().stickerSetsOrderRef(), + MTPDstickerSet::Flag::f_installed_date); } void readFeaturedStickers() { - _readStickerSets(_featuredStickersKey, &Auth().data().featuredStickerSetsOrderRef(), MTPDstickerSet::Flags() | MTPDstickerSet_ClientFlag::f_featured); + _readStickerSets( + _featuredStickersKey, + &Auth().data().featuredStickerSetsOrderRef(), + MTPDstickerSet::Flags() | MTPDstickerSet_ClientFlag::f_featured); auto &sets = Auth().data().stickerSets(); int unreadCount = 0;