2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-24 19:27:17 +00:00
tdesktop/Telegram/SourceFiles/payments/payments_non_panel_process.cpp

177 lines
5.4 KiB
C++
Raw Normal View History

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
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"
2024-08-06 12:48:06 +02:00
#include "data/components/credits.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 "lang/lang_keys.h"
#include "main/main_session.h"
#include "mainwidget.h"
#include "payments/payments_checkout_process.h" // NonPanelPaymentForm.
#include "payments/payments_form.h"
2024-05-24 23:09:14 +03:00
#include "settings/settings_credits_graphics.h"
#include "ui/boxes/boost_box.h" // Ui::StartFireworks.
#include "ui/layers/generic_box.h"
#include "ui/text/format_values.h"
2024-10-11 09:47:41 +04:00
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
2024-07-18 16:41:18 +02:00
#include "window/window_controller.h"
#include "window/window_session_controller.h"
namespace Payments {
bool IsCreditsInvoice(not_null<HistoryItem*> item) {
if (const auto payment = item->Get<HistoryServicePayment>()) {
return payment->isCreditsCurrency;
}
const auto media = item->media();
const auto invoice = media ? media->invoice() : nullptr;
return invoice && (invoice->currency == Ui::kCreditsCurrency);
}
2024-07-18 16:41:18 +02:00
void ProcessCreditsPayment(
2024-09-17 18:59:24 +04:00
std::shared_ptr<Main::SessionShow> show,
QPointer<QWidget> fireworks,
std::shared_ptr<CreditsFormData> form,
Fn<void(CheckoutResult)> maybeReturnToBot) {
2024-08-06 12:48:06 +02:00
const auto done = [=](Settings::SmallBalanceResult result) {
if (result == Settings::SmallBalanceResult::Blocked) {
if (const auto onstack = maybeReturnToBot) {
onstack(CheckoutResult::Failed);
}
return;
} else if (result == Settings::SmallBalanceResult::Cancelled) {
if (const auto onstack = maybeReturnToBot) {
onstack(CheckoutResult::Cancelled);
}
return;
2025-03-04 14:13:39 +04:00
} else if (form->starGiftForm
|| IsPremiumForStarsInvoice(form->id)) {
2024-09-17 18:59:24 +04:00
const auto done = [=](std::optional<QString> error) {
const auto onstack = maybeReturnToBot;
if (error) {
2024-10-11 09:47:41 +04:00
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,
Ui::Text::RichLangValue),
});
} else {
show->showToast(
tr::lng_gift_sold_out_title(tr::now));
}
} else {
show->showToast(*error);
}
2024-09-17 18:59:24 +04:00
if (onstack) {
onstack(CheckoutResult::Failed);
}
} else if (onstack) {
onstack(CheckoutResult::Paid);
}
};
2025-03-04 14:13:39 +04:00
Ui::SendStarsForm(&show->session(), form, done);
2024-09-17 18:59:24 +04:00
return;
2024-08-06 12:48:06 +02:00
}
2024-07-18 16:41:18 +02:00
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 (const auto onstack = maybeReturnToBot) {
onstack(CheckoutResult::Paid);
}
}));
2024-07-18 16:41:18 +02:00
box->boxClosing() | rpl::start_with_next([=] {
crl::on_main([=] {
2024-09-17 18:59:24 +04:00
if (*unsuccessful) {
if (const auto onstack = maybeReturnToBot) {
onstack(CheckoutResult::Cancelled);
}
2024-07-18 16:41:18 +02:00
}
});
}, 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{
2025-01-15 14:26:22 +04:00
.recipientId = starGift->recipient->id,
});
MaybeRequestBalanceIncrease(show, form->invoice.credits, source, done);
2024-07-18 16:41:18 +02:00
}
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,
2024-10-05 21:09:40 +04:00
.description = { receipt->description },
2024-07-18 16:41:18 +02:00
.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,
entry,
Data::SubscriptionEntry{}));
2024-07-18 16:41:18 +02:00
controller->window().activate();
}
Fn<void(NonPanelPaymentForm)> ProcessNonPanelPaymentFormFactory(
not_null<Window::SessionController*> controller,
Fn<void(CheckoutResult)> maybeReturnToBot) {
return [=](NonPanelPaymentForm form) {
using CreditsFormDataPtr = std::shared_ptr<CreditsFormData>;
using CreditsReceiptPtr = std::shared_ptr<CreditsReceiptData>;
2024-07-18 16:41:18 +02:00
v::match(form, [&](const CreditsFormDataPtr &form) {
ProcessCreditsPayment(
controller->uiShow(),
controller->content().get(),
form,
maybeReturnToBot);
controller->window().activate();
2024-07-18 16:41:18 +02:00
}, [&](const CreditsReceiptPtr &receipt) {
ProcessCreditsReceipt(controller, receipt, maybeReturnToBot);
}, [](RealFormPresentedNotification) {});
};
}
Fn<void(NonPanelPaymentForm)> ProcessNonPanelPaymentFormFactory(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item) {
return IsCreditsInvoice(item)
? ProcessNonPanelPaymentFormFactory(controller)
: nullptr;
}
} // namespace Payments