Improve checkout information / card page design.
This commit is contained in:
parent
fafea73ea7
commit
47fdef1e38
|
@ -1866,7 +1866,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_payments_payment_method" = "Payment Method";
|
"lng_payments_payment_method" = "Payment Method";
|
||||||
"lng_payments_new_card" = "New Card...";
|
"lng_payments_new_card" = "New Card...";
|
||||||
"lng_payments_shipping_address" = "Shipping Address";
|
"lng_payments_shipping_address" = "Shipping Address";
|
||||||
"lng_payments_receiver_information" = "Receiver";
|
|
||||||
"lng_payments_address_street1" = "Address 1";
|
"lng_payments_address_street1" = "Address 1";
|
||||||
"lng_payments_address_street2" = "Address 2";
|
"lng_payments_address_street2" = "Address 2";
|
||||||
"lng_payments_address_city" = "City";
|
"lng_payments_address_city" = "City";
|
||||||
|
@ -1878,7 +1877,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_payments_info_name" = "Name";
|
"lng_payments_info_name" = "Name";
|
||||||
"lng_payments_info_email" = "Email";
|
"lng_payments_info_email" = "Email";
|
||||||
"lng_payments_info_phone" = "Phone";
|
"lng_payments_info_phone" = "Phone";
|
||||||
"lng_payments_shipping_address_title" = "Shipping Address";
|
"lng_payments_shipping_address_title" = "Shipping Information";
|
||||||
"lng_payments_save_shipping_about" = "You can save your shipping information for future use.";
|
"lng_payments_save_shipping_about" = "You can save your shipping information for future use.";
|
||||||
"lng_payments_card_title" = "New Card";
|
"lng_payments_card_title" = "New Card";
|
||||||
"lng_payments_card_number" = "Card Number";
|
"lng_payments_card_number" = "Card Number";
|
||||||
|
|
|
@ -87,6 +87,7 @@ CheckoutProcess::CheckoutProcess(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
showForm();
|
showForm();
|
||||||
}, _panel->lifetime());
|
}, _panel->lifetime());
|
||||||
|
showForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckoutProcess::~CheckoutProcess() {
|
CheckoutProcess::~CheckoutProcess() {
|
||||||
|
@ -156,7 +157,7 @@ void CheckoutProcess::handleError(const Error &error) {
|
||||||
showToast({ "Error: " + id });
|
showToast({ "Error: " + id });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Error::Type::Validate:
|
case Error::Type::Validate: {
|
||||||
if (_submitState == SubmitState::Validation) {
|
if (_submitState == SubmitState::Validation) {
|
||||||
_submitState = SubmitState::None;
|
_submitState = SubmitState::None;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +190,21 @@ void CheckoutProcess::handleError(const Error &error) {
|
||||||
} else {
|
} else {
|
||||||
showToast({ "Error: " + id });
|
showToast({ "Error: " + id });
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
|
case Error::Type::Stripe: {
|
||||||
|
using Field = Ui::CardField;
|
||||||
|
if (id == u"InvalidNumber"_q || id == u"IncorrectNumber"_q) {
|
||||||
|
showCardError(Field::Number);
|
||||||
|
} else if (id == u"InvalidCVC"_q || id == u"IncorrectCVC"_q) {
|
||||||
|
showCardError(Field::CVC);
|
||||||
|
} else if (id == u"InvalidExpiryMonth"_q
|
||||||
|
|| id == u"InvalidExpiryYear"_q
|
||||||
|
|| id == u"ExpiredCard"_q) {
|
||||||
|
showCardError(Field::ExpireDate);
|
||||||
|
} else {
|
||||||
|
showToast({ "Error: " + id });
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case Error::Type::Send:
|
case Error::Type::Send:
|
||||||
if (_submitState == SubmitState::Finishing) {
|
if (_submitState == SubmitState::Finishing) {
|
||||||
_submitState = SubmitState::None;
|
_submitState = SubmitState::None;
|
||||||
|
@ -375,6 +390,13 @@ void CheckoutProcess::showInformationError(Ui::InformationField field) {
|
||||||
field);
|
field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckoutProcess::showCardError(Ui::CardField field) {
|
||||||
|
if (_submitState != SubmitState::None) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_panel->showCardError(_form->paymentMethod().ui.native, field);
|
||||||
|
}
|
||||||
|
|
||||||
void CheckoutProcess::chooseShippingOption() {
|
void CheckoutProcess::chooseShippingOption() {
|
||||||
_panel->chooseShippingOption(_form->shippingOptions());
|
_panel->chooseShippingOption(_form->shippingOptions());
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ class Session;
|
||||||
namespace Payments::Ui {
|
namespace Payments::Ui {
|
||||||
class Panel;
|
class Panel;
|
||||||
enum class InformationField;
|
enum class InformationField;
|
||||||
|
enum class CardField;
|
||||||
} // namespace Payments::Ui
|
} // namespace Payments::Ui
|
||||||
|
|
||||||
namespace Payments {
|
namespace Payments {
|
||||||
|
@ -58,6 +59,7 @@ private:
|
||||||
void showForm();
|
void showForm();
|
||||||
void showEditInformation(Ui::InformationField field);
|
void showEditInformation(Ui::InformationField field);
|
||||||
void showInformationError(Ui::InformationField field);
|
void showInformationError(Ui::InformationField field);
|
||||||
|
void showCardError(Ui::CardField field);
|
||||||
void chooseShippingOption();
|
void chooseShippingOption();
|
||||||
void editPaymentMethod();
|
void editPaymentMethod();
|
||||||
|
|
||||||
|
|
|
@ -56,3 +56,14 @@ paymentsIconName: icon {{ "payments/payment_name", menuIconFg }};
|
||||||
paymentsIconEmail: icon {{ "payments/payment_email", menuIconFg }};
|
paymentsIconEmail: icon {{ "payments/payment_email", menuIconFg }};
|
||||||
paymentsIconPhone: icon {{ "payments/payment_phone", menuIconFg }};
|
paymentsIconPhone: icon {{ "payments/payment_phone", menuIconFg }};
|
||||||
paymentsIconShippingMethod: icon {{ "payments/payment_shipping", menuIconFg }};
|
paymentsIconShippingMethod: icon {{ "payments/payment_shipping", menuIconFg }};
|
||||||
|
|
||||||
|
paymentsField: defaultInputField;
|
||||||
|
paymentsFieldPadding: margins(28px, 0px, 28px, 2px);
|
||||||
|
paymentsExpireCvcSkip: 34px;
|
||||||
|
|
||||||
|
paymentsBillingInformationTitle: FlatLabel(defaultFlatLabel) {
|
||||||
|
style: semiboldTextStyle;
|
||||||
|
textFg: windowActiveTextFg;
|
||||||
|
minWidth: 240px;
|
||||||
|
}
|
||||||
|
paymentsBillingInformationTitlePadding: margins(28px, 26px, 28px, 1px);
|
||||||
|
|
|
@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "payments/ui/payments_edit_card.h"
|
#include "payments/ui/payments_edit_card.h"
|
||||||
|
|
||||||
#include "payments/ui/payments_panel_delegate.h"
|
#include "payments/ui/payments_panel_delegate.h"
|
||||||
#include "passport/ui/passport_details_row.h"
|
#include "payments/ui/payments_field.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
@ -52,16 +52,24 @@ EditCard::EditCard(
|
||||||
|
|
||||||
void EditCard::setFocus(CardField field) {
|
void EditCard::setFocus(CardField field) {
|
||||||
_focusField = field;
|
_focusField = field;
|
||||||
if (const auto control = controlForField(field)) {
|
if (const auto control = lookupField(field)) {
|
||||||
_scroll->ensureWidgetVisible(control);
|
_scroll->ensureWidgetVisible(control->widget());
|
||||||
|
control->setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCard::setFocusFast(CardField field) {
|
||||||
|
_focusField = field;
|
||||||
|
if (const auto control = lookupField(field)) {
|
||||||
|
_scroll->ensureWidgetVisible(control->widget());
|
||||||
control->setFocusFast();
|
control->setFocusFast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditCard::showError(CardField field) {
|
void EditCard::showError(CardField field) {
|
||||||
if (const auto control = controlForField(field)) {
|
if (const auto control = lookupField(field)) {
|
||||||
_scroll->ensureWidgetVisible(control);
|
_scroll->ensureWidgetVisible(control->widget());
|
||||||
control->showError(QString());
|
control->showError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,102 +103,69 @@ not_null<RpWidget*> EditCard::setupContent() {
|
||||||
const auto showBox = [=](object_ptr<BoxContent> box) {
|
const auto showBox = [=](object_ptr<BoxContent> box) {
|
||||||
_delegate->panelShowBox(std::move(box));
|
_delegate->panelShowBox(std::move(box));
|
||||||
};
|
};
|
||||||
using Type = Passport::Ui::PanelDetailsType;
|
const auto add = [&](FieldConfig &&config) {
|
||||||
auto maxLabelWidth = 0;
|
auto result = std::make_unique<Field>(inner, std::move(config));
|
||||||
accumulate_max(
|
inner->add(result->ownedWidget(), st::paymentsFieldPadding);
|
||||||
maxLabelWidth,
|
return result;
|
||||||
Row::LabelWidth("Card Number"));
|
};
|
||||||
accumulate_max(
|
_number = add({
|
||||||
maxLabelWidth,
|
.type = FieldType::CardNumber,
|
||||||
Row::LabelWidth("CVC"));
|
.placeholder = tr::lng_payments_card_number(),
|
||||||
accumulate_max(
|
.required = true,
|
||||||
maxLabelWidth,
|
});
|
||||||
Row::LabelWidth("MM/YY"));
|
|
||||||
if (_native.needCardholderName) {
|
if (_native.needCardholderName) {
|
||||||
accumulate_max(
|
_name = add({
|
||||||
maxLabelWidth,
|
.type = FieldType::CardNumber,
|
||||||
Row::LabelWidth("Cardholder Name"));
|
.placeholder = tr::lng_payments_card_holder(),
|
||||||
|
.required = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
auto container = inner->add(
|
||||||
|
object_ptr<FixedHeightWidget>(
|
||||||
|
inner,
|
||||||
|
_number->widget()->height()),
|
||||||
|
st::paymentsFieldPadding);
|
||||||
|
_expire = std::make_unique<Field>(container, FieldConfig{
|
||||||
|
.type = FieldType::CardExpireDate,
|
||||||
|
.placeholder = rpl::single(u"MM / YY"_q),
|
||||||
|
.required = true,
|
||||||
|
});
|
||||||
|
_cvc = std::make_unique<Field>(container, FieldConfig{
|
||||||
|
.type = FieldType::CardCVC,
|
||||||
|
.placeholder = rpl::single(u"CVC"_q),
|
||||||
|
.required = true,
|
||||||
|
});
|
||||||
|
container->widthValue(
|
||||||
|
) | rpl::start_with_next([=](int width) {
|
||||||
|
const auto left = (width - st::paymentsExpireCvcSkip) / 2;
|
||||||
|
const auto right = width - st::paymentsExpireCvcSkip - left;
|
||||||
|
_expire->widget()->resizeToWidth(left);
|
||||||
|
_cvc->widget()->resizeToWidth(right);
|
||||||
|
_expire->widget()->moveToLeft(0, 0, width);
|
||||||
|
_cvc->widget()->moveToRight(0, 0, width);
|
||||||
|
}, container->lifetime());
|
||||||
|
if (_native.needCountry || _native.needZip) {
|
||||||
|
inner->add(
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
inner,
|
||||||
|
tr::lng_payments_billing_address(),
|
||||||
|
st::paymentsBillingInformationTitle),
|
||||||
|
st::paymentsBillingInformationTitlePadding);
|
||||||
}
|
}
|
||||||
if (_native.needCountry) {
|
if (_native.needCountry) {
|
||||||
accumulate_max(
|
_country = add({
|
||||||
maxLabelWidth,
|
.type = FieldType::Country,
|
||||||
Row::LabelWidth("Billing Country"));
|
.placeholder = tr::lng_payments_billing_country(),
|
||||||
|
.required = true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (_native.needZip) {
|
if (_native.needZip) {
|
||||||
accumulate_max(
|
_zip = add({
|
||||||
maxLabelWidth,
|
.type = FieldType::Text,
|
||||||
Row::LabelWidth("Billing Zip"));
|
.placeholder = tr::lng_payments_billing_zip_code(),
|
||||||
}
|
.maxLength = kMaxPostcodeSize,
|
||||||
_number = inner->add(
|
.required = true,
|
||||||
Row::Create(
|
});
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Text,
|
|
||||||
"Card Number",
|
|
||||||
maxLabelWidth,
|
|
||||||
QString(),
|
|
||||||
QString(),
|
|
||||||
1024));
|
|
||||||
_cvc = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Text,
|
|
||||||
"CVC",
|
|
||||||
maxLabelWidth,
|
|
||||||
QString(),
|
|
||||||
QString(),
|
|
||||||
1024));
|
|
||||||
_expire = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Text,
|
|
||||||
"MM/YY",
|
|
||||||
maxLabelWidth,
|
|
||||||
QString(),
|
|
||||||
QString(),
|
|
||||||
1024));
|
|
||||||
if (_native.needCardholderName) {
|
|
||||||
_name = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Text,
|
|
||||||
"Cardholder Name",
|
|
||||||
maxLabelWidth,
|
|
||||||
QString(),
|
|
||||||
QString(),
|
|
||||||
1024));
|
|
||||||
}
|
|
||||||
if (_native.needCountry) {
|
|
||||||
_country = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Country,
|
|
||||||
"Billing Country",
|
|
||||||
maxLabelWidth,
|
|
||||||
QString(),
|
|
||||||
QString()));
|
|
||||||
}
|
|
||||||
if (_native.needZip) {
|
|
||||||
_zip = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Postcode,
|
|
||||||
"Billing Zip Code",
|
|
||||||
maxLabelWidth,
|
|
||||||
QString(),
|
|
||||||
QString(),
|
|
||||||
kMaxPostcodeSize));
|
|
||||||
}
|
}
|
||||||
return inner;
|
return inner;
|
||||||
}
|
}
|
||||||
|
@ -200,7 +175,7 @@ void EditCard::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditCard::focusInEvent(QFocusEvent *e) {
|
void EditCard::focusInEvent(QFocusEvent *e) {
|
||||||
if (const auto control = controlForField(_focusField)) {
|
if (const auto control = lookupField(_focusField)) {
|
||||||
control->setFocusFast();
|
control->setFocusFast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,27 +193,27 @@ void EditCard::updateControlsGeometry() {
|
||||||
_scroll->updateBars();
|
_scroll->updateBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EditCard::controlForField(CardField field) const -> Row* {
|
auto EditCard::lookupField(CardField field) const -> Field* {
|
||||||
switch (field) {
|
switch (field) {
|
||||||
case CardField::Number: return _number;
|
case CardField::Number: return _number.get();
|
||||||
case CardField::CVC: return _cvc;
|
case CardField::CVC: return _cvc.get();
|
||||||
case CardField::ExpireDate: return _expire;
|
case CardField::ExpireDate: return _expire.get();
|
||||||
case CardField::Name: return _name;
|
case CardField::Name: return _name.get();
|
||||||
case CardField::AddressCountry: return _country;
|
case CardField::AddressCountry: return _country.get();
|
||||||
case CardField::AddressZip: return _zip;
|
case CardField::AddressZip: return _zip.get();
|
||||||
}
|
}
|
||||||
Unexpected("Unknown field in EditCard::controlForField.");
|
Unexpected("Unknown field in EditCard::controlForField.");
|
||||||
}
|
}
|
||||||
|
|
||||||
UncheckedCardDetails EditCard::collect() const {
|
UncheckedCardDetails EditCard::collect() const {
|
||||||
return {
|
return {
|
||||||
.number = _number ? _number->valueCurrent() : QString(),
|
.number = _number ? _number->value() : QString(),
|
||||||
.cvc = _cvc ? _cvc->valueCurrent() : QString(),
|
.cvc = _cvc ? _cvc->value() : QString(),
|
||||||
.expireYear = _expire ? ExtractYear(_expire->valueCurrent()) : 0,
|
.expireYear = _expire ? ExtractYear(_expire->value()) : 0,
|
||||||
.expireMonth = _expire ? ExtractMonth(_expire->valueCurrent()) : 0,
|
.expireMonth = _expire ? ExtractMonth(_expire->value()) : 0,
|
||||||
.cardholderName = _name ? _name->valueCurrent() : QString(),
|
.cardholderName = _name ? _name->value() : QString(),
|
||||||
.addressCountry = _country ? _country->valueCurrent() : QString(),
|
.addressCountry = _country ? _country->value() : QString(),
|
||||||
.addressZip = _zip ? _zip->valueCurrent() : QString(),
|
.addressZip = _zip ? _zip->value() : QString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,15 +17,12 @@ class FadeShadow;
|
||||||
class RoundButton;
|
class RoundButton;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Passport::Ui {
|
|
||||||
class PanelDetailsRow;
|
|
||||||
} // namespace Passport::Ui
|
|
||||||
|
|
||||||
namespace Payments::Ui {
|
namespace Payments::Ui {
|
||||||
|
|
||||||
using namespace ::Ui;
|
using namespace ::Ui;
|
||||||
|
|
||||||
class PanelDelegate;
|
class PanelDelegate;
|
||||||
|
class Field;
|
||||||
|
|
||||||
class EditCard final : public RpWidget {
|
class EditCard final : public RpWidget {
|
||||||
public:
|
public:
|
||||||
|
@ -35,19 +32,18 @@ public:
|
||||||
CardField field,
|
CardField field,
|
||||||
not_null<PanelDelegate*> delegate);
|
not_null<PanelDelegate*> delegate);
|
||||||
|
|
||||||
void showError(CardField field);
|
|
||||||
void setFocus(CardField field);
|
void setFocus(CardField field);
|
||||||
|
void setFocusFast(CardField field);
|
||||||
|
void showError(CardField field);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Row = Passport::Ui::PanelDetailsRow;
|
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void focusInEvent(QFocusEvent *e) override;
|
void focusInEvent(QFocusEvent *e) override;
|
||||||
|
|
||||||
void setupControls();
|
void setupControls();
|
||||||
[[nodiscard]] not_null<Ui::RpWidget*> setupContent();
|
[[nodiscard]] not_null<Ui::RpWidget*> setupContent();
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
[[nodiscard]] Row *controlForField(CardField field) const;
|
[[nodiscard]] Field *lookupField(CardField field) const;
|
||||||
|
|
||||||
[[nodiscard]] UncheckedCardDetails collect() const;
|
[[nodiscard]] UncheckedCardDetails collect() const;
|
||||||
|
|
||||||
|
@ -59,12 +55,12 @@ private:
|
||||||
object_ptr<FadeShadow> _bottomShadow;
|
object_ptr<FadeShadow> _bottomShadow;
|
||||||
object_ptr<RoundButton> _done;
|
object_ptr<RoundButton> _done;
|
||||||
|
|
||||||
Row *_number = nullptr;
|
std::unique_ptr<Field> _number;
|
||||||
Row *_cvc = nullptr;
|
std::unique_ptr<Field> _cvc;
|
||||||
Row *_expire = nullptr;
|
std::unique_ptr<Field> _expire;
|
||||||
Row *_name = nullptr;
|
std::unique_ptr<Field> _name;
|
||||||
Row *_country = nullptr;
|
std::unique_ptr<Field> _country;
|
||||||
Row *_zip = nullptr;
|
std::unique_ptr<Field> _zip;
|
||||||
|
|
||||||
CardField _focusField = CardField::Number;
|
CardField _focusField = CardField::Number;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "payments/ui/payments_edit_information.h"
|
#include "payments/ui/payments_edit_information.h"
|
||||||
|
|
||||||
#include "payments/ui/payments_panel_delegate.h"
|
#include "payments/ui/payments_panel_delegate.h"
|
||||||
#include "passport/ui/passport_details_row.h"
|
#include "payments/ui/payments_field.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
@ -48,18 +48,28 @@ EditInformation::EditInformation(
|
||||||
setupControls();
|
setupControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditInformation::~EditInformation() = default;
|
||||||
|
|
||||||
void EditInformation::setFocus(InformationField field) {
|
void EditInformation::setFocus(InformationField field) {
|
||||||
_focusField = field;
|
_focusField = field;
|
||||||
if (const auto control = controlForField(field)) {
|
if (const auto control = lookupField(field)) {
|
||||||
_scroll->ensureWidgetVisible(control);
|
_scroll->ensureWidgetVisible(control->widget());
|
||||||
|
control->setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditInformation::setFocusFast(InformationField field) {
|
||||||
|
_focusField = field;
|
||||||
|
if (const auto control = lookupField(field)) {
|
||||||
|
_scroll->ensureWidgetVisible(control->widget());
|
||||||
control->setFocusFast();
|
control->setFocusFast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditInformation::showError(InformationField field) {
|
void EditInformation::showError(InformationField field) {
|
||||||
if (const auto control = controlForField(field)) {
|
if (const auto control = lookupField(field)) {
|
||||||
_scroll->ensureWidgetVisible(control);
|
_scroll->ensureWidgetVisible(control->widget());
|
||||||
control->showError(QString());
|
control->showError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,106 +103,44 @@ not_null<RpWidget*> EditInformation::setupContent() {
|
||||||
const auto showBox = [=](object_ptr<BoxContent> box) {
|
const auto showBox = [=](object_ptr<BoxContent> box) {
|
||||||
_delegate->panelShowBox(std::move(box));
|
_delegate->panelShowBox(std::move(box));
|
||||||
};
|
};
|
||||||
using Type = Passport::Ui::PanelDetailsType;
|
const auto add = [&](FieldConfig &&config) {
|
||||||
auto maxLabelWidth = 0;
|
auto result = std::make_unique<Field>(inner, std::move(config));
|
||||||
|
inner->add(result->ownedWidget(), st::paymentsFieldPadding);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
if (_invoice.isShippingAddressRequested) {
|
if (_invoice.isShippingAddressRequested) {
|
||||||
accumulate_max(
|
_street1 = add({
|
||||||
maxLabelWidth,
|
.placeholder = tr::lng_payments_address_street1(),
|
||||||
Row::LabelWidth(tr::lng_passport_street(tr::now)));
|
.value = _information.shippingAddress.address1,
|
||||||
accumulate_max(
|
.maxLength = kMaxStreetSize,
|
||||||
maxLabelWidth,
|
.required = true,
|
||||||
Row::LabelWidth(tr::lng_passport_city(tr::now)));
|
});
|
||||||
accumulate_max(
|
_street2 = add({
|
||||||
maxLabelWidth,
|
.placeholder = tr::lng_payments_address_street2(),
|
||||||
Row::LabelWidth(tr::lng_passport_state(tr::now)));
|
.value = _information.shippingAddress.address2,
|
||||||
accumulate_max(
|
.maxLength = kMaxStreetSize,
|
||||||
maxLabelWidth,
|
});
|
||||||
Row::LabelWidth(tr::lng_passport_country(tr::now)));
|
_city = add({
|
||||||
accumulate_max(
|
.placeholder = tr::lng_payments_address_city(),
|
||||||
maxLabelWidth,
|
.value = _information.shippingAddress.city,
|
||||||
Row::LabelWidth(tr::lng_passport_postcode(tr::now)));
|
.required = true,
|
||||||
}
|
});
|
||||||
if (_invoice.isNameRequested) {
|
_state = add({
|
||||||
accumulate_max(
|
.placeholder = tr::lng_payments_address_state(),
|
||||||
maxLabelWidth,
|
.value = _information.shippingAddress.state,
|
||||||
Row::LabelWidth(tr::lng_payments_info_name(tr::now)));
|
});
|
||||||
}
|
_country = add({
|
||||||
if (_invoice.isEmailRequested) {
|
.type = FieldType::Country,
|
||||||
accumulate_max(
|
.placeholder = tr::lng_payments_address_country(),
|
||||||
maxLabelWidth,
|
.value = _information.shippingAddress.countryIso2,
|
||||||
Row::LabelWidth(tr::lng_payments_info_email(tr::now)));
|
.required = true,
|
||||||
}
|
});
|
||||||
if (_invoice.isPhoneRequested) {
|
_postcode = add({
|
||||||
accumulate_max(
|
.placeholder = tr::lng_payments_address_postcode(),
|
||||||
maxLabelWidth,
|
.value = _information.shippingAddress.postcode,
|
||||||
Row::LabelWidth(tr::lng_payments_info_phone(tr::now)));
|
.maxLength = kMaxPostcodeSize,
|
||||||
}
|
.required = true,
|
||||||
if (_invoice.isShippingAddressRequested) {
|
});
|
||||||
_street1 = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Text,
|
|
||||||
tr::lng_passport_street(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.shippingAddress.address1,
|
|
||||||
QString(),
|
|
||||||
kMaxStreetSize));
|
|
||||||
_street2 = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Text,
|
|
||||||
tr::lng_passport_street(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.shippingAddress.address2,
|
|
||||||
QString(),
|
|
||||||
kMaxStreetSize));
|
|
||||||
_city = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Text,
|
|
||||||
tr::lng_passport_city(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.shippingAddress.city,
|
|
||||||
QString(),
|
|
||||||
kMaxStreetSize));
|
|
||||||
_state = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Text,
|
|
||||||
tr::lng_passport_state(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.shippingAddress.state,
|
|
||||||
QString(),
|
|
||||||
kMaxStreetSize));
|
|
||||||
_country = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Country,
|
|
||||||
tr::lng_passport_country(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.shippingAddress.countryIso2,
|
|
||||||
QString()));
|
|
||||||
_postcode = inner->add(
|
|
||||||
Row::Create(
|
|
||||||
inner,
|
|
||||||
showBox,
|
|
||||||
QString(),
|
|
||||||
Type::Postcode,
|
|
||||||
tr::lng_passport_postcode(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.shippingAddress.postcode,
|
|
||||||
QString(),
|
|
||||||
kMaxPostcodeSize));
|
|
||||||
//StreetValidate, // #TODO payments
|
//StreetValidate, // #TODO payments
|
||||||
//CityValidate,
|
//CityValidate,
|
||||||
//CountryValidate,
|
//CountryValidate,
|
||||||
|
@ -200,43 +148,28 @@ not_null<RpWidget*> EditInformation::setupContent() {
|
||||||
//PostcodeValidate,
|
//PostcodeValidate,
|
||||||
}
|
}
|
||||||
if (_invoice.isNameRequested) {
|
if (_invoice.isNameRequested) {
|
||||||
_name = inner->add(
|
_name = add({
|
||||||
Row::Create(
|
.placeholder = tr::lng_payments_info_name(),
|
||||||
inner,
|
.value = _information.name,
|
||||||
showBox,
|
.maxLength = kMaxNameSize,
|
||||||
QString(),
|
.required = true,
|
||||||
Type::Text,
|
});
|
||||||
tr::lng_payments_info_name(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.name,
|
|
||||||
QString(),
|
|
||||||
kMaxNameSize));
|
|
||||||
}
|
}
|
||||||
if (_invoice.isEmailRequested) {
|
if (_invoice.isEmailRequested) {
|
||||||
_email = inner->add(
|
_email = add({
|
||||||
Row::Create(
|
.placeholder = tr::lng_payments_info_email(),
|
||||||
inner,
|
.value = _information.email,
|
||||||
showBox,
|
.maxLength = kMaxEmailSize,
|
||||||
QString(),
|
.required = true,
|
||||||
Type::Text,
|
});
|
||||||
tr::lng_payments_info_email(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.email,
|
|
||||||
QString(),
|
|
||||||
kMaxEmailSize));
|
|
||||||
}
|
}
|
||||||
if (_invoice.isPhoneRequested) {
|
if (_invoice.isPhoneRequested) {
|
||||||
_phone = inner->add(
|
_phone = add({
|
||||||
Row::Create(
|
.placeholder = tr::lng_payments_info_phone(),
|
||||||
inner,
|
.value = _information.phone,
|
||||||
showBox,
|
.maxLength = kMaxPhoneSize,
|
||||||
QString(),
|
.required = true,
|
||||||
Type::Text,
|
});
|
||||||
tr::lng_payments_info_phone(tr::now),
|
|
||||||
maxLabelWidth,
|
|
||||||
_information.phone,
|
|
||||||
QString(),
|
|
||||||
kMaxPhoneSize));
|
|
||||||
}
|
}
|
||||||
return inner;
|
return inner;
|
||||||
}
|
}
|
||||||
|
@ -246,8 +179,8 @@ void EditInformation::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditInformation::focusInEvent(QFocusEvent *e) {
|
void EditInformation::focusInEvent(QFocusEvent *e) {
|
||||||
if (const auto control = controlForField(_focusField)) {
|
if (const auto control = lookupField(_focusField)) {
|
||||||
control->setFocusFast();
|
control->setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,32 +197,32 @@ void EditInformation::updateControlsGeometry() {
|
||||||
_scroll->updateBars();
|
_scroll->updateBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EditInformation::controlForField(InformationField field) const -> Row* {
|
auto EditInformation::lookupField(InformationField field) const -> Field* {
|
||||||
switch (field) {
|
switch (field) {
|
||||||
case InformationField::ShippingStreet: return _street1;
|
case InformationField::ShippingStreet: return _street1.get();
|
||||||
case InformationField::ShippingCity: return _city;
|
case InformationField::ShippingCity: return _city.get();
|
||||||
case InformationField::ShippingState: return _state;
|
case InformationField::ShippingState: return _state.get();
|
||||||
case InformationField::ShippingCountry: return _country;
|
case InformationField::ShippingCountry: return _country.get();
|
||||||
case InformationField::ShippingPostcode: return _postcode;
|
case InformationField::ShippingPostcode: return _postcode.get();
|
||||||
case InformationField::Name: return _name;
|
case InformationField::Name: return _name.get();
|
||||||
case InformationField::Email: return _email;
|
case InformationField::Email: return _email.get();
|
||||||
case InformationField::Phone: return _phone;
|
case InformationField::Phone: return _phone.get();
|
||||||
}
|
}
|
||||||
Unexpected("Unknown field in EditInformation::controlForField.");
|
Unexpected("Unknown field in EditInformation::lookupField.");
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestedInformation EditInformation::collect() const {
|
RequestedInformation EditInformation::collect() const {
|
||||||
return {
|
return {
|
||||||
.name = _name ? _name->valueCurrent() : QString(),
|
.name = _name ? _name->value() : QString(),
|
||||||
.phone = _phone ? _phone->valueCurrent() : QString(),
|
.phone = _phone ? _phone->value() : QString(),
|
||||||
.email = _email ? _email->valueCurrent() : QString(),
|
.email = _email ? _email->value() : QString(),
|
||||||
.shippingAddress = {
|
.shippingAddress = {
|
||||||
.address1 = _street1 ? _street1->valueCurrent() : QString(),
|
.address1 = _street1 ? _street1->value() : QString(),
|
||||||
.address2 = _street2 ? _street2->valueCurrent() : QString(),
|
.address2 = _street2 ? _street2->value() : QString(),
|
||||||
.city = _city ? _city->valueCurrent() : QString(),
|
.city = _city ? _city->value() : QString(),
|
||||||
.state = _state ? _state->valueCurrent() : QString(),
|
.state = _state ? _state->value() : QString(),
|
||||||
.countryIso2 = _country ? _country->valueCurrent() : QString(),
|
.countryIso2 = _country ? _country->value() : QString(),
|
||||||
.postcode = _postcode ? _postcode->valueCurrent() : QString(),
|
.postcode = _postcode ? _postcode->value() : QString(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,17 +15,16 @@ namespace Ui {
|
||||||
class ScrollArea;
|
class ScrollArea;
|
||||||
class FadeShadow;
|
class FadeShadow;
|
||||||
class RoundButton;
|
class RoundButton;
|
||||||
|
class InputField;
|
||||||
|
class MaskedInputField;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Passport::Ui {
|
|
||||||
class PanelDetailsRow;
|
|
||||||
} // namespace Passport::Ui
|
|
||||||
|
|
||||||
namespace Payments::Ui {
|
namespace Payments::Ui {
|
||||||
|
|
||||||
using namespace ::Ui;
|
using namespace ::Ui;
|
||||||
|
|
||||||
class PanelDelegate;
|
class PanelDelegate;
|
||||||
|
class Field;
|
||||||
|
|
||||||
class EditInformation final : public RpWidget {
|
class EditInformation final : public RpWidget {
|
||||||
public:
|
public:
|
||||||
|
@ -35,20 +34,20 @@ public:
|
||||||
const RequestedInformation ¤t,
|
const RequestedInformation ¤t,
|
||||||
InformationField field,
|
InformationField field,
|
||||||
not_null<PanelDelegate*> delegate);
|
not_null<PanelDelegate*> delegate);
|
||||||
|
~EditInformation();
|
||||||
|
|
||||||
void showError(InformationField field);
|
|
||||||
void setFocus(InformationField field);
|
void setFocus(InformationField field);
|
||||||
|
void setFocusFast(InformationField field);
|
||||||
|
void showError(InformationField field);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Row = Passport::Ui::PanelDetailsRow;
|
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void focusInEvent(QFocusEvent *e) override;
|
void focusInEvent(QFocusEvent *e) override;
|
||||||
|
|
||||||
void setupControls();
|
void setupControls();
|
||||||
[[nodiscard]] not_null<Ui::RpWidget*> setupContent();
|
[[nodiscard]] not_null<Ui::RpWidget*> setupContent();
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
[[nodiscard]] Row *controlForField(InformationField field) const;
|
[[nodiscard]] Field *lookupField(InformationField field) const;
|
||||||
|
|
||||||
[[nodiscard]] RequestedInformation collect() const;
|
[[nodiscard]] RequestedInformation collect() const;
|
||||||
|
|
||||||
|
@ -61,15 +60,15 @@ private:
|
||||||
object_ptr<FadeShadow> _bottomShadow;
|
object_ptr<FadeShadow> _bottomShadow;
|
||||||
object_ptr<RoundButton> _done;
|
object_ptr<RoundButton> _done;
|
||||||
|
|
||||||
Row *_street1 = nullptr;
|
std::unique_ptr<Field> _street1;
|
||||||
Row *_street2 = nullptr;
|
std::unique_ptr<Field> _street2;
|
||||||
Row *_city = nullptr;
|
std::unique_ptr<Field> _city;
|
||||||
Row *_state = nullptr;
|
std::unique_ptr<Field> _state;
|
||||||
Row *_country = nullptr;
|
std::unique_ptr<Field> _country;
|
||||||
Row *_postcode = nullptr;
|
std::unique_ptr<Field> _postcode;
|
||||||
Row *_name = nullptr;
|
std::unique_ptr<Field> _name;
|
||||||
Row *_email = nullptr;
|
std::unique_ptr<Field> _email;
|
||||||
Row *_phone = nullptr;
|
std::unique_ptr<Field> _phone;
|
||||||
|
|
||||||
InformationField _focusField = InformationField::ShippingStreet;
|
InformationField _focusField = InformationField::ShippingStreet;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
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/ui/payments_field.h"
|
||||||
|
|
||||||
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "styles/style_payments.h"
|
||||||
|
|
||||||
|
namespace Payments::Ui {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] bool UseMaskedField(FieldType type) {
|
||||||
|
switch (type) {
|
||||||
|
case FieldType::Text:
|
||||||
|
case FieldType::Email:
|
||||||
|
return false;
|
||||||
|
case FieldType::CardNumber:
|
||||||
|
case FieldType::CardExpireDate:
|
||||||
|
case FieldType::CardCVC:
|
||||||
|
case FieldType::Country:
|
||||||
|
case FieldType::Phone:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Unexpected("FieldType in Payments::Ui::UseMaskedField.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] base::unique_qptr<RpWidget> CreateWrap(
|
||||||
|
QWidget *parent,
|
||||||
|
FieldConfig &config) {
|
||||||
|
switch (config.type) {
|
||||||
|
case FieldType::Text:
|
||||||
|
case FieldType::Email:
|
||||||
|
return base::make_unique_q<InputField>(
|
||||||
|
parent,
|
||||||
|
st::paymentsField,
|
||||||
|
std::move(config.placeholder),
|
||||||
|
config.value);
|
||||||
|
case FieldType::CardNumber:
|
||||||
|
case FieldType::CardExpireDate:
|
||||||
|
case FieldType::CardCVC:
|
||||||
|
case FieldType::Country:
|
||||||
|
case FieldType::Phone:
|
||||||
|
return base::make_unique_q<RpWidget>(parent);
|
||||||
|
}
|
||||||
|
Unexpected("FieldType in Payments::Ui::CreateWrap.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] InputField *LookupInputField(
|
||||||
|
not_null<RpWidget*> wrap,
|
||||||
|
FieldConfig &config) {
|
||||||
|
return UseMaskedField(config.type)
|
||||||
|
? nullptr
|
||||||
|
: static_cast<InputField*>(wrap.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] MaskedInputField *LookupMaskedField(
|
||||||
|
not_null<RpWidget*> wrap,
|
||||||
|
FieldConfig &config) {
|
||||||
|
if (!UseMaskedField(config.type)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
switch (config.type) {
|
||||||
|
case FieldType::Text:
|
||||||
|
case FieldType::Email:
|
||||||
|
return nullptr;
|
||||||
|
case FieldType::CardNumber:
|
||||||
|
case FieldType::CardExpireDate:
|
||||||
|
case FieldType::CardCVC:
|
||||||
|
case FieldType::Country:
|
||||||
|
case FieldType::Phone:
|
||||||
|
return CreateChild<MaskedInputField>(
|
||||||
|
wrap.get(),
|
||||||
|
st::paymentsField,
|
||||||
|
std::move(config.placeholder),
|
||||||
|
config.value);
|
||||||
|
}
|
||||||
|
Unexpected("FieldType in Payments::Ui::LookupMaskedField.");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Field::Field(QWidget *parent, FieldConfig &&config)
|
||||||
|
: _type(config.type)
|
||||||
|
, _wrap(CreateWrap(parent, config))
|
||||||
|
, _input(LookupInputField(_wrap.get(), config))
|
||||||
|
, _masked(LookupMaskedField(_wrap.get(), config)) {
|
||||||
|
if (_masked) {
|
||||||
|
_wrap->resize(_masked->size());
|
||||||
|
_wrap->widthValue(
|
||||||
|
) | rpl::start_with_next([=](int width) {
|
||||||
|
_masked->resize(width, _masked->height());
|
||||||
|
}, _masked->lifetime());
|
||||||
|
_masked->heightValue(
|
||||||
|
) | rpl::start_with_next([=](int height) {
|
||||||
|
_wrap->resize(_wrap->width(), height);
|
||||||
|
}, _masked->lifetime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RpWidget *Field::widget() const {
|
||||||
|
return _wrap.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<RpWidget> Field::ownedWidget() const {
|
||||||
|
return object_ptr<RpWidget>::fromRaw(_wrap.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QString Field::value() const {
|
||||||
|
return _input ? _input->getLastText() : _masked->getLastText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Field::setFocus() {
|
||||||
|
if (_input) {
|
||||||
|
_input->setFocus();
|
||||||
|
} else {
|
||||||
|
_masked->setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Field::setFocusFast() {
|
||||||
|
if (_input) {
|
||||||
|
_input->setFocusFast();
|
||||||
|
} else {
|
||||||
|
_masked->setFocusFast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Field::showError() {
|
||||||
|
if (_input) {
|
||||||
|
_input->showError();
|
||||||
|
} else {
|
||||||
|
_masked->showError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Payments::Ui
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
#include "base/object_ptr.h"
|
||||||
|
#include "base/unique_qptr.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RpWidget;
|
||||||
|
class InputField;
|
||||||
|
class MaskedInputField;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Payments::Ui {
|
||||||
|
|
||||||
|
using namespace ::Ui;
|
||||||
|
|
||||||
|
enum class FieldType {
|
||||||
|
Text,
|
||||||
|
CardNumber,
|
||||||
|
CardExpireDate,
|
||||||
|
CardCVC,
|
||||||
|
Country,
|
||||||
|
Phone,
|
||||||
|
Email,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FieldConfig {
|
||||||
|
FieldType type = FieldType::Text;
|
||||||
|
rpl::producer<QString> placeholder;
|
||||||
|
QString value;
|
||||||
|
int maxLength = 0;
|
||||||
|
bool required = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Field final {
|
||||||
|
public:
|
||||||
|
Field(QWidget *parent, FieldConfig &&config);
|
||||||
|
|
||||||
|
[[nodiscard]] RpWidget *widget() const;
|
||||||
|
[[nodiscard]] object_ptr<RpWidget> ownedWidget() const;
|
||||||
|
|
||||||
|
[[nodiscard]] QString value() const;
|
||||||
|
|
||||||
|
void setFocus();
|
||||||
|
void setFocusFast();
|
||||||
|
void showError();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FieldType _type = FieldType::Text;
|
||||||
|
const base::unique_qptr<RpWidget> _wrap;
|
||||||
|
InputField *_input = nullptr;
|
||||||
|
MaskedInputField *_masked = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Payments::Ui
|
|
@ -58,7 +58,7 @@ QString FormSummary::formatAmount(int64 amount) const {
|
||||||
const auto base = FillAmountAndCurrency(
|
const auto base = FillAmountAndCurrency(
|
||||||
std::abs(amount),
|
std::abs(amount),
|
||||||
_invoice.currency);
|
_invoice.currency);
|
||||||
return (amount > 0) ? base : (QString::fromUtf8("\xe2\x88\x92") + base);
|
return (amount < 0) ? (QString::fromUtf8("\xe2\x88\x92") + base) : base;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 FormSummary::computeTotalAmount() const {
|
int64 FormSummary::computeTotalAmount() const {
|
||||||
|
@ -87,6 +87,9 @@ void FormSummary::setupControls() {
|
||||||
_submit->addClickHandler([=] {
|
_submit->addClickHandler([=] {
|
||||||
_delegate->panelSubmit();
|
_delegate->panelSubmit();
|
||||||
});
|
});
|
||||||
|
if (!_invoice) {
|
||||||
|
_submit->hide();
|
||||||
|
}
|
||||||
|
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
|
@ -317,10 +320,12 @@ not_null<RpWidget*> FormSummary::setupContent() {
|
||||||
}, inner->lifetime());
|
}, inner->lifetime());
|
||||||
|
|
||||||
setupCover(inner);
|
setupCover(inner);
|
||||||
|
if (_invoice) {
|
||||||
Settings::AddDivider(inner);
|
Settings::AddDivider(inner);
|
||||||
setupPrices(inner);
|
setupPrices(inner);
|
||||||
Settings::AddDivider(inner);
|
Settings::AddDivider(inner);
|
||||||
setupSections(inner);
|
setupSections(inner);
|
||||||
|
}
|
||||||
|
|
||||||
return inner;
|
return inner;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ namespace Payments::Ui {
|
||||||
Panel::Panel(not_null<PanelDelegate*> delegate)
|
Panel::Panel(not_null<PanelDelegate*> delegate)
|
||||||
: _delegate(delegate)
|
: _delegate(delegate)
|
||||||
, _widget(std::make_unique<SeparatePanel>()) {
|
, _widget(std::make_unique<SeparatePanel>()) {
|
||||||
_widget->setTitle(tr::lng_payments_checkout_title());
|
|
||||||
_widget->setInnerSize(st::passportPanelSize);
|
_widget->setInnerSize(st::passportPanelSize);
|
||||||
_widget->setWindowFlag(Qt::WindowStaysOnTopHint, false);
|
_widget->setWindowFlag(Qt::WindowStaysOnTopHint, false);
|
||||||
|
|
||||||
|
@ -52,6 +51,7 @@ void Panel::showForm(
|
||||||
const RequestedInformation ¤t,
|
const RequestedInformation ¤t,
|
||||||
const PaymentMethodDetails &method,
|
const PaymentMethodDetails &method,
|
||||||
const ShippingOptions &options) {
|
const ShippingOptions &options) {
|
||||||
|
_widget->setTitle(tr::lng_payments_checkout_title());
|
||||||
auto form = base::make_unique_q<FormSummary>(
|
auto form = base::make_unique_q<FormSummary>(
|
||||||
_widget.get(),
|
_widget.get(),
|
||||||
invoice,
|
invoice,
|
||||||
|
@ -74,6 +74,7 @@ void Panel::showEditInformation(
|
||||||
const Invoice &invoice,
|
const Invoice &invoice,
|
||||||
const RequestedInformation ¤t,
|
const RequestedInformation ¤t,
|
||||||
InformationField field) {
|
InformationField field) {
|
||||||
|
_widget->setTitle(tr::lng_payments_shipping_address_title());
|
||||||
auto edit = base::make_unique_q<EditInformation>(
|
auto edit = base::make_unique_q<EditInformation>(
|
||||||
_widget.get(),
|
_widget.get(),
|
||||||
invoice,
|
invoice,
|
||||||
|
@ -83,7 +84,7 @@ void Panel::showEditInformation(
|
||||||
_weakEditInformation = edit.get();
|
_weakEditInformation = edit.get();
|
||||||
_widget->showInner(std::move(edit));
|
_widget->showInner(std::move(edit));
|
||||||
_widget->setBackAllowed(true);
|
_widget->setBackAllowed(true);
|
||||||
_weakEditInformation->setFocus(field);
|
_weakEditInformation->setFocusFast(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::showInformationError(
|
void Panel::showInformationError(
|
||||||
|
@ -125,6 +126,7 @@ void Panel::chooseShippingOption(const ShippingOptions &options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::showEditPaymentMethod(const PaymentMethodDetails &method) {
|
void Panel::showEditPaymentMethod(const PaymentMethodDetails &method) {
|
||||||
|
_widget->setTitle(tr::lng_payments_card_title());
|
||||||
if (method.native.supported) {
|
if (method.native.supported) {
|
||||||
showEditCard(method.native, CardField::Number);
|
showEditCard(method.native, CardField::Number);
|
||||||
} else if (!showWebview(method.url, true)) {
|
} else if (!showWebview(method.url, true)) {
|
||||||
|
@ -221,7 +223,7 @@ void Panel::showEditCard(
|
||||||
_weakEditCard = edit.get();
|
_weakEditCard = edit.get();
|
||||||
_widget->showInner(std::move(edit));
|
_widget->showInner(std::move(edit));
|
||||||
_widget->setBackAllowed(true);
|
_widget->setBackAllowed(true);
|
||||||
_weakEditCard->setFocus(field);
|
_weakEditCard->setFocusFast(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::showCardError(
|
void Panel::showCardError(
|
||||||
|
@ -230,11 +232,12 @@ void Panel::showCardError(
|
||||||
if (_weakEditCard) {
|
if (_weakEditCard) {
|
||||||
_weakEditCard->showError(field);
|
_weakEditCard->showError(field);
|
||||||
} else {
|
} else {
|
||||||
showEditCard(native, field);
|
// We cancelled card edit already.
|
||||||
if (_weakEditCard
|
//showEditCard(native, field);
|
||||||
&& field == CardField::AddressCountry) {
|
//if (_weakEditCard
|
||||||
_weakEditCard->showError(field);
|
// && field == CardField::AddressCountry) {
|
||||||
}
|
// _weakEditCard->showError(field);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,8 @@ PRIVATE
|
||||||
payments/ui/payments_edit_information.h
|
payments/ui/payments_edit_information.h
|
||||||
payments/ui/payments_form_summary.cpp
|
payments/ui/payments_form_summary.cpp
|
||||||
payments/ui/payments_form_summary.h
|
payments/ui/payments_form_summary.h
|
||||||
|
payments/ui/payments_field.cpp
|
||||||
|
payments/ui/payments_field.h
|
||||||
payments/ui/payments_panel.cpp
|
payments/ui/payments_panel.cpp
|
||||||
payments/ui/payments_panel.h
|
payments/ui/payments_panel.h
|
||||||
payments/ui/payments_panel_data.h
|
payments/ui/payments_panel_data.h
|
||||||
|
|
Loading…
Reference in New Issue