diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 60cdcc65cc3a9b..a57fc8b1b13b19 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2486,6 +2486,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_credits_small_balance_about" = "Buy **Stars** and use them on **{bot}** and other miniapps."; "lng_credits_small_balance_reaction" = "Buy **Stars** and send them to {channel} to support their posts."; "lng_credits_small_balance_subscribe" = "Buy **Stars** and subscribe to **{channel}** and other channels."; +"lng_credits_small_balance_star_gift" = "Buy **Stars** to send gifts to {user} and other contacts."; "lng_credits_small_balance_fallback" = "Buy **Stars** to unlock content and services on Telegram."; "lng_credits_purchase_blocked" = "Sorry, you can't purchase this item with Telegram Stars."; "lng_credits_enough" = "You have enough stars at the moment. {link}"; @@ -3014,6 +3015,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_stars_about" = "Give {name} gifts that can be kept on your profile or converted to Stars. {link}"; "lng_gift_stars_link" = "What are Stars >"; "lng_gift_stars_limited" = "limited"; +"lng_gift_stars_sold_out" = "sold out"; "lng_gift_stars_tabs_all" = "All Gifts"; "lng_gift_stars_tabs_limited" = "Limited"; "lng_gift_send_title" = "Send a Gift"; @@ -3047,6 +3049,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_display_done_hide" = "The gift is now hidden from your profile page."; "lng_gift_got_stars#one" = "You got **{count} Star** for this gift."; "lng_gift_got_stars#other" = "You got **{count} Stars** for this gift."; +"lng_gift_sold_out_title" = "Sold Out!"; +"lng_gift_sold_out_text#one" = "All {count} gift was already sold."; +"lng_gift_sold_out_text#other" = "All {count} gifts were already sold."; "lng_accounts_limit_title" = "Limit Reached"; "lng_accounts_limit1#one" = "You have reached the limit of **{count}** connected account."; diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index ce239e2475609b..306c00dfbedc03 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -514,6 +514,7 @@ void PreviewWrap::paintEvent(QPaintEvent *e) { .convertStars = gift.convertStars, .document = gift.document, .limitedCount = gift.limitedCount, + .limitedLeft = gift.limitedLeft, }); } auto &map = Map[session]; @@ -1081,6 +1082,7 @@ void SendGiftBox( } }; button->setClickedCallback([=] { + const auto star = std::get_if(&descriptor); if (v::is(descriptor)) { if (state->sending) { return; @@ -1093,6 +1095,14 @@ void SendGiftBox( api, GiftDetails{ descriptor }, premiumSent); + } else if (star && star->limitedCount && !star->limitedLeft) { + window->showToast({ + .title = tr::lng_gift_sold_out_title(tr::now), + .text = tr::lng_gift_sold_out_text( + tr::now, + lt_count_decimal, + star->limitedCount), + }); } else { window->show( Box(SendGiftBox, window, peer, api, descriptor)); diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp index 45b26cd352c8ab..83649bf5a4b11d 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp @@ -253,15 +253,20 @@ void GiftButton::paintEvent(QPaintEvent *e) { p.setFont(font); const auto text = v::match(_descriptor, [&](GiftTypePremium data) { if (data.discountPercent > 0) { - p.setBrush(st::attentionBoxButton.textFg); + p.setBrush(st::attentionButtonFg); const auto kMinus = QChar(0x2212); return kMinus + QString::number(data.discountPercent) + '%'; } return QString(); }, [&](const GiftTypeStars &data) { if (const auto count = data.limitedCount) { - p.setBrush(st::windowActiveTextFg); - return !data.userpic + const auto soldOut = !data.userpic && !data.limitedLeft; + p.setBrush(soldOut + ? st::attentionButtonFg + : st::windowActiveTextFg); + return soldOut + ? tr::lng_gift_stars_sold_out(tr::now) + : !data.userpic ? tr::lng_gift_stars_limited(tr::now) : (count == 1) ? tr::lng_gift_limited_of_one(tr::now) diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h index 5c63e8885b0171..6fd2b74138d885 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h @@ -48,6 +48,7 @@ struct GiftTypeStars { DocumentData *document = nullptr; PeerData *from = nullptr; int limitedCount = 0; + int limitedLeft = 0; bool userpic = false; bool hidden = false; bool mine = false; diff --git a/Telegram/SourceFiles/payments/payments_non_panel_process.cpp b/Telegram/SourceFiles/payments/payments_non_panel_process.cpp index 3f269a5341108f..baa019072edb02 100644 --- a/Telegram/SourceFiles/payments/payments_non_panel_process.cpp +++ b/Telegram/SourceFiles/payments/payments_non_panel_process.cpp @@ -93,11 +93,14 @@ void ProcessCreditsPayment( }); }, box->lifetime()); }; - Settings::MaybeRequestBalanceIncrease( - show, - form->invoice.credits, - Settings::SmallBalanceBot{ .botId = form->botId }, - done); + using namespace Settings; + const auto starGift = std::get_if(&form->id.value); + auto source = !starGift + ? SmallBalanceSource(SmallBalanceBot{ .botId = form->botId }) + : SmallBalanceSource(SmallBalanceStarGift{ + .userId = peerToUser(starGift->user->id) + }); + MaybeRequestBalanceIncrease(show, form->invoice.credits, source, done); } void ProcessCreditsReceipt( diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 407f22d169fca8..01ffb1aff3014a 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -1555,13 +1555,17 @@ void SmallBalanceBox( const auto owner = &show->session().data(); const auto name = v::match(source, [&](SmallBalanceBot value) { - return owner->peer(peerFromUser(value.botId))->name(); + return value.botId + ? owner->peer(peerFromUser(value.botId))->name() + : QString(); }, [&](SmallBalanceReaction value) { return owner->peer(peerFromChannel(value.channelId))->name(); }, [](SmallBalanceSubscription value) { return value.name; }, [](SmallBalanceDeepLink value) { return QString(); + }, [&](SmallBalanceStarGift value) { + return owner->peer(peerFromUser(value.userId))->shortName(); }); auto needed = show->session().credits().balanceValue( @@ -1591,6 +1595,14 @@ void SmallBalanceBox( : v::is(source) ? DeepLinkBalanceAbout( v::get(source).purpose) + : v::is(source) + ? tr::lng_credits_small_balance_star_gift( + lt_user, + rpl::single(Ui::Text::Bold(name)), + Ui::Text::RichLangValue) + : name.isEmpty() + ? tr::lng_credits_small_balance_fallback( + Ui::Text::RichLangValue) : tr::lng_credits_small_balance_about( lt_bot, rpl::single(TextWithEntities{ name }), diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.h b/Telegram/SourceFiles/settings/settings_credits_graphics.h index 37b14c949ccf6c..bfc266e3ebe432 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.h +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.h @@ -138,11 +138,15 @@ struct SmallBalanceSubscription { struct SmallBalanceDeepLink { QString purpose; }; +struct SmallBalanceStarGift { + UserId userId = 0; +}; struct SmallBalanceSource : std::variant< SmallBalanceBot, SmallBalanceReaction, SmallBalanceSubscription, - SmallBalanceDeepLink> { + SmallBalanceDeepLink, + SmallBalanceStarGift> { using variant::variant; };