diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 232bc877c5..776536aa4c 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1507,7 +1507,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_passport_request2" = "to sign you up for their services"; "lng_passport_password_placeholder" = "Your password"; "lng_passport_next" = "Next"; -"lng_passport_password_wrong" = "Wrong password"; +"lng_passport_password_wrong" = "The password you entered is not valid."; "lng_passport_header" = "Requested information"; "lng_passport_identity_title" = "Identity document"; "lng_passport_identity_description" = "Upload a scan of your passport or other ID"; @@ -1534,8 +1534,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_passport_choose_image" = "Choose scan image"; "lng_passport_delete_scan_undo" = "Undo"; "lng_passport_scan_uploaded" = "Uploaded on {date}"; -"lng_passport_first_name" = "First name"; -"lng_passport_last_name" = "Last name"; +"lng_passport_first_name" = "Name"; +"lng_passport_last_name" = "Surname"; +"lng_passport_birth_date" = "Date of birth"; +"lng_passport_gender" = "Gender"; +"lng_passport_country" = "Country"; +"lng_passport_document_number" = "Card Number"; +"lng_passport_expiry_date" = "Expiry date"; +"lng_passport_street" = "Street"; +"lng_passport_city" = "City"; +"lng_passport_state" = "State"; +"lng_passport_postcode" = "Postcode"; // Wnd specific diff --git a/Telegram/SourceFiles/passport/passport_panel_controller.cpp b/Telegram/SourceFiles/passport/passport_panel_controller.cpp index 5c8d6ae713..ee3b2cea03 100644 --- a/Telegram/SourceFiles/passport/passport_panel_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_panel_controller.cpp @@ -8,12 +8,133 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "passport/passport_panel_controller.h" #include "lang/lang_keys.h" -#include "passport/passport_panel_edit_identity.h" +#include "passport/passport_panel_edit_document.h" #include "passport/passport_panel.h" #include "boxes/confirm_box.h" #include "layout.h" namespace Passport { +namespace { + +PanelEditDocument::Scheme GetDocumentScheme(Scope::Type type) { + using Scheme = PanelEditDocument::Scheme; + + const auto DontValidate = nullptr; + const auto NotEmptyValidate = [](const QString &value) { + return !value.isEmpty(); + }; + const auto DateValidate = [](const QString &value) { + return QRegularExpression( + "^\\d{2}\\.\\d{2}\\.\\d{4}$" + ).match(value).hasMatch(); + }; + const auto DateOrEmptyValidate = [=](const QString &value) { + return value.isEmpty() || DateValidate(value); + }; + const auto GenderValidate = [](const QString &value) { + return value == qstr("male") || value == qstr("female"); + }; + const auto CountryValidate = [](const QString &value) { + return QRegularExpression("^[A-Z]{2}$").match(value).hasMatch(); + }; + + switch (type) { + case Scope::Type::Identity: { + auto result = Scheme(); + result.rows = { + { + Scheme::ValueType::Fields, + qsl("first_name"), + lang(lng_passport_first_name), + NotEmptyValidate + }, + { + Scheme::ValueType::Fields, + qsl("last_name"), + lang(lng_passport_last_name), + DontValidate + }, + { + Scheme::ValueType::Fields, + qsl("birth_date"), + lang(lng_passport_birth_date), + DateValidate, + }, + { + Scheme::ValueType::Fields, + qsl("gender"), + lang(lng_passport_gender), + GenderValidate, + }, + { + Scheme::ValueType::Fields, + qsl("country_code"), + lang(lng_passport_country), + CountryValidate, + }, + { + Scheme::ValueType::Scans, + qsl("document_no"), + lang(lng_passport_document_number), + NotEmptyValidate, + }, + { + Scheme::ValueType::Scans, + qsl("expiry_date"), + lang(lng_passport_expiry_date), + DateOrEmptyValidate, + }, + }; + return result; + } break; + + case Scope::Type::Address: { + auto result = Scheme(); + result.rows = { + { + Scheme::ValueType::Fields, + qsl("street_line1"), + lang(lng_passport_street), + NotEmptyValidate + }, + { + Scheme::ValueType::Fields, + qsl("street_line2"), + lang(lng_passport_street), + DontValidate + }, + { + Scheme::ValueType::Fields, + qsl("city"), + lang(lng_passport_city), + NotEmptyValidate + }, + { + Scheme::ValueType::Fields, + qsl("state"), + lang(lng_passport_state), + DontValidate + }, + { + Scheme::ValueType::Fields, + qsl("country_code"), + lang(lng_passport_country), + CountryValidate + }, + { + Scheme::ValueType::Fields, + qsl("post_code"), + lang(lng_passport_postcode), + NotEmptyValidate + }, + }; + return result; + } break; + } + Unexpected("Type in GetDocumentScheme()."); +} + +} // namespace BoxPointer::BoxPointer(QPointer value) : _value(value) { @@ -241,12 +362,20 @@ void PanelController::editScope(int index) { auto content = [&]() -> object_ptr { switch (_editScope->type) { case Scope::Type::Identity: - return object_ptr( - _panel.get(), - this, - _editScope->fields->data.parsed, - _editScope->files[_editScopeFilesIndex]->data.parsed, - valueFiles(*_editScope->files[_editScopeFilesIndex])); + case Scope::Type::Address: + return (_editScopeFilesIndex >= 0) + ? object_ptr( + _panel.get(), + this, + std::move(GetDocumentScheme(_editScope->type)), + _editScope->fields->data.parsed, + _editScope->files[_editScopeFilesIndex]->data.parsed, + valueFiles(*_editScope->files[_editScopeFilesIndex])) + : object_ptr( + _panel.get(), + this, + std::move(GetDocumentScheme(_editScope->type)), + _editScope->fields->data.parsed); } return { nullptr }; }(); diff --git a/Telegram/SourceFiles/passport/passport_panel_details_row.cpp b/Telegram/SourceFiles/passport/passport_panel_details_row.cpp index b45830563f..c40b5c0f71 100644 --- a/Telegram/SourceFiles/passport/passport_panel_details_row.cpp +++ b/Telegram/SourceFiles/passport/passport_panel_details_row.cpp @@ -20,8 +20,13 @@ PanelDetailsRow::PanelDetailsRow( , _field(this, st::passportDetailsField, nullptr, value) { } -QPointer PanelDetailsRow::field() const { - return _field.data(); +bool PanelDetailsRow::setFocusFast() { + _field->setFocusFast(); + return true; +} + +QString PanelDetailsRow::getValue() const { + return _field->getLastText(); } int PanelDetailsRow::resizeGetHeight(int newWidth) { diff --git a/Telegram/SourceFiles/passport/passport_panel_details_row.h b/Telegram/SourceFiles/passport/passport_panel_details_row.h index 9cbda048ff..55b6dc4133 100644 --- a/Telegram/SourceFiles/passport/passport_panel_details_row.h +++ b/Telegram/SourceFiles/passport/passport_panel_details_row.h @@ -22,7 +22,8 @@ public: const QString &label, const QString &value); - QPointer field() const; + bool setFocusFast(); + QString getValue() const; protected: int resizeGetHeight(int newWidth) override; diff --git a/Telegram/SourceFiles/passport/passport_panel_edit_identity.cpp b/Telegram/SourceFiles/passport/passport_panel_edit_document.cpp similarity index 58% rename from Telegram/SourceFiles/passport/passport_panel_edit_identity.cpp rename to Telegram/SourceFiles/passport/passport_panel_edit_document.cpp index 907fcba04c..d5df557327 100644 --- a/Telegram/SourceFiles/passport/passport_panel_edit_identity.cpp +++ b/Telegram/SourceFiles/passport/passport_panel_edit_document.cpp @@ -5,7 +5,7 @@ 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 "passport/passport_panel_edit_identity.h" +#include "passport/passport_panel_edit_document.h" #include "passport/passport_panel_controller.h" #include "passport/passport_panel_details_row.h" @@ -25,13 +25,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Passport { -PanelEditIdentity::PanelEditIdentity( +PanelEditDocument::PanelEditDocument( QWidget*, not_null controller, + Scheme scheme, const ValueMap &data, const ValueMap &scanData, std::vector &&files) : _controller(controller) +, _scheme(std::move(scheme)) , _scroll(this, st::passportPanelScroll) , _topShadow(this) , _bottomShadow(this) @@ -39,12 +41,29 @@ PanelEditIdentity::PanelEditIdentity( this, langFactory(lng_passport_save_value), st::passportPanelSaveValue) { - setupControls(data, scanData, std::move(files)); + setupControls(data, &scanData, std::move(files)); } -void PanelEditIdentity::setupControls( +PanelEditDocument::PanelEditDocument( + QWidget*, + not_null controller, + Scheme scheme, + const ValueMap &data) +: _controller(controller) +, _scheme(std::move(scheme)) +, _scroll(this, st::passportPanelScroll) +, _topShadow(this) +, _bottomShadow(this) +, _done( + this, + langFactory(lng_passport_save_value), + st::passportPanelSaveValue) { + setupControls(data, nullptr, {}); +} + +void PanelEditDocument::setupControls( const ValueMap &data, - const ValueMap &scanData, + const ValueMap *scanData, std::vector &&files) { const auto inner = setupContent(data, scanData, std::move(files)); @@ -59,9 +78,9 @@ void PanelEditIdentity::setupControls( }); } -not_null PanelEditIdentity::setupContent( +not_null PanelEditDocument::setupContent( const ValueMap &data, - const ValueMap &scanData, + const ValueMap *scanData, std::vector &&files) { const auto inner = _scroll->setOwnedWidget( object_ptr(this)); @@ -70,8 +89,10 @@ not_null PanelEditIdentity::setupContent( inner->resizeToWidth(width); }, inner->lifetime()); - _editScans = inner->add( - object_ptr(inner, _controller, std::move(files))); + if (scanData) { + _editScans = inner->add( + object_ptr(inner, _controller, std::move(files))); + } inner->add(object_ptr( inner, @@ -84,34 +105,45 @@ not_null PanelEditIdentity::setupContent( st::passportFormHeader), st::passportDetailsHeaderPadding); - const auto valueOrEmpty = [&](const QString &key) { - if (const auto i = data.fields.find(key); i != data.fields.end()) { + const auto valueOrEmpty = [&]( + const ValueMap &values, + const QString &key) { + const auto &fields = values.fields; + if (const auto i = fields.find(key); i != fields.end()) { return i->second; } return QString(); }; - _firstName = inner->add(object_ptr( - inner, - lang(lng_passport_first_name), - valueOrEmpty("first_name")))->field(); - _lastName = inner->add(object_ptr( - inner, - lang(lng_passport_last_name), - valueOrEmpty("last_name")))->field(); + for (const auto &row : _scheme.rows) { + auto fields = (row.type == Scheme::ValueType::Fields) + ? &data + : scanData; + if (!fields) { + continue; + } + _details.push_back(inner->add(object_ptr( + inner, + row.label, + valueOrEmpty(*fields, row.key)))); + } return inner; } -void PanelEditIdentity::focusInEvent(QFocusEvent *e) { - _firstName->setFocusFast(); +void PanelEditDocument::focusInEvent(QFocusEvent *e) { + for (const auto row : _details) { + if (row->setFocusFast()) { + return; + } + } } -void PanelEditIdentity::resizeEvent(QResizeEvent *e) { +void PanelEditDocument::resizeEvent(QResizeEvent *e) { updateControlsGeometry(); } -void PanelEditIdentity::updateControlsGeometry() { +void PanelEditDocument::updateControlsGeometry() { const auto submitTop = height() - _done->height(); _scroll->setGeometry(0, 0, width(), submitTop); _topShadow->resizeToWidth(width()); @@ -124,11 +156,18 @@ void PanelEditIdentity::updateControlsGeometry() { _scroll->updateBars(); } -void PanelEditIdentity::save() { +void PanelEditDocument::save() { + Expects(_details.size() == _scheme.rows.size()); + auto data = ValueMap(); - data.fields["first_name"] = _firstName->getLastText(); - data.fields["last_name"] = _lastName->getLastText(); auto scanData = ValueMap(); + for (auto i = 0, count = int(_details.size()); i != count; ++i) { + const auto &row = _scheme.rows[i]; + auto &fields = (row.type == Scheme::ValueType::Fields) + ? data + : scanData; + fields.fields[row.key] = _details[i]->getValue(); + } _controller->saveScope(std::move(data), std::move(scanData)); } diff --git a/Telegram/SourceFiles/passport/passport_panel_edit_identity.h b/Telegram/SourceFiles/passport/passport_panel_edit_document.h similarity index 67% rename from Telegram/SourceFiles/passport/passport_panel_edit_identity.h rename to Telegram/SourceFiles/passport/passport_panel_edit_document.h index 5a1f0f77f1..4b04cd05fb 100644 --- a/Telegram/SourceFiles/passport/passport_panel_edit_identity.h +++ b/Telegram/SourceFiles/passport/passport_panel_edit_document.h @@ -23,15 +23,37 @@ class PanelController; struct ValueMap; struct ScanInfo; class EditScans; +class PanelDetailsRow; -class PanelEditIdentity : public Ui::RpWidget { +class PanelEditDocument : public Ui::RpWidget { public: - PanelEditIdentity( + struct Scheme { + enum class ValueType { + Fields, + Scans, + }; + struct Row { + ValueType type = ValueType::Fields; + QString key; + QString label; + base::lambda validate; + }; + std::vector rows; + + }; + + PanelEditDocument( QWidget *parent, not_null controller, + Scheme scheme, const ValueMap &data, const ValueMap &scanData, std::vector &&files); + PanelEditDocument( + QWidget *parent, + not_null controller, + Scheme scheme, + const ValueMap &data); protected: void focusInEvent(QFocusEvent *e) override; @@ -40,25 +62,25 @@ protected: private: void setupControls( const ValueMap &data, - const ValueMap &scanData, + const ValueMap *scanData, std::vector &&files); not_null setupContent( const ValueMap &data, - const ValueMap &scanData, + const ValueMap *scanData, std::vector &&files); void updateControlsGeometry(); void save(); not_null _controller; + Scheme _scheme; object_ptr _scroll; object_ptr _topShadow; object_ptr _bottomShadow; QPointer _editScans; - QPointer _firstName; - QPointer _lastName; + std::vector> _details; object_ptr _done; diff --git a/Telegram/gyp/telegram_sources.txt b/Telegram/gyp/telegram_sources.txt index ef19383fab..80f7637b5c 100644 --- a/Telegram/gyp/telegram_sources.txt +++ b/Telegram/gyp/telegram_sources.txt @@ -466,8 +466,8 @@ <(src_loc)/passport/passport_panel_controller.h <(src_loc)/passport/passport_panel_details_row.cpp <(src_loc)/passport/passport_panel_details_row.h -<(src_loc)/passport/passport_panel_edit_identity.cpp -<(src_loc)/passport/passport_panel_edit_identity.h +<(src_loc)/passport/passport_panel_edit_document.cpp +<(src_loc)/passport/passport_panel_edit_document.h <(src_loc)/passport/passport_panel_edit_scans.cpp <(src_loc)/passport/passport_panel_edit_scans.h <(src_loc)/passport/passport_panel_form.cpp