Warn before closing payment panel.

This commit is contained in:
John Preston 2021-04-02 16:10:23 +04:00
parent 69b70cda54
commit 62684ab9bb
6 changed files with 54 additions and 20 deletions

View file

@ -1855,6 +1855,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_theme_editor_menu_show" = "Show palette file";
"lng_payments_not_supported" = "Sorry, Telegram Desktop doesn't support payments yet. Please use one of our mobile apps to do this.";
"lng_payments_sure_close" = "Are you sure you want to close this payment form? The changes you made will be lost.";
"lng_payments_receipt_label" = "Receipt";
"lng_payments_receipt_label_test" = "Test receipt";
"lng_payments_invoice_label" = "Invoice";

View file

@ -301,7 +301,11 @@ void CheckoutProcess::handleError(const Error &error) {
}
void CheckoutProcess::panelRequestClose() {
panelCloseSure(); // #TODO payments confirmation
if (_form->hasChanges()) {
_panel->showCloseConfirm();
} else {
panelCloseSure();
}
}
void CheckoutProcess::panelCloseSure() {
@ -353,7 +357,7 @@ void CheckoutProcess::panelSubmit() {
|| invoice.isEmailRequested
|| invoice.isPhoneRequested)) {
_submitState = SubmitState::Validating;
_form->validateInformation(_form->savedInformation());
_form->validateInformation(_form->information());
} else if (!method.newCredentials && !method.savedCredentials) {
editPaymentMethod();
} else {
@ -461,7 +465,7 @@ void CheckoutProcess::panelEditPhone() {
void CheckoutProcess::showForm() {
_panel->showForm(
_form->invoice(),
_form->savedInformation(),
_form->information(),
_form->paymentMethod().ui,
_form->shippingOptions());
}
@ -473,7 +477,7 @@ void CheckoutProcess::showEditInformation(Ui::InformationField field) {
}
_panel->showEditInformation(
_form->invoice(),
_form->savedInformation(),
_form->information(),
field);
}
@ -485,7 +489,7 @@ void CheckoutProcess::showInformationError(Ui::InformationField field) {
}
_panel->showInformationError(
_form->invoice(),
_form->savedInformation(),
_form->information(),
field);
}
@ -613,7 +617,7 @@ void CheckoutProcess::panelShowBox(object_ptr<Ui::BoxContent> box) {
void CheckoutProcess::performInitialSilentValidation() {
const auto &invoice = _form->invoice();
const auto &saved = _form->savedInformation();
const auto &saved = _form->information();
if (invoice.receipt
|| (invoice.isNameRequested && saved.name.isEmpty())
|| (invoice.isEmailRequested && saved.email.isEmpty())

View file

@ -383,7 +383,7 @@ void Form::processDetails(const MTPDpayments_paymentReceipt &data) {
void Form::processSavedInformation(const MTPDpaymentRequestedInfo &data) {
const auto address = data.vshipping_address();
_savedInformation = Ui::RequestedInformation{
_savedInformation = _information = Ui::RequestedInformation{
.defaultPhone = defaultPhone(),
.defaultCountry = defaultCountry(),
.name = qs(data.vname().value_or_empty()),
@ -578,7 +578,10 @@ void Form::validateInformation(const Ui::RequestedInformation &information) {
&& _shippingOptions.list.size() == 1) {
_shippingOptions.selectedId = _shippingOptions.list.front().id;
}
_savedInformation = _validatedInformation;
_information = _validatedInformation;
if (_information.save) {
_savedInformation = _information;
}
_updates.fire(ValidateFinished{});
}).fail([=](const MTP::Error &error) {
_validateRequestId = 0;
@ -586,6 +589,15 @@ void Form::validateInformation(const Ui::RequestedInformation &information) {
}).send();
}
bool Form::hasChanges() const {
const auto &information = _validateRequestId
? _validatedInformation
: _information;
return (information != _savedInformation)
|| (_stripe != nullptr)
|| !_paymentMethod.newCredentials.empty();
}
bool Form::validateInformationLocal(
const Ui::RequestedInformation &information) const {
if (const auto error = informationErrorLocal(information)) {

View file

@ -164,8 +164,8 @@ public:
[[nodiscard]] const FormDetails &details() const {
return _details;
}
[[nodiscard]] const Ui::RequestedInformation &savedInformation() const {
return _savedInformation;
[[nodiscard]] const Ui::RequestedInformation &information() const {
return _information;
}
[[nodiscard]] const PaymentMethod &paymentMethod() const {
return _paymentMethod;
@ -173,6 +173,7 @@ public:
[[nodiscard]] const Ui::ShippingOptions &shippingOptions() const {
return _shippingOptions;
}
[[nodiscard]] bool hasChanges() const;
[[nodiscard]] rpl::producer<FormUpdate> updates() const {
return _updates.events();
@ -234,7 +235,6 @@ private:
[[nodiscard]] Error cardErrorLocal(
const Ui::UncheckedCardDetails &details) const;
const not_null<Main::Session*> _session;
MTP::Sender _api;
not_null<PeerData*> _peer;
@ -245,6 +245,7 @@ private:
std::unique_ptr<ThumbnailLoadProcess> _thumbnailLoadProcess;
FormDetails _details;
Ui::RequestedInformation _savedInformation;
Ui::RequestedInformation _information;
PaymentMethod _paymentMethod;
Ui::RequestedInformation _validatedInformation;

View file

@ -113,7 +113,7 @@ void Panel::showInformationError(
}
void Panel::chooseShippingOption(const ShippingOptions &options) {
showBox(Box([=](not_null<Ui::GenericBox*> box) {
showBox(Box([=](not_null<GenericBox*> box) {
const auto i = ranges::find(
options.list,
options.selectedId,
@ -121,14 +121,14 @@ void Panel::chooseShippingOption(const ShippingOptions &options) {
const auto index = (i != end(options.list))
? (i - begin(options.list))
: -1;
const auto group = std::make_shared<Ui::RadiobuttonGroup>(index);
const auto group = std::make_shared<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>(
object_ptr<Radiobutton>(
layout,
group,
index,
@ -185,7 +185,7 @@ void Panel::chooseTips(const Invoice &invoice) {
const auto max = invoice.tipsMax;
const auto now = invoice.tipsSelected;
const auto currency = invoice.currency;
showBox(Box([=](not_null<Ui::GenericBox*> box) {
showBox(Box([=](not_null<GenericBox*> box) {
box->setTitle(tr::lng_payments_tips_box_title());
const auto row = box->lifetime().make_state<Field>(
box,
@ -363,7 +363,7 @@ void Panel::choosePaymentMethod(const PaymentMethodDetails &method) {
showEditPaymentMethod(method);
return;
}
showBox(Box([=](not_null<Ui::GenericBox*> box) {
showBox(Box([=](not_null<GenericBox*> box) {
const auto save = [=](int option) {
if (option) {
showEditPaymentMethod(method);
@ -379,9 +379,9 @@ void Panel::choosePaymentMethod(const PaymentMethodDetails &method) {
}
void Panel::askSetPassword() {
showBox(Box([=](not_null<Ui::GenericBox*> box) {
showBox(Box([=](not_null<GenericBox*> box) {
box->addRow(
object_ptr<Ui::FlatLabel>(
object_ptr<FlatLabel>(
box.get(),
tr::lng_payments_need_password(),
st::boxLabel),
@ -394,6 +394,21 @@ void Panel::askSetPassword() {
}));
}
void Panel::showCloseConfirm() {
showBox(Box([=](not_null<GenericBox*> box) {
box->addRow(
object_ptr<FlatLabel>(
box.get(),
tr::lng_payments_sure_close(),
st::boxLabel),
st::boxPadding);
box->addButton(tr::lng_close(), [=] {
_delegate->panelCloseSure();
});
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
}));
}
void Panel::showEditCard(
const NativeMethodDetails &native,
CardField field) {
@ -438,10 +453,10 @@ rpl::producer<> Panel::backRequests() const {
return _widget->backRequests();
}
void Panel::showBox(object_ptr<Ui::BoxContent> box) {
void Panel::showBox(object_ptr<BoxContent> box) {
_widget->showBox(
std::move(box),
Ui::LayerOption::KeepOther,
LayerOption::KeepOther,
anim::type::normal);
}

View file

@ -68,6 +68,7 @@ public:
void chooseTips(const Invoice &invoice);
void choosePaymentMethod(const PaymentMethodDetails &method);
void askSetPassword();
void showCloseConfirm();
bool showWebview(
const QString &url,