From 940455f7862a11f262ecbd0ef553353ea81d3798 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 5 Mar 2025 17:28:00 +0400 Subject: [PATCH] Preload gifts for the gift to user layer. --- Telegram/SourceFiles/boxes/star_gift_box.cpp | 62 ++++++++++++++++++- .../peer_gifts/info_peer_gifts_widget.cpp | 5 ++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index 89c53f604..0107b2fbc 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -108,6 +108,7 @@ constexpr auto kSentToastDuration = 3 * crl::time(1000); constexpr auto kSwitchUpgradeCoverInterval = 3 * crl::time(1000); constexpr auto kCrossfadeDuration = crl::time(400); constexpr auto kUpgradeDoneToastDuration = 4 * crl::time(1000); +constexpr auto kGiftsPreloadTimeout = 3 * crl::time(1000); using namespace HistoryView; using namespace Info::PeerGifts; @@ -2193,7 +2194,66 @@ void ChooseStarGiftRecipient( void ShowStarGiftBox( not_null controller, not_null peer) { - controller->show(Box(GiftBox, controller, peer)); + struct Session { + PeerData *peer = nullptr; + bool premiumGiftsReady = false; + bool starsGiftsReady = false; + rpl::lifetime lifetime; + }; + static auto Map = base::flat_map, Session>(); + + const auto session = &controller->session(); + auto i = Map.find(session); + if (i == end(Map)) { + i = Map.emplace(session).first; + session->lifetime().add([=] { Map.remove(session); }); + } else if (i->second.peer == peer) { + return; + } + i->second = Session{ .peer = peer }; + + const auto weak = base::make_weak(controller); + const auto show = [=] { + Map[session] = Session(); + if (const auto strong = weak.get()) { + strong->show(Box(GiftBox, strong, peer)); + } + }; + + base::timer_once( + kGiftsPreloadTimeout + ) | rpl::start_with_next(show, i->second.lifetime); + + const auto user = peer->asUser(); + if (user && !user->isSelf()) { + GiftsPremium( + session, + peer + ) | rpl::start_with_next([=](PremiumGiftsDescriptor &&gifts) { + if (!gifts.list.empty()) { + auto &entry = Map[session]; + entry.premiumGiftsReady = true; + if (entry.starsGiftsReady) { + show(); + } + } + }, i->second.lifetime); + } else { + i->second.premiumGiftsReady = true; + } + + GiftsStars( + session, + peer + ) | rpl::start_with_next([=](std::vector &&gifts) { + if (!gifts.empty()) { + auto &entry = Map[session]; + entry.starsGiftsReady = true; + if (entry.premiumGiftsReady) { + show(); + } + } + }, i->second.lifetime); } void AddUniqueGiftCover( diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp index 376b95c07..63106347d 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp @@ -199,6 +199,8 @@ void InnerWidget::subscribeToUpdates() { } else if (update.action == Action::Save || update.action == Action::Unsave) { i->gift.hidden = (update.action == Action::Unsave); + + const auto unpin = i->gift.hidden && i->gift.pinned; v::match(i->descriptor, [](GiftTypePremium &) { }, [&](GiftTypeStars &data) { data.hidden = i->gift.hidden; @@ -209,6 +211,9 @@ void InnerWidget::subscribeToUpdates() { view.manageId = {}; } } + if (unpin) { + markUnpinned(i); + } } else if (update.action == Action::Pin || update.action == Action::Unpin) { if (update.action == Action::Pin) {