From 7d75c2521457ae322970a59058b1dd5a11077c96 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sat, 25 May 2024 01:12:56 +0300 Subject: [PATCH] Added box for small balance of credits. --- Telegram/Resources/langs/lang.strings | 3 + .../info_statistics_list_controllers.cpp | 2 +- .../payments/payments_checkout_process.cpp | 2 + .../payments/payments_non_panel_process.cpp | 32 +++++++- .../SourceFiles/settings/settings_credits.cpp | 2 +- .../settings/settings_credits_graphics.cpp | 82 +++++++++++++++++++ .../settings/settings_credits_graphics.h | 8 ++ Telegram/SourceFiles/ui/effects/credits.style | 5 ++ 8 files changed, 133 insertions(+), 3 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index efb548724..9bae741a0 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2324,6 +2324,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_credits_box_history_entry_id_copied" = "Transaction ID copied to clipboard."; "lng_credits_box_history_entry_about" = "You can dispute this transaction {link}."; "lng_credits_box_history_entry_about_link" = "here"; +"lng_credits_small_balance_title#one" = "{count} Star Needed"; +"lng_credits_small_balance_title#other" = "{count} Stars Needed"; +"lng_credits_small_balance_about" = "Buy **Stars** and use them on **{bot}** and other miniapps."; "lng_location_title" = "Location"; "lng_location_about" = "Display the location of your business on your account."; diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp index 0cdbe6233..b608b7218 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp @@ -868,7 +868,7 @@ CreditsController::CreditsController(CreditsDescriptor d) , _premiumBot(d.premiumBot) , _entryClickedCallback(std::move(d.entryClickedCallback)) , _creditIcon(d.creditIcon) -, _api(d.premiumBot, d.in, d.out) +, _api(d.premiumBot->session().user(), d.in, d.out) , _firstSlice(std::move(d.firstSlice)) { PeerListController::setStyleOverrides(&st::boostsListBox); } diff --git a/Telegram/SourceFiles/payments/payments_checkout_process.cpp b/Telegram/SourceFiles/payments/payments_checkout_process.cpp index 3080c149b..cbb435389 100644 --- a/Telegram/SourceFiles/payments/payments_checkout_process.cpp +++ b/Telegram/SourceFiles/payments/payments_checkout_process.cpp @@ -414,11 +414,13 @@ void CheckoutProcess::handleFormUpdate(const FormUpdate &update) { if (_nonPanelPaymentFormProcess) { _nonPanelPaymentFormProcess( std::make_shared(data.data)); + close(); } }, [&](const CreditsReceiptReady &data) { if (_nonPanelPaymentFormProcess) { _nonPanelPaymentFormProcess( std::make_shared(data.data)); + close(); } }, [&](const Error &error) { handleError(error); diff --git a/Telegram/SourceFiles/payments/payments_non_panel_process.cpp b/Telegram/SourceFiles/payments/payments_non_panel_process.cpp index f2874d62e..12fb6a13f 100644 --- a/Telegram/SourceFiles/payments/payments_non_panel_process.cpp +++ b/Telegram/SourceFiles/payments/payments_non_panel_process.cpp @@ -7,12 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "payments/payments_non_panel_process.h" +#include "api/api_credits.h" #include "base/unixtime.h" #include "boxes/send_credits_box.h" #include "data/data_credits.h" #include "data/data_photo.h" +#include "data/data_user.h" #include "history/history_item.h" #include "history/history_item_components.h" +#include "main/main_session.h" #include "payments/payments_checkout_process.h" // NonPanelPaymentForm. #include "payments/payments_form.h" #include "settings/settings_credits_graphics.h" @@ -40,7 +43,34 @@ Fn ProcessNonPanelPaymentFormFactory( using CreditsFormDataPtr = std::shared_ptr; using CreditsReceiptPtr = std::shared_ptr; if (const auto creditsData = std::get_if(&form)) { - controller->uiShow()->show(Box(Ui::SendCreditsBox, *creditsData)); + const auto form = *creditsData; + const auto lifetime = std::make_shared(); + const auto api = lifetime->make_state( + controller->session().user()); + const auto sendBox = [=, weak = base::make_weak(controller)] { + if (const auto strong = weak.get()) { + controller->uiShow()->show(Box(Ui::SendCreditsBox, form)); + } + }; + const auto weak = base::make_weak(controller); + api->request({}, [=](Data::CreditsStatusSlice slice) { + if (const auto strong = weak.get()) { + strong->session().setCredits(slice.balance); + const auto creditsNeeded = int64(form->invoice.credits) + - int64(slice.balance); + if (creditsNeeded <= 0) { + sendBox(); + } else { + strong->uiShow()->show(Box( + Settings::SmallBalanceBox, + strong, + creditsNeeded, + form->botId, + sendBox)); + } + } + lifetime->destroy(); + }); } if (const auto r = std::get_if(&form)) { const auto receipt = *r; diff --git a/Telegram/SourceFiles/settings/settings_credits.cpp b/Telegram/SourceFiles/settings/settings_credits.cpp index adffaba25..48a3eb9ba 100644 --- a/Telegram/SourceFiles/settings/settings_credits.cpp +++ b/Telegram/SourceFiles/settings/settings_credits.cpp @@ -298,7 +298,7 @@ void Credits::setupContent() { Ui::StartFireworks(_parent); } }; - FillCreditOptions(_controller, content, paid); + FillCreditOptions(_controller, content, 0, paid); setupHistory(content); Ui::ResizeFitChild(this, content); diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 2511079c6..cab21f9ea 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -166,6 +166,7 @@ QImage GenerateStars(int height, int count) { void FillCreditOptions( not_null controller, not_null container, + int minCredits, Fn paid) { const auto options = container->add( object_ptr>( @@ -193,6 +194,9 @@ void FillCreditOptions( const auto buttonHeight = st.height + rect::m::sum::v(st.padding); for (auto i = 0; i < options.size(); i++) { const auto &option = options[i]; + if (option.credits < minCredits) { + continue; + } const auto button = content->add(object_ptr( content, rpl::never(), @@ -536,4 +540,82 @@ object_ptr HistoryEntryPhoto( return owned; } +void SmallBalanceBox( + not_null box, + not_null controller, + int creditsNeeded, + UserId botId, + Fn paid) { + box->setWidth(st::boxWideWidth); + box->addButton(tr::lng_close(), [=] { box->closeBox(); }); + const auto done = [=] { + box->closeBox(); + paid(); + }; + + const auto bot = controller->session().data().user(botId).get(); + + const auto content = [&]() -> Ui::Premium::TopBarAbstract* { + const auto weak = base::make_weak(controller); + const auto clickContextOther = [=] { + return QVariant::fromValue(ClickHandlerContext{ + .sessionWindow = weak, + .botStartAutoSubmit = true, + }); + }; + return box->setPinnedToTopContent(object_ptr( + box, + st::creditsLowBalancePremiumCover, + Ui::Premium::TopBarDescriptor{ + .clickContextOther = clickContextOther, + .title = tr::lng_credits_small_balance_title( + lt_count, + rpl::single(creditsNeeded) | tr::to_count()), + .about = tr::lng_credits_small_balance_about( + lt_bot, + rpl::single(TextWithEntities{ bot->name() }), + Ui::Text::RichLangValue), + .light = true, + .gradientStops = Ui::Premium::CreditsIconGradientStops(), + })); + }(); + + FillCreditOptions(controller, box->verticalLayout(), creditsNeeded, done); + + content->setMaximumHeight(st::creditsLowBalancePremiumCoverHeight); + content->setMinimumHeight(st::infoLayerTopBarHeight); + + content->resize(content->width(), content->maximumHeight()); + content->additionalHeight( + ) | rpl::start_with_next([=](int additionalHeight) { + const auto wasMax = (content->height() == content->maximumHeight()); + content->setMaximumHeight(st::creditsLowBalancePremiumCoverHeight + + additionalHeight); + if (wasMax) { + content->resize(content->width(), content->maximumHeight()); + } + }, content->lifetime()); + + { + const auto balance = AddBalanceWidget( + content, + controller->session().creditsValue(), + true); + const auto api = balance->lifetime().make_state( + controller->session().user()); + api->request({}, [=](Data::CreditsStatusSlice slice) { + controller->session().setCredits(slice.balance); + }); + rpl::combine( + balance->sizeValue(), + content->sizeValue() + ) | rpl::start_with_next([=](const QSize &, const QSize &) { + balance->moveToRight( + st::creditsHistoryRightSkip * 2, + st::creditsHistoryRightSkip); + balance->update(); + }, balance->lifetime()); + } +} + } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.h b/Telegram/SourceFiles/settings/settings_credits_graphics.h index 3c09ff50f..cb6c27e7e 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.h +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.h @@ -33,6 +33,7 @@ namespace Settings { void FillCreditOptions( not_null controller, not_null container, + int minCredits, Fn paid); [[nodiscard]] not_null AddBalanceWidget( @@ -51,5 +52,12 @@ void ReceiptCreditsBox( not_null photo, int photoSize); +void SmallBalanceBox( + not_null box, + not_null controller, + int creditsNeeded, + UserId botId, + Fn paid); + } // namespace Settings diff --git a/Telegram/SourceFiles/ui/effects/credits.style b/Telegram/SourceFiles/ui/effects/credits.style index 9f6866f96..bc05f58f8 100644 --- a/Telegram/SourceFiles/ui/effects/credits.style +++ b/Telegram/SourceFiles/ui/effects/credits.style @@ -16,6 +16,11 @@ creditsPremiumCover: PremiumCover(defaultPremiumCover) { textFg: boxTitleFg; } } +creditsLowBalancePremiumCover: PremiumCover(creditsPremiumCover) { + starSize: size(64px, 62px); + starTopSkip: 30px; +} +creditsLowBalancePremiumCoverHeight: 180px; creditsTopupButton: SettingsButton(settingsButton) { style: semiboldTextStyle; }