From 627152e2a93b7168e9b24934dfd3e004e37870b5 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 5 Dec 2025 12:39:03 +0400 Subject: [PATCH] Nice gifts promo box. --- Telegram/Resources/langs/lang.strings | 2 + .../SourceFiles/boxes/premium_preview_box.cpp | 66 ++++++++- .../boxes/star_gift_auction_box.cpp | 139 +++--------------- Telegram/SourceFiles/boxes/star_gift_box.cpp | 4 +- 4 files changed, 89 insertions(+), 122 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index ebae79d6a8..ec43c18149 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3908,6 +3908,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_upgrade_tradable_about" = "Sell or auction your gift on third-party NFT marketplaces."; "lng_gift_upgrade_tradable_about_user" = "{name} will be able to sell the gift on Telegram and NFT marketplaces."; "lng_gift_upgrade_tradable_about_channel" = "Admins of {name} will be able to sell the gift on Telegram and NFT marketplaces."; +"lng_gift_upgrade_wearable_title" = "Wearable"; +"lng_gift_upgrade_wearable_about" = "Display gifts on your page and set them as profile covers or statuses."; "lng_gift_upgrade_button" = "Upgrade for {price}"; "lng_gift_upgrade_decreases" = "Price decreases in {time}"; "lng_gift_upgrade_see_table" = "See how this price will decrease {arrow}"; diff --git a/Telegram/SourceFiles/boxes/premium_preview_box.cpp b/Telegram/SourceFiles/boxes/premium_preview_box.cpp index a893ce828b..0fb6da1ea4 100644 --- a/Telegram/SourceFiles/boxes/premium_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/premium_preview_box.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_streaming.h" #include "data/data_peer_values.h" #include "data/data_premium_limits.h" +#include "info/profile/info_profile_icon.h" #include "lang/lang_keys.h" #include "main/main_session.h" #include "main/main_domain.h" // kMaxAccounts @@ -43,7 +44,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "api/api_premium.h" #include "apiwrap.h" +#include "styles/style_credits.h" // upgradeGiftSubtext +#include "styles/style_info.h" // infoStarsUnderstood #include "styles/style_layers.h" +#include "styles/style_menu_icons.h" #include "styles/style_premium.h" #include "styles/style_settings.h" @@ -899,6 +903,45 @@ struct VideoPreviewDocument { return result; } +void AddGiftsInfoRows(not_null container) { + const auto infoRow = [&]( + rpl::producer title, + rpl::producer text, + not_null icon) { + auto raw = container->add( + object_ptr(container)); + raw->add( + object_ptr( + raw, + std::move(title) | Ui::Text::ToBold(), + st::defaultFlatLabel), + st::settingsPremiumRowTitlePadding); + raw->add( + object_ptr( + raw, + std::move(text), + st::upgradeGiftSubtext), + st::settingsPremiumRowAboutPadding); + object_ptr( + raw, + *icon, + st::starrefInfoIconPosition); + }; + + infoRow( + tr::lng_gift_upgrade_unique_title(), + tr::lng_gift_upgrade_unique_about(), + &st::menuIconUnique); + infoRow( + tr::lng_gift_upgrade_tradable_title(), + tr::lng_gift_upgrade_tradable_about(), + &st::menuIconTradable); + infoRow( + tr::lng_gift_upgrade_wearable_title(), + tr::lng_gift_upgrade_wearable_about(), + &st::menuIconNftWear); +} + void PreviewBox( not_null box, std::shared_ptr show, @@ -1104,16 +1147,31 @@ void PreviewBox( st::premiumPreviewAboutPadding, style::al_top )->setTryMakeSimilarLines(true); - box->addRow( - CreateSwitch(box->verticalLayout(), &state->selected, state->order), - st::premiumDotsMargin); + + const auto gifts = (state->selected.current() == PremiumFeature::Gifts); + if (gifts) { + box->setStyle(st::giftBox); + AddGiftsInfoRows(box->verticalLayout()); + } else { + box->addRow( + CreateSwitch(box->verticalLayout(), &state->selected, state->order), + st::premiumDotsMargin); + } const auto showFinished = [=] { state->showFinished = true; if (base::take(state->preloadScheduled)) { state->preload(); } }; - if ((descriptor.fromSettings && show->session().premium()) + if (gifts) { + box->setShowFinishedCallback(showFinished); + box->addButton( + rpl::single(QString()), + [=] { box->closeBox(); } + )->setText(rpl::single(Ui::Text::IconEmoji( + &st::infoStarsUnderstood + ).append(' ').append(tr::lng_auction_about_understood(tr::now)))); + } else if ((descriptor.fromSettings && show->session().premium()) || descriptor.hideSubscriptionButton) { box->setShowFinishedCallback(showFinished); box->addButton(tr::lng_close(), [=] { box->closeBox(); }); diff --git a/Telegram/SourceFiles/boxes/star_gift_auction_box.cpp b/Telegram/SourceFiles/boxes/star_gift_auction_box.cpp index ba8c8c5a2c..1170705b6b 100644 --- a/Telegram/SourceFiles/boxes/star_gift_auction_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_auction_box.cpp @@ -1320,126 +1320,31 @@ void AuctionInfoBox( state->minutesTillEnd = MinutesLeftTillValue(now.endDate); state->secondsTillStart = SecondsLeftTillValue(now.startDate); const auto started = !state->secondsTillStart.current(); - const auto perRound = now.gift->auctionGiftsPerRound; box->setStyle(st::giftBox); box->setNoContentMargin(true); - if (!started) { - const auto container = box->verticalLayout(); - auto gift = MakePreviewAuctionStream( - *now.gift, - state->attributes.value()); - AddUniqueGiftCover(container, std::move(gift), { - .pretitle = tr::lng_auction_preview_name(), - .subtitle = tr::lng_auction_preview_learn_gifts( - lt_arrow, - rpl::single(Text::IconEmoji(&st::textMoreIconEmoji)), - tr::link), - .subtitleClick = [=] { - ShowPremiumPreviewBox( - window, - PremiumFeature::AnimatedEmoji); AssertIsDebug(); - }, - .subtitleLinkColored = true, - }); - AddSkip(container, st::defaultVerticalListSkip * 2); - AddUniqueCloseButton(box, {}, MakeAuctionFillMenuCallback(show, now)); - } else { - const auto name = now.gift->resellTitle; - const auto extend = st::defaultDropdownMenu.wrap.shadow.extend; - const auto side = st::giftBoxGiftSmall; - const auto size = QSize(side, side).grownBy(extend); - const auto preview = box->addRow( - object_ptr(box, size.height()), - st::auctionInfoPreviewMargin); - const auto gift = CreateChild(preview, &state->delegate); - gift->setAttribute(Qt::WA_TransparentForMouseEvents); - gift->setDescriptor(GiftTypeStars{ - .info = *now.gift, - }, GiftButtonMode::Minimal); + const auto container = box->verticalLayout(); + auto gift = MakePreviewAuctionStream( + *now.gift, + state->attributes.value()); + AddUniqueGiftCover(container, std::move(gift), { + .pretitle = started ? nullptr : tr::lng_auction_preview_name(), + .subtitle = tr::lng_auction_preview_learn_gifts( + lt_arrow, + rpl::single(Text::IconEmoji(&st::textMoreIconEmoji)), + tr::link), + .subtitleClick = [=] { + ShowPremiumPreviewBox(window, PremiumFeature::Gifts); + }, + .subtitleLinkColored = true, + }); + AddSkip(container, st::defaultVerticalListSkip * 2); - preview->widthValue() | rpl::start_with_next([=](int width) { - const auto left = (width - size.width()) / 2; - gift->setGeometry( - QRect(QPoint(left, 0), size).marginsRemoved(extend), - extend); - }, gift->lifetime()); - - const auto rounds = state->value.current().totalRounds; - auto aboutText = state->value.value( - ) | rpl::map([=](const Data::GiftAuctionState &state) { - if (state.finished()) { - return tr::lng_auction_text_ended(tr::now, tr::marked); - } - return tr::lng_auction_text( - tr::now, - lt_count, - perRound, - lt_name, - tr::bold(name), - lt_link, - tr::lng_auction_text_link( - tr::now, - lt_arrow, - Text::IconEmoji(&st::textMoreIconEmoji), - tr::link), - tr::rich); - }); - box->addRow( - object_ptr( - box, - name, - st::uniqueGiftTitle), - style::al_top); - const auto about = box->addRow( - object_ptr( - box, - std::move(aboutText), - st::uniqueGiftSubtitle), - (st::boxRowPadding - + QMargins(0, st::auctionInfoSubtitleSkip, 0, 0)), - style::al_top); - about->setTryMakeSimilarLines(true); - - about->setClickHandlerFilter([=](const auto &...) { - show->show(Box(AuctionAboutBox, rounds, perRound, nullptr)); - return false; - }); - - const auto close = CreateChild( - box->verticalLayout(), - st::boxTitleClose); - close->setClickedCallback([=] { box->closeBox(); }); - - const auto menu = CreateChild( - box->verticalLayout(), - st::boxTitleMenu); - menu->setClickedCallback(MakeAuctionMenuCallback(menu, show, now)); - const auto weakMenu = base::make_weak(menu); - - box->verticalLayout()->widthValue() | rpl::start_with_next([=](int) { - close->moveToRight(0, 0); - if (const auto strong = weakMenu.get()) { - strong->moveToRight(close->width(), 0); - } - }, close->lifetime()); - - rpl::combine( - state->value.value(), - state->minutesTillEnd.value() - ) | rpl::start_with_next([=]( - const Data::GiftAuctionState &state, - int minutes) { - const auto finished = state.finished() || (minutes <= 0); - about->setTextColorOverride(finished - ? st::attentionButtonFg->c - : std::optional()); - if (const auto strong = finished ? weakMenu.get() : nullptr) { - delete strong; - } - }, box->lifetime()); - } + AddUniqueCloseButton( + box, + {}, + now.finished() ? nullptr : MakeAuctionFillMenuCallback(show, now)); box->addRow( AuctionInfoTable(box, box->verticalLayout(), state->value.value()), @@ -1736,10 +1641,10 @@ void SetAuctionButtonCountdownText( ) | rpl::map([=](const Data::GiftAuctionState &state, int leftTill) { return (state.finished() || (!preview && leftTill <= 0)) ? tr::lng_box_ok(tr::marked) - : (type != AuctionButtonCountdownType::Place) - ? tr::lng_auction_join_button(tr::marked) : preview ? tr::lng_auction_join_early_bid(tr::marked) + : (type != AuctionButtonCountdownType::Place) + ? tr::lng_auction_join_button(tr::marked) : tr::lng_auction_join_bid(tr::marked); }) | rpl::flatten_latest(); diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index a888e621d0..cdf4418e57 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -3166,7 +3166,7 @@ void AddUniqueGiftCover( } subtitle->moveToLeft(skip, top); - top += subtitle->height() + skip; + top += subtitle->height() + (skip / 2); if (attrs) { attrs->resizeToWidth(width @@ -3174,6 +3174,8 @@ void AddUniqueGiftCover( - st::giftBoxPadding.right()); attrs->moveToLeft(st::giftBoxPadding.left(), top); top += attrs->height() + (skip / 2); + } else { + top += (skip / 2); } cover->resize(width, top);