From e7104b5ebe3f4b9862ade7e82e5b0950360d9757 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 30 Mar 2021 18:51:45 +0300 Subject: [PATCH] Added support for archived masks. --- Telegram/SourceFiles/apiwrap.cpp | 6 +- .../SourceFiles/boxes/sticker_set_box.cpp | 14 ++++- Telegram/SourceFiles/boxes/stickers_box.cpp | 58 ++++++++++++++----- Telegram/SourceFiles/boxes/stickers_box.h | 3 + .../data/stickers/data_stickers.cpp | 54 ++++++++++++----- .../SourceFiles/data/stickers/data_stickers.h | 7 +++ .../SourceFiles/storage/storage_account.cpp | 52 ++++++++++++++--- .../SourceFiles/storage/storage_account.h | 3 + 8 files changed, 158 insertions(+), 39 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 1354a5ba93..dd59fca254 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -2101,7 +2101,11 @@ void ApiWrap::saveStickerSets( session().saveSettings(); } if (writeArchived) { - storage.writeArchivedStickers(); + if (setsMasks) { + storage.writeArchivedMasks(); + } else { + storage.writeArchivedStickers(); + } } if (writeCloudRecent) { storage.writeRecentStickers(); diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index a34986e64d..4f805d0e55 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -494,9 +494,13 @@ void StickerSetBox::Inner::installDone( const bool wasArchived = (_setFlags & MTPDstickerSet::Flag::f_archived); if (wasArchived) { - const auto index = stickers.archivedSetsOrderRef().indexOf(_setId); + const auto index = (isMasks + ? stickers.archivedMaskSetsOrderRef() + : stickers.archivedSetsOrderRef()).indexOf(_setId); if (index >= 0) { - stickers.archivedSetsOrderRef().removeAt(index); + (isMasks + ? stickers.archivedMaskSetsOrderRef() + : stickers.archivedSetsOrderRef()).removeAt(index); } } _setInstallDate = base::unixtime::now(); @@ -556,7 +560,11 @@ void StickerSetBox::Inner::installDone( } else { auto &storage = _controller->session().local(); if (wasArchived) { - storage.writeArchivedStickers(); + if (isMasks) { + storage.writeArchivedMasks(); + } else { + storage.writeArchivedStickers(); + } } if (isMasks) { storage.writeInstalledMasks(); diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index d36ec20dd0..e78fd0cb67 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -90,7 +90,7 @@ public: void saveGroupSet(); - void rebuild(); + void rebuild(bool masks); void updateSize(int newWidth = 0); void updateRows(); // refresh only pack cover stickers bool appendSet(not_null set); @@ -454,7 +454,7 @@ void StickersBox::getArchivedDone( } auto &stickers = result.c_messages_archivedStickers(); - auto &archived = session().data().stickers().archivedSetsOrderRef(); + auto &archived = archivedSetsOrderRef(); if (offsetId) { auto index = archived.indexOf(offsetId); if (index >= 0) { @@ -521,7 +521,11 @@ void StickersBox::getArchivedDone( void StickersBox::prepare() { if (_section == Section::Installed) { if (_tabs) { - session().local().readArchivedStickers(); + if (_isMasks) { + session().local().readArchivedMasks(); + } else { + session().local().readArchivedStickers(); + } } else { setTitle(tr::lng_stickers_group_set()); } @@ -531,7 +535,7 @@ void StickersBox::prepare() { setTitle(tr::lng_stickers_attached_sets()); } if (_tabs) { - if (session().data().stickers().archivedSetsOrder().isEmpty()) { + if (archivedSetsOrder().isEmpty()) { preloadArchivedSets(); } setNoContentMargin(true); @@ -645,7 +649,7 @@ void StickersBox::refreshTabs() { sections.push_back(tr::lng_stickers_featured_tab(tr::now).toUpper()); _tabIndices.push_back(Section::Featured); } - if (!stickers.archivedSetsOrder().isEmpty() && _archived.widget()) { + if (!archivedSetsOrder().isEmpty() && _archived.widget()) { sections.push_back(tr::lng_stickers_archived_tab(tr::now).toUpper()); _tabIndices.push_back(Section::Archived); } @@ -672,7 +676,7 @@ void StickersBox::loadMoreArchived() { } uint64 lastId = 0; - const auto &order = session().data().stickers().archivedSetsOrder(); + const auto &order = archivedSetsOrder(); const auto &sets = session().data().stickers().sets(); for (auto setIt = order.cend(), e = order.cbegin(); setIt != e;) { --setIt; @@ -684,8 +688,11 @@ void StickersBox::loadMoreArchived() { } } } + const auto flags = _isMasks + ? MTPmessages_GetArchivedStickers::Flag::f_masks + : MTPmessages_GetArchivedStickers::Flags(0); _archivedRequestId = _api.request(MTPmessages_GetArchivedStickers( - MTP_flags(0), + MTP_flags(flags), MTP_long(lastId), MTP_int(kArchivedLimitPerPage) )).done([=](const MTPmessages_ArchivedStickers &result) { @@ -864,8 +871,11 @@ void StickersBox::preloadArchivedSets() { return; } if (!_archivedRequestId) { + const auto flags = _isMasks + ? MTPmessages_GetArchivedStickers::Flag::f_masks + : MTPmessages_GetArchivedStickers::Flags(0); _archivedRequestId = _api.request(MTPmessages_GetArchivedStickers( - MTP_flags(0), + MTP_flags(flags), MTP_long(0), MTP_int(kArchivedLimitFirstRequest) )).done([=](const MTPmessages_ArchivedStickers &result) { @@ -881,7 +891,7 @@ void StickersBox::requestArchivedSets() { } const auto &sets = session().data().stickers().sets(); - const auto &order = session().data().stickers().archivedSetsOrder(); + const auto &order = archivedSetsOrder(); for (const auto setId : order) { auto it = sets.find(setId); if (it != sets.cend()) { @@ -918,7 +928,7 @@ void StickersBox::handleStickersUpdated() { } else { _tab->widget()->updateRows(); } - if (session().data().stickers().archivedSetsOrder().isEmpty()) { + if (archivedSetsOrder().isEmpty()) { preloadArchivedSets(); } else { refreshTabs(); @@ -937,7 +947,7 @@ void StickersBox::rebuildList(Tab *tab) { _localOrder = tab->widget()->getFullOrder(); _localRemoved = tab->widget()->getRemovedSets(); } - tab->widget()->rebuild(); + tab->widget()->rebuild(_isMasks); if ((tab == &_installed) || (tab == &_masks)) { tab->widget()->setFullOrder(_localOrder); } @@ -957,7 +967,11 @@ void StickersBox::saveChanges() { } if (_someArchivedLoaded) { - session().local().writeArchivedStickers(); + if (_isMasks) { + session().local().writeArchivedMasks(); + } else { + session().local().writeArchivedStickers(); + } } if (installed) { session().api().saveStickerSets( @@ -979,6 +993,18 @@ void StickersBox::setInnerFocus() { } } +const Data::StickersSetsOrder &StickersBox::archivedSetsOrder() const { + return !_isMasks + ? session().data().stickers().archivedSetsOrder() + : session().data().stickers().archivedMaskSetsOrder(); +} + +Data::StickersSetsOrder &StickersBox::archivedSetsOrderRef() { + return !_isMasks + ? session().data().stickers().archivedSetsOrderRef() + : session().data().stickers().archivedMaskSetsOrderRef(); +} + StickersBox::~StickersBox() = default; StickersBox::Inner::Row::Row( @@ -1935,7 +1961,7 @@ void StickersBox::Inner::rebuildMegagroupSet() { } } -void StickersBox::Inner::rebuild() { +void StickersBox::Inner::rebuild(bool masks) { _itemsTop = st::membersMarginTop; if (_megagroupSet) { @@ -1959,7 +1985,9 @@ void StickersBox::Inner::rebuild() { } else if (_section == Section::Featured) { return session().data().stickers().featuredSetsOrder(); } - return session().data().stickers().archivedSetsOrder(); + return masks + ? session().data().stickers().archivedMaskSetsOrder() + : session().data().stickers().archivedSetsOrder(); })(); _rows.reserve(order.size() + 1); _shiftingStartTimes.reserve(order.size() + 1); @@ -1999,7 +2027,7 @@ void StickersBox::Inner::rebuild() { void StickersBox::Inner::setMegagroupSelectedSet(const MTPInputStickerSet &set) { _megagroupSetInput = set; - rebuild(); + rebuild(false); _scrollsToY.fire(0); updateSelected(); } diff --git a/Telegram/SourceFiles/boxes/stickers_box.h b/Telegram/SourceFiles/boxes/stickers_box.h index 12d7353d11..75b549bc25 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.h +++ b/Telegram/SourceFiles/boxes/stickers_box.h @@ -134,6 +134,9 @@ private: uint64 offsetId); void showAttachedStickers(); + const Data::StickersSetsOrder &archivedSetsOrder() const; + Data::StickersSetsOrder &archivedSetsOrderRef(); + std::array widgets() const; const not_null _controller; diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index 1e310792ba..a8b80af5dd 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -263,10 +263,12 @@ void Stickers::checkSavedGif(not_null item) { void Stickers::applyArchivedResult( const MTPDmessages_stickerSetInstallResultArchive &d) { auto &v = d.vsets().v; - auto &order = setsOrderRef(); StickersSetsOrder archived; archived.reserve(v.size()); QMap setsToRequest; + + auto masksCount = 0; + auto stickersCount = 0; for (const auto &stickerSet : v) { const MTPDstickerSet *setData = nullptr; switch (stickerSet.type()) { @@ -288,7 +290,10 @@ void Stickers::applyArchivedResult( if (set->stickers.isEmpty()) { setsToRequest.insert(set->id, set->access); } - auto index = order.indexOf(set->id); + const auto masks = !!(set->flags & MTPDstickerSet::Flag::f_masks); + (masks ? masksCount : stickersCount)++; + auto &order = masks ? maskSetsOrderRef() : setsOrderRef(); + const auto index = order.indexOf(set->id); if (index >= 0) { order.removeAt(index); } @@ -301,8 +306,14 @@ void Stickers::applyArchivedResult( } session().api().requestStickerSets(); } - session().local().writeInstalledStickers(); - session().local().writeArchivedStickers(); + if (stickersCount) { + session().local().writeInstalledStickers(); + session().local().writeArchivedStickers(); + } + if (masksCount) { + session().local().writeInstalledMasks(); + session().local().writeArchivedMasks(); + } Ui::Toast::Show(Ui::Toast::Config{ .text = { tr::lng_stickers_packs_archived(tr::now) }, @@ -360,12 +371,14 @@ void Stickers::installLocally(uint64 setId) { const auto set = it->second.get(); auto flags = set->flags; - set->flags &= ~(MTPDstickerSet::Flag::f_archived | MTPDstickerSet_ClientFlag::f_unread); + set->flags &= ~(MTPDstickerSet::Flag::f_archived + | MTPDstickerSet_ClientFlag::f_unread); set->flags |= MTPDstickerSet::Flag::f_installed_date; set->installDate = base::unixtime::now(); auto changedFlags = flags ^ set->flags; - auto &order = setsOrderRef(); + const auto masks = !!(flags & MTPDstickerSet::Flag::f_masks); + auto &order = masks ? maskSetsOrderRef() : setsOrderRef(); int insertAtIndex = 0, currentIndex = order.indexOf(setId); if (currentIndex != insertAtIndex) { if (currentIndex > 0) { @@ -390,10 +403,17 @@ void Stickers::installLocally(uint64 setId) { session().local().writeFeaturedStickers(); } if (changedFlags & MTPDstickerSet::Flag::f_archived) { - auto index = archivedSetsOrderRef().indexOf(setId); + auto &archivedOrder = masks + ? archivedMaskSetsOrderRef() + : archivedSetsOrderRef(); + const auto index = archivedOrder.indexOf(setId); if (index >= 0) { - archivedSetsOrderRef().removeAt(index); - session().local().writeArchivedStickers(); + archivedOrder.removeAt(index); + if (masks) { + session().local().writeArchivedMasks(); + } else { + session().local().writeArchivedStickers(); + } } } notifyUpdated(); @@ -1234,13 +1254,17 @@ StickersSet *Stickers::feedSet(const MTPDstickerSet &data) { const auto set = it->second.get(); auto changedFlags = (flags ^ set->flags); if (changedFlags & MTPDstickerSet::Flag::f_archived) { - auto index = archivedSetsOrder().indexOf(set->id); + const auto masks = !!(set->flags & MTPDstickerSet::Flag::f_masks); + auto &archivedOrder = masks + ? archivedMaskSetsOrderRef() + : archivedSetsOrderRef(); + const auto index = archivedOrder.indexOf(set->id); if (set->flags & MTPDstickerSet::Flag::f_archived) { if (index < 0) { - archivedSetsOrderRef().push_front(set->id); + archivedOrder.push_front(set->id); } } else if (index >= 0) { - archivedSetsOrderRef().removeAt(index); + archivedOrder.removeAt(index); } } return it->second.get(); @@ -1358,7 +1382,11 @@ StickersSet *Stickers::feedSetFull(const MTPmessages_StickerSet &data) { session().local().writeFeaturedStickers(); } if (wasArchived != isArchived) { - session().local().writeArchivedStickers(); + if (isMasks) { + session().local().writeArchivedMasks(); + } else { + session().local().writeArchivedStickers(); + } } } diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.h b/Telegram/SourceFiles/data/stickers/data_stickers.h index 8f040ae3fd..8a24fa85f3 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.h +++ b/Telegram/SourceFiles/data/stickers/data_stickers.h @@ -152,6 +152,12 @@ public: StickersSetsOrder &archivedSetsOrderRef() { return _archivedSetsOrder; } + const StickersSetsOrder &archivedMaskSetsOrder() const { + return _archivedMaskSetsOrder; + } + StickersSetsOrder &archivedMaskSetsOrderRef() { + return _archivedMaskSetsOrder; + } const SavedGifs &savedGifs() const { return _savedGifs; } @@ -241,6 +247,7 @@ private: StickersSetsOrder _maskSetsOrder; StickersSetsOrder _featuredSetsOrder; StickersSetsOrder _archivedSetsOrder; + StickersSetsOrder _archivedMaskSetsOrder; SavedGifs _savedGifs; }; diff --git a/Telegram/SourceFiles/storage/storage_account.cpp b/Telegram/SourceFiles/storage/storage_account.cpp index e73ca0b016..1600130629 100644 --- a/Telegram/SourceFiles/storage/storage_account.cpp +++ b/Telegram/SourceFiles/storage/storage_account.cpp @@ -187,6 +187,7 @@ base::flat_set Account::collectGoodNames() const { _trustedBotsKey, _installedMasksKey, _recentMasksKey, + _archivedMasksKey, }; auto result = base::flat_set{ "map0", @@ -267,7 +268,7 @@ Account::ReadMapResult Account::readMapWith( quint64 locationsKey = 0, reportSpamStatusesKey = 0, trustedBotsKey = 0; quint64 recentStickersKeyOld = 0; quint64 installedStickersKey = 0, featuredStickersKey = 0, recentStickersKey = 0, favedStickersKey = 0, archivedStickersKey = 0; - quint64 installedMasksKey = 0, recentMasksKey = 0; + quint64 installedMasksKey = 0, recentMasksKey = 0, archivedMasksKey = 0; quint64 savedGifsKey = 0; quint64 legacyBackgroundKeyDay = 0, legacyBackgroundKeyNight = 0; quint64 userSettingsKey = 0, recentHashtagsAndBotsKey = 0, exportSettingsKey = 0; @@ -365,7 +366,10 @@ Account::ReadMapResult Account::readMapWith( map.stream >> exportSettingsKey; } break; case lskMasksKeys: { - map.stream >> installedMasksKey >> recentMasksKey; + map.stream + >> installedMasksKey + >> recentMasksKey + >> archivedMasksKey; } break; default: LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType)); @@ -393,6 +397,7 @@ Account::ReadMapResult Account::readMapWith( _savedGifsKey = savedGifsKey; _installedMasksKey = installedMasksKey; _recentMasksKey = recentMasksKey; + _archivedMasksKey = archivedMasksKey; _legacyBackgroundKeyDay = legacyBackgroundKeyDay; _legacyBackgroundKeyNight = legacyBackgroundKeyNight; _settingsKey = userSettingsKey; @@ -497,8 +502,8 @@ void Account::writeMap() { if (_settingsKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_recentHashtagsAndBotsKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_exportSettingsKey) mapSize += sizeof(quint32) + sizeof(quint64); - if (_installedMasksKey || _recentMasksKey) { - mapSize += sizeof(quint32) + 2 * sizeof(quint64); + if (_installedMasksKey || _recentMasksKey || _archivedMasksKey) { + mapSize += sizeof(quint32) + 3 * sizeof(quint64); } EncryptedDescriptor mapData(mapSize); @@ -545,11 +550,12 @@ void Account::writeMap() { if (_exportSettingsKey) { mapData.stream << quint32(lskExportSettings) << quint64(_exportSettingsKey); } - if (_installedMasksKey || _recentMasksKey) { + if (_installedMasksKey || _recentMasksKey || _archivedMasksKey) { mapData.stream << quint32(lskMasksKeys); mapData.stream << quint64(_installedMasksKey) - << quint64(_recentMasksKey); + << quint64(_recentMasksKey) + << quint64(_archivedMasksKey); } map.writeEncrypted(mapData, _localKey); @@ -571,6 +577,7 @@ void Account::reset() { _savedGifsKey = 0; _installedMasksKey = 0; _recentMasksKey = 0; + _archivedMasksKey = 0; _legacyBackgroundKeyDay = _legacyBackgroundKeyNight = 0; _settingsKey = _recentHashtagsAndBotsKey = _exportSettingsKey = 0; _oldMapVersion = 0; @@ -1885,6 +1892,8 @@ void Account::writeInstalledStickers() { } } else if (!(set.flags & MTPDstickerSet::Flag::f_installed_date) || (set.flags & MTPDstickerSet::Flag::f_archived)) { return StickerSetCheckResult::Skip; + } else if (set.flags & MTPDstickerSet::Flag::f_masks) { + return StickerSetCheckResult::Skip; } else if (set.flags & MTPDstickerSet_ClientFlag::f_not_loaded) { // waiting to receive return StickerSetCheckResult::Abort; } else if (set.stickers.isEmpty()) { @@ -1933,6 +1942,9 @@ void Account::writeFavedStickers() { void Account::writeArchivedStickers() { writeStickerSets(_archivedStickersKey, [](const Data::StickersSet &set) { + if (set.flags & MTPDstickerSet::Flag::f_masks) { + return StickerSetCheckResult::Skip; + } if (!(set.flags & MTPDstickerSet::Flag::f_archived) || set.stickers.isEmpty()) { return StickerSetCheckResult::Skip; } @@ -1940,6 +1952,18 @@ void Account::writeArchivedStickers() { }, _owner->session().data().stickers().archivedSetsOrder()); } +void Account::writeArchivedMasks() { + writeStickerSets(_archivedStickersKey, [](const Data::StickersSet &set) { + if (!(set.flags & MTPDstickerSet::Flag::f_masks)) { + return StickerSetCheckResult::Skip; + } + if (!(set.flags & MTPDstickerSet::Flag::f_archived) || set.stickers.isEmpty()) { + return StickerSetCheckResult::Skip; + } + return StickerSetCheckResult::Write; + }, _owner->session().data().stickers().archivedMaskSetsOrder()); +} + void Account::writeInstalledMasks() { writeStickerSets(_installedMasksKey, [](const Data::StickersSet &set) { if (!(set.flags & MTPDstickerSet::Flag::f_masks) || set.stickers.isEmpty()) { @@ -2123,13 +2147,27 @@ void Account::readFavedStickers() { } void Account::readArchivedStickers() { + // TODO: refactor to support for multiple accounts. static bool archivedStickersRead = false; if (!archivedStickersRead) { - readStickerSets(_archivedStickersKey, &_owner->session().data().stickers().archivedSetsOrderRef()); + readStickerSets( + _archivedStickersKey, + &_owner->session().data().stickers().archivedSetsOrderRef()); archivedStickersRead = true; } } +void Account::readArchivedMasks() { + // TODO: refactor to support for multiple accounts. + static bool archivedMasksRead = false; + if (!archivedMasksRead) { + readStickerSets( + _archivedMasksKey, + &_owner->session().data().stickers().archivedMaskSetsOrderRef()); + archivedMasksRead = true; + } +} + void Account::readInstalledMasks() { readStickerSets( _installedMasksKey, diff --git a/Telegram/SourceFiles/storage/storage_account.h b/Telegram/SourceFiles/storage/storage_account.h index a8e0136732..df9093ea40 100644 --- a/Telegram/SourceFiles/storage/storage_account.h +++ b/Telegram/SourceFiles/storage/storage_account.h @@ -111,11 +111,13 @@ public: void writeRecentStickers(); void writeFavedStickers(); void writeArchivedStickers(); + void writeArchivedMasks(); void readInstalledStickers(); void readFeaturedStickers(); void readRecentStickers(); void readFavedStickers(); void readArchivedStickers(); + void readArchivedMasks(); void writeSavedGifs(); void readSavedGifs(); void writeInstalledMasks(); @@ -252,6 +254,7 @@ private: FileKey _recentStickersKey = 0; FileKey _favedStickersKey = 0; FileKey _archivedStickersKey = 0; + FileKey _archivedMasksKey = 0; FileKey _savedGifsKey = 0; FileKey _recentStickersKeyOld = 0; FileKey _legacyBackgroundKeyDay = 0;