diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 635cb67ec..441ad22e4 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -2659,17 +2659,17 @@ void ApiWrap::requestCustomEmoji(TimeId now) { return; } const auto done = [=](const MTPmessages_AllStickers &result) { - _session->data().stickers().setLastMasksUpdate(crl::now()); - _masksUpdateRequest = 0; + _session->data().stickers().setLastEmojiUpdate(crl::now()); + _customEmojiUpdateRequest = 0; result.match([&](const MTPDmessages_allStickersNotModified&) { }, [&](const MTPDmessages_allStickers &data) { - _session->data().stickers().masksReceived( + _session->data().stickers().emojiReceived( data.vsets().v, data.vhash().v); }); }; - _masksUpdateRequest = request(MTPmessages_GetEmojiStickers( + _customEmojiUpdateRequest = request(MTPmessages_GetEmojiStickers( MTP_long(Api::CountCustomEmojiHash(_session, true)) )).done(done).fail([=] { LOG(("App Fail: Failed to get custom emoji!")); diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 254a79030..d74739ca0 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -201,6 +201,7 @@ private: uint64 _setId = 0; uint64 _setAccessHash = 0; uint64 _setHash = 0; + uint64 _setThumbnailDocumentId = 0; QString _setTitle, _setShortName; int _setCount = 0; Data::StickersSetFlags _setFlags; @@ -549,6 +550,7 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) { _setCount = set.vcount().v; _setFlags = Data::ParseStickersSetFlags(set); _setInstallDate = set.vinstalled_date().value_or(0); + _setThumbnailDocumentId = set.vthumb_document_id().value_or_empty(); _setThumbnail = [&] { if (const auto thumbs = set.vthumbs()) { for (const auto &thumb : thumbs->v) { @@ -661,6 +663,7 @@ void StickerSetBox::Inner::installDone( it->second->installDate = _setInstallDate; } const auto set = it->second.get(); + set->thumbnailDocumentId = _setThumbnailDocumentId; set->setThumbnail(_setThumbnail); set->stickers = _pack; set->emoji = _emoji; diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp index ace1b4b0b..f0ac54c3c 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp @@ -1159,6 +1159,7 @@ void EmojiListWidget::refreshCustom() { return true; }(); if (valid) { + i->thumbnailDocument = it->second->lookupThumbnailDocument(); _custom.push_back(std::move(*i)); continue; } @@ -1198,6 +1199,7 @@ void EmojiListWidget::refreshCustom() { _custom.push_back({ .id = setId, .set = it->second.get(), + .thumbnailDocument = it->second->lookupThumbnailDocument(), .title = it->second->title, .list = std::move(set), }); @@ -1223,7 +1225,7 @@ std::vector EmojiListWidget::fillIcons() { } for (const auto &custom : _custom) { const auto set = custom.set; - const auto s = custom.list[0].document; + const auto s = custom.thumbnailDocument; const auto availw = st::stickerIconWidth - 2 * st::stickerIconPadding; const auto availh = st::emojiFooterHeight - 2 * st::stickerIconPadding; const auto size = set->hasThumbnail() diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h index 668225161..fc97b2222 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h @@ -110,6 +110,7 @@ private: struct CustomSet { uint64 id = 0; not_null set; + DocumentData *thumbnailDocument = nullptr; QString title; std::vector list; std::unique_ptr ripple; diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index aa42d58ed..e69fe1738 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -99,6 +99,7 @@ struct StickersListWidget::Set { uint64 id = 0; Data::StickersSet *set = nullptr; + DocumentData *thumbnailDocument = nullptr; Data::StickersSetFlags flags; QString title; QString shortName; @@ -2087,6 +2088,7 @@ bool StickersListWidget::appendSet( set->count, externalLayout, std::move(elements)); + to.back().thumbnailDocument = set->lookupThumbnailDocument(); if (!externalLayout && _premiumsIndex >= 0 && session().premium()) { for (const auto &sticker : to.back().stickers) { const auto document = sticker.document; @@ -2380,7 +2382,7 @@ std::vector StickersListWidget::fillIcons() { } const auto set = _mySets[i].set; Assert(set != nullptr); - const auto s = _mySets[i].stickers[0].document; + const auto s = _mySets[i].thumbnailDocument; const auto availw = st::stickerIconWidth - 2 * st::stickerIconPadding; const auto availh = st::emojiFooterHeight - 2 * st::stickerIconPadding; const auto size = set->hasThumbnail() diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index fd9d5681b..2bfae4b58 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -1003,7 +1003,6 @@ void Stickers::featuredSetsReceived( data->vcount().v, flags | SetFlag::NotLoaded, installDate)).first; - it->second->setThumbnail(thumbnail); } else { const auto set = it->second.get(); set->accessHash = data->vaccess_hash().v; @@ -1012,13 +1011,14 @@ void Stickers::featuredSetsReceived( set->flags = flags | (set->flags & (SetFlag::NotLoaded | SetFlag::Special)); set->installDate = installDate; - set->setThumbnail(thumbnail); if (set->count != data->vcount().v || set->hash != data->vhash().v || set->emoji.isEmpty()) { set->count = data->vcount().v; set->hash = data->vhash().v; set->flags |= SetFlag::NotLoaded; // need to request this set } } + it->second->setThumbnail(thumbnail); + it->second->thumbnailDocumentId = data->vthumb_document_id().value_or_empty(); setsOrder.push_back(data->vid().v); if (it->second->stickers.isEmpty() || (it->second->flags & SetFlag::NotLoaded)) { @@ -1310,7 +1310,6 @@ StickersSet *Stickers::feedSet(const MTPDstickerSet &data) { data.vcount().v, flags | SetFlag::NotLoaded, data.vinstalled_date().value_or_empty())).first; - it->second->setThumbnail(thumbnail); } else { const auto set = it->second.get(); set->accessHash = data.vaccess_hash().v; @@ -1327,7 +1326,6 @@ StickersSet *Stickers::feedSet(const MTPDstickerSet &data) { set->installDate = installDate ? (installDate->v ? installDate->v : base::unixtime::now()) : TimeId(0); - it->second->setThumbnail(thumbnail); if (set->count != data.vcount().v || set->hash != data.vhash().v || set->emoji.isEmpty()) { @@ -1338,6 +1336,8 @@ StickersSet *Stickers::feedSet(const MTPDstickerSet &data) { } } const auto set = it->second.get(); + set->setThumbnail(thumbnail); + set->thumbnailDocumentId = data.vthumb_document_id().value_or_empty(); auto changedFlags = (oldFlags ^ set->flags); if (changedFlags & SetFlag::Archived) { const auto masks = !!(set->flags & SetFlag::Masks); diff --git a/Telegram/SourceFiles/data/stickers/data_stickers_set.cpp b/Telegram/SourceFiles/data/stickers/data_stickers_set.cpp index 3e54047d2..43081472d 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers_set.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers_set.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "data/data_session.h" #include "data/data_file_origin.h" +#include "data/data_document.h" #include "storage/file_download.h" #include "ui/image/image.h" @@ -165,6 +166,23 @@ int StickersSet::thumbnailByteSize() const { return _thumbnail.byteSize; } +DocumentData *StickersSet::lookupThumbnailDocument() const { + if (thumbnailDocumentId) { + const auto i = ranges::find( + stickers, + thumbnailDocumentId, + &DocumentData::id); + if (i != stickers.end()) { + return *i; + } + } + return !stickers.empty() + ? stickers.front() + : !covers.empty() + ? covers.front() + : nullptr; +} + std::shared_ptr StickersSet::createThumbnailView() { if (auto active = activeThumbnailView()) { return active; diff --git a/Telegram/SourceFiles/data/stickers/data_stickers_set.h b/Telegram/SourceFiles/data/stickers/data_stickers_set.h index 66de1ea3b..c2c2803b4 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers_set.h +++ b/Telegram/SourceFiles/data/stickers/data_stickers_set.h @@ -91,6 +91,7 @@ public: [[nodiscard]] const ImageLocation &thumbnailLocation() const; [[nodiscard]] Storage::Cache::Key thumbnailBigFileBaseCacheKey() const; [[nodiscard]] int thumbnailByteSize() const; + [[nodiscard]] DocumentData *lookupThumbnailDocument() const; [[nodiscard]] std::shared_ptr createThumbnailView(); [[nodiscard]] std::shared_ptr activeThumbnailView(); @@ -98,6 +99,7 @@ public: uint64 id = 0; uint64 accessHash = 0; uint64 hash = 0; + uint64 thumbnailDocumentId = 0; QString title, shortName; int count = 0; StickersSetFlags flags; diff --git a/Telegram/SourceFiles/storage/storage_account.cpp b/Telegram/SourceFiles/storage/storage_account.cpp index 01039ea0d..bf24da1f6 100644 --- a/Telegram/SourceFiles/storage/storage_account.cpp +++ b/Telegram/SourceFiles/storage/storage_account.cpp @@ -43,7 +43,7 @@ using Database = Cache::Database; constexpr auto kDelayedWriteTimeout = crl::time(1000); constexpr auto kStickersVersionTag = quint32(-1); -constexpr auto kStickersSerializeVersion = 2; +constexpr auto kStickersSerializeVersion = 3; constexpr auto kMaxSavedStickerSetsCount = 1000; constexpr auto kDefaultStickerInstallDate = TimeId(1); @@ -1633,7 +1633,8 @@ void Account::writeStickerSet( << set.shortName << qint32(count) << qint32(set.flags) - << qint32(set.installDate); + << qint32(set.installDate) + << quint64(set.thumbnailDocumentId); Serialize::writeImageLocation(stream, set.thumbnailLocation()); }; if (set.flags & SetFlag::NotLoaded) { @@ -1789,7 +1790,7 @@ void Account::readStickerSets( qint32 version = 0; stickers.stream >> versionTag >> version; if (versionTag != kStickersVersionTag - || version != kStickersSerializeVersion) { + || (version != 2 && version != kStickersSerializeVersion)) { // Old data, without sticker set thumbnails. return failed(); } @@ -1802,6 +1803,7 @@ void Account::readStickerSets( } for (auto i = 0; i != count; ++i) { quint64 setId = 0, setAccessHash = 0, setHash = 0; + quint64 setThumbnailDocumentId = 0; QString setTitle, setShortName; qint32 scnt = 0; qint32 setInstallDate = 0; @@ -1818,6 +1820,9 @@ void Account::readStickerSets( >> scnt >> setFlagsValue >> setInstallDate; + if (version > 2) { + stickers.stream >> setThumbnailDocumentId; + } const auto thumbnail = Serialize::readImageLocation( stickers.version, stickers.stream); @@ -1864,6 +1869,7 @@ void Account::readStickerSets( setInstallDate)).first; it->second->setThumbnail( ImageWithLocation{ .location = setThumbnail }); + it->second->thumbnailDocumentId = setThumbnailDocumentId; } const auto set = it->second.get(); const auto inputSet = set->identifier(); @@ -2015,7 +2021,7 @@ void Account::writeInstalledStickers() { } else if (!(set.flags & SetFlag::Installed) || (set.flags & SetFlag::Archived)) { return StickerSetCheckResult::Skip; - } else if (set.flags & SetFlag::Masks) { + } else if (set.flags & (SetFlag::Masks | SetFlag::Emoji)) { return StickerSetCheckResult::Skip; } else if (set.flags & SetFlag::NotLoaded) { // waiting to receive @@ -2072,7 +2078,7 @@ void Account::writeArchivedStickers() { using SetFlag = Data::StickersSetFlag; writeStickerSets(_archivedStickersKey, [](const Data::StickersSet &set) { - if (set.flags & SetFlag::Masks) { + if (set.flags & (SetFlag::Masks | SetFlag::Emoji)) { return StickerSetCheckResult::Skip; } if (!(set.flags & SetFlag::Archived)