mirror of https://github.com/procxx/kepka.git
Ask native names after all other fields are done.
This commit is contained in:
parent
9f6d683415
commit
e25ecce887
|
@ -1633,6 +1633,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_passport_country_choose" = "Choose country";
|
"lng_passport_country_choose" = "Choose country";
|
||||||
"lng_passport_document_number" = "Document Number";
|
"lng_passport_document_number" = "Document Number";
|
||||||
"lng_passport_expiry_date" = "Expiry date";
|
"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" = "Address";
|
||||||
"lng_passport_address_enter" = "Enter your address";
|
"lng_passport_address_enter" = "Enter your address";
|
||||||
"lng_passport_street" = "Street";
|
"lng_passport_street" = "Street";
|
||||||
|
|
|
@ -200,3 +200,6 @@ passportPasswordAbout1Padding: margins(10px, 28px, 10px, 0px);
|
||||||
passportPasswordAbout2Padding: margins(10px, 0px, 10px, 28px);
|
passportPasswordAbout2Padding: margins(10px, 0px, 10px, 28px);
|
||||||
passportPasswordIconHeight: 224px;
|
passportPasswordIconHeight: 224px;
|
||||||
passportPasswordIcon: icon {{ "passport_password_setup", windowSubTextFg }};
|
passportPasswordIcon: icon {{ "passport_password_setup", windowSubTextFg }};
|
||||||
|
|
||||||
|
passportNativeNameAboutMargin: margins(0px, 16px, 0px, 0px);
|
||||||
|
passportNativeNameHeaderPadding: margins(22px, 28px, 33px, 10px);
|
||||||
|
|
|
@ -380,7 +380,7 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
|
||||||
scope.details ? scope.details->nativeNames : false);
|
scope.details ? scope.details->nativeNames : false);
|
||||||
for (const auto &row : scheme.rows) {
|
for (const auto &row : scheme.rows) {
|
||||||
const auto format = row.format;
|
const auto format = row.format;
|
||||||
if (row.valueClass == EditDocumentScheme::ValueClass::Fields) {
|
if (row.valueClass != EditDocumentScheme::ValueClass::Scans) {
|
||||||
if (!fields) {
|
if (!fields) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,40 +202,35 @@ EditDocumentScheme GetDocumentScheme(
|
||||||
Unexpected("scansType in GetDocumentScheme:Identity.");
|
Unexpected("scansType in GetDocumentScheme:Identity.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using Validator = EditDocumentScheme::Row::Validator;
|
|
||||||
result.rows = {
|
result.rows = {
|
||||||
{
|
{
|
||||||
ValueClass::Fields,
|
ValueClass::Fields,
|
||||||
PanelDetailsType::Text,
|
PanelDetailsType::Text,
|
||||||
nativeNames ? qsl("first_name_native") : qsl("first_name"),
|
qsl("first_name"),
|
||||||
lang(lng_passport_first_name),
|
lang(lng_passport_first_name),
|
||||||
nativeNames ? Validator(NativeNameValidate) : NameValidate,
|
NameValidate,
|
||||||
DontFormat,
|
DontFormat,
|
||||||
kMaxNameSize,
|
kMaxNameSize,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ValueClass::Fields,
|
ValueClass::Fields,
|
||||||
PanelDetailsType::Text,
|
PanelDetailsType::Text,
|
||||||
(nativeNames
|
qsl("middle_name"),
|
||||||
? qsl("middle_name_native")
|
|
||||||
: qsl("middle_name")),
|
|
||||||
lang(lng_passport_middle_name),
|
lang(lng_passport_middle_name),
|
||||||
(nativeNames
|
NameOrEmptyValidate,
|
||||||
? Validator(NativeNameOrEmptyValidate)
|
|
||||||
: NameOrEmptyValidate),
|
|
||||||
DontFormat,
|
DontFormat,
|
||||||
kMaxNameSize,
|
kMaxNameSize,
|
||||||
nativeNames ? qsl("first_name_native") : qsl("first_name"),
|
qsl("first_name"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ValueClass::Fields,
|
ValueClass::Fields,
|
||||||
PanelDetailsType::Text,
|
PanelDetailsType::Text,
|
||||||
nativeNames ? qsl("last_name_native") : qsl("last_name"),
|
qsl("last_name"),
|
||||||
lang(lng_passport_last_name),
|
lang(lng_passport_last_name),
|
||||||
nativeNames ? Validator(NativeNameValidate) : NameValidate,
|
NameValidate,
|
||||||
DontFormat,
|
DontFormat,
|
||||||
kMaxNameSize,
|
kMaxNameSize,
|
||||||
nativeNames ? qsl("first_name_native") : qsl("first_name"),
|
qsl("first_name"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ValueClass::Fields,
|
ValueClass::Fields,
|
||||||
|
@ -287,6 +282,55 @@ EditDocumentScheme GetDocumentScheme(
|
||||||
DontFormat,
|
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;
|
return result;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -344,22 +344,15 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
|
||||||
std::move(translations)));
|
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) {
|
const auto enumerateRows = [&](auto &&callback) {
|
||||||
for (auto i = 0, count = int(_scheme.rows.size()); i != count; ++i) {
|
for (auto i = 0, count = int(_scheme.rows.size()); i != count; ++i) {
|
||||||
const auto &row = _scheme.rows[i];
|
const auto &row = _scheme.rows[i];
|
||||||
auto fields = (row.valueClass == Scheme::ValueClass::Fields)
|
|
||||||
? data
|
Assert(row.valueClass != Scheme::ValueClass::Additional
|
||||||
: scansData;
|
|| !_scheme.additionalDependencyKey.isEmpty());
|
||||||
|
auto fields = (row.valueClass == Scheme::ValueClass::Scans)
|
||||||
|
? scansData
|
||||||
|
: data;
|
||||||
if (!fields) {
|
if (!fields) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -397,32 +390,58 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
|
||||||
st::passportDetailsHeaderPadding);
|
st::passportDetailsHeaderPadding);
|
||||||
enumerateRows([&](
|
enumerateRows([&](
|
||||||
int i,
|
int i,
|
||||||
const EditDocumentScheme::Row &row,
|
const Scheme::Row &row,
|
||||||
const ValueMap &fields) {
|
const ValueMap &fields) {
|
||||||
const auto current = valueOrEmpty(fields, row.key);
|
if (row.valueClass != Scheme::ValueClass::Additional) {
|
||||||
const auto [it, ok] = _details.emplace(
|
createDetailsRow(inner, i, row, fields, maxLabelWidth);
|
||||||
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 (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(
|
inner->add(
|
||||||
object_ptr<Ui::FixedHeightWidget>(inner, st::passportDetailsSkip));
|
object_ptr<Ui::FixedHeightWidget>(inner, st::passportDetailsSkip));
|
||||||
|
@ -442,6 +461,60 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
|
||||||
return inner;
|
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() {
|
void PanelEditDocument::updateCommonError() {
|
||||||
if (_commonError) {
|
if (_commonError) {
|
||||||
_commonError->toggle(!_fieldsChanged, anim::type::normal);
|
_commonError->toggle(!_fieldsChanged, anim::type::normal);
|
||||||
|
@ -484,9 +557,9 @@ PanelEditDocument::Result PanelEditDocument::collect() const {
|
||||||
auto result = Result();
|
auto result = Result();
|
||||||
for (const auto [i, field] : _details) {
|
for (const auto [i, field] : _details) {
|
||||||
const auto &row = _scheme.rows[i];
|
const auto &row = _scheme.rows[i];
|
||||||
auto &fields = (row.valueClass == Scheme::ValueClass::Fields)
|
auto &fields = (row.valueClass == Scheme::ValueClass::Scans)
|
||||||
? result.data
|
? result.filesData
|
||||||
: result.filesData;
|
: result.data;
|
||||||
fields.fields[row.key].text = field->valueCurrent();
|
fields.fields[row.key].text = field->valueCurrent();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -16,6 +16,7 @@ class FadeShadow;
|
||||||
class PlainShadow;
|
class PlainShadow;
|
||||||
class FlatLabel;
|
class FlatLabel;
|
||||||
class RoundButton;
|
class RoundButton;
|
||||||
|
class VerticalLayout;
|
||||||
template <typename Widget>
|
template <typename Widget>
|
||||||
class SlideWrap;
|
class SlideWrap;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
@ -40,6 +41,7 @@ struct ScanListData;
|
||||||
struct EditDocumentScheme {
|
struct EditDocumentScheme {
|
||||||
enum class ValueClass {
|
enum class ValueClass {
|
||||||
Fields,
|
Fields,
|
||||||
|
Additional,
|
||||||
Scans,
|
Scans,
|
||||||
};
|
};
|
||||||
struct Row {
|
struct Row {
|
||||||
|
@ -59,6 +61,11 @@ struct EditDocumentScheme {
|
||||||
QString detailsHeader;
|
QString detailsHeader;
|
||||||
QString scansHeader;
|
QString scansHeader;
|
||||||
|
|
||||||
|
QString additionalDependencyKey;
|
||||||
|
Fn<bool(const QString &dependency)> additionalShown;
|
||||||
|
QString additionalHeader;
|
||||||
|
Fn<QString(const QString &dependency)> additionalDescription;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PanelEditDocument : public Ui::RpWidget {
|
class PanelEditDocument : public Ui::RpWidget {
|
||||||
|
@ -123,6 +130,14 @@ private:
|
||||||
bool validate();
|
bool validate();
|
||||||
void save();
|
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;
|
not_null<PanelController*> _controller;
|
||||||
Scheme _scheme;
|
Scheme _scheme;
|
||||||
|
|
||||||
|
|
|
@ -697,7 +697,7 @@ void EditScans::setupSpecialScans(std::map<FileType, ScanInfo> &&files) {
|
||||||
inner->add(object_ptr<Ui::DividerLabel>(
|
inner->add(object_ptr<Ui::DividerLabel>(
|
||||||
inner,
|
inner,
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
_content,
|
inner,
|
||||||
description(type),
|
description(type),
|
||||||
Ui::FlatLabel::InitType::Simple,
|
Ui::FlatLabel::InitType::Simple,
|
||||||
st::boxDividerLabel),
|
st::boxDividerLabel),
|
||||||
|
|
Loading…
Reference in New Issue