Fill all required fields in identity and address.

This commit is contained in:
John Preston 2018-04-05 21:01:22 +04:00
parent 2790919733
commit 94bfd59b76
7 changed files with 252 additions and 47 deletions

View File

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

View File

@ -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<BoxContent> value)
: _value(value) {
@ -241,12 +362,20 @@ void PanelController::editScope(int index) {
auto content = [&]() -> object_ptr<Ui::RpWidget> {
switch (_editScope->type) {
case Scope::Type::Identity:
return object_ptr<PanelEditIdentity>(
_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<PanelEditDocument>(
_panel.get(),
this,
std::move(GetDocumentScheme(_editScope->type)),
_editScope->fields->data.parsed,
_editScope->files[_editScopeFilesIndex]->data.parsed,
valueFiles(*_editScope->files[_editScopeFilesIndex]))
: object_ptr<PanelEditDocument>(
_panel.get(),
this,
std::move(GetDocumentScheme(_editScope->type)),
_editScope->fields->data.parsed);
}
return { nullptr };
}();

View File

@ -20,8 +20,13 @@ PanelDetailsRow::PanelDetailsRow(
, _field(this, st::passportDetailsField, nullptr, value) {
}
QPointer<Ui::InputField> 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) {

View File

@ -22,7 +22,8 @@ public:
const QString &label,
const QString &value);
QPointer<Ui::InputField> field() const;
bool setFocusFast();
QString getValue() const;
protected:
int resizeGetHeight(int newWidth) override;

View File

@ -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<PanelController*> controller,
Scheme scheme,
const ValueMap &data,
const ValueMap &scanData,
std::vector<ScanInfo> &&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<PanelController*> 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<ScanInfo> &&files) {
const auto inner = setupContent(data, scanData, std::move(files));
@ -59,9 +78,9 @@ void PanelEditIdentity::setupControls(
});
}
not_null<Ui::RpWidget*> PanelEditIdentity::setupContent(
not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
const ValueMap &data,
const ValueMap &scanData,
const ValueMap *scanData,
std::vector<ScanInfo> &&files) {
const auto inner = _scroll->setOwnedWidget(
object_ptr<Ui::VerticalLayout>(this));
@ -70,8 +89,10 @@ not_null<Ui::RpWidget*> PanelEditIdentity::setupContent(
inner->resizeToWidth(width);
}, inner->lifetime());
_editScans = inner->add(
object_ptr<EditScans>(inner, _controller, std::move(files)));
if (scanData) {
_editScans = inner->add(
object_ptr<EditScans>(inner, _controller, std::move(files)));
}
inner->add(object_ptr<BoxContentDivider>(
inner,
@ -84,34 +105,45 @@ not_null<Ui::RpWidget*> 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<PanelDetailsRow>(
inner,
lang(lng_passport_first_name),
valueOrEmpty("first_name")))->field();
_lastName = inner->add(object_ptr<PanelDetailsRow>(
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<PanelDetailsRow>(
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));
}

View File

@ -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<bool(const QString &value)> validate;
};
std::vector<Row> rows;
};
PanelEditDocument(
QWidget *parent,
not_null<PanelController*> controller,
Scheme scheme,
const ValueMap &data,
const ValueMap &scanData,
std::vector<ScanInfo> &&files);
PanelEditDocument(
QWidget *parent,
not_null<PanelController*> 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<ScanInfo> &&files);
not_null<Ui::RpWidget*> setupContent(
const ValueMap &data,
const ValueMap &scanData,
const ValueMap *scanData,
std::vector<ScanInfo> &&files);
void updateControlsGeometry();
void save();
not_null<PanelController*> _controller;
Scheme _scheme;
object_ptr<Ui::ScrollArea> _scroll;
object_ptr<Ui::FadeShadow> _topShadow;
object_ptr<Ui::PlainShadow> _bottomShadow;
QPointer<EditScans> _editScans;
QPointer<Ui::InputField> _firstName;
QPointer<Ui::InputField> _lastName;
std::vector<QPointer<PanelDetailsRow>> _details;
object_ptr<Ui::RoundButton> _done;

View File

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