mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-19 06:26:55 +00:00
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_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";
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user