Support thumb_document_id in emoji sets.

This commit is contained in:
John Preston 2022-07-13 18:05:29 +03:00
parent 64f25a6dae
commit a821c3c31d
9 changed files with 49 additions and 15 deletions

View file

@ -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!"));

View file

@ -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;

View file

@ -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<StickerIcon> 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()

View file

@ -110,6 +110,7 @@ private:
struct CustomSet {
uint64 id = 0;
not_null<Data::StickersSet*> set;
DocumentData *thumbnailDocument = nullptr;
QString title;
std::vector<CustomOne> list;
std::unique_ptr<Ui::RippleAnimation> ripple;

View file

@ -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<StickerIcon> 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()

View file

@ -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);

View file

@ -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<StickersSetThumbnailView> StickersSet::createThumbnailView() {
if (auto active = activeThumbnailView()) {
return active;

View file

@ -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<StickersSetThumbnailView> createThumbnailView();
[[nodiscard]] std::shared_ptr<StickersSetThumbnailView> 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;

View file

@ -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)