Improve design of shipping option selection.

This commit is contained in:
John Preston 2021-03-30 21:18:39 +04:00
parent 21b502c754
commit 619f70ab22
9 changed files with 107 additions and 24 deletions

View file

@ -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";

View file

@ -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<MTPShippingOption> &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<MTPShippingOption> &data) {
};
});
}) | ranges::to_vector };
_shippingOptions.currency = _invoice.currency;
}
} // namespace Payments

View file

@ -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);

View file

@ -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<RpWidget*> EditInformation::setupContent() {
.defaultPhone = _information.defaultPhone,
});
}
_save = inner->add(
object_ptr<Ui::Checkbox>(
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(),

View file

@ -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<Field> _name;
std::unique_ptr<Field> _email;
std::unique_ptr<Field> _phone;
Checkbox *_save = nullptr;
InformationField _focusField = InformationField::ShippingStreet;

View file

@ -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<VerticalLayout*> layout) {
if (_invoice.isPhoneRequested) {
add(
tr::lng_payments_info_phone(),
_information.phone,
(_information.phone.isEmpty()
? QString()
: App::formatPhone(_information.phone)),
&st::paymentsIconPhone,
[=] { _delegate->panelEditPhone(); });
}

View file

@ -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<Ui::GenericBox*> 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<Ui::RadiobuttonGroup>(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<Ui::Radiobutton>(
layout,
group,
index,
QString(),
st::defaultBoxCheckbox,
st::defaultRadio),
st::paymentsShippingMargin);
const auto label = CreateChild<FlatLabel>(
layout.get(),
option.title,
st::paymentsShippingLabel);
const auto total = ranges::accumulate(
option.prices,
int64(0),
std::plus<>(),
&LabeledPrice::price);
const auto price = CreateChild<FlatLabel>(
layout.get(),
FillAmountAndCurrency(total, options.currency),
st::paymentsShippingPrice);
const auto area = CreateChild<AbstractButton>(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();
}
});
}));
}

View file

@ -70,6 +70,7 @@ struct ShippingOption {
};
struct ShippingOptions {
QString currency;
std::vector<ShippingOption> list;
QString selectedId;
};
@ -107,6 +108,7 @@ struct Address {
struct RequestedInformation {
QString defaultPhone;
QString defaultCountry;
bool save = true;
QString name;
QString phone;

View file

@ -354,14 +354,19 @@ QString FillAmountAndCurrency(int64 amount, const QString &currency) {
{ 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 &currency) {
|| std::floor(value) != value)
? exponent
: 0;
result.append(FormatWithSeparators(
result.append(prefix).append(FormatWithSeparators(
value,
precision,
rule.decimal,