summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Preston <johnprestonmail@gmail.com>2021-03-26 17:05:31 +0400
committerJohn Preston <johnprestonmail@gmail.com>2021-03-26 17:05:31 +0400
commit1aefada45d0db1bef0776f31a7036600e4b77f8f (patch)
treea846cee13713aca56f9f52809f7ab75a5e954b85
parentf5a8bf0e744a3c410dee1b5f5079b271908a4623 (diff)
Improve checkout main page design.
-rw-r--r--Telegram/Resources/icons/payments/payment_address.pngbin0 -> 802 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_address@2x.pngbin0 -> 1638 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_address@3x.pngbin0 -> 2402 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_card.pngbin0 -> 357 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_card@2x.pngbin0 -> 560 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_card@3x.pngbin0 -> 985 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_email.pngbin0 -> 949 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_email@2x.pngbin0 -> 1936 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_email@3x.pngbin0 -> 2860 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_name.pngbin0 -> 473 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_name@2x.pngbin0 -> 884 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_name@3x.pngbin0 -> 1411 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_phone.pngbin0 -> 711 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_phone@2x.pngbin0 -> 1327 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_phone@3x.pngbin0 -> 2090 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_shipping.pngbin0 -> 526 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_shipping@2x.pngbin0 -> 1022 bytes
-rw-r--r--Telegram/Resources/icons/payments/payment_shipping@3x.pngbin0 -> 1469 bytes
-rw-r--r--Telegram/Resources/langs/lang.strings27
-rw-r--r--Telegram/SourceFiles/payments/payments_checkout_process.cpp15
-rw-r--r--Telegram/SourceFiles/payments/payments_form.cpp120
-rw-r--r--Telegram/SourceFiles/payments/payments_form.h31
-rw-r--r--Telegram/SourceFiles/payments/ui/payments.style46
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_form_summary.cpp307
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_form_summary.h11
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_panel.cpp23
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_panel.h3
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_panel_data.h9
28 files changed, 450 insertions, 142 deletions
diff --git a/Telegram/Resources/icons/payments/payment_address.png b/Telegram/Resources/icons/payments/payment_address.png
new file mode 100644
index 0000000000..dcc9b2f812
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_address.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_address@2x.png b/Telegram/Resources/icons/payments/payment_address@2x.png
new file mode 100644
index 0000000000..5b4cea3d39
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_address@2x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_address@3x.png b/Telegram/Resources/icons/payments/payment_address@3x.png
new file mode 100644
index 0000000000..f155680197
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_address@3x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_card.png b/Telegram/Resources/icons/payments/payment_card.png
new file mode 100644
index 0000000000..6e80687c6c
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_card.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_card@2x.png b/Telegram/Resources/icons/payments/payment_card@2x.png
new file mode 100644
index 0000000000..1fd98a77c0
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_card@2x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_card@3x.png b/Telegram/Resources/icons/payments/payment_card@3x.png
new file mode 100644
index 0000000000..ae50fe67da
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_card@3x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_email.png b/Telegram/Resources/icons/payments/payment_email.png
new file mode 100644
index 0000000000..41154157ba
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_email.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_email@2x.png b/Telegram/Resources/icons/payments/payment_email@2x.png
new file mode 100644
index 0000000000..d6b6ab1505
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_email@2x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_email@3x.png b/Telegram/Resources/icons/payments/payment_email@3x.png
new file mode 100644
index 0000000000..5f113ae768
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_email@3x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_name.png b/Telegram/Resources/icons/payments/payment_name.png
new file mode 100644
index 0000000000..fdeb96631e
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_name.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_name@2x.png b/Telegram/Resources/icons/payments/payment_name@2x.png
new file mode 100644
index 0000000000..2bcacb3746
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_name@2x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_name@3x.png b/Telegram/Resources/icons/payments/payment_name@3x.png
new file mode 100644
index 0000000000..23d2ee2435
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_name@3x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_phone.png b/Telegram/Resources/icons/payments/payment_phone.png
new file mode 100644
index 0000000000..87b185d8c6
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_phone.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_phone@2x.png b/Telegram/Resources/icons/payments/payment_phone@2x.png
new file mode 100644
index 0000000000..d047fb5b4b
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_phone@2x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_phone@3x.png b/Telegram/Resources/icons/payments/payment_phone@3x.png
new file mode 100644
index 0000000000..ff201d3e80
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_phone@3x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_shipping.png b/Telegram/Resources/icons/payments/payment_shipping.png
new file mode 100644
index 0000000000..aa618f5fb6
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_shipping.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_shipping@2x.png b/Telegram/Resources/icons/payments/payment_shipping@2x.png
new file mode 100644
index 0000000000..3315d9a9cc
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_shipping@2x.png
Binary files differ
diff --git a/Telegram/Resources/icons/payments/payment_shipping@3x.png b/Telegram/Resources/icons/payments/payment_shipping@3x.png
new file mode 100644
index 0000000000..8b08421d09
--- /dev/null
+++ b/Telegram/Resources/icons/payments/payment_shipping@3x.png
Binary files differ
diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 11bb8041cb..6be8d6bd0b 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -1865,24 +1865,27 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_payments_pay_amount" = "Pay {amount}";
"lng_payments_payment_method" = "Payment Method";
"lng_payments_new_card" = "New Card...";
-"lng_payments_payment_method_ph" = "Enter your card details";
-"lng_payments_shipping_address" = "Shipping Information";
-"lng_payments_shipping_address_ph" = "Enter your shipping information";
+"lng_payments_shipping_address" = "Shipping Address";
+"lng_payments_receiver_information" = "Receiver";
+"lng_payments_address_street1" = "Address 1";
+"lng_payments_address_street2" = "Address 2";
+"lng_payments_address_city" = "City";
+"lng_payments_address_state" = "State";
+"lng_payments_address_country" = "Country";
+"lng_payments_address_postcode" = "Postcode";
+
"lng_payments_shipping_method" = "Shipping Method";
-"lng_payments_shipping_method_ph" = "Choose your shipping method";
"lng_payments_info_name" = "Name";
-"lng_payments_info_name_ph" = "Enter your name";
"lng_payments_info_email" = "Email";
-"lng_payments_info_email_ph" = "Enter your email";
"lng_payments_info_phone" = "Phone";
-"lng_payments_info_phone_ph" = "Enter your phone number";
"lng_payments_shipping_address_title" = "Shipping Address";
"lng_payments_save_shipping_about" = "You can save your shipping information for future use.";
-"lng_payments_payment_card" = "Payment Card";
-"lng_payments_cardholder_title" = "Cardholder";
-"lng_payments_cardholder_about" = "Cardholder Name";
-"lng_payments_billing_address" = "Billing Address";
-"lng_payments_zip_code" = "Zip Code";
+"lng_payments_card_title" = "New Card";
+"lng_payments_card_number" = "Card Number";
+"lng_payments_card_holder" = "Cardholder name";
+"lng_payments_billing_address" = "Billing Information";
+"lng_payments_billing_country" = "Country";
+"lng_payments_billing_zip_code" = "Zip Code";
"lng_payments_save_payment_about" = "You can save your payment information for future use.";
"lng_payments_save_information" = "Save Information";
diff --git a/Telegram/SourceFiles/payments/payments_checkout_process.cpp b/Telegram/SourceFiles/payments/payments_checkout_process.cpp
index d6ae27bb5a..5b7287066f 100644
--- a/Telegram/SourceFiles/payments/payments_checkout_process.cpp
+++ b/Telegram/SourceFiles/payments/payments_checkout_process.cpp
@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_domain.h"
#include "history/history_item.h"
#include "history/history.h"
+#include "data/data_user.h" // UserData::isBot.
#include "core/local_url_handlers.h" // TryConvertUrlToLocal.
#include "core/file_utilities.h" // File::OpenUrl.
#include "apiwrap.h"
@@ -105,6 +106,8 @@ void CheckoutProcess::handleFormUpdate(const FormUpdate &update) {
if (!_initialSilentValidation) {
showForm();
}
+ }, [&](const ThumbnailUpdated &data) {
+ _panel->updateFormThumbnail(data.thumbnail);
}, [&](const ValidateFinished &) {
if (_initialSilentValidation) {
_initialSilentValidation = false;
@@ -114,16 +117,16 @@ void CheckoutProcess::handleFormUpdate(const FormUpdate &update) {
_submitState = SubmitState::Validated;
panelSubmit();
}
- }, [&](const PaymentMethodUpdate&) {
+ }, [&](const PaymentMethodUpdate &) {
showForm();
- }, [&](const VerificationNeeded &info) {
- if (!_panel->showWebview(info.url, false)) {
- File::OpenUrl(info.url);
+ }, [&](const VerificationNeeded &data) {
+ if (!_panel->showWebview(data.url, false)) {
+ File::OpenUrl(data.url);
panelCloseSure();
}
- }, [&](const PaymentFinished &result) {
+ }, [&](const PaymentFinished &data) {
const auto weak = base::make_weak(this);
- _session->api().applyUpdates(result.updates);
+ _session->api().applyUpdates(data.updates);
if (weak) {
panelCloseSure();
}
diff --git a/Telegram/SourceFiles/payments/payments_form.cpp b/Telegram/SourceFiles/payments/payments_form.cpp
index b6ad2c95e6..6114bcb651 100644
--- a/Telegram/SourceFiles/payments/payments_form.cpp
+++ b/Telegram/SourceFiles/payments/payments_form.cpp
@@ -9,10 +9,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "data/data_session.h"
-#include "apiwrap.h"
+#include "data/data_media_types.h"
+#include "data/data_user.h"
+#include "data/data_photo.h"
+#include "data/data_photo_media.h"
+#include "data/data_file_origin.h"
+#include "history/history_item.h"
#include "stripe/stripe_api_client.h"
#include "stripe/stripe_error.h"
#include "stripe/stripe_token.h"
+#include "ui/image/image.h"
+#include "apiwrap.h"
+#include "styles/style_payments.h" // paymentsThumbnailSize.
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
@@ -82,15 +90,110 @@ namespace {
Form::Form(not_null<Main::Session*> session, FullMsgId itemId)
: _session(session)
, _api(&_session->mtp())
-, _msgId(itemId.msg) {
+, _msgId(itemId) {
+ fillInvoiceFromMessage();
requestForm();
}
Form::~Form() = default;
+void Form::fillInvoiceFromMessage() {
+ if (const auto item = _session->data().message(_msgId)) {
+ if (const auto media = item->media()) {
+ if (const auto invoice = media->invoice()) {
+ _invoice.cover = Ui::Cover{
+ .title = invoice->title,
+ .description = invoice->description,
+ };
+ if (const auto photo = invoice->photo) {
+ loadThumbnail(photo);
+ }
+ }
+ }
+ }
+}
+
+void Form::loadThumbnail(not_null<PhotoData*> photo) {
+ Expects(!_thumbnailLoadProcess);
+
+ auto view = photo->createMediaView();
+ if (auto good = prepareGoodThumbnail(view); !good.isNull()) {
+ _invoice.cover.thumbnail = std::move(good);
+ return;
+ }
+ _thumbnailLoadProcess = std::make_unique<ThumbnailLoadProcess>();
+ if (auto blurred = prepareBlurredThumbnail(view); !blurred.isNull()) {
+ _invoice.cover.thumbnail = std::move(blurred);
+ _thumbnailLoadProcess->blurredSet = true;
+ } else {
+ _invoice.cover.thumbnail = prepareEmptyThumbnail();
+ }
+ _thumbnailLoadProcess->view = std::move(view);
+ photo->load(Data::PhotoSize::Thumbnail, _msgId);
+ _session->downloaderTaskFinished(
+ ) | rpl::start_with_next([=] {
+ const auto &view = _thumbnailLoadProcess->view;
+ if (auto good = prepareGoodThumbnail(view); !good.isNull()) {
+ _invoice.cover.thumbnail = std::move(good);
+ _thumbnailLoadProcess = nullptr;
+ } else if (_thumbnailLoadProcess->blurredSet) {
+ return;
+ } else if (auto blurred = prepareBlurredThumbnail(view)
+ ; !blurred.isNull()) {
+ _invoice.cover.thumbnail = std::move(blurred);
+ _thumbnailLoadProcess->blurredSet = true;
+ } else {
+ return;
+ }
+ _updates.fire(ThumbnailUpdated{ _invoice.cover.thumbnail });
+ }, _thumbnailLoadProcess->lifetime);
+}
+
+QImage Form::prepareGoodThumbnail(
+ const std::shared_ptr<Data::PhotoMedia> &view) const {
+ using Size = Data::PhotoSize;
+ if (const auto large = view->image(Size::Large)) {
+ return prepareThumbnail(large);
+ } else if (const auto thumbnail = view->image(Size::Thumbnail)) {
+ return prepareThumbnail(thumbnail);
+ }
+ return QImage();
+}
+
+QImage Form::prepareBlurredThumbnail(
+ const std::shared_ptr<Data::PhotoMedia> &view) const {
+ if (const auto small = view->image(Data::PhotoSize::Small)) {
+ return prepareThumbnail(small, true);
+ } else if (const auto blurred = view->thumbnailInline()) {
+ return prepareThumbnail(blurred, true);
+ }
+ return QImage();
+}
+
+QImage Form::prepareThumbnail(
+ not_null<const Image*> image,
+ bool blurred) const {
+ auto result = image->original().scaled(
+ st::paymentsThumbnailSize * cIntRetinaFactor(),
+ Qt::KeepAspectRatio,
+ Qt::SmoothTransformation);
+ Images::prepareRound(result, ImageRoundRadius::Large);
+ result.setDevicePixelRatio(cRetinaFactor());
+ return result;
+}
+
+QImage Form::prepareEmptyThumbnail() const {
+ auto result = QImage(
+ st::paymentsThumbnailSize * cIntRetinaFactor(),
+ QImage::Format_ARGB32_Premultiplied);
+ result.setDevicePixelRatio(cRetinaFactor());
+ result.fill(Qt::transparent);
+ return result;
+}
+
void Form::requestForm() {
_api.request(MTPpayments_GetPaymentForm(
- MTP_int(_msgId)
+ MTP_int(_msgId.msg)
)).done([=](const MTPpayments_PaymentForm &result) {
result.match([&](const auto &data) {
processForm(data);
@@ -123,6 +226,8 @@ void Form::processForm(const MTPDpayments_paymentForm &data) {
void Form::processInvoice(const MTPDinvoice &data) {
_invoice = Ui::Invoice{
+ .cover = std::move(_invoice.cover),
+
.prices = ParsePrices(data.vprices()),
.currency = qs(data.vcurrency()),
@@ -154,6 +259,11 @@ void Form::processDetails(const MTPDpayments_paymentForm &data) {
.canSaveCredentials = data.is_can_save_credentials(),
.passwordMissing = data.is_password_missing(),
};
+ if (_details.botId) {
+ if (const auto bot = _session->data().userLoaded(_details.botId)) {
+ _invoice.cover.seller = bot->name;
+ }
+ }
}
void Form::processSavedInformation(const MTPDpaymentRequestedInfo &data) {
@@ -240,7 +350,7 @@ void Form::submit() {
| (_shippingOptions.selectedId.isEmpty()
? Flag(0)
: Flag::f_shipping_option_id)),
- MTP_int(_msgId),
+ MTP_int(_msgId.msg),
MTP_string(_requestedInformationId),
MTP_string(_shippingOptions.selectedId),
MTP_inputPaymentCredentials(
@@ -267,7 +377,7 @@ void Form::validateInformation(const Ui::RequestedInformation &information) {
_validatedInformation = information;
_validateRequestId = _api.request(MTPpayments_ValidateRequestedInfo(
MTP_flags(0), // #TODO payments save information
- MTP_int(_msgId),
+ MTP_int(_msgId.msg),
Serialize(information)
)).done([=](const MTPpayments_ValidatedRequestedInfo &result) {
_validateRequestId = 0;
diff --git a/Telegram/SourceFiles/payments/payments_form.h b/Telegram/SourceFiles/payments/payments_form.h
index 7fbbe6c2a3..803dd4b3fa 100644
--- a/Telegram/SourceFiles/payments/payments_form.h
+++ b/Telegram/SourceFiles/payments/payments_form.h
@@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/weak_ptr.h"
#include "mtproto/sender.h"
+class Image;
+
namespace Stripe {
class APIClient;
} // namespace Stripe
@@ -19,6 +21,10 @@ namespace Main {
class Session;
} // namespace Main
+namespace Data {
+class PhotoMedia;
+} // namespace Data
+
namespace Payments {
struct FormDetails {
@@ -38,6 +44,12 @@ struct FormDetails {
}
};
+struct ThumbnailLoadProcess {
+ std::shared_ptr<Data::PhotoMedia> view;
+ bool blurredSet = false;
+ rpl::lifetime lifetime;
+};
+
struct SavedCredentials {
QString id;
QString title;
@@ -88,6 +100,9 @@ struct PaymentMethod {
};
struct FormReady {};
+struct ThumbnailUpdated {
+ QImage thumbnail;
+};
struct ValidateFinished {};
struct PaymentMethodUpdate {};
struct VerificationNeeded {
@@ -109,6 +124,7 @@ struct Error {
struct FormUpdate : std::variant<
FormReady,
+ ThumbnailUpdated,
ValidateFinished,
PaymentMethodUpdate,
VerificationNeeded,
@@ -149,6 +165,18 @@ public:
void submit();
private:
+ void fillInvoiceFromMessage();
+
+ void loadThumbnail(not_null<PhotoData*> photo);
+ [[nodiscard]] QImage prepareGoodThumbnail(
+ const std::shared_ptr<Data::PhotoMedia> &view) const;
+ [[nodiscard]] QImage prepareBlurredThumbnail(
+ const std::shared_ptr<Data::PhotoMedia> &view) const;
+ [[nodiscard]] QImage prepareThumbnail(
+ not_null<const Image*> image,
+ bool blurred = false) const;
+ [[nodiscard]] QImage prepareEmptyThumbnail() const;
+
void requestForm();
void processForm(const MTPDpayments_paymentForm &data);
void processInvoice(const MTPDinvoice &data);
@@ -167,9 +195,10 @@ private:
const not_null<Main::Session*> _session;
MTP::Sender _api;
- MsgId _msgId = 0;
+ FullMsgId _msgId;
Ui::Invoice _invoice;
+ std::unique_ptr<ThumbnailLoadProcess> _thumbnailLoadProcess;
FormDetails _details;
Ui::RequestedInformation _savedInformation;
PaymentMethod _paymentMethod;
diff --git a/Telegram/SourceFiles/payments/ui/payments.style b/Telegram/SourceFiles/payments/ui/payments.style
index d331d30336..811f70160b 100644
--- a/Telegram/SourceFiles/payments/ui/payments.style
+++ b/Telegram/SourceFiles/payments/ui/payments.style
@@ -7,12 +7,52 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
using "ui/basic.style";
-using "passport/passport.style";
+using "info/info.style";
-paymentsFormPricePadding: margins(22px, 7px, 22px, 6px);
-paymentsPanelSubmit: RoundButton(passportPasswordSubmit) {
+paymentsPanelSubmit: RoundButton(defaultActiveButton) {
width: 0px;
height: 49px;
padding: margins(0px, -3px, 0px, 0px);
textTop: 16px;
}
+
+paymentsCoverPadding: margins(26px, 0px, 26px, 13px);
+paymentsDescription: FlatLabel(defaultFlatLabel) {
+ minWidth: 160px;
+ textFg: windowFg;
+}
+paymentsTitle: FlatLabel(paymentsDescription) {
+ style: semiboldTextStyle;
+}
+paymentsSeller: FlatLabel(paymentsDescription) {
+ textFg: windowSubTextFg;
+}
+paymentsPriceLabel: paymentsDescription;
+paymentsPriceAmount: defaultFlatLabel;
+paymentsFullPriceLabel: paymentsTitle;
+paymentsFullPriceAmount: FlatLabel(defaultFlatLabel) {
+ style: semiboldTextStyle;
+}
+
+paymentsTitleTop: 0px;
+paymentsDescriptionTop: 3px;
+paymentsSellerTop: 4px;
+
+paymentsThumbnailSize: size(80px, 80px);
+paymentsThumbnailSkip: 18px;
+
+paymentsPricesTopSkip: 12px;
+paymentsPricesBottomSkip: 13px;
+paymentsPricePadding: margins(28px, 6px, 28px, 5px);
+
+paymentsSectionsTopSkip: 11px;
+paymentsSectionButton: SettingsButton(infoProfileButton) {
+ padding: margins(68px, 11px, 14px, 9px);
+}
+
+paymentsIconPaymentMethod: icon {{ "payments/payment_card", menuIconFg }};
+paymentsIconShippingAddress: icon {{ "payments/payment_address", menuIconFg }};
+paymentsIconName: icon {{ "payments/payment_name", menuIconFg }};
+paymentsIconEmail: icon {{ "payments/payment_email", menuIconFg }};
+paymentsIconPhone: icon {{ "payments/payment_phone", menuIconFg }};
+paymentsIconShippingMethod: icon {{ "payments/payment_shipping", menuIconFg }};
diff --git a/Telegram/SourceFiles/payments/ui/payments_form_summary.cpp b/Telegram/SourceFiles/payments/ui/payments_form_summary.cpp
index dfcee629e4..0f63805bee 100644
--- a/Telegram/SourceFiles/payments/ui/payments_form_summary.cpp
+++ b/Telegram/SourceFiles/payments/ui/payments_form_summary.cpp
@@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "payments/ui/payments_form_summary.h"
#include "payments/ui/payments_panel_delegate.h"
-#include "passport/ui/passport_form_row.h"
+#include "settings/settings_common.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
@@ -22,7 +22,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Payments::Ui {
using namespace ::Ui;
-using namespace Passport::Ui;
class PanelDelegate;
@@ -45,16 +44,24 @@ FormSummary::FormSummary(
this,
tr::lng_payments_pay_amount(
lt_amount,
- rpl::single(computeTotalAmount())),
+ rpl::single(formatAmount(computeTotalAmount()))),
st::paymentsPanelSubmit) {
setupControls();
}
-QString FormSummary::computeAmount(int64 amount) const {
- return FillAmountAndCurrency(amount, _invoice.currency);
+void FormSummary::updateThumbnail(const QImage &thumbnail) {
+ _invoice.cover.thumbnail = thumbnail;
+ _thumbnails.fire_copy(thumbnail);
}
-QString FormSummary::computeTotalAmount() const {
+QString FormSummary::formatAmount(int64 amount) const {
+ const auto base = FillAmountAndCurrency(
+ std::abs(amount),
+ _invoice.currency);
+ return (amount > 0) ? base : (QString::fromUtf8("\xe2\x88\x92") + base);
+}
+
+int64 FormSummary::computeTotalAmount() const {
const auto total = ranges::accumulate(
_invoice.prices,
int64(0),
@@ -71,7 +78,7 @@ QString FormSummary::computeTotalAmount() const {
std::plus<>(),
&LabeledPrice::price)
: int64(0);
- return computeAmount(total + shipping);
+ return total + shipping;
}
void FormSummary::setupControls() {
@@ -92,22 +99,125 @@ void FormSummary::setupControls() {
_1 + _2 < _3));
}
-not_null<Ui::RpWidget*> FormSummary::setupContent() {
- const auto inner = _scroll->setOwnedWidget(
- object_ptr<Ui::VerticalLayout>(this));
+void FormSummary::setupCover(not_null<VerticalLayout*> layout) {
+ struct State {
+ QImage thumbnail;
+ FlatLabel *title = nullptr;
+ FlatLabel *description = nullptr;
+ FlatLabel *seller = nullptr;
+ };
- _scroll->widthValue(
- ) | rpl::start_with_next([=](int width) {
- inner->resizeToWidth(width);
- }, inner->lifetime());
+ const auto cover = layout->add(object_ptr<RpWidget>(layout));
+ const auto state = cover->lifetime().make_state<State>();
+ state->title = CreateChild<FlatLabel>(
+ cover,
+ _invoice.cover.title,
+ st::paymentsTitle);
+ state->description = CreateChild<FlatLabel>(
+ cover,
+ _invoice.cover.description,
+ st::paymentsDescription);
+ state->seller = CreateChild<FlatLabel>(
+ cover,
+ _invoice.cover.seller,
+ st::paymentsSeller);
+ cover->paintRequest(
+ ) | rpl::start_with_next([=](QRect clip) {
+ if (state->thumbnail.isNull()) {
+ return;
+ }
+ const auto &padding = st::paymentsCoverPadding;
+ const auto thumbnailSkip = st::paymentsThumbnailSize.width()
+ + st::paymentsThumbnailSkip;
+ const auto left = padding.left();
+ const auto top = padding.top();
+ const auto rect = QRect(
+ QPoint(left, top),
+ state->thumbnail.size() / state->thumbnail.devicePixelRatio());
+ if (rect.intersects(clip)) {
+ QPainter(cover).drawImage(rect, state->thumbnail);
+ }
+ }, cover->lifetime());
+ rpl::combine(
+ cover->widthValue(),
+ _thumbnails.events_starting_with_copy(_invoice.cover.thumbnail)
+ ) | rpl::start_with_next([=](int width, QImage &&thumbnail) {
+ const auto &padding = st::paymentsCoverPadding;
+ const auto thumbnailSkip = st::paymentsThumbnailSize.width()
+ + st::paymentsThumbnailSkip;
+ const auto left = padding.left()
+ + (thumbnail.isNull() ? 0 : thumbnailSkip);
+ const auto available = width
+ - padding.left()
+ - padding.right()
+ - (thumbnail.isNull() ? 0 : thumbnailSkip);
+ state->title->resizeToNaturalWidth(available);
+ state->title->moveToLeft(
+ left,
+ padding.top() + st::paymentsTitleTop);
+ state->description->resizeToNaturalWidth(available);
+ state->description->moveToLeft(
+ left,
+ (state->title->y()
+ + state->title->height()
+ + st::paymentsDescriptionTop));
+ state->seller->resizeToNaturalWidth(available);
+ state->seller->moveToLeft(
+ left,
+ (state->description->y()
+ + state->description->height()
+ + st::paymentsSellerTop));
+ const auto thumbnailHeight = padding.top()
+ + (thumbnail.isNull()
+ ? 0
+ : int(thumbnail.height() / thumbnail.devicePixelRatio()))
+ + padding.bottom();
+ const auto height = state->seller->y()
+ + state->seller->height()
+ + padding.bottom();
+ cover->resize(width, std::max(thumbnailHeight, height));
+ state->thumbnail = std::move(thumbnail);
+ cover->update();
+ }, cover->lifetime());
+}
+void FormSummary::setupPrices(not_null<VerticalLayout*> layout) {
+ Settings::AddSkip(layout, st::paymentsPricesTopSkip);
+ const auto add = [&](
+ const QString &label,
+ int64 amount,
+ bool full = false) {
+ const auto &st = full
+ ? st::paymentsFullPriceAmount
+ : st::paymentsPriceAmount;
+ const auto right = CreateChild<FlatLabel>(
+ layout.get(),
+ formatAmount(amount),
+ st);
+ const auto &padding = st::paymentsPricePadding;
+ const auto left = layout->add(
+ object_ptr<FlatLabel>(
+ layout,
+ label,
+ (full
+ ? st::paymentsFullPriceLabel
+ : st::paymentsPriceLabel)),
+ style::margins(
+ padding.left(),
+ padding.top(),
+ (padding.right()
+ + right->naturalWidth()
+ + 2 * st.style.font->spacew),
+ padding.bottom()));
+ rpl::combine(
+ left->topValue(),
+ layout->widthValue()
+ ) | rpl::start_with_next([=](int top, int width) {
+ right->moveToRight(st::paymentsPricePadding.right(), top, width);
+ }, right->lifetime());
+ };
for (const auto &price : _invoice.prices) {
- inner->add(
- object_ptr<Ui::FlatLabel>(
- inner,
- price.label + ": " + computeAmount(price.price),
- st::passportFormPolicy),
- st::paymentsFormPricePadding);
+ add(price.label, price.price);
}
const auto selected = ranges::find(
_options.list,
@@ -115,44 +225,35 @@ not_null<Ui::RpWidget*> FormSummary::setupContent() {
&ShippingOption::id);
if (selected != end(_options.list)) {
for (const auto &price : selected->prices) {
- inner->add(
- object_ptr<Ui::FlatLabel>(
- inner,
- price.label + ": " + computeAmount(price.price),
- st::passportFormPolicy),
- st::paymentsFormPricePadding);
+ add(price.label, price.price);
}
}
- inner->add(
- object_ptr<Ui::FlatLabel>(
- inner,
- "Total: " + computeTotalAmount(),
- st::passportFormHeader),
- st::passportFormHeaderPadding);
-
- inner->add(
- object_ptr<Ui::BoxContentDivider>(
- inner,
- st::passportFormDividerHeight),
- { 0, 0, 0, st::passportFormHeaderPadding.top() });
-
- const auto method = inner->add(object_ptr<FormRow>(inner));
- method->addClickHandler([=] {
- _delegate->panelEditPaymentMethod();
- });
- method->updateContent(
- tr::lng_payments_payment_method(tr::now),
- (_method.ready
- ? _method.title
- : tr::lng_payments_payment_method_ph(tr::now)),
- _method.ready,
- false,
- anim::type::instant);
+ add(tr::lng_payments_total_label(tr::now), computeTotalAmount(), true);
+ Settings::AddSkip(layout, st::paymentsPricesBottomSkip);
+}
+
+void FormSummary::setupSections(not_null<VerticalLayout*> layout) {
+ Settings::AddSkip(layout, st::paymentsSectionsTopSkip);
+
+ const auto add = [&](
+ rpl::producer<QString> title,
+ const QString &label,
+ const style::icon *icon,
+ Fn<void()> handler) {
+ Settings::AddButtonWithLabel(
+ layout,
+ std::move(title),
+ rpl::single(label),
+ st::paymentsSectionButton,
+ icon
+ )->addClickHandler(std::move(handler));
+ };
+ add(
+ tr::lng_payments_payment_method(),
+ _method.title,
+ &st::paymentsIconPaymentMethod,
+ [=] { _delegate->panelEditPaymentMethod(); });
if (_invoice.isShippingAddressRequested) {
- const auto info = inner->add(object_ptr<FormRow>(inner));
- info->addClickHandler([=] {
- _delegate->panelEditShippingInformation();
- });
auto list = QStringList();
const auto push = [&](const QString &value) {
if (!value.isEmpty()) {
@@ -165,65 +266,61 @@ not_null<Ui::RpWidget*> FormSummary::setupContent() {
push(_information.shippingAddress.state);
push(_information.shippingAddress.countryIso2);
push(_information.shippingAddress.postcode);
- info->updateContent(
- tr::lng_payments_shipping_address(tr::now),
- (list.isEmpty()
- ? tr::lng_payments_shipping_address_ph(tr::now)
- : list.join(", ")),
- !list.isEmpty(),
- false,
- anim::type::instant);
+ add(
+ tr::lng_payments_shipping_address(),
+ list.join(", "),
+ &st::paymentsIconShippingAddress,
+ [=] { _delegate->panelEditShippingInformation(); });
}
if (!_options.list.empty()) {
- const auto options = inner->add(object_ptr<FormRow>(inner));
- options->addClickHandler([=] {
- _delegate->panelChooseShippingOption();
- });
- options->updateContent(
- tr::lng_payments_shipping_method(tr::now),
- (selected != end(_options.list)
- ? selected->title
- : tr::lng_payments_shipping_method_ph(tr::now)),
- (selected != end(_options.list)),
- false,
- anim::type::instant);
+ const auto selected = ranges::find(
+ _options.list,
+ _options.selectedId,
+ &ShippingOption::id);
+ add(
+ tr::lng_payments_shipping_method(),
+ (selected != end(_options.list)) ? selected->title : QString(),
+ &st::paymentsIconShippingMethod,
+ [=] { _delegate->panelChooseShippingOption(); });
}
if (_invoice.