Added box for small balance of credits.

This commit is contained in:
23rd 2024-05-25 01:12:56 +03:00 committed by John Preston
parent 5defb9fb17
commit 7d75c25214
8 changed files with 133 additions and 3 deletions

View file

@ -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.";

View file

@ -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);
}

View file

@ -414,11 +414,13 @@ void CheckoutProcess::handleFormUpdate(const FormUpdate &update) {
if (_nonPanelPaymentFormProcess) {
_nonPanelPaymentFormProcess(
std::make_shared<CreditsFormData>(data.data));
close();
}
}, [&](const CreditsReceiptReady &data) {
if (_nonPanelPaymentFormProcess) {
_nonPanelPaymentFormProcess(
std::make_shared<CreditsReceiptData>(data.data));
close();
}
}, [&](const Error &error) {
handleError(error);

View file

@ -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<void(NonPanelPaymentForm)> ProcessNonPanelPaymentFormFactory(
using CreditsFormDataPtr = std::shared_ptr<CreditsFormData>;
using CreditsReceiptPtr = std::shared_ptr<CreditsReceiptData>;
if (const auto creditsData = std::get_if<CreditsFormDataPtr>(&form)) {
controller->uiShow()->show(Box(Ui::SendCreditsBox, *creditsData));
const auto form = *creditsData;
const auto lifetime = std::make_shared<rpl::lifetime>();
const auto api = lifetime->make_state<Api::CreditsStatus>(
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<CreditsReceiptPtr>(&form)) {
const auto receipt = *r;

View file

@ -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);

View file

@ -166,6 +166,7 @@ QImage GenerateStars(int height, int count) {
void FillCreditOptions(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container,
int minCredits,
Fn<void()> paid) {
const auto options = container->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
@ -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<Ui::SettingsButton>(
content,
rpl::never<QString>(),
@ -536,4 +540,82 @@ object_ptr<Ui::RpWidget> HistoryEntryPhoto(
return owned;
}
void SmallBalanceBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller,
int creditsNeeded,
UserId botId,
Fn<void()> 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<Ui::Premium::TopBar>(
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<Api::CreditsStatus>(
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

View file

@ -33,6 +33,7 @@ namespace Settings {
void FillCreditOptions(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container,
int minCredits,
Fn<void()> paid);
[[nodiscard]] not_null<Ui::RpWidget*> AddBalanceWidget(
@ -51,5 +52,12 @@ void ReceiptCreditsBox(
not_null<PhotoData*> photo,
int photoSize);
void SmallBalanceBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller,
int creditsNeeded,
UserId botId,
Fn<void()> paid);
} // namespace Settings

View file

@ -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;
}