mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Improve bot checkout error messages.
This commit is contained in:
parent
484c647b5b
commit
f8b756d447
13 changed files with 221 additions and 120 deletions
|
@ -3161,6 +3161,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_bot_add_to_side_menu" = "{bot} asks your permission to be added as an option to your main menu so you can access it any time.";
|
"lng_bot_add_to_side_menu" = "{bot} asks your permission to be added as an option to your main menu so you can access it any time.";
|
||||||
"lng_bot_add_to_side_menu_done" = "Bot added to the main menu.";
|
"lng_bot_add_to_side_menu_done" = "Bot added to the main menu.";
|
||||||
"lng_bot_no_scan_qr" = "QR Codes for bots are not supported on Desktop. Please use one of Telegram's mobile apps.";
|
"lng_bot_no_scan_qr" = "QR Codes for bots are not supported on Desktop. Please use one of Telegram's mobile apps.";
|
||||||
|
"lng_bot_click_to_start" = "Click here to use this bot.";
|
||||||
|
|
||||||
"lng_typing" = "typing";
|
"lng_typing" = "typing";
|
||||||
"lng_user_typing" = "{user} is typing";
|
"lng_user_typing" = "{user} is typing";
|
||||||
|
@ -3757,6 +3758,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_payments_card_declined" = "Your card was declined.";
|
"lng_payments_card_declined" = "Your card was declined.";
|
||||||
"lng_payments_payment_failed" = "Payment failed. Your card has not been billed.";
|
"lng_payments_payment_failed" = "Payment failed. Your card has not been billed.";
|
||||||
"lng_payments_precheckout_failed" = "The bot couldn't process your payment. Your card has not been billed.";
|
"lng_payments_precheckout_failed" = "The bot couldn't process your payment. Your card has not been billed.";
|
||||||
|
"lng_payments_precheckout_timeout" = "The bot didn't respond in time. Your card has not been billed.";
|
||||||
|
"lng_payments_precheckout_stars_failed" = "The bot couldn't process your payment.";
|
||||||
|
"lng_payments_precheckout_stars_timeout" = "The bot didn't respond in time.";
|
||||||
"lng_payments_already_paid" = "You have already paid for this item.";
|
"lng_payments_already_paid" = "You have already paid for this item.";
|
||||||
|
|
||||||
"lng_payments_terms_title" = "Terms of Service";
|
"lng_payments_terms_title" = "Terms of Service";
|
||||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "payments/payments_checkout_process.h"
|
#include "payments/payments_checkout_process.h"
|
||||||
#include "payments/payments_form.h"
|
#include "payments/payments_form.h"
|
||||||
#include "settings/settings_credits_graphics.h"
|
#include "settings/settings_credits_graphics.h"
|
||||||
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "ui/controls/userpic_button.h"
|
#include "ui/controls/userpic_button.h"
|
||||||
#include "ui/effects/premium_graphics.h"
|
#include "ui/effects/premium_graphics.h"
|
||||||
#include "ui/effects/premium_top_bar.h" // Ui::Premium::ColorizedSvg.
|
#include "ui/effects/premium_top_bar.h" // Ui::Premium::ColorizedSvg.
|
||||||
|
@ -257,6 +258,8 @@ void SendCreditsBox(
|
||||||
if (state->confirmButtonBusy.current()) {
|
if (state->confirmButtonBusy.current()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto show = box->uiShow();
|
||||||
|
const auto weak = MakeWeak(box.get());
|
||||||
state->confirmButtonBusy = true;
|
state->confirmButtonBusy = true;
|
||||||
session->api().request(
|
session->api().request(
|
||||||
MTPpayments_SendStarsForm(
|
MTPpayments_SendStarsForm(
|
||||||
|
@ -264,12 +267,31 @@ void SendCreditsBox(
|
||||||
MTP_long(form->formId),
|
MTP_long(form->formId),
|
||||||
form->inputInvoice)
|
form->inputInvoice)
|
||||||
).done([=](auto result) {
|
).done([=](auto result) {
|
||||||
state->confirmButtonBusy = false;
|
if (weak) {
|
||||||
box->closeBox();
|
state->confirmButtonBusy = false;
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
sent();
|
sent();
|
||||||
}).fail([=](const MTP::Error &error) {
|
}).fail([=](const MTP::Error &error) {
|
||||||
state->confirmButtonBusy = false;
|
if (weak) {
|
||||||
box->uiShow()->showToast(error.type());
|
state->confirmButtonBusy = false;
|
||||||
|
}
|
||||||
|
const auto id = error.type();
|
||||||
|
if (id == u"BOT_PRECHECKOUT_FAILED"_q) {
|
||||||
|
auto error = ::Ui::MakeInformBox(
|
||||||
|
tr::lng_payments_precheckout_stars_failed(tr::now));
|
||||||
|
error->boxClosing() | rpl::start_with_next([=] {
|
||||||
|
if (const auto paybox = weak.data()) {
|
||||||
|
paybox->closeBox();
|
||||||
|
}
|
||||||
|
}, error->lifetime());
|
||||||
|
show->showBox(std::move(error));
|
||||||
|
} else if (id == u"BOT_PRECHECKOUT_TIMEOUT"_q) {
|
||||||
|
show->showToast(
|
||||||
|
tr::lng_payments_precheckout_stars_timeout(tr::now));
|
||||||
|
} else {
|
||||||
|
show->showToast(id);
|
||||||
|
}
|
||||||
}).send();
|
}).send();
|
||||||
});
|
});
|
||||||
{
|
{
|
||||||
|
|
|
@ -241,19 +241,20 @@ ClickHandlerPtr MakePaidMediaLink(not_null<HistoryItem*> item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const auto reactivate = controller
|
||||||
|
? crl::guard(
|
||||||
|
controller,
|
||||||
|
[=](auto) { controller->widget()->activate(); })
|
||||||
|
: Fn<void(Payments::CheckoutResult)>();
|
||||||
|
const auto credits = Payments::IsCreditsInvoice(item);
|
||||||
|
const auto nonPanelPaymentFormProcess = (controller && credits)
|
||||||
|
? Payments::ProcessNonPanelPaymentFormFactory(controller, done)
|
||||||
|
: nullptr;
|
||||||
Payments::CheckoutProcess::Start(
|
Payments::CheckoutProcess::Start(
|
||||||
item,
|
item,
|
||||||
Payments::Mode::Payment,
|
Payments::Mode::Payment,
|
||||||
(controller
|
reactivate,
|
||||||
? crl::guard(
|
nonPanelPaymentFormProcess);
|
||||||
controller,
|
|
||||||
[=](auto) { controller->widget()->activate(); })
|
|
||||||
: Fn<void(Payments::CheckoutResult)>()),
|
|
||||||
((controller && Payments::IsCreditsInvoice(item))
|
|
||||||
? Payments::ProcessNonPanelPaymentFormFactory(
|
|
||||||
controller,
|
|
||||||
done)
|
|
||||||
: nullptr));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -621,16 +621,38 @@ void AttachWebView::botHandleInvoice(QString slug) {
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_panel->hideForPayment();
|
|
||||||
Payments::CheckoutProcess::Start(
|
Payments::CheckoutProcess::Start(
|
||||||
&_bot->session(),
|
&_bot->session(),
|
||||||
slug,
|
slug,
|
||||||
reactivate,
|
reactivate,
|
||||||
_context
|
nonPanelPaymentFormFactory(reactivate));
|
||||||
? Payments::ProcessNonPanelPaymentFormFactory(
|
}
|
||||||
_context->controller.get(),
|
|
||||||
reactivate)
|
auto AttachWebView::nonPanelPaymentFormFactory(
|
||||||
: nullptr);
|
Fn<void(Payments::CheckoutResult)> reactivate)
|
||||||
|
-> Fn<void(Payments::NonPanelPaymentForm)> {
|
||||||
|
using namespace Payments;
|
||||||
|
const auto panel = base::make_weak(_panel.get());
|
||||||
|
const auto weak = _context ? _context->controller : nullptr;
|
||||||
|
return [=](Payments::NonPanelPaymentForm form) {
|
||||||
|
using CreditsFormDataPtr = std::shared_ptr<CreditsFormData>;
|
||||||
|
using CreditsReceiptPtr = std::shared_ptr<CreditsReceiptData>;
|
||||||
|
v::match(form, [&](const CreditsFormDataPtr &form) {
|
||||||
|
if (const auto strong = panel.get()) {
|
||||||
|
ProcessCreditsPayment(
|
||||||
|
uiShow(),
|
||||||
|
strong->toastParent().get(),
|
||||||
|
form,
|
||||||
|
reactivate);
|
||||||
|
}
|
||||||
|
}, [&](const CreditsReceiptPtr &receipt) {
|
||||||
|
if (const auto controller = weak.get()) {
|
||||||
|
ProcessCreditsReceipt(controller, receipt, reactivate);
|
||||||
|
}
|
||||||
|
}, [&](RealFormPresentedNotification) {
|
||||||
|
_panel->hideForPayment();
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachWebView::botHandleMenuButton(Ui::BotWebView::MenuButton button) {
|
void AttachWebView::botHandleMenuButton(Ui::BotWebView::MenuButton button) {
|
||||||
|
|
|
@ -40,6 +40,11 @@ namespace Data {
|
||||||
class DocumentMedia;
|
class DocumentMedia;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
namespace Payments {
|
||||||
|
struct NonPanelPaymentForm;
|
||||||
|
enum class CheckoutResult;
|
||||||
|
} // namespace Payments
|
||||||
|
|
||||||
namespace InlineBots {
|
namespace InlineBots {
|
||||||
|
|
||||||
enum class PeerType : uint8 {
|
enum class PeerType : uint8 {
|
||||||
|
@ -246,6 +251,8 @@ private:
|
||||||
void showToast(
|
void showToast(
|
||||||
const QString &text,
|
const QString &text,
|
||||||
Window::SessionController *controller = nullptr);
|
Window::SessionController *controller = nullptr);
|
||||||
|
Fn<void(Payments::NonPanelPaymentForm)> nonPanelPaymentFormFactory(
|
||||||
|
Fn<void(Payments::CheckoutResult)> reactivate);
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Main::Session*> _session;
|
||||||
|
|
||||||
|
|
|
@ -536,6 +536,8 @@ void CheckoutProcess::handleError(const Error &error) {
|
||||||
showToast({ tr::lng_payments_payment_failed(tr::now) });
|
showToast({ tr::lng_payments_payment_failed(tr::now) });
|
||||||
} else if (id == u"BOT_PRECHECKOUT_FAILED"_q) {
|
} else if (id == u"BOT_PRECHECKOUT_FAILED"_q) {
|
||||||
showToast({ tr::lng_payments_precheckout_failed(tr::now) });
|
showToast({ tr::lng_payments_precheckout_failed(tr::now) });
|
||||||
|
} else if (id == u"BOT_PRECHECKOUT_TIMEOUT"_q) {
|
||||||
|
showToast({ tr::lng_payments_precheckout_timeout(tr::now) });
|
||||||
} else if (id == u"REQUESTED_INFO_INVALID"_q
|
} else if (id == u"REQUESTED_INFO_INVALID"_q
|
||||||
|| id == u"SHIPPING_OPTION_INVALID"_q
|
|| id == u"SHIPPING_OPTION_INVALID"_q
|
||||||
|| id == u"PAYMENT_CREDENTIALS_INVALID"_q
|
|| id == u"PAYMENT_CREDENTIALS_INVALID"_q
|
||||||
|
@ -764,6 +766,14 @@ void CheckoutProcess::showForm() {
|
||||||
_form->information(),
|
_form->information(),
|
||||||
_form->paymentMethod().ui,
|
_form->paymentMethod().ui,
|
||||||
_form->shippingOptions());
|
_form->shippingOptions());
|
||||||
|
if (_nonPanelPaymentFormProcess && !_realFormNotified) {
|
||||||
|
_realFormNotified = true;
|
||||||
|
const auto weak = base::make_weak(_panel.get());
|
||||||
|
_nonPanelPaymentFormProcess(RealFormPresentedNotification());
|
||||||
|
if (weak) {
|
||||||
|
requestActivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckoutProcess::showEditInformation(Ui::InformationField field) {
|
void CheckoutProcess::showEditInformation(Ui::InformationField field) {
|
||||||
|
|
|
@ -55,9 +55,13 @@ enum class CheckoutResult {
|
||||||
Failed,
|
Failed,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NonPanelPaymentForm : std::variant<
|
struct RealFormPresentedNotification {
|
||||||
std::shared_ptr<CreditsFormData>,
|
};
|
||||||
std::shared_ptr<CreditsReceiptData>> {
|
struct NonPanelPaymentForm
|
||||||
|
: std::variant<
|
||||||
|
std::shared_ptr<CreditsFormData>,
|
||||||
|
std::shared_ptr<CreditsReceiptData>,
|
||||||
|
RealFormPresentedNotification> {
|
||||||
using variant::variant;
|
using variant::variant;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,6 +187,7 @@ private:
|
||||||
Fn<void(NonPanelPaymentForm)> _nonPanelPaymentFormProcess;
|
Fn<void(NonPanelPaymentForm)> _nonPanelPaymentFormProcess;
|
||||||
SubmitState _submitState = SubmitState::None;
|
SubmitState _submitState = SubmitState::None;
|
||||||
bool _initialSilentValidation = false;
|
bool _initialSilentValidation = false;
|
||||||
|
bool _realFormNotified = false;
|
||||||
bool _sendFormPending = false;
|
bool _sendFormPending = false;
|
||||||
bool _sendFormFailed = false;
|
bool _sendFormFailed = false;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/boxes/boost_box.h" // Ui::StartFireworks.
|
#include "ui/boxes/boost_box.h" // Ui::StartFireworks.
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
namespace Payments {
|
namespace Payments {
|
||||||
|
@ -37,84 +38,98 @@ bool IsCreditsInvoice(not_null<HistoryItem*> item) {
|
||||||
return invoice && (invoice->currency == Ui::kCreditsCurrency);
|
return invoice && (invoice->currency == Ui::kCreditsCurrency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProcessCreditsPayment(
|
||||||
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
|
QPointer<QWidget> fireworks,
|
||||||
|
std::shared_ptr<CreditsFormData> form,
|
||||||
|
Fn<void(CheckoutResult)> maybeReturnToBot) {
|
||||||
|
const auto lifetime = std::make_shared<rpl::lifetime>();
|
||||||
|
const auto api = lifetime->make_state<Api::CreditsStatus>(
|
||||||
|
show->session().user());
|
||||||
|
const auto sendBox = [=] {
|
||||||
|
const auto unsuccessful = std::make_shared<bool>(true);
|
||||||
|
const auto box = show->show(Box(
|
||||||
|
Ui::SendCreditsBox,
|
||||||
|
form,
|
||||||
|
[=] {
|
||||||
|
*unsuccessful = false;
|
||||||
|
if (const auto widget = fireworks.data()) {
|
||||||
|
Ui::StartFireworks(widget);
|
||||||
|
}
|
||||||
|
if (maybeReturnToBot) {
|
||||||
|
maybeReturnToBot(CheckoutResult::Paid);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
box->boxClosing() | rpl::start_with_next([=] {
|
||||||
|
crl::on_main([=] {
|
||||||
|
if ((*unsuccessful) && maybeReturnToBot) {
|
||||||
|
maybeReturnToBot(CheckoutResult::Cancelled);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, box->lifetime());
|
||||||
|
};
|
||||||
|
api->request({}, [=](Data::CreditsStatusSlice slice) {
|
||||||
|
show->session().setCredits(slice.balance);
|
||||||
|
const auto creditsNeeded = int64(form->invoice.credits)
|
||||||
|
- int64(slice.balance);
|
||||||
|
if (creditsNeeded <= 0) {
|
||||||
|
sendBox();
|
||||||
|
} else if (show->session().premiumPossible()) {
|
||||||
|
show->show(Box(
|
||||||
|
Settings::SmallBalanceBox,
|
||||||
|
show,
|
||||||
|
creditsNeeded,
|
||||||
|
form->botId,
|
||||||
|
sendBox));
|
||||||
|
} else {
|
||||||
|
show->showToast(
|
||||||
|
tr::lng_credits_purchase_blocked(tr::now));
|
||||||
|
if (maybeReturnToBot) {
|
||||||
|
maybeReturnToBot(CheckoutResult::Failed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lifetime->destroy();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessCreditsReceipt(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
std::shared_ptr<CreditsReceiptData> receipt,
|
||||||
|
Fn<void(CheckoutResult)> maybeReturnToBot) {
|
||||||
|
const auto entry = Data::CreditsHistoryEntry{
|
||||||
|
.id = receipt->id,
|
||||||
|
.title = receipt->title,
|
||||||
|
.description = receipt->description,
|
||||||
|
.date = base::unixtime::parse(receipt->date),
|
||||||
|
.photoId = receipt->photo ? receipt->photo->id : 0,
|
||||||
|
.credits = receipt->credits,
|
||||||
|
.bareMsgId = uint64(),
|
||||||
|
.barePeerId = receipt->peerId.value,
|
||||||
|
.peerType = Data::CreditsHistoryEntry::PeerType::Peer,
|
||||||
|
};
|
||||||
|
controller->uiShow()->show(Box(
|
||||||
|
Settings::ReceiptCreditsBox,
|
||||||
|
controller,
|
||||||
|
nullptr,
|
||||||
|
entry));
|
||||||
|
controller->window().activate();
|
||||||
|
}
|
||||||
|
|
||||||
Fn<void(NonPanelPaymentForm)> ProcessNonPanelPaymentFormFactory(
|
Fn<void(NonPanelPaymentForm)> ProcessNonPanelPaymentFormFactory(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
Fn<void(CheckoutResult)> maybeReturnToBot) {
|
Fn<void(CheckoutResult)> maybeReturnToBot) {
|
||||||
return [=](NonPanelPaymentForm form) {
|
return [=](NonPanelPaymentForm form) {
|
||||||
using CreditsFormDataPtr = std::shared_ptr<CreditsFormData>;
|
using CreditsFormDataPtr = std::shared_ptr<CreditsFormData>;
|
||||||
using CreditsReceiptPtr = std::shared_ptr<CreditsReceiptData>;
|
using CreditsReceiptPtr = std::shared_ptr<CreditsReceiptData>;
|
||||||
if (const auto creditsData = std::get_if<CreditsFormDataPtr>(&form)) {
|
v::match(form, [&](const CreditsFormDataPtr &form) {
|
||||||
const auto form = *creditsData;
|
ProcessCreditsPayment(
|
||||||
const auto lifetime = std::make_shared<rpl::lifetime>();
|
controller->uiShow(),
|
||||||
const auto api = lifetime->make_state<Api::CreditsStatus>(
|
controller->content().get(),
|
||||||
controller->session().user());
|
form,
|
||||||
const auto sendBox = [=, weak = base::make_weak(controller)] {
|
maybeReturnToBot);
|
||||||
if (const auto strong = weak.get()) {
|
}, [&](const CreditsReceiptPtr &receipt) {
|
||||||
const auto unsuccessful = std::make_shared<bool>(true);
|
ProcessCreditsReceipt(controller, receipt, maybeReturnToBot);
|
||||||
const auto box = controller->uiShow()->show(Box(
|
}, [](RealFormPresentedNotification) {});
|
||||||
Ui::SendCreditsBox,
|
|
||||||
form,
|
|
||||||
crl::guard(strong, [=] {
|
|
||||||
*unsuccessful = false;
|
|
||||||
Ui::StartFireworks(strong->content());
|
|
||||||
if (maybeReturnToBot) {
|
|
||||||
maybeReturnToBot(CheckoutResult::Paid);
|
|
||||||
}
|
|
||||||
})));
|
|
||||||
box->boxClosing() | rpl::start_with_next([=] {
|
|
||||||
crl::on_main([=] {
|
|
||||||
if ((*unsuccessful) && maybeReturnToBot) {
|
|
||||||
maybeReturnToBot(CheckoutResult::Cancelled);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, box->lifetime());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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 if (strong->session().premiumPossible()) {
|
|
||||||
strong->uiShow()->show(Box(
|
|
||||||
Settings::SmallBalanceBox,
|
|
||||||
strong,
|
|
||||||
creditsNeeded,
|
|
||||||
form->botId,
|
|
||||||
sendBox));
|
|
||||||
} else {
|
|
||||||
strong->uiShow()->showToast(
|
|
||||||
tr::lng_credits_purchase_blocked(tr::now));
|
|
||||||
if (maybeReturnToBot) {
|
|
||||||
maybeReturnToBot(CheckoutResult::Failed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lifetime->destroy();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (const auto r = std::get_if<CreditsReceiptPtr>(&form)) {
|
|
||||||
const auto receipt = *r;
|
|
||||||
const auto entry = Data::CreditsHistoryEntry{
|
|
||||||
.id = receipt->id,
|
|
||||||
.title = receipt->title,
|
|
||||||
.description = receipt->description,
|
|
||||||
.date = base::unixtime::parse(receipt->date),
|
|
||||||
.photoId = receipt->photo ? receipt->photo->id : 0,
|
|
||||||
.credits = receipt->credits,
|
|
||||||
.bareMsgId = uint64(),
|
|
||||||
.barePeerId = receipt->peerId.value,
|
|
||||||
.peerType = Data::CreditsHistoryEntry::PeerType::Peer,
|
|
||||||
};
|
|
||||||
controller->uiShow()->show(Box(
|
|
||||||
Settings::ReceiptCreditsBox,
|
|
||||||
controller,
|
|
||||||
nullptr,
|
|
||||||
entry));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
class HistoryItem;
|
class HistoryItem;
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class SessionShow;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
class SessionController;
|
class SessionController;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
@ -16,10 +20,23 @@ class SessionController;
|
||||||
namespace Payments {
|
namespace Payments {
|
||||||
|
|
||||||
enum class CheckoutResult;
|
enum class CheckoutResult;
|
||||||
|
struct CreditsFormData;
|
||||||
|
struct CreditsReceiptData;
|
||||||
struct NonPanelPaymentForm;
|
struct NonPanelPaymentForm;
|
||||||
|
|
||||||
[[nodiscard]] bool IsCreditsInvoice(not_null<HistoryItem*> item);
|
[[nodiscard]] bool IsCreditsInvoice(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
|
void ProcessCreditsPayment(
|
||||||
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
|
QPointer<QWidget> fireworks,
|
||||||
|
std::shared_ptr<CreditsFormData> form,
|
||||||
|
Fn<void(CheckoutResult)> maybeReturnToBot = nullptr);
|
||||||
|
|
||||||
|
void ProcessCreditsReceipt(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
std::shared_ptr<CreditsReceiptData> receipt,
|
||||||
|
Fn<void(CheckoutResult)> maybeReturnToBot = nullptr);
|
||||||
|
|
||||||
Fn<void(NonPanelPaymentForm)> ProcessNonPanelPaymentFormFactory(
|
Fn<void(NonPanelPaymentForm)> ProcessNonPanelPaymentFormFactory(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
Fn<void(Payments::CheckoutResult)> maybeReturnToBot = nullptr);
|
Fn<void(Payments::CheckoutResult)> maybeReturnToBot = nullptr);
|
||||||
|
|
|
@ -289,7 +289,7 @@ void Credits::setupContent() {
|
||||||
Ui::StartFireworks(_parent);
|
Ui::StartFireworks(_parent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
FillCreditOptions(_controller, content, 0, paid);
|
FillCreditOptions(_controller->uiShow(), content, 0, paid);
|
||||||
setupHistory(content);
|
setupHistory(content);
|
||||||
|
|
||||||
Ui::ResizeFitChild(this, content);
|
Ui::ResizeFitChild(this, content);
|
||||||
|
|
|
@ -225,7 +225,7 @@ void AddViewMediaHandler(
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void FillCreditOptions(
|
void FillCreditOptions(
|
||||||
not_null<Window::SessionController*> controller,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
int minimumCredits,
|
int minimumCredits,
|
||||||
Fn<void()> paid) {
|
Fn<void()> paid) {
|
||||||
|
@ -302,7 +302,7 @@ void FillCreditOptions(
|
||||||
}, button->lifetime());
|
}, button->lifetime());
|
||||||
button->setClickedCallback([=] {
|
button->setClickedCallback([=] {
|
||||||
const auto invoice = Payments::InvoiceCredits{
|
const auto invoice = Payments::InvoiceCredits{
|
||||||
.session = &controller->session(),
|
.session = &show->session(),
|
||||||
.randomId = UniqueIdFromOption(option),
|
.randomId = UniqueIdFromOption(option),
|
||||||
.credits = option.credits,
|
.credits = option.credits,
|
||||||
.product = option.product,
|
.product = option.product,
|
||||||
|
@ -348,18 +348,18 @@ void FillCreditOptions(
|
||||||
|
|
||||||
using ApiOptions = Api::CreditsTopupOptions;
|
using ApiOptions = Api::CreditsTopupOptions;
|
||||||
const auto apiCredits = content->lifetime().make_state<ApiOptions>(
|
const auto apiCredits = content->lifetime().make_state<ApiOptions>(
|
||||||
controller->session().user());
|
show->session().user());
|
||||||
|
|
||||||
if (controller->session().premiumPossible()) {
|
if (show->session().premiumPossible()) {
|
||||||
apiCredits->request(
|
apiCredits->request(
|
||||||
) | rpl::start_with_error_done([=](const QString &error) {
|
) | rpl::start_with_error_done([=](const QString &error) {
|
||||||
controller->showToast(error);
|
show->showToast(error);
|
||||||
}, [=] {
|
}, [=] {
|
||||||
fill(apiCredits->options());
|
fill(apiCredits->options());
|
||||||
}, content->lifetime());
|
}, content->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
controller->session().premiumPossibleValue(
|
show->session().premiumPossibleValue(
|
||||||
) | rpl::start_with_next([=](bool premiumPossible) {
|
) | rpl::start_with_next([=](bool premiumPossible) {
|
||||||
if (!premiumPossible) {
|
if (!premiumPossible) {
|
||||||
fill({});
|
fill({});
|
||||||
|
@ -739,7 +739,7 @@ object_ptr<Ui::RpWidget> PaidMediaThumbnail(
|
||||||
|
|
||||||
void SmallBalanceBox(
|
void SmallBalanceBox(
|
||||||
not_null<Ui::GenericBox*> box,
|
not_null<Ui::GenericBox*> box,
|
||||||
not_null<Window::SessionController*> controller,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
int creditsNeeded,
|
int creditsNeeded,
|
||||||
UserId botId,
|
UserId botId,
|
||||||
Fn<void()> paid) {
|
Fn<void()> paid) {
|
||||||
|
@ -750,21 +750,13 @@ void SmallBalanceBox(
|
||||||
paid();
|
paid();
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto bot = controller->session().data().user(botId).get();
|
const auto bot = show->session().data().user(botId).get();
|
||||||
|
|
||||||
const auto content = [&]() -> Ui::Premium::TopBarAbstract* {
|
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>(
|
return box->setPinnedToTopContent(object_ptr<Ui::Premium::TopBar>(
|
||||||
box,
|
box,
|
||||||
st::creditsLowBalancePremiumCover,
|
st::creditsLowBalancePremiumCover,
|
||||||
Ui::Premium::TopBarDescriptor{
|
Ui::Premium::TopBarDescriptor{
|
||||||
.clickContextOther = clickContextOther,
|
|
||||||
.title = tr::lng_credits_small_balance_title(
|
.title = tr::lng_credits_small_balance_title(
|
||||||
lt_count,
|
lt_count,
|
||||||
rpl::single(creditsNeeded) | tr::to_count()),
|
rpl::single(creditsNeeded) | tr::to_count()),
|
||||||
|
@ -777,7 +769,7 @@ void SmallBalanceBox(
|
||||||
}));
|
}));
|
||||||
}();
|
}();
|
||||||
|
|
||||||
FillCreditOptions(controller, box->verticalLayout(), creditsNeeded, done);
|
FillCreditOptions(show, box->verticalLayout(), creditsNeeded, done);
|
||||||
|
|
||||||
content->setMaximumHeight(st::creditsLowBalancePremiumCoverHeight);
|
content->setMaximumHeight(st::creditsLowBalancePremiumCoverHeight);
|
||||||
content->setMinimumHeight(st::infoLayerTopBarHeight);
|
content->setMinimumHeight(st::infoLayerTopBarHeight);
|
||||||
|
@ -796,12 +788,12 @@ void SmallBalanceBox(
|
||||||
{
|
{
|
||||||
const auto balance = AddBalanceWidget(
|
const auto balance = AddBalanceWidget(
|
||||||
content,
|
content,
|
||||||
controller->session().creditsValue(),
|
show->session().creditsValue(),
|
||||||
true);
|
true);
|
||||||
const auto api = balance->lifetime().make_state<Api::CreditsStatus>(
|
const auto api = balance->lifetime().make_state<Api::CreditsStatus>(
|
||||||
controller->session().user());
|
show->session().user());
|
||||||
api->request({}, [=](Data::CreditsStatusSlice slice) {
|
api->request({}, [=](Data::CreditsStatusSlice slice) {
|
||||||
controller->session().setCredits(slice.balance);
|
show->session().setCredits(slice.balance);
|
||||||
});
|
});
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
balance->sizeValue(),
|
balance->sizeValue(),
|
||||||
|
|
|
@ -16,6 +16,10 @@ namespace Data {
|
||||||
struct CreditsHistoryEntry;
|
struct CreditsHistoryEntry;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class SessionShow;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
class SessionController;
|
class SessionController;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
@ -29,7 +33,7 @@ class VerticalLayout;
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
void FillCreditOptions(
|
void FillCreditOptions(
|
||||||
not_null<Window::SessionController*> controller,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
int minCredits,
|
int minCredits,
|
||||||
Fn<void()> paid);
|
Fn<void()> paid);
|
||||||
|
@ -77,7 +81,7 @@ void ShowRefundInfoBox(
|
||||||
|
|
||||||
void SmallBalanceBox(
|
void SmallBalanceBox(
|
||||||
not_null<Ui::GenericBox*> box,
|
not_null<Ui::GenericBox*> box,
|
||||||
not_null<Window::SessionController*> controller,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
int creditsNeeded,
|
int creditsNeeded,
|
||||||
UserId botId,
|
UserId botId,
|
||||||
Fn<void()> paid);
|
Fn<void()> paid);
|
||||||
|
|
|
@ -1344,8 +1344,10 @@ void Panel::invoiceClosed(const QString &slug, const QString &status) {
|
||||||
{ u"slug"_q, slug },
|
{ u"slug"_q, slug },
|
||||||
{ u"status"_q, status },
|
{ u"status"_q, status },
|
||||||
});
|
});
|
||||||
_widget->showAndActivate();
|
if (_hiddenForPayment) {
|
||||||
_hiddenForPayment = false;
|
_hiddenForPayment = false;
|
||||||
|
_widget->showAndActivate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::hideForPayment() {
|
void Panel::hideForPayment() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue