From dda6b92becc623d2b9a222c45735f5502169de90 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 24 May 2024 20:47:15 +0300 Subject: [PATCH] Added initial ability to process non-panel payment forms. --- Telegram/CMakeLists.txt | 2 + Telegram/SourceFiles/api/api_bot.cpp | 19 +++---- .../SourceFiles/core/local_url_handlers.cpp | 4 +- Telegram/SourceFiles/history/history_item.cpp | 6 ++- .../media/history_view_extended_preview.cpp | 8 ++- .../inline_bots/bot_attach_web_view.cpp | 10 +++- .../payments/payments_checkout_process.cpp | 49 ++++++++++++++++--- .../payments/payments_checkout_process.h | 9 +++- .../payments/payments_non_panel_process.cpp | 46 +++++++++++++++++ .../payments/payments_non_panel_process.h | 27 ++++++++++ 10 files changed, 155 insertions(+), 25 deletions(-) create mode 100644 Telegram/SourceFiles/payments/payments_non_panel_process.cpp create mode 100644 Telegram/SourceFiles/payments/payments_non_panel_process.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index a562048ec..75ab2b48f 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1221,6 +1221,8 @@ PRIVATE payments/payments_checkout_process.h payments/payments_form.cpp payments/payments_form.h + payments/payments_non_panel_process.cpp + payments/payments_non_panel_process.h platform/linux/file_utilities_linux.cpp platform/linux/file_utilities_linux.h platform/linux/launcher_linux.cpp diff --git a/Telegram/SourceFiles/api/api_bot.cpp b/Telegram/SourceFiles/api/api_bot.cpp index f4331cd1f..cf4611563 100644 --- a/Telegram/SourceFiles/api/api_bot.cpp +++ b/Telegram/SourceFiles/api/api_bot.cpp @@ -10,7 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "api/api_cloud_password.h" #include "api/api_send_progress.h" -#include "boxes/send_credits_box.h" #include "boxes/share_box.h" #include "boxes/passcode_box.h" #include "boxes/url_auth_box.h" @@ -28,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_item_components.h" #include "inline_bots/bot_attach_web_view.h" #include "payments/payments_checkout_process.h" +#include "payments/payments_non_panel_process.h" #include "main/main_session.h" #include "mainwidget.h" #include "mainwindow.h" @@ -331,16 +331,13 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) { } break; case ButtonType::Buy: { - if (Ui::IsCreditsInvoice(item)) { - // controller->uiShow()->show(Box(Ui::SendCreditsBox, item)); - } else { - Payments::CheckoutProcess::Start( - item, - Payments::Mode::Payment, - crl::guard(controller, [=](auto) { - controller->widget()->activate(); - })); - } + Payments::CheckoutProcess::Start( + item, + Payments::Mode::Payment, + crl::guard(controller, [=](auto) { + controller->widget()->activate(); + }), + Payments::ProcessNonPanelPaymentFormFactory(controller, item)); } break; case ButtonType::Url: { diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index 6fa9d7bb6..544038640 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/background_preview_box.h" #include "ui/boxes/confirm_box.h" #include "ui/boxes/edit_birthday_box.h" +#include "payments/payments_non_panel_process.h" #include "boxes/share_box.h" #include "boxes/connection_box.h" #include "boxes/edit_privacy_box.h" @@ -1092,7 +1093,8 @@ bool ResolveInvoice( Payments::CheckoutProcess::Start( &controller->session(), slug, - crl::guard(window, [=](auto) { window->activate(); })); + crl::guard(window, [=](auto) { window->activate(); }), + Payments::ProcessNonPanelPaymentFormFactory(controller)); return true; } diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 30cc8a9c3..c1af45c5f 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -63,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_web_page.h" #include "chat_helpers/stickers_gift_box_pack.h" #include "payments/payments_checkout_process.h" // CheckoutProcess::Start. +#include "payments/payments_non_panel_process.h" // ProcessNonPanelPaymentFormFactory. #include "platform/platform_notifications_manager.h" #include "spellcheck/spellcheck_highlight_syntax.h" #include "styles/style_dialogs.h" @@ -3950,7 +3951,10 @@ void HistoryItem::createServiceFromMtp(const MTPDmessageService &message) { CheckoutProcess::Start( item, Mode::Receipt, - crl::guard(weak, [=](auto) { weak->window().activate(); })); + crl::guard(weak, [=](auto) { weak->window().activate(); }), + Payments::ProcessNonPanelPaymentFormFactory( + weak.get(), + item)); } }); } else if (type == mtpc_messageActionGroupCall diff --git a/Telegram/SourceFiles/history/view/media/history_view_extended_preview.cpp b/Telegram/SourceFiles/history/view/media/history_view_extended_preview.cpp index d127fc4fc..9db9acc07 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_extended_preview.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_extended_preview.cpp @@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/power_saving.h" #include "data/data_session.h" #include "payments/payments_checkout_process.h" +#include "payments/payments_non_panel_process.h" #include "window/window_session_controller.h" #include "mainwindow.h" #include "core/click_handler_types.h" @@ -41,7 +42,12 @@ namespace { ? crl::guard( controller, [=](auto) { controller->widget()->activate(); }) - : Fn())); + : Fn()), + (controller + ? Payments::ProcessNonPanelPaymentFormFactory( + controller, + item) + : nullptr)); }); } diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 1eb99362b..03561bdd6 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -43,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history.h" #include "history/history_item.h" #include "payments/payments_checkout_process.h" +#include "payments/payments_non_panel_process.h" #include "storage/storage_account.h" #include "boxes/peer_list_controllers.h" #include "lang/lang_keys.h" @@ -603,7 +604,14 @@ void AttachWebView::botHandleInvoice(QString slug) { } }; _panel->hideForPayment(); - Payments::CheckoutProcess::Start(&_bot->session(), slug, reactivate); + Payments::CheckoutProcess::Start( + &_bot->session(), + slug, + reactivate, + _context + ? Payments::ProcessNonPanelPaymentFormFactory( + _context->controller.get()) + : nullptr); } void AttachWebView::botHandleMenuButton(Ui::BotWebView::MenuButton button) { diff --git a/Telegram/SourceFiles/payments/payments_checkout_process.cpp b/Telegram/SourceFiles/payments/payments_checkout_process.cpp index 14e7d695d..597d7687b 100644 --- a/Telegram/SourceFiles/payments/payments_checkout_process.cpp +++ b/Telegram/SourceFiles/payments/payments_checkout_process.cpp @@ -64,7 +64,9 @@ base::flat_map, SessionProcesses> Processes; void CheckoutProcess::Start( not_null item, Mode mode, - Fn reactivate) { + Fn reactivate, + Fn nonPanelPaymentFormProcess) { + const auto hasNonPanelPaymentFormProcess = !!nonPanelPaymentFormProcess; auto &processes = LookupSessionProcesses(&item->history()->session()); const auto media = item->media(); const auto invoice = media ? media->invoice() : nullptr; @@ -83,7 +85,11 @@ void CheckoutProcess::Start( const auto i = processes.byItem.find(id); if (i != end(processes.byItem)) { i->second->setReactivateCallback(std::move(reactivate)); - i->second->requestActivate(); + i->second->setNonPanelPaymentFormProcess( + std::move(nonPanelPaymentFormProcess)); + if (!hasNonPanelPaymentFormProcess) { + i->second->requestActivate(); + } return; } const auto j = processes.byItem.emplace( @@ -92,19 +98,28 @@ void CheckoutProcess::Start( InvoiceId{ InvoiceMessage{ item->history()->peer, id.msg } }, mode, std::move(reactivate), + std::move(nonPanelPaymentFormProcess), PrivateTag{})).first; - j->second->requestActivate(); + if (!hasNonPanelPaymentFormProcess) { + j->second->requestActivate(); + } } void CheckoutProcess::Start( not_null session, const QString &slug, - Fn reactivate) { + Fn reactivate, + Fn nonPanelPaymentFormProcess) { + const auto hasNonPanelPaymentFormProcess = !!nonPanelPaymentFormProcess; auto &processes = LookupSessionProcesses(session); const auto i = processes.bySlug.find(slug); if (i != end(processes.bySlug)) { i->second->setReactivateCallback(std::move(reactivate)); - i->second->requestActivate(); + i->second->setNonPanelPaymentFormProcess( + std::move(nonPanelPaymentFormProcess)); + if (!hasNonPanelPaymentFormProcess) { + i->second->requestActivate(); + } return; } const auto j = processes.bySlug.emplace( @@ -113,8 +128,11 @@ void CheckoutProcess::Start( InvoiceId{ InvoiceSlug{ session, slug } }, Mode::Payment, std::move(reactivate), + std::move(nonPanelPaymentFormProcess), PrivateTag{})).first; - j->second->requestActivate(); + if (!hasNonPanelPaymentFormProcess) { + j->second->requestActivate(); + } } void CheckoutProcess::Start( @@ -135,6 +153,7 @@ void CheckoutProcess::Start( std::move(id), Mode::Payment, std::move(reactivate), + nullptr, PrivateTag{})).first; j->second->requestActivate(); } @@ -157,6 +176,7 @@ void CheckoutProcess::Start( std::move(id), Mode::Payment, std::move(reactivate), + nullptr, PrivateTag{})).first; j->second->requestActivate(); } @@ -280,11 +300,13 @@ CheckoutProcess::CheckoutProcess( InvoiceId id, Mode mode, Fn reactivate, + Fn nonPanelPaymentFormProcess, PrivateTag) : _session(SessionFromId(id)) , _form(std::make_unique
(id, (mode == Mode::Receipt))) , _panel(std::make_unique(panelDelegate())) -, _reactivate(std::move(reactivate)) { +, _reactivate(std::move(reactivate)) +, _nonPanelPaymentFormProcess(std::move(nonPanelPaymentFormProcess)) { _form->updates( ) | rpl::start_with_next([=](const FormUpdate &update) { handleFormUpdate(update); @@ -299,7 +321,9 @@ CheckoutProcess::CheckoutProcess( ) | rpl::start_with_next([=] { panelCancelEdit(); }, _panel->lifetime()); - showForm(); + if (!_nonPanelPaymentFormProcess) { + showForm(); + } _panel->toggleProgress(true); if (mode == Mode::Payment) { @@ -318,6 +342,11 @@ void CheckoutProcess::setReactivateCallback( _reactivate = std::move(reactivate); } +void CheckoutProcess::setNonPanelPaymentFormProcess( + Fn callback) { + _nonPanelPaymentFormProcess = std::move(callback); +} + void CheckoutProcess::requestActivate() { _panel->requestActivate(); } @@ -382,6 +411,10 @@ void CheckoutProcess::handleFormUpdate(const FormUpdate &update) { closeAndReactivate(CheckoutResult::Paid); } }, [&](const CreditsPaymentStarted &data) { + if (_nonPanelPaymentFormProcess) { + _nonPanelPaymentFormProcess( + std::make_shared(data.data)); + } }, [&](const Error &error) { handleError(error); }); diff --git a/Telegram/SourceFiles/payments/payments_checkout_process.h b/Telegram/SourceFiles/payments/payments_checkout_process.h index e26fff3cd..2f939d5a6 100644 --- a/Telegram/SourceFiles/payments/payments_checkout_process.h +++ b/Telegram/SourceFiles/payments/payments_checkout_process.h @@ -71,11 +71,13 @@ public: static void Start( not_null item, Mode mode, - Fn reactivate); + Fn reactivate, + Fn nonPanelPaymentFormProcess); static void Start( not_null session, const QString &slug, - Fn reactivate); + Fn reactivate, + Fn nonPanelPaymentFormProcess); static void Start( InvoicePremiumGiftCode giftCodeInvoice, Fn reactivate); @@ -93,6 +95,7 @@ public: InvoiceId id, Mode mode, Fn reactivate, + Fn nonPanelPaymentFormProcess, PrivateTag); ~CheckoutProcess(); @@ -111,6 +114,7 @@ private: static void UnregisterPaymentStart(not_null process); void setReactivateCallback(Fn reactivate); + void setNonPanelPaymentFormProcess(Fn); void requestActivate(); void closeAndReactivate(CheckoutResult result); void close(); @@ -173,6 +177,7 @@ private: const std::unique_ptr _panel; QPointer _enterPasswordBox; Fn _reactivate; + Fn _nonPanelPaymentFormProcess; SubmitState _submitState = SubmitState::None; bool _initialSilentValidation = false; bool _sendFormPending = false; diff --git a/Telegram/SourceFiles/payments/payments_non_panel_process.cpp b/Telegram/SourceFiles/payments/payments_non_panel_process.cpp new file mode 100644 index 000000000..3669576d9 --- /dev/null +++ b/Telegram/SourceFiles/payments/payments_non_panel_process.cpp @@ -0,0 +1,46 @@ +/* +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 "payments/payments_checkout_process.h" // NonPanelPaymentForm. +#include "payments/payments_form.h" +#include "history/history_item.h" +#include "ui/layers/generic_box.h" +#include "window/window_session_controller.h" +#include "boxes/send_credits_box.h" + +namespace Payments { +namespace { + +bool IsCreditsInvoice(not_null item) { + const auto media = item->media(); + const auto invoice = media ? media->invoice() : nullptr; + return invoice && (invoice->currency == "XTR"); +} + +} // namespace + +Fn ProcessNonPanelPaymentFormFactory( + not_null controller) { + return [=](NonPanelPaymentForm form) { + using CreditsFormDataPtr = std::shared_ptr; + if (const auto creditsData = std::get_if(&form)) { + controller->uiShow()->show(Box(Ui::SendCreditsBox, *creditsData)); + } + }; +} + +Fn ProcessNonPanelPaymentFormFactory( + not_null controller, + not_null item) { + return IsCreditsInvoice(item) + ? ProcessNonPanelPaymentFormFactory(controller) + : nullptr; +} + +} // namespace Payments diff --git a/Telegram/SourceFiles/payments/payments_non_panel_process.h b/Telegram/SourceFiles/payments/payments_non_panel_process.h new file mode 100644 index 000000000..76939415d --- /dev/null +++ b/Telegram/SourceFiles/payments/payments_non_panel_process.h @@ -0,0 +1,27 @@ +/* +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 +*/ +#pragma once + +class HistoryItem; + +namespace Window { +class SessionController; +} // namespace Window + +namespace Payments { + +struct NonPanelPaymentForm; + +Fn ProcessNonPanelPaymentFormFactory( + not_null controller); + +Fn ProcessNonPanelPaymentFormFactory( + not_null controller, + not_null item); + +} // namespace Payments