diff --git a/Telegram/SourceFiles/data/components/recent_shared_media_gifts.cpp b/Telegram/SourceFiles/data/components/recent_shared_media_gifts.cpp index dcb3f3a918..30dbc559e3 100644 --- a/Telegram/SourceFiles/data/components/recent_shared_media_gifts.cpp +++ b/Telegram/SourceFiles/data/components/recent_shared_media_gifts.cpp @@ -7,12 +7,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/components/recent_shared_media_gifts.h" +#include "api/api_credits.h" // InputSavedStarGiftId #include "api/api_premium.h" #include "apiwrap.h" +#include "chat_helpers/compose/compose_show.h" #include "data/data_document.h" #include "data/data_peer.h" #include "data/data_session.h" +#include "data/data_user.h" +#include "lang/lang_keys.h" +#include "main/main_app_config.h" #include "main/main_session.h" +#include "ui/text/text_utilities.h" +#include "ui/toast/toast.h" namespace Data { namespace { @@ -108,4 +115,120 @@ void RecentSharedMediaGifts::clearLastRequestTime( } } +void RecentSharedMediaGifts::togglePinned( + std::shared_ptr show, + not_null peer, + const Data::SavedStarGiftId &manageId, + bool pinned, + std::shared_ptr uniqueData, + std::shared_ptr replacingData) { + const auto performToggle = [=](const std::vector &gifts) { + const auto limit = _session->appConfig().pinnedGiftsLimit(); + auto manageIds = std::vector(); + + if (pinned) { + manageIds.push_back(manageId); + for (const auto &gift : gifts) { + if (gift.pinned && gift.manageId != manageId) { + manageIds.push_back(gift.manageId); + if (manageIds.size() >= limit) { + break; + } + } + } + } else { + for (const auto &gift : gifts) { + if (gift.pinned && gift.manageId != manageId) { + manageIds.push_back(gift.manageId); + } + } + } + + auto inputs = QVector(); + inputs.reserve(manageIds.size()); + for (const auto &id : manageIds) { + inputs.push_back(Api::InputSavedStarGiftId(id)); + } + + _session->api().request(MTPpayments_ToggleStarGiftsPinnedToTop( + peer->input, + MTP_vector(std::move(inputs)) + )).done([=] { + const auto updateLocal = [=] { + using GiftAction = Data::GiftUpdate::Action; + _session->data().notifyGiftUpdate({ + .id = manageId, + .action = (pinned ? GiftAction::Pin : GiftAction::Unpin), + }); + if (pinned) { + show->showToast({ + .title = (uniqueData + ? tr::lng_gift_pinned_done_title( + tr::now, + lt_gift, + Data::UniqueGiftName(*uniqueData)) + : QString()), + .text = (replacingData + ? tr::lng_gift_pinned_done_replaced( + tr::now, + lt_gift, + TextWithEntities{ + Data::UniqueGiftName(*replacingData), + }, + Ui::Text::WithEntities) + : tr::lng_gift_pinned_done( + tr::now, + Ui::Text::WithEntities)), + .duration = Ui::Toast::kDefaultDuration * 2, + }); + } + }; + + if (!pinned) { + auto result = std::deque(); + for (const auto &id : manageIds) { + for (const auto &gift : gifts) { + if (gift.manageId == id) { + result.push_back(gift); + break; + } + } + } + _recent[peer->id].gifts = std::move(result); + updateLocal(); + } else { + _session->api().request(MTPpayments_GetSavedStarGift( + MTP_vector( + 1, + Api::InputSavedStarGiftId(manageId)) + )).done([=](const MTPpayments_SavedStarGifts &result) { + const auto &tlGift = result.data().vgifts().v.front(); + if (auto parsed = Api::FromTL(peer, tlGift)) { + auto result = std::deque(); + for (const auto &id : manageIds) { + if (parsed->manageId == id) { + parsed->pinned = true; + result.push_back(*parsed); + continue; + } + for (const auto &gift : gifts) { + if (gift.manageId == id) { + result.push_back(gift); + break; + } + } + } + _recent[peer->id].gifts = std::move(result); + updateLocal(); + } + }).send(); + } + }).fail([=](const MTP::Error &error) { + show->showToast(error.type()); + }).send(); + }; + + request(peer, performToggle, true); +} + } // namespace Data diff --git a/Telegram/SourceFiles/data/components/recent_shared_media_gifts.h b/Telegram/SourceFiles/data/components/recent_shared_media_gifts.h index 380e17d499..ebffd7d7bd 100644 --- a/Telegram/SourceFiles/data/components/recent_shared_media_gifts.h +++ b/Telegram/SourceFiles/data/components/recent_shared_media_gifts.h @@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_star_gift.h" +namespace ChatHelpers { +class Show; +} // namespace ChatHelpers + namespace Main { class Session; } // namespace Main @@ -27,6 +31,14 @@ public: void clearLastRequestTime(not_null peer); + void togglePinned( + std::shared_ptr show, + not_null peer, + const Data::SavedStarGiftId &manageId, + bool pinned, + std::shared_ptr uniqueData, + std::shared_ptr replacingData = nullptr); + private: [[nodiscard]] std::vector filterGifts( const std::deque &gifts, diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 75f4881600..0410bbf5b1 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/click_handler_types.h" // UrlClickHandler #include "core/ui_integration.h" #include "data/components/credits.h" +#include "data/components/recent_shared_media_gifts.h" #include "data/data_boosts.h" #include "data/data_channel.h" #include "data/data_document.h" @@ -216,69 +217,6 @@ void ToggleStarGiftSaved( }).send(); } -void ToggleStarGiftPinned( - std::shared_ptr show, - Data::SavedStarGiftId savedId, - std::vector already, - bool pinned, - std::shared_ptr uniqueData = nullptr, - std::shared_ptr replacingData = nullptr) { - already.erase(ranges::remove(already, savedId), end(already)); - if (pinned) { - already.insert(begin(already), savedId); - const auto limit = show->session().appConfig().pinnedGiftsLimit(); - if (already.size() > limit) { - already.erase(begin(already) + limit, end(already)); - } - } - - auto inputs = QVector(); - inputs.reserve(already.size()); - for (const auto &id : already) { - inputs.push_back(Api::InputSavedStarGiftId(id)); - } - - const auto api = &show->session().api(); - const auto peer = savedId.chat() - ? savedId.chat() - : show->session().user(); - api->request(MTPpayments_ToggleStarGiftsPinnedToTop( - peer->input, - MTP_vector(std::move(inputs)) - )).done([=] { - using GiftAction = Data::GiftUpdate::Action; - show->session().data().notifyGiftUpdate({ - .id = savedId, - .action = (pinned ? GiftAction::Pin : GiftAction::Unpin), - }); - - if (pinned) { - show->showToast({ - .title = (uniqueData - ? tr::lng_gift_pinned_done_title( - tr::now, - lt_gift, - Data::UniqueGiftName(*uniqueData)) - : QString()), - .text = (replacingData - ? tr::lng_gift_pinned_done_replaced( - tr::now, - lt_gift, - TextWithEntities{ - Data::UniqueGiftName(*replacingData), - }, - Ui::Text::WithEntities) - : tr::lng_gift_pinned_done( - tr::now, - Ui::Text::WithEntities)), - .duration = Ui::Toast::kDefaultDuration * 2, - }); - } - }).fail([=](const MTP::Error &error) { - show->showToast(error.type()); - }).send(); -} - void ConfirmConvertStarGift( std::shared_ptr show, rpl::producer confirmText, @@ -1035,7 +973,12 @@ void FillUniqueGiftMenu( }; if (e.giftPinned) { menu->addAction(tr::lng_context_unpin_from_top(tr::now), [=] { - ToggleStarGiftPinned(show, savedId, ids(pinned()), false); + session->recentSharedGifts().togglePinned( + show, + giftChannel ? giftChannel : session->user(), + savedId, + false, + unique); }, st.unpin ? st.unpin : &st::menuIconUnpin); } else { menu->addAction(tr::lng_context_pin_to_top(tr::now), [=] { @@ -1061,19 +1004,19 @@ void FillUniqueGiftMenu( .action = GiftAction::Unpin, }); - ToggleStarGiftPinned( + session->recentSharedGifts().togglePinned( show, + giftChannel ? giftChannel : session->user(), savedId, - already, true, unique, replaced); }); } else { - ToggleStarGiftPinned( + session->recentSharedGifts().togglePinned( show, + giftChannel ? giftChannel : session->user(), savedId, - already, true, unique); }