Fixed display of credits payment form even with small credits balance.

This commit is contained in:
23rd
2026-01-26 16:29:59 +03:00
parent 67818a2c28
commit ae851b8733
3 changed files with 92 additions and 50 deletions
@@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item.h"
#include "info/channel_statistics/boosts/giveaway/boost_badge.h" // InfiniteRadialAnimationWidget.
#include "lang/lang_keys.h"
#include "main/session/session_show.h"
#include "main/main_session.h"
#include "payments/payments_checkout_process.h"
#include "payments/payments_form.h"
@@ -301,7 +302,7 @@ void AddTerms(
void SendCreditsBox(
not_null<Ui::GenericBox*> box,
std::shared_ptr<Payments::CreditsFormData> form,
Fn<void()> sent) {
Fn<void(Settings::SmallBalanceResult)> sent) {
if (!form) {
return;
}
@@ -391,7 +392,7 @@ void SendCreditsBox(
Ui::AddSkip(content);
Ui::AddSkip(content);
const auto button = box->addButton(rpl::single(QString()), [=] {
const auto sendStars = [=] {
if (state->confirmButtonBusy.current()) {
return;
}
@@ -411,7 +412,7 @@ void SendCreditsBox(
state->confirmButtonBusy = false;
box->closeBox();
}
sent();
sent(Settings::SmallBalanceResult::Success);
}).fail([=](const MTP::Error &error) {
if (weak) {
state->confirmButtonBusy = false;
@@ -433,6 +434,22 @@ void SendCreditsBox(
show->showToast(id);
}
}).send();
};
const auto button = box->addButton(rpl::single(QString()), [=] {
const auto weak = base::make_weak(box.get());
Settings::MaybeRequestBalanceIncrease(
Main::MakeSessionShow(box->uiShow(), session),
form->invoice.credits,
SmallBalanceSourceFromForm(form),
[=](Settings::SmallBalanceResult result) {
if (result == Settings::SmallBalanceResult::Cancelled) {
} else if (result == Settings::SmallBalanceResult::Success) {
sendStars();
} else {
sent(result);
}
});
});
if (form->invoice.subscriptionPeriod) {
AddTerms(box, button, stBox);
@@ -573,4 +590,16 @@ void SendStarsForm(
}).send();
}
Settings::SmallBalanceSource SmallBalanceSourceFromForm(
std::shared_ptr<Payments::CreditsFormData> form) {
using namespace Payments;
using namespace Settings;
const auto starGift = std::get_if<InvoiceStarGift>(&form->id.value);
return !starGift
? SmallBalanceSource(SmallBalanceBot{ .botId = form->botId })
: SmallBalanceSource(SmallBalanceStarGift{
.recipientId = starGift->recipient->id,
});
}
} // namespace Ui
@@ -21,6 +21,11 @@ namespace Payments {
struct CreditsFormData;
} // namespace Payments
namespace Settings {
enum class SmallBalanceResult;
struct SmallBalanceSource;
} // namespace Settings
namespace Ui {
class RpWidget;
@@ -30,7 +35,7 @@ class FlatLabel;
void SendCreditsBox(
not_null<Ui::GenericBox*> box,
std::shared_ptr<Payments::CreditsFormData> data,
Fn<void()> sent);
Fn<void(Settings::SmallBalanceResult)> sent);
[[nodiscard]] TextWithEntities CreditsEmoji();
@@ -55,4 +60,7 @@ void SendStarsForm(
std::shared_ptr<Payments::CreditsFormData> data,
Fn<void(std::optional<QString>)> done);
[[nodiscard]] Settings::SmallBalanceSource SmallBalanceSourceFromForm(
std::shared_ptr<Payments::CreditsFormData> form);
} // namespace Ui
@@ -46,64 +46,77 @@ void ProcessCreditsPayment(
QPointer<QWidget> fireworks,
std::shared_ptr<CreditsFormData> form,
Fn<void(CheckoutResult)> maybeReturnToBot) {
const auto done = [=](Settings::SmallBalanceResult result) {
const auto hasBadResult = [=](Settings::SmallBalanceResult result) {
if (result == Settings::SmallBalanceResult::Blocked) {
if (const auto onstack = maybeReturnToBot) {
onstack(CheckoutResult::Failed);
}
return;
return true;
} else if (result == Settings::SmallBalanceResult::Cancelled) {
if (const auto onstack = maybeReturnToBot) {
onstack(CheckoutResult::Cancelled);
}
return true;
}
return false;
};
const auto done = [=](Settings::SmallBalanceResult result) {
if (hasBadResult(result)) {
return;
} else if (form->starGiftForm
|| IsPremiumForStarsInvoice(form->id)) {
const auto done = [=](std::optional<QString> error) {
const auto onstack = maybeReturnToBot;
if (error) {
if (*error == u"STARGIFT_USAGE_LIMITED"_q) {
if (form->starGiftLimitedCount) {
show->showToast({
.title = tr::lng_gift_sold_out_title(
tr::now),
.text = tr::lng_gift_sold_out_text(
tr::now,
lt_count_decimal,
form->starGiftLimitedCount,
tr::rich),
});
} else {
show->showToast(
tr::lng_gift_sold_out_title(tr::now));
}
} else if (*error == u"STARGIFT_USER_USAGE_LIMITED"_q) {
}
const auto done = [=](std::optional<QString> error) {
const auto onstack = maybeReturnToBot;
if (error) {
if (*error == u"STARGIFT_USAGE_LIMITED"_q) {
if (form->starGiftLimitedCount) {
show->showToast({
.text = tr::lng_gift_sent_finished(
.title = tr::lng_gift_sold_out_title(
tr::now),
.text = tr::lng_gift_sold_out_text(
tr::now,
lt_count,
std::max(form->starGiftPerUserLimit, 1),
lt_count_decimal,
form->starGiftLimitedCount,
tr::rich),
});
} else {
show->showToast(*error);
show->showToast(
tr::lng_gift_sold_out_title(tr::now));
}
if (onstack) {
onstack(CheckoutResult::Failed);
}
} else if (onstack) {
onstack(CheckoutResult::Paid);
} else if (*error == u"STARGIFT_USER_USAGE_LIMITED"_q) {
show->showToast({
.text = tr::lng_gift_sent_finished(
tr::now,
lt_count,
std::max(form->starGiftPerUserLimit, 1),
tr::rich),
});
} else {
show->showToast(*error);
}
};
Ui::SendStarsForm(&show->session(), form, done);
return;
}
if (onstack) {
onstack(CheckoutResult::Failed);
}
} else if (onstack) {
onstack(CheckoutResult::Paid);
}
};
Ui::SendStarsForm(&show->session(), form, done);
};
using namespace Settings;
auto source = Ui::SmallBalanceSourceFromForm(form);
if (form->starGiftForm || IsPremiumForStarsInvoice(form->id)) {
const auto credits = form->invoice.credits;
MaybeRequestBalanceIncrease(show, credits, source, done);
} else {
const auto unsuccessful = std::make_shared<bool>(true);
const auto box = show->show(Box(
Ui::SendCreditsBox,
form,
[=] {
[=](Settings::SmallBalanceResult result) {
*unsuccessful = false;
if (hasBadResult(result)) {
return;
}
if (const auto widget = fireworks.data()) {
Ui::StartFireworks(widget);
}
@@ -120,15 +133,7 @@ void ProcessCreditsPayment(
}
});
}, box->lifetime());
};
using namespace Settings;
const auto starGift = std::get_if<InvoiceStarGift>(&form->id.value);
auto source = !starGift
? SmallBalanceSource(SmallBalanceBot{ .botId = form->botId })
: SmallBalanceSource(SmallBalanceStarGift{
.recipientId = starGift->recipient->id,
});
MaybeRequestBalanceIncrease(show, form->invoice.credits, source, done);
}
}
void ProcessCreditsReceipt(