Ask native names after all other fields are done.

This commit is contained in:
John Preston 2018-08-17 16:42:07 +03:00
parent 9f6d683415
commit e25ecce887
7 changed files with 192 additions and 55 deletions

View File

@ -1633,6 +1633,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_passport_country_choose" = "Choose country";
"lng_passport_document_number" = "Document Number";
"lng_passport_expiry_date" = "Expiry date";
"lng_passport_native_name_title" = "Name in document language";
"lng_passport_native_name_about" = "Your name in the language of the country ({country}) that issued the document.";
"lng_passport_address" = "Address";
"lng_passport_address_enter" = "Enter your address";
"lng_passport_street" = "Street";

View File

@ -200,3 +200,6 @@ passportPasswordAbout1Padding: margins(10px, 28px, 10px, 0px);
passportPasswordAbout2Padding: margins(10px, 0px, 10px, 28px);
passportPasswordIconHeight: 224px;
passportPasswordIcon: icon {{ "passport_password_setup", windowSubTextFg }};
passportNativeNameAboutMargin: margins(0px, 16px, 0px, 0px);
passportNativeNameHeaderPadding: margins(22px, 28px, 33px, 10px);

View File

@ -380,7 +380,7 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
scope.details ? scope.details->nativeNames : false);
for (const auto &row : scheme.rows) {
const auto format = row.format;
if (row.valueClass == EditDocumentScheme::ValueClass::Fields) {
if (row.valueClass != EditDocumentScheme::ValueClass::Scans) {
if (!fields) {
continue;
}

View File

@ -202,40 +202,35 @@ EditDocumentScheme GetDocumentScheme(
Unexpected("scansType in GetDocumentScheme:Identity.");
}
}
using Validator = EditDocumentScheme::Row::Validator;
result.rows = {
{
ValueClass::Fields,
PanelDetailsType::Text,
nativeNames ? qsl("first_name_native") : qsl("first_name"),
qsl("first_name"),
lang(lng_passport_first_name),
nativeNames ? Validator(NativeNameValidate) : NameValidate,
NameValidate,
DontFormat,
kMaxNameSize,
},
{
ValueClass::Fields,
PanelDetailsType::Text,
(nativeNames
? qsl("middle_name_native")
: qsl("middle_name")),
qsl("middle_name"),
lang(lng_passport_middle_name),
(nativeNames
? Validator(NativeNameOrEmptyValidate)
: NameOrEmptyValidate),
NameOrEmptyValidate,
DontFormat,
kMaxNameSize,
nativeNames ? qsl("first_name_native") : qsl("first_name"),
qsl("first_name"),
},
{
ValueClass::Fields,
PanelDetailsType::Text,
nativeNames ? qsl("last_name_native") : qsl("last_name"),
qsl("last_name"),
lang(lng_passport_last_name),
nativeNames ? Validator(NativeNameValidate) : NameValidate,
NameValidate,
DontFormat,
kMaxNameSize,
nativeNames ? qsl("first_name_native") : qsl("first_name"),
qsl("first_name"),
},
{
ValueClass::Fields,
@ -287,6 +282,55 @@ EditDocumentScheme GetDocumentScheme(
DontFormat,
},
};
if (nativeNames) {
result.additionalDependencyKey = qsl("residence_country_code");
result.additionalHeader = lang(lng_passport_native_name_title);
result.additionalDescription = [](const QString &countryCode) {
const auto name = CountrySelectBox::NameByISO(countryCode);
Assert(!name.isEmpty());
return lng_passport_native_name_about(
lt_country,
name);
};
result.additionalShown = [](const QString &countryCode) {
return !countryCode.isEmpty();
};
using Row = EditDocumentScheme::Row;
auto additional = std::initializer_list<Row>{
{
ValueClass::Additional,
PanelDetailsType::Text,
qsl("first_name_native"),
lang(lng_passport_first_name),
NativeNameValidate,
DontFormat,
kMaxNameSize,
},
{
ValueClass::Additional,
PanelDetailsType::Text,
qsl("middle_name_native"),
lang(lng_passport_middle_name),
NativeNameOrEmptyValidate,
DontFormat,
kMaxNameSize,
qsl("first_name_native"),
},
{
ValueClass::Additional,
PanelDetailsType::Text,
qsl("last_name_native"),
lang(lng_passport_last_name),
NativeNameValidate,
DontFormat,
kMaxNameSize,
qsl("first_name_native"),
},
};
for (auto &row : additional) {
result.rows.push_back(std::move(row));
}
}
return result;
} break;

View File

@ -344,22 +344,15 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
std::move(translations)));
}
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 ValueField();
};
const auto enumerateRows = [&](auto &&callback) {
for (auto i = 0, count = int(_scheme.rows.size()); i != count; ++i) {
const auto &row = _scheme.rows[i];
auto fields = (row.valueClass == Scheme::ValueClass::Fields)
? data
: scansData;
Assert(row.valueClass != Scheme::ValueClass::Additional
|| !_scheme.additionalDependencyKey.isEmpty());
auto fields = (row.valueClass == Scheme::ValueClass::Scans)
? scansData
: data;
if (!fields) {
continue;
}
@ -397,32 +390,58 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
st::passportDetailsHeaderPadding);
enumerateRows([&](
int i,
const EditDocumentScheme::Row &row,
const Scheme::Row &row,
const ValueMap &fields) {
const auto current = valueOrEmpty(fields, row.key);
const auto [it, ok] = _details.emplace(
i,
inner->add(PanelDetailsRow::Create(
inner,
row.inputType,
_controller,
row.label,
maxLabelWidth,
current.text,
current.error,
row.lengthLimit)));
const bool details = (&fields == data);
it->second->value(
) | rpl::skip(1) | rpl::start_with_next([=] {
if (details) {
_fieldsChanged = true;
updateCommonError();
} else {
Assert(_editScans != nullptr);
_editScans->scanFieldsChanged(true);
}
}, it->second->lifetime());
if (row.valueClass != Scheme::ValueClass::Additional) {
createDetailsRow(inner, i, row, fields, maxLabelWidth);
}
});
if (data && !_scheme.additionalDependencyKey.isEmpty()) {
const auto row = findRow(_scheme.additionalDependencyKey);
const auto wrap = inner->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
inner,
object_ptr<Ui::VerticalLayout>(inner)));
const auto added = wrap->entity();
added->add(
object_ptr<Ui::FlatLabel>(
added,
_scheme.additionalHeader,
Ui::FlatLabel::InitType::Simple,
st::passportFormHeader),
st::passportNativeNameHeaderPadding);
enumerateRows([&](
int i,
const Scheme::Row &row,
const ValueMap &fields) {
if (row.valueClass == Scheme::ValueClass::Additional) {
createDetailsRow(added, i, row, fields, maxLabelWidth);
}
});
auto description = row->value(
) | rpl::filter([=](const QString &code) {
return _scheme.additionalShown(code);
}) | rpl::map([=](const QString &code) {
return _scheme.additionalDescription(code);
});
added->add(
object_ptr<Ui::DividerLabel>(
added,
object_ptr<Ui::FlatLabel>(
added,
std::move(description),
st::boxDividerLabel),
st::passportFormLabelPadding),
st::passportNativeNameAboutMargin);
wrap->toggleOn(row->value(
) | rpl::map([=](const QString &code) {
return _scheme.additionalShown(code);
}));
wrap->finishAnimating();
}
inner->add(
object_ptr<Ui::FixedHeightWidget>(inner, st::passportDetailsSkip));
@ -442,6 +461,60 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
return inner;
}
void PanelEditDocument::createDetailsRow(
not_null<Ui::VerticalLayout*> container,
int i,
const Scheme::Row &row,
const ValueMap &fields,
int maxLabelWidth) {
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 ValueField();
};
const auto current = valueOrEmpty(fields, row.key);
const auto [it, ok] = _details.emplace(
i,
container->add(PanelDetailsRow::Create(
container,
row.inputType,
_controller,
row.label,
maxLabelWidth,
current.text,
current.error,
row.lengthLimit)));
const bool details = (row.valueClass != Scheme::ValueClass::Scans);
it->second->value(
) | rpl::skip(1) | rpl::start_with_next([=] {
if (details) {
_fieldsChanged = true;
updateCommonError();
} else {
Assert(_editScans != nullptr);
_editScans->scanFieldsChanged(true);
}
}, it->second->lifetime());
}
not_null<PanelDetailsRow*> PanelEditDocument::findRow(
const QString &key) const {
for (auto i = 0, count = int(_scheme.rows.size()); i != count; ++i) {
const auto &row = _scheme.rows[i];
if (row.key == key) {
const auto it = _details.find(i);
Assert(it != end(_details));
return it->second.data();
}
}
Unexpected("Row not found in PanelEditDocument::findRow.");
}
void PanelEditDocument::updateCommonError() {
if (_commonError) {
_commonError->toggle(!_fieldsChanged, anim::type::normal);
@ -484,9 +557,9 @@ PanelEditDocument::Result PanelEditDocument::collect() const {
auto result = Result();
for (const auto [i, field] : _details) {
const auto &row = _scheme.rows[i];
auto &fields = (row.valueClass == Scheme::ValueClass::Fields)
? result.data
: result.filesData;
auto &fields = (row.valueClass == Scheme::ValueClass::Scans)
? result.filesData
: result.data;
fields.fields[row.key].text = field->valueCurrent();
}
return result;

View File

@ -16,6 +16,7 @@ class FadeShadow;
class PlainShadow;
class FlatLabel;
class RoundButton;
class VerticalLayout;
template <typename Widget>
class SlideWrap;
} // namespace Ui
@ -40,6 +41,7 @@ struct ScanListData;
struct EditDocumentScheme {
enum class ValueClass {
Fields,
Additional,
Scans,
};
struct Row {
@ -59,6 +61,11 @@ struct EditDocumentScheme {
QString detailsHeader;
QString scansHeader;
QString additionalDependencyKey;
Fn<bool(const QString &dependency)> additionalShown;
QString additionalHeader;
Fn<QString(const QString &dependency)> additionalDescription;
};
class PanelEditDocument : public Ui::RpWidget {
@ -123,6 +130,14 @@ private:
bool validate();
void save();
void createDetailsRow(
not_null<Ui::VerticalLayout*> container,
int i,
const Scheme::Row &row,
const ValueMap &fields,
int maxLabelWidth);
not_null<PanelDetailsRow*> findRow(const QString &key) const;
not_null<PanelController*> _controller;
Scheme _scheme;

View File

@ -697,7 +697,7 @@ void EditScans::setupSpecialScans(std::map<FileType, ScanInfo> &&files) {
inner->add(object_ptr<Ui::DividerLabel>(
inner,
object_ptr<Ui::FlatLabel>(
_content,
inner,
description(type),
Ui::FlatLabel::InitType::Simple,
st::boxDividerLabel),