From 070456882ea9b2cc4dba81b37a0dffa565727bd0 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 2 Aug 2017 22:57:49 +0200 Subject: [PATCH] Manage faved stickers from sticker context menu. --- Telegram/Resources/langs/lang.strings | 3 + Telegram/SourceFiles/apiwrap.cpp | 458 +++++------------- Telegram/SourceFiles/apiwrap.h | 11 +- .../SourceFiles/boxes/sticker_set_box.cpp | 2 +- Telegram/SourceFiles/boxes/stickers_box.cpp | 10 +- .../SourceFiles/chat_helpers/stickers.cpp | 327 ++++++++++++- Telegram/SourceFiles/chat_helpers/stickers.h | 17 +- .../chat_helpers/stickers_list_widget.cpp | 14 +- Telegram/SourceFiles/facades.cpp | 2 +- Telegram/SourceFiles/facades.h | 2 +- .../history/history_inner_widget.cpp | 25 +- .../history/history_inner_widget.h | 3 +- Telegram/SourceFiles/structs.cpp | 2 +- 13 files changed, 485 insertions(+), 391 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index ade766354..678446bce 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -885,6 +885,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_recent_stickers" = "Frequently used"; "lng_faved_stickers" = "Favorite stickers"; +"lng_faved_stickers_add" = "Add to Favorites"; +"lng_faved_stickers_remove" = "Remove from Favorites"; + "lng_switch_stickers" = "Stickers"; "lng_switch_emoji" = "Emoji"; "lng_switch_gifs" = "GIFs"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index e0ae6bd51..3eace03df 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -34,6 +34,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "window/themes/window_theme.h" #include "window/notifications_manager.h" #include "chat_helpers/message_field.h" +#include "chat_helpers/stickers.h" namespace { @@ -1537,370 +1538,141 @@ void ApiWrap::stickersSaveOrder() { void ApiWrap::updateStickers() { auto now = getms(true); - if (!Global::LastStickersUpdate() || now >= Global::LastStickersUpdate() + kStickersUpdateTimeout) { - if (!_stickersUpdateRequest) { - _stickersUpdateRequest = request(MTPmessages_GetAllStickers(MTP_int(Local::countStickersHash(true)))).done([this](const MTPmessages_AllStickers &result) { - stickersGot(result); - }).fail([this](const RPCError &error) { - LOG(("App Fail: Failed to get stickers!")); - Global::SetLastStickersUpdate(getms(true)); - _stickersUpdateRequest = 0; - }).send(); - } - } - if (!Global::LastRecentStickersUpdate() || now >= Global::LastRecentStickersUpdate() + kStickersUpdateTimeout) { - if (!_recentStickersUpdateRequest) { - _recentStickersUpdateRequest = request(MTPmessages_GetRecentStickers(MTP_flags(0), MTP_int(Local::countRecentStickersHash()))).done([this](const MTPmessages_RecentStickers &result) { - recentStickersGot(result); - }).fail([this](const RPCError &error) { - LOG(("App Fail: Failed to get recent stickers!")); - Global::SetLastRecentStickersUpdate(getms(true)); - _recentStickersUpdateRequest = 0; - }).send(); - } - } - if (!Global::LastFavedStickersUpdate() || now >= Global::LastFavedStickersUpdate() + kStickersUpdateTimeout) { - if (!_favedStickersUpdateRequest) { - _favedStickersUpdateRequest = request(MTPmessages_GetFavedStickers(MTP_int(Local::countFavedStickersHash()))).done([this](const MTPmessages_FavedStickers &result) { - favedStickersGot(result); - }).fail([this](const RPCError &error) { - LOG(("App Fail: Failed to get faved stickers!")); - Global::SetLastFavedStickersUpdate(getms(true)); - _favedStickersUpdateRequest = 0; - }).send(); - } - } - if (!Global::LastFeaturedStickersUpdate() || now >= Global::LastFeaturedStickersUpdate() + kStickersUpdateTimeout) { - if (!_featuredStickersUpdateRequest) { - _featuredStickersUpdateRequest = request(MTPmessages_GetFeaturedStickers(MTP_int(Local::countFeaturedStickersHash()))).done([this](const MTPmessages_FeaturedStickers &result) { - featuredStickersGot(result); - }).fail([this](const RPCError &error) { - LOG(("App Fail: Failed to get featured stickers!")); - Global::SetLastFeaturedStickersUpdate(getms(true)); - _featuredStickersUpdateRequest = 0; - }).send(); - } - } - if (!cLastSavedGifsUpdate() || now >= cLastSavedGifsUpdate() + kStickersUpdateTimeout) { - if (!_savedGifsUpdateRequest) { - _savedGifsUpdateRequest = request(MTPmessages_GetSavedGifs(MTP_int(Local::countSavedGifsHash()))).done([this](const MTPmessages_SavedGifs &result) { - savedGifsGot(result); - }).fail([this](const RPCError &error) { - LOG(("App Fail: Failed to get saved gifs!")); - cSetLastSavedGifsUpdate(getms(true)); - _savedGifsUpdateRequest = 0; - }).send(); - } - } + requestStickers(now); + requestRecentStickers(now); + requestFavedStickers(now); + requestFeaturedStickers(now); + requestSavedGifs(now); } -void ApiWrap::stickersGot(const MTPmessages_AllStickers &stickers) { - Global::SetLastStickersUpdate(getms(true)); - _stickersUpdateRequest = 0; - - if (stickers.type() != mtpc_messages_allStickers) return; - auto &d = stickers.c_messages_allStickers(); - - auto &d_sets = d.vsets.v; - - auto &setsOrder = Global::RefStickerSetsOrder(); - setsOrder.clear(); - - auto &sets = Global::RefStickerSets(); - QMap setsToRequest; - for (auto &set : sets) { - if (!(set.flags & MTPDstickerSet::Flag::f_archived)) { - set.flags &= ~MTPDstickerSet::Flag::f_installed; // mark for removing - } +void ApiWrap::requestStickers(TimeId now) { + if (Global::LastStickersUpdate() != 0 && now < Global::LastStickersUpdate() + kStickersUpdateTimeout) { + return; } - for_const (auto &setData, d_sets) { - if (setData.type() == mtpc_stickerSet) { - auto set = Stickers::feedSet(setData.c_stickerSet()); - if (!(set->flags & MTPDstickerSet::Flag::f_archived) || (set->flags & MTPDstickerSet::Flag::f_official)) { - setsOrder.push_back(set->id); - if (set->stickers.isEmpty() || (set->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) { - setsToRequest.insert(set->id, set->access); - } - } - } + if (_stickersUpdateRequest) { + return; } - bool writeRecent = false; - RecentStickerPack &recent(cGetRecentStickers()); - for (Stickers::Sets::iterator it = sets.begin(), e = sets.end(); it != e;) { - bool installed = (it->flags & MTPDstickerSet::Flag::f_installed); - bool featured = (it->flags & MTPDstickerSet_ClientFlag::f_featured); - bool special = (it->flags & MTPDstickerSet_ClientFlag::f_special); - bool archived = (it->flags & MTPDstickerSet::Flag::f_archived); - if (!installed) { // remove not mine sets from recent stickers - for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) { - if (it->stickers.indexOf(i->first) >= 0) { - i = recent.erase(i); - writeRecent = true; - } else { - ++i; - } - } + auto onDone = [this](const MTPmessages_AllStickers &result) { + Global::SetLastStickersUpdate(getms(true)); + _stickersUpdateRequest = 0; + + switch (result.type()) { + case mtpc_messages_allStickersNotModified: return; + case mtpc_messages_allStickers: { + auto &d = result.c_messages_allStickers(); + Stickers::SetsReceived(d.vsets.v, d.vhash.v); + } return; + default: Unexpected("Type in ApiWrap::stickersDone()"); } - if (installed || featured || special || archived) { - ++it; - } else { - it = sets.erase(it); - } - } - - if (Local::countStickersHash() != d.vhash.v) { - LOG(("API Error: received stickers hash %1 while counted hash is %2").arg(d.vhash.v).arg(Local::countStickersHash())); - } - - if (!setsToRequest.isEmpty() && App::api()) { - for (QMap::const_iterator i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) { - App::api()->scheduleStickerSetRequest(i.key(), i.value()); - } - App::api()->requestStickerSets(); - } - - Local::writeInstalledStickers(); - if (writeRecent) Local::writeUserSettings(); - - if (App::main()) emit App::main()->stickersUpdated(); + }; + _stickersUpdateRequest = request(MTPmessages_GetAllStickers(MTP_int(Local::countStickersHash(true)))).done(onDone).fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get stickers!")); + onDone(MTP_messages_allStickersNotModified()); + }).send(); } -void ApiWrap::recentStickersGot(const MTPmessages_RecentStickers &stickers) { - Global::SetLastRecentStickersUpdate(getms(true)); - _recentStickersUpdateRequest = 0; - - if (stickers.type() != mtpc_messages_recentStickers) return; - auto &d = stickers.c_messages_recentStickers(); - - insertSpecialStickersSet(Stickers::CloudRecentSetId, lang(lng_recent_stickers), d.vstickers, d.vhash); - - if (Local::countRecentStickersHash() != d.vhash.v) { - LOG(("API Error: received stickers hash %1 while counted hash is %2").arg(d.vhash.v).arg(Local::countRecentStickersHash())); +void ApiWrap::requestRecentStickers(TimeId now) { + if (Global::LastRecentStickersUpdate() != 0 && now < Global::LastRecentStickersUpdate() + kStickersUpdateTimeout) { + return; } + if (_recentStickersUpdateRequest) { + return; + } + auto onDone = [this](const MTPmessages_RecentStickers &result) { + Global::SetLastRecentStickersUpdate(getms(true)); + _recentStickersUpdateRequest = 0; - Local::writeRecentStickers(); - - if (App::main()) emit App::main()->stickersUpdated(); + switch (result.type()) { + 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); + } 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) { + LOG(("App Fail: Failed to get recent stickers!")); + onDone(MTP_messages_recentStickersNotModified()); + }).send(); } -void ApiWrap::favedStickersGot(const MTPmessages_FavedStickers &stickers) { - Global::SetLastFavedStickersUpdate(getms(true)); - _favedStickersUpdateRequest = 0; - - if (stickers.type() != mtpc_messages_favedStickers) return; - auto &d = stickers.c_messages_favedStickers(); - - insertSpecialStickersSet(Stickers::FavedSetId, lang(lng_faved_stickers), d.vstickers, d.vhash); - - if (Local::countRecentStickersHash() != d.vhash.v) { - LOG(("API Error: received stickers hash %1 while counted hash is %2").arg(d.vhash.v).arg(Local::countRecentStickersHash())); +void ApiWrap::requestFavedStickers(TimeId now) { + if (Global::LastFavedStickersUpdate() != 0 && now < Global::LastFavedStickersUpdate() + kStickersUpdateTimeout) { + return; } + if (_favedStickersUpdateRequest) { + return; + } + auto onDone = [this](const MTPmessages_FavedStickers &result) { + Global::SetLastFavedStickersUpdate(getms(true)); + _favedStickersUpdateRequest = 0; - Local::writeRecentStickers(); - - if (App::main()) emit App::main()->stickersUpdated(); + switch (result.type()) { + case mtpc_messages_favedStickersNotModified: return; + case mtpc_messages_favedStickers: { + auto &d = result.c_messages_favedStickers(); + Stickers::SpecialSetReceived(Stickers::FavedSetId, lang(lng_faved_stickers), d.vstickers.v, d.vhash.v); + } return; + default: Unexpected("Type in ApiWrap::favedStickersDone()"); + } + }; + _favedStickersUpdateRequest = request(MTPmessages_GetFavedStickers(MTP_int(Local::countFavedStickersHash()))).done(onDone).fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get faved stickers!")); + onDone(MTP_messages_favedStickersNotModified()); + }).send(); } -void ApiWrap::insertSpecialStickersSet(uint64 setId, const QString &setTitle, const MTPVector &items, MTPint hash) { - auto &sets = Global::RefStickerSets(); - auto it = sets.find(setId); - - auto &d_docs = items.v; - if (d_docs.isEmpty()) { - if (it != sets.cend()) { - sets.erase(it); - } - } else { - if (it == sets.cend()) { - it = sets.insert(setId, Stickers::Set(Stickers::FavedSetId, 0, setTitle, QString(), 0, 0, qFlags(MTPDstickerSet_ClientFlag::f_special))); - } else { - it->title = setTitle; - } - it->hash = hash.v; - - auto custom = sets.find(Stickers::CustomSetId); - auto pack = StickerPack(); - pack.reserve(d_docs.size()); - for_const (auto &mtpDocument, d_docs) { - auto document = App::feedDocument(mtpDocument); - if (!document || !document->sticker()) continue; - - pack.push_back(document); - if (custom != sets.cend()) { - auto index = custom->stickers.indexOf(document); - if (index >= 0) { - custom->stickers.removeAt(index); - } - } - } - if (custom != sets.cend() && custom->stickers.isEmpty()) { - sets.erase(custom); - custom = sets.end(); - } - - auto writeRecent = false; - auto &recent = cGetRecentStickers(); - for (auto i = recent.begin(); i != recent.cend();) { - if (it->stickers.indexOf(i->first) >= 0 && pack.indexOf(i->first) < 0) { - i = recent.erase(i); - writeRecent = true; - } else { - ++i; - } - } - - if (pack.isEmpty()) { - sets.erase(it); - } else { - it->stickers = pack; - it->emoji.clear(); - } - - if (writeRecent) { - Local::writeUserSettings(); - } +void ApiWrap::requestFeaturedStickers(TimeId now) { + if (Global::LastFeaturedStickersUpdate() != 0 && now < Global::LastFeaturedStickersUpdate() + kStickersUpdateTimeout) { + return; } + if (_featuredStickersUpdateRequest) { + return; + } + auto onDone = [this](const MTPmessages_FeaturedStickers &result) { + Global::SetLastFeaturedStickersUpdate(getms(true)); + _featuredStickersUpdateRequest = 0; + + switch (result.type()) { + case mtpc_messages_featuredStickersNotModified: return; + case mtpc_messages_featuredStickers: { + auto &d = result.c_messages_featuredStickers(); + Stickers::FeaturedSetsReceived(d.vsets.v, d.vunread.v, d.vhash.v); + } return; + default: Unexpected("Type in ApiWrap::featuredStickersDone()"); + } + }; + _featuredStickersUpdateRequest = request(MTPmessages_GetFeaturedStickers(MTP_int(Local::countFeaturedStickersHash()))).done(onDone).fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get featured stickers!")); + onDone(MTP_messages_featuredStickersNotModified()); + }).send(); } -void ApiWrap::featuredStickersGot(const MTPmessages_FeaturedStickers &stickers) { - Global::SetLastFeaturedStickersUpdate(getms(true)); - _featuredStickersUpdateRequest = 0; - - if (stickers.type() != mtpc_messages_featuredStickers) return; - auto &d = stickers.c_messages_featuredStickers(); - - OrderedSet unread; - for_const (auto &unreadSetId, d.vunread.v) { - unread.insert(unreadSetId.v); +void ApiWrap::requestSavedGifs(TimeId now) { + if (cLastSavedGifsUpdate() != 0 && now < cLastSavedGifsUpdate() + kStickersUpdateTimeout) { + return; } - - auto &d_sets = d.vsets.v; - - auto &setsOrder = Global::RefFeaturedStickerSetsOrder(); - setsOrder.clear(); - - auto &sets = Global::RefStickerSets(); - QMap setsToRequest; - for (auto &set : sets) { - set.flags &= ~MTPDstickerSet_ClientFlag::f_featured; // mark for removing + if (_savedGifsUpdateRequest) { + return; } - for (int i = 0, l = d_sets.size(); i != l; ++i) { - auto &setData = d_sets[i]; - const MTPDstickerSet *set = nullptr; - switch (setData.type()) { - case mtpc_stickerSetCovered: { - auto &d = setData.c_stickerSetCovered(); - if (d.vset.type() == mtpc_stickerSet) { - set = &d.vset.c_stickerSet(); - } - } break; - case mtpc_stickerSetMultiCovered: { - auto &d = setData.c_stickerSetMultiCovered(); - if (d.vset.type() == mtpc_stickerSet) { - set = &d.vset.c_stickerSet(); - } - } break; + auto onDone = [this](const MTPmessages_SavedGifs &result) { + cSetLastSavedGifsUpdate(getms(true)); + _savedGifsUpdateRequest = 0; + + switch (result.type()) { + case mtpc_messages_savedGifsNotModified: return; + case mtpc_messages_savedGifs: { + auto &d = result.c_messages_savedGifs(); + Stickers::GifsReceived(d.vgifs.v, d.vhash.v); + } return; + default: Unexpected("Type in ApiWrap::savedGifsDone()"); } - - if (set) { - auto it = sets.find(set->vid.v); - auto title = stickerSetTitle(*set); - if (it == sets.cend()) { - auto setClientFlags = MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded; - if (unread.contains(set->vid.v)) { - setClientFlags |= MTPDstickerSet_ClientFlag::f_unread; - } - 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 | setClientFlags)); - } else { - it->access = set->vaccess_hash.v; - it->title = title; - it->shortName = qs(set->vshort_name); - 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; - if (unread.contains(it->id)) { - it->flags |= MTPDstickerSet_ClientFlag::f_unread; - } else { - it->flags &= ~MTPDstickerSet_ClientFlag::f_unread; - } - 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 - } - } - setsOrder.push_back(set->vid.v); - if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) { - setsToRequest.insert(set->vid.v, set->vaccess_hash.v); - } - } - } - - int unreadCount = 0; - for (auto it = sets.begin(), e = sets.end(); it != e;) { - bool installed = (it->flags & MTPDstickerSet::Flag::f_installed); - bool featured = (it->flags & MTPDstickerSet_ClientFlag::f_featured); - bool special = (it->flags & MTPDstickerSet_ClientFlag::f_special); - bool archived = (it->flags & MTPDstickerSet::Flag::f_archived); - if (installed || featured || special || archived) { - if (featured && (it->flags & MTPDstickerSet_ClientFlag::f_unread)) { - ++unreadCount; - } - ++it; - } else { - it = sets.erase(it); - } - } - if (Global::FeaturedStickerSetsUnreadCount() != unreadCount) { - Global::SetFeaturedStickerSetsUnreadCount(unreadCount); - Global::RefFeaturedStickerSetsUnreadCountChanged().notify(); - } - - if (Local::countFeaturedStickersHash() != d.vhash.v) { - LOG(("API Error: received featured stickers hash %1 while counted hash is %2").arg(d.vhash.v).arg(Local::countFeaturedStickersHash())); - } - - if (!setsToRequest.isEmpty() && App::api()) { - for (QMap::const_iterator i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) { - App::api()->scheduleStickerSetRequest(i.key(), i.value()); - } - App::api()->requestStickerSets(); - } - - Local::writeFeaturedStickers(); - - if (App::main()) emit App::main()->stickersUpdated(); -} - -void ApiWrap::savedGifsGot(const MTPmessages_SavedGifs &gifs) { - cSetLastSavedGifsUpdate(getms(true)); - _savedGifsUpdateRequest = 0; - - if (gifs.type() != mtpc_messages_savedGifs) return; - auto &d = gifs.c_messages_savedGifs(); - - auto &gifsList = d.vgifs.v; - - auto &saved = cRefSavedGifs(); - saved.clear(); - - saved.reserve(gifsList.size()); - for (auto &gif : gifsList) { - auto document = App::feedDocument(gif); - if (!document || !document->isGifv()) { - LOG(("API Error: bad document returned in HistoryWidget::savedGifsGot!")); - continue; - } - - saved.push_back(document); - } - if (Local::countSavedGifsHash() != d.vhash.v) { - LOG(("API Error: received saved gifs hash %1 while counted hash is %2").arg(d.vhash.v).arg(Local::countSavedGifsHash())); - } - - Local::writeSavedGifs(); - - AuthSession::Current().data().savedGifsUpdated().notify(); + }; + _savedGifsUpdateRequest = request(MTPmessages_GetSavedGifs(MTP_int(Local::countSavedGifsHash()))).done(onDone).fail([this, onDone](const RPCError &error) { + LOG(("App Fail: Failed to get saved gifs!")); + onDone(MTP_messages_savedGifsNotModified()); + }).send(); } void ApiWrap::applyUpdatesNoPtsCheck(const MTPUpdates &updates) { diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 470444d8e..bc0a2935e 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -132,12 +132,11 @@ private: void stickerSetDisenabled(mtpRequestId requestId); void stickersSaveOrder(); - void stickersGot(const MTPmessages_AllStickers &stickers); - void recentStickersGot(const MTPmessages_RecentStickers &stickers); - void favedStickersGot(const MTPmessages_FavedStickers &stickers); - void featuredStickersGot(const MTPmessages_FeaturedStickers &stickers); - void savedGifsGot(const MTPmessages_SavedGifs &gifs); - void insertSpecialStickersSet(uint64 setId, const QString &setTitle, const MTPVector &items, MTPint hash); + void requestStickers(TimeId now); + void requestRecentStickers(TimeId now); + void requestFavedStickers(TimeId now); + void requestFeaturedStickers(TimeId now); + void requestSavedGifs(TimeId now); gsl::not_null _session; mtpRequestId _changelogSubscription = 0; diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index c74883b98..4d984f175 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -248,7 +248,7 @@ void StickerSetBox::Inner::installDone(const MTPmessages_StickerSetInstallResult } if (result.type() == mtpc_messages_stickerSetInstallResultArchive) { - Stickers::applyArchivedResult(result.c_messages_stickerSetInstallResultArchive()); + Stickers::ApplyArchivedResult(result.c_messages_stickerSetInstallResultArchive()); } else { if (wasArchived) { Local::writeArchivedStickers(); diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index b6fd8b5d6..1489c1757 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -191,7 +191,7 @@ void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedSti } if (!setData) continue; - if (auto set = Stickers::feedSet(*setData)) { + if (auto set = Stickers::FeedSet(*setData)) { auto index = archived.indexOf(set->id); if (archived.isEmpty() || index != archived.size() - 1) { changedSets = true; @@ -452,13 +452,13 @@ void StickersBox::installSet(uint64 setId) { 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)); - Stickers::installLocally(setId); + Stickers::InstallLocally(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()); } } @@ -472,7 +472,7 @@ bool StickersBox::installFail(uint64 setId, const RPCError &error) { return true; } - Stickers::undoInstallLocally(setId); + Stickers::UndoInstallLocally(setId); return true; } @@ -1350,7 +1350,7 @@ void StickersBox::Inner::readVisibleSets() { continue; } if (!_rows[i]->sticker || _rows[i]->sticker->thumb->loaded() || _rows[i]->sticker->loaded()) { - Stickers::markFeaturedAsRead(_rows[i]->id); + Stickers::MarkFeaturedAsRead(_rows[i]->id); } } } diff --git a/Telegram/SourceFiles/chat_helpers/stickers.cpp b/Telegram/SourceFiles/chat_helpers/stickers.cpp index a77dea10e..6b12aeed5 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers.cpp @@ -38,10 +38,10 @@ QPointer FeaturedReaderInstance; } // namespace -void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) { +void ApplyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) { auto &v = d.vsets.v; auto &order = Global::RefStickerSetsOrder(); - Stickers::Order archived; + Order archived; archived.reserve(v.size()); QMap setsToRequest; for_const (auto &stickerSet, v) { @@ -61,7 +61,7 @@ void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) { } break; } if (setData) { - auto set = Stickers::feedSet(*setData); + auto set = FeedSet(*setData); if (set->stickers.isEmpty()) { setsToRequest.insert(set->id, set->access); } @@ -92,7 +92,7 @@ void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) { } // For testing: Just apply random subset or your sticker sets as archived. -bool applyArchivedResultFake() { +bool ApplyArchivedResultFake() { auto sets = QVector(); for (auto &set : Global::RefStickerSets()) { if ((set.flags & MTPDstickerSet::Flag::f_installed) && !(set.flags & MTPDstickerSet_ClientFlag::f_special)) { @@ -104,11 +104,11 @@ bool applyArchivedResultFake() { } if (sets.size() > 3) sets = sets.mid(0, 3); auto fakeResult = MTP_messages_stickerSetInstallResultArchive(MTP_vector(sets)); - applyArchivedResult(fakeResult.c_messages_stickerSetInstallResultArchive()); + ApplyArchivedResult(fakeResult.c_messages_stickerSetInstallResultArchive()); return true; } -void installLocally(uint64 setId) { +void InstallLocally(uint64 setId) { auto &sets = Global::RefStickerSets(); auto it = sets.find(setId); if (it == sets.end()) { @@ -129,7 +129,7 @@ void installLocally(uint64 setId) { order.insert(insertAtIndex, setId); } - auto custom = sets.find(Stickers::CustomSetId); + auto custom = sets.find(CustomSetId); if (custom != sets.cend()) { for_const (auto sticker, it->stickers) { int removeIndex = custom->stickers.indexOf(sticker); @@ -151,7 +151,7 @@ void installLocally(uint64 setId) { emit App::main()->stickersUpdated(); } -void undoInstallLocally(uint64 setId) { +void UndoInstallLocally(uint64 setId) { auto &sets = Global::RefStickerSets(); auto it = sets.find(setId); if (it == sets.end()) { @@ -172,7 +172,7 @@ void undoInstallLocally(uint64 setId) { Ui::show(Box(lang(lng_stickers_not_found)), KeepOtherLayers); } -void markFeaturedAsRead(uint64 setId) { +void MarkFeaturedAsRead(uint64 setId) { if (!FeaturedReaderInstance) { if (auto main = App::main()) { FeaturedReaderInstance = object_ptr(main); @@ -183,6 +183,315 @@ void markFeaturedAsRead(uint64 setId) { FeaturedReaderInstance->scheduleRead(setId); } +bool IsFaved(DocumentData *document) { + auto it = Global::StickerSets().constFind(FavedSetId); + return (it != Global::StickerSets().cend()) && it->stickers.contains(document); +} + +void SetFaved(DocumentData *document, bool faved) { + auto &sets = Global::RefStickerSets(); + auto it = sets.find(FavedSetId); + if (faved) { + if (it == sets.end()) { + it = sets.insert(FavedSetId, Set(FavedSetId, 0, lang(lng_faved_stickers), QString(), 0, 0, qFlags(MTPDstickerSet_ClientFlag::f_special))); + } + auto index = it->stickers.indexOf(document); + if (index != 0) { + if (index > 0) { + // Push this sticker to the front. + while (index-- != 0) { + it->stickers[index + 1] = it->stickers[index]; + } + it->stickers[0] = document; + } else { + it->stickers.push_front(document); + } + Local::writeFavedStickers(); + emit App::main()->stickersUpdated(); + App::main()->onStickersInstalled(FavedSetId); + } + } else if (it != sets.end()) { + auto index = it->stickers.indexOf(document); + if (index >= 0) { + it->stickers.removeAt(index); + if (it->stickers.empty()) { + sets.erase(it); + } + Local::writeFavedStickers(); + emit App::main()->stickersUpdated(); + } + } +} + +void SetsReceived(const QVector &data, int32 hash) { + auto &setsOrder = Global::RefStickerSetsOrder(); + setsOrder.clear(); + + auto &sets = Global::RefStickerSets(); + QMap setsToRequest; + for (auto &set : sets) { + if (!(set.flags & MTPDstickerSet::Flag::f_archived)) { + set.flags &= ~MTPDstickerSet::Flag::f_installed; // mark for removing + } + } + for_const (auto &setData, data) { + if (setData.type() == mtpc_stickerSet) { + auto set = FeedSet(setData.c_stickerSet()); + if (!(set->flags & MTPDstickerSet::Flag::f_archived) || (set->flags & MTPDstickerSet::Flag::f_official)) { + setsOrder.push_back(set->id); + if (set->stickers.isEmpty() || (set->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) { + setsToRequest.insert(set->id, set->access); + } + } + } + } + auto writeRecent = false; + auto &recent = cGetRecentStickers(); + for (auto it = sets.begin(), e = sets.end(); it != e;) { + bool installed = (it->flags & MTPDstickerSet::Flag::f_installed); + bool featured = (it->flags & MTPDstickerSet_ClientFlag::f_featured); + bool special = (it->flags & MTPDstickerSet_ClientFlag::f_special); + bool archived = (it->flags & MTPDstickerSet::Flag::f_archived); + if (!installed) { // remove not mine sets from recent stickers + for (auto i = recent.begin(); i != recent.cend();) { + if (it->stickers.indexOf(i->first) >= 0) { + i = recent.erase(i); + writeRecent = true; + } else { + ++i; + } + } + } + if (installed || featured || special || archived) { + ++it; + } else { + it = sets.erase(it); + } + } + + if (!setsToRequest.isEmpty()) { + auto &api = AuthSession::Current().api(); + for (auto i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) { + api.scheduleStickerSetRequest(i.key(), i.value()); + } + api.requestStickerSets(); + } + + Local::writeInstalledStickers(); + if (writeRecent) Local::writeUserSettings(); + + if (Local::countStickersHash() != hash) { + LOG(("API Error: received stickers hash %1 while counted hash is %2").arg(hash).arg(Local::countStickersHash())); + } + + if (App::main()) emit App::main()->stickersUpdated(); +} + +void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVector &items, int32 hash) { + auto &sets = Global::RefStickerSets(); + auto it = sets.find(setId); + + auto &d_docs = items; + if (d_docs.isEmpty()) { + if (it != sets.cend()) { + sets.erase(it); + } + } else { + if (it == sets.cend()) { + it = sets.insert(setId, Set(setId, 0, setTitle, QString(), 0, 0, qFlags(MTPDstickerSet_ClientFlag::f_special))); + } else { + it->title = setTitle; + } + it->hash = hash; + + auto custom = sets.find(CustomSetId); + auto pack = StickerPack(); + pack.reserve(d_docs.size()); + for_const (auto &mtpDocument, d_docs) { + auto document = App::feedDocument(mtpDocument); + if (!document || !document->sticker()) continue; + + pack.push_back(document); + if (custom != sets.cend()) { + auto index = custom->stickers.indexOf(document); + if (index >= 0) { + custom->stickers.removeAt(index); + } + } + } + if (custom != sets.cend() && custom->stickers.isEmpty()) { + sets.erase(custom); + custom = sets.end(); + } + + auto writeRecent = false; + auto &recent = cGetRecentStickers(); + for (auto i = recent.begin(); i != recent.cend();) { + if (it->stickers.indexOf(i->first) >= 0 && pack.indexOf(i->first) < 0) { + i = recent.erase(i); + writeRecent = true; + } else { + ++i; + } + } + + if (pack.isEmpty()) { + sets.erase(it); + } else { + it->stickers = pack; + it->emoji.clear(); + } + + if (writeRecent) { + Local::writeUserSettings(); + } + } + + switch (setId) { + case CloudRecentSetId: { + if (Local::countRecentStickersHash() != hash) { + LOG(("API Error: received recent stickers hash %1 while counted hash is %2").arg(hash).arg(Local::countRecentStickersHash())); + } + Local::writeRecentStickers(); + } break; + case FavedSetId: { + if (Local::countFavedStickersHash() != hash) { + LOG(("API Error: received faved stickers hash %1 while counted hash is %2").arg(hash).arg(Local::countFavedStickersHash())); + } + Local::writeFavedStickers(); + } break; + default: Unexpected("setId in SpecialSetReceived()"); + } + + if (App::main()) emit App::main()->stickersUpdated(); +} + +void FeaturedSetsReceived(const QVector &data, const QVector &unread, int32 hash) { + OrderedSet unreadMap; + for_const (auto &unreadSetId, unread) { + unreadMap.insert(unreadSetId.v); + } + + auto &setsOrder = Global::RefFeaturedStickerSetsOrder(); + setsOrder.clear(); + + auto &sets = Global::RefStickerSets(); + QMap setsToRequest; + for (auto &set : sets) { + set.flags &= ~MTPDstickerSet_ClientFlag::f_featured; // mark for removing + } + for (int i = 0, l = data.size(); i != l; ++i) { + auto &setData = data[i]; + const MTPDstickerSet *set = nullptr; + switch (setData.type()) { + case mtpc_stickerSetCovered: { + auto &d = setData.c_stickerSetCovered(); + if (d.vset.type() == mtpc_stickerSet) { + set = &d.vset.c_stickerSet(); + } + } break; + case mtpc_stickerSetMultiCovered: { + auto &d = setData.c_stickerSetMultiCovered(); + if (d.vset.type() == mtpc_stickerSet) { + set = &d.vset.c_stickerSet(); + } + } break; + } + + if (set) { + auto it = sets.find(set->vid.v); + auto title = stickerSetTitle(*set); + 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)); + } else { + it->access = set->vaccess_hash.v; + it->title = title; + it->shortName = qs(set->vshort_name); + 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; + if (unreadMap.contains(it->id)) { + it->flags |= MTPDstickerSet_ClientFlag::f_unread; + } else { + it->flags &= ~MTPDstickerSet_ClientFlag::f_unread; + } + 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 + } + } + setsOrder.push_back(set->vid.v); + if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) { + setsToRequest.insert(set->vid.v, set->vaccess_hash.v); + } + } + } + + auto unreadCount = 0; + for (auto it = sets.begin(), e = sets.end(); it != e;) { + bool installed = (it->flags & MTPDstickerSet::Flag::f_installed); + bool featured = (it->flags & MTPDstickerSet_ClientFlag::f_featured); + bool special = (it->flags & MTPDstickerSet_ClientFlag::f_special); + bool archived = (it->flags & MTPDstickerSet::Flag::f_archived); + if (installed || featured || special || archived) { + if (featured && (it->flags & MTPDstickerSet_ClientFlag::f_unread)) { + ++unreadCount; + } + ++it; + } else { + it = sets.erase(it); + } + } + if (Global::FeaturedStickerSetsUnreadCount() != unreadCount) { + Global::SetFeaturedStickerSetsUnreadCount(unreadCount); + Global::RefFeaturedStickerSetsUnreadCountChanged().notify(); + } + + if (Local::countFeaturedStickersHash() != hash) { + LOG(("API Error: received featured stickers hash %1 while counted hash is %2").arg(hash).arg(Local::countFeaturedStickersHash())); + } + + if (!setsToRequest.isEmpty()) { + auto &api = AuthSession::Current().api(); + for (auto i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) { + api.scheduleStickerSetRequest(i.key(), i.value()); + } + api.requestStickerSets(); + } + + Local::writeFeaturedStickers(); + + if (App::main()) emit App::main()->stickersUpdated(); +} + +void GifsReceived(const QVector &items, int32 hash) { + auto &saved = cRefSavedGifs(); + saved.clear(); + + saved.reserve(items.size()); + for_const (auto &gif, items) { + auto document = App::feedDocument(gif); + if (!document || !document->isGifv()) { + LOG(("API Error: bad document returned in HistoryWidget::savedGifsGot!")); + continue; + } + + saved.push_back(document); + } + if (Local::countSavedGifsHash() != hash) { + LOG(("API Error: received saved gifs hash %1 while counted hash is %2").arg(hash).arg(Local::countSavedGifsHash())); + } + + Local::writeSavedGifs(); + + AuthSession::Current().data().savedGifsUpdated().notify(); +} + namespace internal { FeaturedReader::FeaturedReader(QObject *parent) : QObject(parent) diff --git a/Telegram/SourceFiles/chat_helpers/stickers.h b/Telegram/SourceFiles/chat_helpers/stickers.h index 02db56d27..d199635ff 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers.h +++ b/Telegram/SourceFiles/chat_helpers/stickers.h @@ -26,11 +26,18 @@ namespace Stickers { constexpr auto kPanelPerRow = 5; -void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d); -bool applyArchivedResultFake(); // For testing. -void installLocally(uint64 setId); -void undoInstallLocally(uint64 setId); -void markFeaturedAsRead(uint64 setId); +void ApplyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d); +bool ApplyArchivedResultFake(); // For testing. +void InstallLocally(uint64 setId); +void UndoInstallLocally(uint64 setId); +void MarkFeaturedAsRead(uint64 setId); +bool IsFaved(DocumentData *document); +void SetFaved(DocumentData *document, bool faved); + +void SetsReceived(const QVector &data, int32 hash); +void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVector &items, int32 hash); +void FeaturedSetsReceived(const QVector &data, const QVector &unread, int32 hash); +void GifsReceived(const QVector &items, int32 hash); namespace internal { diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index 579a4f997..30a1b4892 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -487,7 +487,7 @@ void StickersListWidget::readVisibleSets() { } } if (loaded == count) { - Stickers::markFeaturedAsRead(set.id); + Stickers::MarkFeaturedAsRead(set.id); } } } @@ -504,7 +504,7 @@ bool StickersListWidget::enumerateSections(Callback callback) const { info.section = i; info.count = _mySets[i].pack.size(); info.rowsCount = (info.count / kStickersPanelPerRow) + ((info.count % kStickersPanelPerRow) ? 1 : 0); - info.rowsTop = info.top + ((_mySets[i].flags & MTPDstickerSet_ClientFlag::f_special) ? st::stickerPanPadding : st::emojiPanHeader); + info.rowsTop = info.top + ((_mySets[i].id == Stickers::RecentSetId) ? st::stickerPanPadding : st::emojiPanHeader); info.rowsBottom = info.rowsTop + info.rowsCount * st::stickerPanSize.height(); if (!callback(info)) { return false; @@ -717,7 +717,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) { return false; } auto &set = _mySets[info.section]; - if (!(set.flags & MTPDstickerSet_ClientFlag::f_special) && clip.top() < info.rowsTop) { + if (set.id != Stickers::RecentSetId && clip.top() < info.rowsTop) { auto titleText = set.title; auto titleWidth = st::stickersTrendingHeaderFont->width(titleText); auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::buttonRadius); @@ -1177,7 +1177,7 @@ void StickersListWidget::refreshRecentStickers(bool performResize) { void StickersListWidget::refreshFavedStickers() { clearSelection(); auto &sets = Global::StickerSets(); - auto it = sets.constFind(Stickers::CloudRecentSetId); + auto it = sets.constFind(Stickers::FavedSetId); if (it == sets.cend() || it->stickers.isEmpty()) { return; } @@ -1407,15 +1407,15 @@ void StickersListWidget::installSet(quint64 setId) { if (it != sets.cend()) { request(MTPmessages_InstallStickerSet(Stickers::inputSetId(*it), MTP_bool(false))).done([this](const MTPmessages_StickerSetInstallResult &result) { if (result.type() == mtpc_messages_stickerSetInstallResultArchive) { - Stickers::applyArchivedResult(result.c_messages_stickerSetInstallResultArchive()); + Stickers::ApplyArchivedResult(result.c_messages_stickerSetInstallResultArchive()); } }).fail([this, setId](const RPCError &error) { notInstalledLocally(setId); - Stickers::undoInstallLocally(setId); + Stickers::UndoInstallLocally(setId); }).send(); installedLocally(setId); - Stickers::installLocally(setId); + Stickers::InstallLocally(setId); } } diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 85d613c6e..286d879a9 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -537,7 +537,7 @@ DefineVar(Sandbox, ProxyData, PreLaunchProxy); namespace Stickers { -Set *feedSet(const MTPDstickerSet &set) { +Set *FeedSet(const MTPDstickerSet &set) { MTPDstickerSet::Flags flags = 0; auto &sets = Global::RefStickerSets(); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 4f154cfd9..e673a8dee 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -278,7 +278,7 @@ inline MTPInputStickerSet inputSetId(const Set &set) { return MTP_inputStickerSetShortName(MTP_string(set.shortName)); } -Set *feedSet(const MTPDstickerSet &set); +Set *FeedSet(const MTPDstickerSet &set); } // namespace Stickers diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 2d0543f60..d42f1a0de 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -28,6 +28,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "ui/widgets/popup_menu.h" #include "window/window_controller.h" #include "chat_helpers/message_field.h" +#include "chat_helpers/stickers.h" #include "history/history_widget.h" #include "mainwindow.h" #include "mainwidget.h" @@ -1291,7 +1292,8 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { if (media->type() == MediaTypeSticker) { if (auto document = media->getDocument()) { if (document->sticker() && document->sticker()->set.type() != mtpc_inputStickerSetEmpty) { - _menu->addAction(lang(document->sticker()->setInstalled() ? lng_context_pack_info : lng_context_pack_add), [this] { showStickerPackInfo(); }); + _menu->addAction(lang(document->sticker()->setInstalled() ? lng_context_pack_info : lng_context_pack_add), [this, document] { showStickerPackInfo(document); }); + _menu->addAction(lang(Stickers::IsFaved(document) ? lng_faved_stickers_remove : lng_faved_stickers_add), [this, document] { toggleFavedSticker(document); }); } _menu->addAction(lang(lng_context_save_image), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [this, document] { saveDocumentToFile(document); @@ -1410,20 +1412,21 @@ void HistoryInner::copyContextImage(PhotoData *photo) { QApplication::clipboard()->setPixmap(photo->full->pix()); } -void HistoryInner::showStickerPackInfo() { - if (!App::contextItem()) return; - - if (auto media = App::contextItem()->getMedia()) { - if (auto doc = media->getDocument()) { - if (auto sticker = doc->sticker()) { - if (sticker->set.type() != mtpc_inputStickerSetEmpty) { - App::main()->stickersBox(sticker->set); - } - } +void HistoryInner::showStickerPackInfo(DocumentData *document) { + if (auto sticker = document->sticker()) { + if (sticker->set.type() != mtpc_inputStickerSetEmpty) { + App::main()->stickersBox(sticker->set); } } } +void HistoryInner::toggleFavedSticker(DocumentData *document) { + auto unfave = Stickers::IsFaved(document); + MTP::send(MTPmessages_FaveSticker(document->mtpInput(), MTP_bool(unfave)), rpcDone([document, unfave](const MTPBool &result) { + Stickers::SetFaved(document, !unfave); + })); +} + void HistoryInner::cancelContextDownload() { if (auto lnkDocument = dynamic_cast(_contextMenuLink.data())) { lnkDocument->document()->cancel(); diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index e09c4e373..728c631c5 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -145,7 +145,8 @@ private: void savePhotoToFile(PhotoData *photo); void saveDocumentToFile(DocumentData *document); void copyContextImage(PhotoData *photo); - void showStickerPackInfo(); + void showStickerPackInfo(DocumentData *document); + void toggleFavedSticker(DocumentData *document); void touchResetSpeed(); void touchUpdateSpeed(); diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 4877806e4..da49fdc7e 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -1374,7 +1374,7 @@ bool StickerData::setInstalled() const { return (it != Global::StickerSets().cend()) && !(it->flags & MTPDstickerSet::Flag::f_archived) && (it->flags & MTPDstickerSet::Flag::f_installed); } break; case mtpc_inputStickerSetShortName: { - QString name = qs(set.c_inputStickerSetShortName().vshort_name).toLower(); + auto name = qs(set.c_inputStickerSetShortName().vshort_name).toLower(); for (auto it = Global::StickerSets().cbegin(), e = Global::StickerSets().cend(); it != e; ++it) { if (it->shortName.toLower() == name) { return !(it->flags & MTPDstickerSet::Flag::f_archived) && (it->flags & MTPDstickerSet::Flag::f_installed);