From 619f70ab22cc62fa0e6347da8ba0aca8b19a170d Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 30 Mar 2021 21:18:39 +0400 Subject: [PATCH] Improve design of shipping option selection. --- Telegram/Resources/langs/lang.strings | 2 +- .../SourceFiles/payments/payments_form.cpp | 7 +- .../SourceFiles/payments/ui/payments.style | 11 +++ .../payments/ui/payments_edit_information.cpp | 8 ++ .../payments/ui/payments_edit_information.h | 2 + .../payments/ui/payments_form_summary.cpp | 13 ++-- .../payments/ui/payments_panel.cpp | 75 +++++++++++++++---- .../payments/ui/payments_panel_data.h | 2 + .../SourceFiles/ui/text/format_values.cpp | 11 ++- 9 files changed, 107 insertions(+), 24 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 97cab33a9..00d88d43c 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1888,7 +1888,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "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"; +"lng_payments_save_information" = "Save Information for future use"; "lng_payments_tips_label" = "Tips"; "lng_payments_tips_title" = "Tips"; "lng_payments_tips_enter" = "Enter tips amount"; diff --git a/Telegram/SourceFiles/payments/payments_form.cpp b/Telegram/SourceFiles/payments/payments_form.cpp index ff9084857..62c671a8c 100644 --- a/Telegram/SourceFiles/payments/payments_form.cpp +++ b/Telegram/SourceFiles/payments/payments_form.cpp @@ -487,8 +487,9 @@ void Form::validateInformation(const Ui::RequestedInformation &information) { Assert(!_invoice.isEmailRequested || !information.email.isEmpty()); Assert(!_invoice.isPhoneRequested || !information.phone.isEmpty()); + using Flag = MTPpayments_ValidateRequestedInfo::Flag; _validateRequestId = _api.request(MTPpayments_ValidateRequestedInfo( - MTP_flags(0), // #TODO payments save information + MTP_flags(information.save ? Flag::f_save : Flag(0)), _peer->input, MTP_int(_msgId), Serialize(information) @@ -684,7 +685,8 @@ void Form::setTips(int64 value) { } void Form::processShippingOptions(const QVector &data) { - _shippingOptions = Ui::ShippingOptions{ ranges::views::all( + const auto currency = _invoice.currency; + _shippingOptions = Ui::ShippingOptions{ currency, ranges::views::all( data ) | ranges::views::transform([](const MTPShippingOption &option) { return option.match([](const MTPDshippingOption &data) { @@ -695,6 +697,7 @@ void Form::processShippingOptions(const QVector &data) { }; }); }) | ranges::to_vector }; + _shippingOptions.currency = _invoice.currency; } } // namespace Payments diff --git a/Telegram/SourceFiles/payments/ui/payments.style b/Telegram/SourceFiles/payments/ui/payments.style index 20e44354a..d6931c82f 100644 --- a/Telegram/SourceFiles/payments/ui/payments.style +++ b/Telegram/SourceFiles/payments/ui/payments.style @@ -59,6 +59,7 @@ paymentsIconShippingMethod: icon {{ "payments/payment_shipping", menuIconFg }}; paymentsField: defaultInputField; paymentsFieldPadding: margins(28px, 0px, 28px, 2px); +paymentsSaveCheckboxPadding: margins(28px, 20px, 28px, 8px); paymentsExpireCvcSkip: 34px; paymentsBillingInformationTitle: FlatLabel(defaultFlatLabel) { @@ -67,3 +68,13 @@ paymentsBillingInformationTitle: FlatLabel(defaultFlatLabel) { minWidth: 240px; } paymentsBillingInformationTitlePadding: margins(28px, 26px, 28px, 1px); + +paymentsShippingMargin: margins(27px, 11px, 27px, 20px); +paymentsShippingLabel: FlatLabel(defaultFlatLabel) { + style: boxTextStyle; +} +paymentsShippingPrice: FlatLabel(defaultFlatLabel) { + textFg: windowSubTextFg; +} +paymentsShippingLabelPosition: point(43px, 8px); +paymentsShippingPricePosition: point(43px, 29px); diff --git a/Telegram/SourceFiles/payments/ui/payments_edit_information.cpp b/Telegram/SourceFiles/payments/ui/payments_edit_information.cpp index d9b4f2562..b216d1d30 100644 --- a/Telegram/SourceFiles/payments/ui/payments_edit_information.cpp +++ b/Telegram/SourceFiles/payments/ui/payments_edit_information.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/scroll_area.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" +#include "ui/widgets/checkbox.h" #include "ui/wrap/vertical_layout.h" #include "ui/wrap/fade_wrap.h" #include "lang/lang_keys.h" @@ -168,6 +169,12 @@ not_null EditInformation::setupContent() { .defaultPhone = _information.defaultPhone, }); } + _save = inner->add( + object_ptr( + inner, + tr::lng_payments_save_information(tr::now), + true), + st::paymentsSaveCheckboxPadding); return inner; } @@ -212,6 +219,7 @@ RequestedInformation EditInformation::collect() const { return { .defaultPhone = _information.defaultPhone, .defaultCountry = _information.defaultCountry, + .save = _save->checked(), .name = _name ? _name->value() : QString(), .phone = _phone ? _phone->value() : QString(), .email = _email ? _email->value() : QString(), diff --git a/Telegram/SourceFiles/payments/ui/payments_edit_information.h b/Telegram/SourceFiles/payments/ui/payments_edit_information.h index 978b72b43..5864f8328 100644 --- a/Telegram/SourceFiles/payments/ui/payments_edit_information.h +++ b/Telegram/SourceFiles/payments/ui/payments_edit_information.h @@ -17,6 +17,7 @@ class FadeShadow; class RoundButton; class InputField; class MaskedInputField; +class Checkbox; } // namespace Ui namespace Payments::Ui { @@ -69,6 +70,7 @@ private: std::unique_ptr _name; std::unique_ptr _email; std::unique_ptr _phone; + Checkbox *_save = nullptr; InformationField _focusField = InformationField::ShippingStreet; diff --git a/Telegram/SourceFiles/payments/ui/payments_form_summary.cpp b/Telegram/SourceFiles/payments/ui/payments_form_summary.cpp index 6ee83fd83..8f441f6a7 100644 --- a/Telegram/SourceFiles/payments/ui/payments_form_summary.cpp +++ b/Telegram/SourceFiles/payments/ui/payments_form_summary.cpp @@ -22,6 +22,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_payments.h" #include "styles/style_passport.h" +namespace App { +QString formatPhone(QString phone); // #TODO +} // namespace App + namespace Payments::Ui { using namespace ::Ui; @@ -62,10 +66,7 @@ void FormSummary::updateThumbnail(const QImage &thumbnail) { } QString FormSummary::formatAmount(int64 amount) const { - const auto base = FillAmountAndCurrency( - std::abs(amount), - _invoice.currency); - return (amount < 0) ? (QString::fromUtf8("\xe2\x88\x92") + base) : base; + return FillAmountAndCurrency(amount, _invoice.currency); } int64 FormSummary::computeTotalAmount() const { @@ -352,7 +353,9 @@ void FormSummary::setupSections(not_null layout) { if (_invoice.isPhoneRequested) { add( tr::lng_payments_info_phone(), - _information.phone, + (_information.phone.isEmpty() + ? QString() + : App::formatPhone(_information.phone)), &st::paymentsIconPhone, [=] { _delegate->panelEditPhone(); }); } diff --git a/Telegram/SourceFiles/payments/ui/payments_panel.cpp b/Telegram/SourceFiles/payments/ui/payments_panel.cpp index 35ab4df37..48a19dea1 100644 --- a/Telegram/SourceFiles/payments/ui/payments_panel.cpp +++ b/Telegram/SourceFiles/payments/ui/payments_panel.cpp @@ -13,11 +13,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "payments/ui/payments_panel_delegate.h" #include "payments/ui/payments_field.h" #include "ui/widgets/separate_panel.h" +#include "ui/widgets/checkbox.h" #include "ui/boxes/single_choice_box.h" +#include "ui/text/format_values.h" #include "lang/lang_keys.h" #include "webview/webview_embed.h" #include "styles/style_payments.h" #include "styles/style_passport.h" +#include "styles/style_layers.h" namespace Payments::Ui { namespace { @@ -119,23 +122,69 @@ void Panel::showInformationError( void Panel::chooseShippingOption(const ShippingOptions &options) { showBox(Box([=](not_null box) { - auto list = options.list | ranges::views::transform( - &ShippingOption::title - ) | ranges::to_vector; const auto i = ranges::find( options.list, options.selectedId, &ShippingOption::id); - const auto save = [=](int option) { - _delegate->panelChangeShippingOption(options.list[option].id); - }; - SingleChoiceBox(box, { - .title = tr::lng_payments_shipping_method(), - .options = list, - .initialSelection = (i != end(options.list) - ? (i - begin(options.list)) - : -1), - .callback = save, + const auto index = (i != end(options.list)) + ? (i - begin(options.list)) + : -1; + const auto group = std::make_shared(index); + + const auto layout = box->verticalLayout(); + auto counter = 0; + for (const auto &option : options.list) { + const auto index = counter++; + const auto button = layout->add( + object_ptr( + layout, + group, + index, + QString(), + st::defaultBoxCheckbox, + st::defaultRadio), + st::paymentsShippingMargin); + const auto label = CreateChild( + layout.get(), + option.title, + st::paymentsShippingLabel); + const auto total = ranges::accumulate( + option.prices, + int64(0), + std::plus<>(), + &LabeledPrice::price); + const auto price = CreateChild( + layout.get(), + FillAmountAndCurrency(total, options.currency), + st::paymentsShippingPrice); + const auto area = CreateChild(layout.get()); + area->setClickedCallback([=] { group->setValue(index); }); + button->geometryValue( + ) | rpl::start_with_next([=](QRect geometry) { + label->move( + geometry.topLeft() + st::paymentsShippingLabelPosition); + price->move( + geometry.topLeft() + st::paymentsShippingPricePosition); + const auto right = geometry.x() + + st::paymentsShippingLabelPosition.x(); + area->setGeometry( + right, + geometry.y(), + std::max( + label->x() + label->width() - right, + price->x() + price->width() - right), + price->y() + price->height() - geometry.y()); + }, button->lifetime()); + } + + box->setTitle(tr::lng_payments_shipping_method()); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + group->setChangedCallback([=](int index) { + if (index >= 0) { + _delegate->panelChangeShippingOption( + options.list[index].id); + box->closeBox(); + } }); })); } diff --git a/Telegram/SourceFiles/payments/ui/payments_panel_data.h b/Telegram/SourceFiles/payments/ui/payments_panel_data.h index 13efeeff6..ce17f7c61 100644 --- a/Telegram/SourceFiles/payments/ui/payments_panel_data.h +++ b/Telegram/SourceFiles/payments/ui/payments_panel_data.h @@ -70,6 +70,7 @@ struct ShippingOption { }; struct ShippingOptions { + QString currency; std::vector list; QString selectedId; }; @@ -107,6 +108,7 @@ struct Address { struct RequestedInformation { QString defaultPhone; QString defaultCountry; + bool save = true; QString name; QString phone; diff --git a/Telegram/SourceFiles/ui/text/format_values.cpp b/Telegram/SourceFiles/ui/text/format_values.cpp index 7020b74b7..edcca777c 100644 --- a/Telegram/SourceFiles/ui/text/format_values.cpp +++ b/Telegram/SourceFiles/ui/text/format_values.cpp @@ -354,14 +354,19 @@ QString FillAmountAndCurrency(int64 amount, const QString ¤cy) { { u"XPF"_q, 0 }, { u"MRO"_q, 1 }, }; + + const auto prefix = (amount < 0) + ? QString::fromUtf8("\xe2\x88\x92") + : QString(); + const auto exponentIt = kExponents.find(currency); const auto exponent = (exponentIt != end(kExponents)) ? exponentIt->second : 2; - const auto value = amount / std::pow(10., exponent); + const auto value = std::abs(amount) / std::pow(10., exponent); const auto ruleIt = kRulesMap.find(currency); if (ruleIt == end(kRulesMap)) { - return QLocale::system().toCurrencyString(value, currency); + return prefix + QLocale::system().toCurrencyString(value, currency); } const auto &rule = ruleIt->second; const auto name = (*rule.international) @@ -376,7 +381,7 @@ QString FillAmountAndCurrency(int64 amount, const QString ¤cy) { || std::floor(value) != value) ? exponent : 0; - result.append(FormatWithSeparators( + result.append(prefix).append(FormatWithSeparators( value, precision, rule.decimal,