From ccef155f7a9ab369b3a46a5b6cabe86290c4fc60 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 7 Mar 2018 20:43:26 +0300 Subject: [PATCH] Receive and track recent sticker usage date. --- Telegram/SourceFiles/apiwrap.cpp | 7 +++-- .../SourceFiles/chat_helpers/stickers.cpp | 27 +++++++++++----- Telegram/SourceFiles/chat_helpers/stickers.h | 4 ++- Telegram/SourceFiles/mainwidget.cpp | 7 +++++ Telegram/SourceFiles/storage/localstorage.cpp | 31 +++++++++++++++++++ .../storage/serialize_document.cpp | 5 ++- 6 files changed, 70 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 226f5e633..18a402c92 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -1397,7 +1397,9 @@ void ApiWrap::saveStickerSets( writeRecent = true; } - _stickersClearRecentRequestId = request(MTPmessages_ClearRecentStickers(MTP_flags(0))).done([this](const MTPBool &result) { + _stickersClearRecentRequestId = request(MTPmessages_ClearRecentStickers( + MTP_flags(0) + )).done([this](const MTPBool &result) { _stickersClearRecentRequestId = 0; }).fail([this](const RPCError &error) { _stickersClearRecentRequestId = 0; @@ -2301,7 +2303,8 @@ void ApiWrap::requestRecentStickers(TimeId now) { lang(lng_recent_stickers), d.vstickers.v, d.vhash.v, - d.vpacks.v); + d.vpacks.v, + d.vdates.v); } return; default: Unexpected("Type in ApiWrap::recentStickersDone()"); } diff --git a/Telegram/SourceFiles/chat_helpers/stickers.cpp b/Telegram/SourceFiles/chat_helpers/stickers.cpp index e522a91ac..c7ade0d99 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers.cpp @@ -405,8 +405,13 @@ void SetsReceived(const QVector &data, int32 hash) { Auth().data().notifyStickersUpdated(); } -void SetPackAndEmoji(Set &set, Pack &&pack, const QVector &packs) { +void SetPackAndEmoji( + Set &set, + Pack &&pack, + const std::vector &&dates, + const QVector &packs) { set.stickers = std::move(pack); + set.dates = std::move(dates); set.emoji.clear(); for_const (auto &mtpPack, packs) { Assert(mtpPack.type() == mtpc_stickerPack); @@ -433,12 +438,12 @@ void SpecialSetReceived( const QString &setTitle, const QVector &items, int32 hash, - const QVector &packs) { + const QVector &packs, + const QVector &usageDates) { auto &sets = Auth().data().stickerSetsRef(); auto it = sets.find(setId); - auto &d_docs = items; - if (d_docs.isEmpty()) { + if (items.isEmpty()) { if (it != sets.cend()) { sets.erase(it); } @@ -458,14 +463,22 @@ void SpecialSetReceived( } it->hash = hash; + auto dates = std::vector(); + auto dateIndex = 0; + auto datesAvailable = (items.size() == usageDates.size()); + auto custom = sets.find(CustomSetId); auto pack = Pack(); - pack.reserve(d_docs.size()); - for_const (auto &mtpDocument, d_docs) { + pack.reserve(items.size()); + for_const (auto &mtpDocument, items) { + const auto date = datesAvailable + ? TimeId(usageDates[dateIndex++].v) + : TimeId(); auto document = Auth().data().document(mtpDocument); if (!document->sticker()) continue; pack.push_back(document); + dates.push_back(date); if (custom != sets.cend()) { auto index = custom->stickers.indexOf(document); if (index >= 0) { @@ -492,7 +505,7 @@ void SpecialSetReceived( if (pack.isEmpty()) { sets.erase(it); } else { - SetPackAndEmoji(*it, std::move(pack), packs); + SetPackAndEmoji(*it, std::move(pack), std::move(dates), packs); } if (writeRecent) { diff --git a/Telegram/SourceFiles/chat_helpers/stickers.h b/Telegram/SourceFiles/chat_helpers/stickers.h index a52436675..d406068fc 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers.h +++ b/Telegram/SourceFiles/chat_helpers/stickers.h @@ -52,6 +52,7 @@ struct Set { MTPDstickerSet::Flags flags; TimeId installDate = 0; Pack stickers; + std::vector dates; Pack covers; ByEmojiMap emoji; }; @@ -77,7 +78,8 @@ void SpecialSetReceived( const QString &setTitle, const QVector &items, int32 hash, - const QVector &packs = QVector()); + const QVector &packs = QVector(), + const QVector &usageDates = QVector()); void FeaturedSetsReceived( const QVector &data, const QVector &unread, diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index dbe0d8f11..787a16351 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -4060,9 +4060,16 @@ void MainWidget::incrementSticker(DocumentData *sticker) { } auto index = it->stickers.indexOf(sticker); if (index > 0) { + if (!it->dates.empty()) { + Assert(it->dates.size() == it->stickers.size()); + it->dates.erase(it->dates.begin() + index); + } it->stickers.removeAt(index); } if (index) { + if (it->dates.size() == it->stickers.size()) { + it->dates.insert(it->dates.begin(), unixtime()); + } it->stickers.push_front(sticker); writeRecentStickers = true; } diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index f4d85d8b9..47c1066c6 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -3216,6 +3216,15 @@ void _writeStickerSet(QDataStream &stream, const Stickers::Set &set) { for (auto j = set.stickers.cbegin(), e = set.stickers.cend(); j != e; ++j) { Serialize::Document::writeToStream(stream, *j); } + if (AppVersion > 1002008) { + stream << qint32(set.dates.size()); + if (!set.dates.empty()) { + Assert(set.dates.size() == set.stickers.size()); + for (const auto date : set.dates) { + stream << qint32(date); + } + } + } if (AppVersion > 9018) { stream << qint32(set.emoji.size()); @@ -3267,6 +3276,11 @@ void _writeStickerSets(FileKey &stickersKey, CheckSet checkSet, const Stickers:: for_const (auto &sticker, set.stickers) { size += Serialize::Document::sizeInStream(sticker); } + size += sizeof(qint32); // dates count + if (!set.dates.empty()) { + Assert(set.stickers.size() == set.dates.size()); + size += set.dates.size() * sizeof(qint32); + } size += sizeof(qint32); // emojiCount for (auto j = set.emoji.cbegin(), e = set.emoji.cend(); j != e; ++j) { @@ -3432,6 +3446,23 @@ void _readStickerSets(FileKey &stickersKey, Stickers::Order *outOrder = nullptr, } } + if (stickers.version > 1002008) { + auto datesCount = qint32(0); + stickers.stream >> datesCount; + if (datesCount > 0) { + if (datesCount != scnt) { + // Bad file. + return; + } + set.dates.reserve(datesCount); + for (auto i = 0; i != datesCount; ++i) { + auto date = qint32(); + stickers.stream >> date; + set.dates.push_back(TimeId(date)); + } + } + } + if (stickers.version > 9018) { qint32 emojiCount; stickers.stream >> emojiCount; diff --git a/Telegram/SourceFiles/storage/serialize_document.cpp b/Telegram/SourceFiles/storage/serialize_document.cpp index 04f980632..91e0a7a7d 100644 --- a/Telegram/SourceFiles/storage/serialize_document.cpp +++ b/Telegram/SourceFiles/storage/serialize_document.cpp @@ -82,7 +82,10 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream & if (typeOfSet == StickerSetTypeEmpty) { attributes.push_back(MTP_documentAttributeSticker(MTP_flags(0), MTP_string(alt), MTP_inputStickerSetEmpty(), MTPMaskCoords())); } else if (info) { - if (info->setId == Stickers::DefaultSetId || info->setId == Stickers::CloudRecentSetId || info->setId == Stickers::FavedSetId || info->setId == Stickers::CustomSetId) { + if (info->setId == Stickers::DefaultSetId + || info->setId == Stickers::CloudRecentSetId + || info->setId == Stickers::FavedSetId + || info->setId == Stickers::CustomSetId) { typeOfSet = StickerSetTypeEmpty; }