summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Preston <johnprestonmail@gmail.com>2021-04-01 19:06:48 +0400
committerJohn Preston <johnprestonmail@gmail.com>2021-04-06 18:41:16 +0400
commitbdffdea358d6964f3485259311cc339d02a9ecfb (patch)
tree0302d0141d978e5c3d55c33bab9f3269ef765494
parent491ec2db7f554f180898fab1bd6d96d9bcdd2dfe (diff)
Always jump to next field in payments.
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_edit_card.cpp31
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_edit_information.cpp14
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_field.cpp45
-rw-r--r--Telegram/SourceFiles/payments/ui/payments_field.h6
4 files changed, 81 insertions, 15 deletions
diff --git a/Telegram/SourceFiles/payments/ui/payments_edit_card.cpp b/Telegram/SourceFiles/payments/ui/payments_edit_card.cpp
index d084cc1bd1..dbd6e4c2dc 100644
--- a/Telegram/SourceFiles/payments/ui/payments_edit_card.cpp
+++ b/Telegram/SourceFiles/payments/ui/payments_edit_card.cpp
@@ -276,8 +276,18 @@ not_null<RpWidget*> EditCard::setupContent() {
const auto showBox = [=](object_ptr<BoxContent> box) {
_delegate->panelShowBox(std::move(box));
};
+ auto last = (Field*)nullptr;
+ const auto make = [&](QWidget *parent, FieldConfig &&config) {
+ auto result = std::make_unique<Field>(parent, std::move(config));
+ if (last) {
+ last->setNextField(result.get());
+ result->setPreviousField(last);
+ }
+ last = result.get();
+ return result;
+ };
const auto add = [&](FieldConfig &&config) {
- auto result = std::make_unique<Field>(inner, std::move(config));
+ auto result = make(inner, std::move(config));
inner->add(result->ownedWidget(), st::paymentsFieldPadding);
return result;
};
@@ -291,12 +301,12 @@ not_null<RpWidget*> EditCard::setupContent() {
inner,
_number->widget()->height()),
st::paymentsFieldPadding);
- _expire = std::make_unique<Field>(container, FieldConfig{
+ _expire = make(container, {
.type = FieldType::CardExpireDate,
.placeholder = rpl::single(u"MM / YY"_q),
.validator = ExpireDateValidator(),
});
- _cvc = std::make_unique<Field>(container, FieldConfig{
+ _cvc = make(container, {
.type = FieldType::CardCVC,
.placeholder = rpl::single(u"CVC"_q),
.validator = CvcValidator([=] { return _number->value(); }),
@@ -319,15 +329,6 @@ not_null<RpWidget*> EditCard::setupContent() {
});
}
- _number->setNextField(_expire.get());
- _expire->setPreviousField(_number.get());
- _expire->setNextField(_cvc.get());
- _cvc->setPreviousField(_expire.get());
- if (_name) {
- _cvc->setNextField(_name.get());
- _name->setPreviousField(_cvc.get());
- }
-
if (_native.needCountry || _native.needZip) {
inner->add(
object_ptr<Ui::FlatLabel>(
@@ -366,6 +367,12 @@ not_null<RpWidget*> EditCard::setupContent() {
false),
st::paymentsSaveCheckboxPadding);
}
+
+ last->submitted(
+ ) | rpl::start_with_next([=] {
+ _delegate->panelValidateCard(collect(), _save && _save->checked());
+ }, lifetime());
+
return inner;
}
diff --git a/Telegram/SourceFiles/payments/ui/payments_edit_information.cpp b/Telegram/SourceFiles/payments/ui/payments_edit_information.cpp
index d62abd1adb..ab96a8a9ea 100644
--- a/Telegram/SourceFiles/payments/ui/payments_edit_information.cpp
+++ b/Telegram/SourceFiles/payments/ui/payments_edit_information.cpp
@@ -113,9 +113,15 @@ not_null<RpWidget*> EditInformation::setupContent() {
const auto showBox = [=](object_ptr<BoxContent> box) {
_delegate->panelShowBox(std::move(box));
};
+ auto last = (Field*)nullptr;
const auto add = [&](FieldConfig &&config) {
auto result = std::make_unique<Field>(inner, std::move(config));
inner->add(result->ownedWidget(), st::paymentsFieldPadding);
+ if (last) {
+ last->setNextField(result.get());
+ result->setPreviousField(last);
+ }
+ last = result.get();
return result;
};
if (_invoice.isShippingAddressRequested) {
@@ -200,6 +206,14 @@ not_null<RpWidget*> EditInformation::setupContent() {
tr::lng_payments_save_information(tr::now),
true),
st::paymentsSaveCheckboxPadding);
+
+ if (last) {
+ last->submitted(
+ ) | rpl::start_with_next([=] {
+ _delegate->panelValidateInformation(collect());
+ }, lifetime());
+ }
+
return inner;
}
diff --git a/Telegram/SourceFiles/payments/ui/payments_field.cpp b/Telegram/SourceFiles/payments/ui/payments_field.cpp
index 287d6046b1..f4d99fccd2 100644
--- a/Telegram/SourceFiles/payments/ui/payments_field.cpp
+++ b/Telegram/SourceFiles/payments/ui/payments_field.cpp
@@ -430,6 +430,7 @@ Field::Field(QWidget *parent, FieldConfig &&config)
setupValidator(MoneyValidator(LookupCurrencyRule(config.currency)));
}
setupFrontBackspace();
+ setupSubmit();
}
RpWidget *Field::widget() const {
@@ -455,6 +456,10 @@ rpl::producer<> Field::finished() const {
return _finished.events();
}
+rpl::producer<> Field::submitted() const {
+ return _submitted.events();
+}
+
void Field::setupMaskedGeometry() {
Expects(_masked != nullptr);
@@ -492,6 +497,13 @@ void Field::setupCountry() {
_masked->setText(Data::CountryNameByISO2(iso2));
_masked->hideError();
raw->closeBox();
+ if (!iso2.isEmpty()) {
+ if (_nextField) {
+ _nextField->activate();
+ } else {
+ _submitted.fire({});
+ }
+ }
}, _masked->lifetime());
raw->boxClosing() | rpl::start_with_next([=] {
setFocus();
@@ -563,6 +575,8 @@ void Field::setupValidator(Fn<ValidateResult(ValidateRequest)> validator) {
.nowValue = now.value,
.nowPosition = now.position,
});
+ _valid = result.finished || !result.invalid;
+
const auto changed = (result.value != now.value);
if (changed) {
setText(result.value);
@@ -609,7 +623,26 @@ void Field::setupFrontBackspace() {
}
}
+void Field::setupSubmit() {
+ const auto submitted = [=] {
+ if (!_valid) {
+ showError();
+ } else if (_nextField) {
+ _nextField->activate();
+ } else {
+ _submitted.fire({});
+ }
+ };
+ if (_masked) {
+ QObject::connect(_masked, &MaskedInputField::submitted, submitted);
+ } else {
+ QObject::connect(_input, &InputField::submitted, submitted);
+ }
+}
+
void Field::setNextField(not_null<Field*> field) {
+ _nextField = field;
+
finished() | rpl::start_with_next([=] {
field->setFocus();
}, _masked ? _masked->lifetime() : _input->lifetime());
@@ -622,13 +655,19 @@ void Field::setPreviousField(not_null<Field*> field) {
}, _masked ? _masked->lifetime() : _input->lifetime());
}
+void Field::activate() {
+ if (_input) {
+ _input->setFocus();
+ } else {
+ _masked->setFocus();
+ }
+}
+
void Field::setFocus() {
if (_config.type == FieldType::Country) {
_wrap->setFocus();
- } else if (_input) {
- _input->setFocus();
} else {
- _masked->setFocus();
+ activate();
}
}
diff --git a/Telegram/SourceFiles/payments/ui/payments_field.h b/Telegram/SourceFiles/payments/ui/payments_field.h
index 5c9c371096..26711ddd93 100644
--- a/Telegram/SourceFiles/payments/ui/payments_field.h
+++ b/Telegram/SourceFiles/payments/ui/payments_field.h
@@ -98,7 +98,9 @@ public:
[[nodiscard]] QString value() const;
[[nodiscard]] rpl::producer<> frontBackspace() const;
[[nodiscard]] rpl::producer<> finished() const;
+ [[nodiscard]] rpl::producer<> submitted() const;
+ void activate();
void setFocus();
void setFocusFast();
void showError();
@@ -120,17 +122,21 @@ private:
void setupCountry();
void setupValidator(Fn<ValidateResult(ValidateRequest)> validator);
void setupFrontBackspace();
+ void setupSubmit();
const FieldConfig _config;
const base::unique_qptr<RpWidget> _wrap;
rpl::event_stream<> _frontBackspace;
rpl::event_stream<> _finished;
+ rpl::event_stream<> _submitted;
rpl::event_stream<> _textPossiblyChanged; // Must be above _masked.
InputField *_input = nullptr;
MaskedInputField *_masked = nullptr;
+ Field *_nextField = nullptr;
QString _countryIso2;
State _was;
bool _validating = false;
+ bool _valid = true;
};