mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Removed static storing of passport config.
This commit is contained in:
parent
adb0a9b6f0
commit
2efd735243
7 changed files with 198 additions and 150 deletions
|
@ -42,8 +42,6 @@ constexpr auto kTranslationScansLimit = 20;
|
||||||
constexpr auto kShortPollTimeout = crl::time(3000);
|
constexpr auto kShortPollTimeout = crl::time(3000);
|
||||||
constexpr auto kRememberCredentialsDelay = crl::time(1800 * 1000);
|
constexpr auto kRememberCredentialsDelay = crl::time(1800 * 1000);
|
||||||
|
|
||||||
Config GlobalConfig;
|
|
||||||
|
|
||||||
bool ForwardServiceErrorRequired(const QString &error) {
|
bool ForwardServiceErrorRequired(const QString &error) {
|
||||||
return (error == qstr("BOT_INVALID"))
|
return (error == qstr("BOT_INVALID"))
|
||||||
|| (error == qstr("PUBLIC_KEY_REQUIRED"))
|
|| (error == qstr("PUBLIC_KEY_REQUIRED"))
|
||||||
|
@ -239,46 +237,35 @@ QString ValidateUrl(const QString &url) {
|
||||||
: result;
|
: result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto ParseConfig(const QByteArray &json) {
|
||||||
|
auto languagesByCountryCode = std::map<QString, QString>();
|
||||||
|
auto error = QJsonParseError{ 0, QJsonParseError::NoError };
|
||||||
|
const auto document = QJsonDocument::fromJson(json, &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
LOG(("API Error: Failed to parse passport config, error: %1."
|
||||||
|
).arg(error.errorString()));
|
||||||
|
return languagesByCountryCode;
|
||||||
|
} else if (!document.isObject()) {
|
||||||
|
LOG(("API Error: Not an object received in passport config."));
|
||||||
|
return languagesByCountryCode;
|
||||||
|
}
|
||||||
|
const auto object = document.object();
|
||||||
|
for (auto i = object.constBegin(); i != object.constEnd(); ++i) {
|
||||||
|
const auto countryCode = i.key();
|
||||||
|
const auto language = i.value();
|
||||||
|
if (!language.isString()) {
|
||||||
|
LOG(("API Error: Not a string in passport config item."));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
languagesByCountryCode.emplace(
|
||||||
|
countryCode,
|
||||||
|
language.toString());
|
||||||
|
}
|
||||||
|
return languagesByCountryCode;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Config &ConfigInstance() {
|
|
||||||
return GlobalConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
Config ParseConfig(const MTPhelp_PassportConfig &data) {
|
|
||||||
return data.match([](const MTPDhelp_passportConfig &data) {
|
|
||||||
auto result = Config();
|
|
||||||
result.hash = data.vhash().v;
|
|
||||||
auto error = QJsonParseError{ 0, QJsonParseError::NoError };
|
|
||||||
const auto document = QJsonDocument::fromJson(
|
|
||||||
data.vcountries_langs().c_dataJSON().vdata().v,
|
|
||||||
&error);
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
LOG(("API Error: Failed to parse passport config, error: %1."
|
|
||||||
).arg(error.errorString()));
|
|
||||||
return result;
|
|
||||||
} else if (!document.isObject()) {
|
|
||||||
LOG(("API Error: Not an object received in passport config."));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const auto object = document.object();
|
|
||||||
for (auto i = object.constBegin(); i != object.constEnd(); ++i) {
|
|
||||||
const auto countryCode = i.key();
|
|
||||||
const auto language = i.value();
|
|
||||||
if (!language.isString()) {
|
|
||||||
LOG(("API Error: Not a string in passport config item."));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
result.languagesByCountryCode.emplace(
|
|
||||||
countryCode,
|
|
||||||
language.toString());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}, [](const MTPDhelp_passportConfigNotModified &data) {
|
|
||||||
return ConfigInstance();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QString NonceNameByScope(const QString &scope) {
|
QString NonceNameByScope(const QString &scope) {
|
||||||
if (scope.startsWith('{') && scope.endsWith('}')) {
|
if (scope.startsWith('{') && scope.endsWith('}')) {
|
||||||
return qsl("nonce");
|
return qsl("nonce");
|
||||||
|
@ -638,7 +625,6 @@ Main::Session &FormController::session() const {
|
||||||
void FormController::show() {
|
void FormController::show() {
|
||||||
requestForm();
|
requestForm();
|
||||||
requestPassword();
|
requestPassword();
|
||||||
requestConfig();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UserData *FormController::bot() const {
|
UserData *FormController::bot() const {
|
||||||
|
@ -1242,6 +1228,44 @@ void FormController::fillErrors() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<EditDocumentCountry> FormController::preferredLanguage(
|
||||||
|
const QString &countryCode) {
|
||||||
|
const auto findLang = [=] {
|
||||||
|
if (countryCode.isEmpty()) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
auto &langs = _passportConfig.languagesByCountryCode;
|
||||||
|
const auto i = langs.find(countryCode);
|
||||||
|
return (i == end(langs)) ? QString() : i->second;
|
||||||
|
};
|
||||||
|
return [=](auto consumer) {
|
||||||
|
const auto hash = _passportConfig.hash;
|
||||||
|
if (hash) {
|
||||||
|
consumer.put_next({ countryCode, findLang() });
|
||||||
|
consumer.put_done();
|
||||||
|
return rpl::lifetime() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
_api.request(MTPhelp_GetPassportConfig(
|
||||||
|
MTP_int(hash)
|
||||||
|
)).done([=](const MTPhelp_PassportConfig &result) {
|
||||||
|
result.match([&](const MTPDhelp_passportConfig &data) {
|
||||||
|
_passportConfig.hash = data.vhash().v;
|
||||||
|
_passportConfig.languagesByCountryCode = ParseConfig(
|
||||||
|
data.vcountries_langs().c_dataJSON().vdata().v);
|
||||||
|
}, [](const MTPDhelp_passportConfigNotModified &data) {
|
||||||
|
});
|
||||||
|
consumer.put_next({ countryCode, findLang() });
|
||||||
|
consumer.put_done();
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
consumer.put_next({ countryCode, QString() });
|
||||||
|
consumer.put_done();
|
||||||
|
}).send();
|
||||||
|
|
||||||
|
return rpl::lifetime();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void FormController::fillNativeFromFallback() {
|
void FormController::fillNativeFromFallback() {
|
||||||
// Check if additional values (*_name_native) were requested.
|
// Check if additional values (*_name_native) were requested.
|
||||||
const auto i = _form.values.find(Value::Type::PersonalDetails);
|
const auto i = _form.values.find(Value::Type::PersonalDetails);
|
||||||
|
@ -1254,48 +1278,58 @@ void FormController::fillNativeFromFallback() {
|
||||||
const auto scheme = GetDocumentScheme(
|
const auto scheme = GetDocumentScheme(
|
||||||
Scope::Type::PersonalDetails,
|
Scope::Type::PersonalDetails,
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
true);
|
true,
|
||||||
|
[=](const QString &code) { return preferredLanguage(code); });
|
||||||
const auto dependencyIt = values.fields.find(
|
const auto dependencyIt = values.fields.find(
|
||||||
scheme.additionalDependencyKey);
|
scheme.additionalDependencyKey);
|
||||||
const auto dependency = (dependencyIt == end(values.fields))
|
const auto dependency = (dependencyIt == end(values.fields))
|
||||||
? QString()
|
? QString()
|
||||||
: dependencyIt->second.text;
|
: dependencyIt->second.text;
|
||||||
if (scheme.additionalShown(dependency)
|
|
||||||
!= EditDocumentScheme::AdditionalVisibility::OnlyIfError) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy additional values from fallback if they're not filled yet.
|
// Copy additional values from fallback if they're not filled yet.
|
||||||
auto changed = false;
|
|
||||||
using Scheme = EditDocumentScheme;
|
using Scheme = EditDocumentScheme;
|
||||||
for (const auto &row : scheme.rows) {
|
scheme.preferredLanguage(
|
||||||
if (row.valueClass == Scheme::ValueClass::Additional) {
|
dependency
|
||||||
const auto nativeIt = values.fields.find(row.key);
|
) | rpl::map(
|
||||||
const auto native = (nativeIt == end(values.fields))
|
scheme.additionalShown
|
||||||
? QString()
|
) | rpl::take(
|
||||||
: nativeIt->second.text;
|
1
|
||||||
if (!native.isEmpty()
|
) | rpl::start_with_next([=](Scheme::AdditionalVisibility v) {
|
||||||
|| (nativeIt != end(values.fields)
|
if (v != Scheme::AdditionalVisibility::OnlyIfError) {
|
||||||
&& !nativeIt->second.error.isEmpty())) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
auto values = i->second.data.parsed;
|
||||||
const auto latinIt = values.fields.find(
|
auto changed = false;
|
||||||
row.additionalFallbackKey);
|
|
||||||
const auto latin = (latinIt == end(values.fields))
|
for (const auto &row : scheme.rows) {
|
||||||
? QString()
|
if (row.valueClass == Scheme::ValueClass::Additional) {
|
||||||
: latinIt->second.text;
|
const auto nativeIt = values.fields.find(row.key);
|
||||||
if (row.error(latin).has_value()) {
|
const auto native = (nativeIt == end(values.fields))
|
||||||
return;
|
? QString()
|
||||||
} else if (native != latin) {
|
: nativeIt->second.text;
|
||||||
values.fields[row.key].text = latin;
|
if (!native.isEmpty()
|
||||||
changed = true;
|
|| (nativeIt != end(values.fields)
|
||||||
|
&& !nativeIt->second.error.isEmpty())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto latinIt = values.fields.find(
|
||||||
|
row.additionalFallbackKey);
|
||||||
|
const auto latin = (latinIt == end(values.fields))
|
||||||
|
? QString()
|
||||||
|
: latinIt->second.text;
|
||||||
|
if (row.error(latin).has_value()) {
|
||||||
|
return;
|
||||||
|
} else if (native != latin) {
|
||||||
|
values.fields[row.key].text = latin;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (changed) {
|
||||||
if (changed) {
|
startValueEdit(&i->second);
|
||||||
startValueEdit(&i->second);
|
saveValueEdit(&i->second, std::move(values));
|
||||||
saveValueEdit(&i->second, std::move(values));
|
}
|
||||||
}
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormController::decryptValue(Value &value) const {
|
void FormController::decryptValue(Value &value) const {
|
||||||
|
@ -2507,20 +2541,6 @@ void FormController::formDone(const MTPaccount_AuthorizationForm &result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormController::requestConfig() {
|
|
||||||
const auto hash = ConfigInstance().hash;
|
|
||||||
_configRequestId = _api.request(MTPhelp_GetPassportConfig(
|
|
||||||
MTP_int(hash)
|
|
||||||
)).done([=](const MTPhelp_PassportConfig &result) {
|
|
||||||
_configRequestId = 0;
|
|
||||||
ConfigInstance() = ParseConfig(result);
|
|
||||||
showForm();
|
|
||||||
}).fail([=](const MTP::Error &error) {
|
|
||||||
_configRequestId = 0;
|
|
||||||
showForm();
|
|
||||||
}).send();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FormController::parseForm(const MTPaccount_AuthorizationForm &result) {
|
bool FormController::parseForm(const MTPaccount_AuthorizationForm &result) {
|
||||||
Expects(result.type() == mtpc_account_authorizationForm);
|
Expects(result.type() == mtpc_account_authorizationForm);
|
||||||
|
|
||||||
|
@ -2614,7 +2634,7 @@ void FormController::shortPollEmailConfirmation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormController::showForm() {
|
void FormController::showForm() {
|
||||||
if (_formRequestId || _passwordRequestId || _configRequestId) {
|
if (_formRequestId || _passwordRequestId) {
|
||||||
return;
|
return;
|
||||||
} else if (!_bot) {
|
} else if (!_bot) {
|
||||||
formFail(Lang::Hard::NoAuthorizationBot());
|
formFail(Lang::Hard::NoAuthorizationBot());
|
||||||
|
|
|
@ -29,12 +29,7 @@ class Session;
|
||||||
|
|
||||||
namespace Passport {
|
namespace Passport {
|
||||||
|
|
||||||
struct Config {
|
struct EditDocumentCountry;
|
||||||
int32 hash = 0;
|
|
||||||
std::map<QString, QString> languagesByCountryCode;
|
|
||||||
};
|
|
||||||
Config &ConfigInstance();
|
|
||||||
Config ParseConfig(const MTPhelp_PassportConfig &data);
|
|
||||||
|
|
||||||
struct SavedCredentials {
|
struct SavedCredentials {
|
||||||
bytes::vector hashForAuth;
|
bytes::vector hashForAuth;
|
||||||
|
@ -416,6 +411,9 @@ public:
|
||||||
void cancel();
|
void cancel();
|
||||||
void cancelSure();
|
void cancelSure();
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<EditDocumentCountry> preferredLanguage(
|
||||||
|
const QString &countryCode);
|
||||||
|
|
||||||
rpl::lifetime &lifetime();
|
rpl::lifetime &lifetime();
|
||||||
|
|
||||||
~FormController();
|
~FormController();
|
||||||
|
@ -439,7 +437,6 @@ private:
|
||||||
|
|
||||||
void requestForm();
|
void requestForm();
|
||||||
void requestPassword();
|
void requestPassword();
|
||||||
void requestConfig();
|
|
||||||
|
|
||||||
void formDone(const MTPaccount_AuthorizationForm &result);
|
void formDone(const MTPaccount_AuthorizationForm &result);
|
||||||
void formFail(const QString &error);
|
void formFail(const QString &error);
|
||||||
|
@ -560,7 +557,6 @@ private:
|
||||||
mtpRequestId _formRequestId = 0;
|
mtpRequestId _formRequestId = 0;
|
||||||
mtpRequestId _passwordRequestId = 0;
|
mtpRequestId _passwordRequestId = 0;
|
||||||
mtpRequestId _passwordCheckRequestId = 0;
|
mtpRequestId _passwordCheckRequestId = 0;
|
||||||
mtpRequestId _configRequestId = 0;
|
|
||||||
|
|
||||||
PasswordSettings _password;
|
PasswordSettings _password;
|
||||||
crl::time _lastSrpIdInvalidTime = 0;
|
crl::time _lastSrpIdInvalidTime = 0;
|
||||||
|
@ -572,6 +568,11 @@ private:
|
||||||
mtpRequestId _recoverRequestId = 0;
|
mtpRequestId _recoverRequestId = 0;
|
||||||
base::flat_map<FileKey, std::unique_ptr<mtpFileLoader>> _fileLoaders;
|
base::flat_map<FileKey, std::unique_ptr<mtpFileLoader>> _fileLoaders;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int32 hash = 0;
|
||||||
|
std::map<QString, QString> languagesByCountryCode;
|
||||||
|
} _passportConfig;
|
||||||
|
|
||||||
rpl::event_stream<not_null<const EditFile*>> _scanUpdated;
|
rpl::event_stream<not_null<const EditFile*>> _scanUpdated;
|
||||||
rpl::event_stream<not_null<const Value*>> _valueSaveFinished;
|
rpl::event_stream<not_null<const Value*>> _valueSaveFinished;
|
||||||
rpl::event_stream<not_null<const Value*>> _verificationNeeded;
|
rpl::event_stream<not_null<const Value*>> _verificationNeeded;
|
||||||
|
|
|
@ -377,7 +377,8 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
|
||||||
const auto scheme = GetDocumentScheme(
|
const auto scheme = GetDocumentScheme(
|
||||||
scope.type,
|
scope.type,
|
||||||
document ? base::make_optional(document->type) : std::nullopt,
|
document ? base::make_optional(document->type) : std::nullopt,
|
||||||
scope.details ? scope.details->nativeNames : false);
|
scope.details ? scope.details->nativeNames : false,
|
||||||
|
nullptr);
|
||||||
using ValueClass = EditDocumentScheme::ValueClass;
|
using ValueClass = EditDocumentScheme::ValueClass;
|
||||||
const auto skipAdditional = [&] {
|
const auto skipAdditional = [&] {
|
||||||
if (!fields) {
|
if (!fields) {
|
||||||
|
|
|
@ -117,7 +117,8 @@ std::map<FileType, ScanInfo> PrepareSpecialFiles(const Value &value) {
|
||||||
EditDocumentScheme GetDocumentScheme(
|
EditDocumentScheme GetDocumentScheme(
|
||||||
Scope::Type type,
|
Scope::Type type,
|
||||||
std::optional<Value::Type> scansType,
|
std::optional<Value::Type> scansType,
|
||||||
bool nativeNames) {
|
bool nativeNames,
|
||||||
|
preferredLangCallback &&preferredLanguage) {
|
||||||
using Scheme = EditDocumentScheme;
|
using Scheme = EditDocumentScheme;
|
||||||
using ValueClass = Scheme::ValueClass;
|
using ValueClass = Scheme::ValueClass;
|
||||||
const auto DontFormat = nullptr;
|
const auto DontFormat = nullptr;
|
||||||
|
@ -294,21 +295,17 @@ EditDocumentScheme GetDocumentScheme(
|
||||||
if (nativeNames) {
|
if (nativeNames) {
|
||||||
result.additionalDependencyKey = qsl("residence_country_code");
|
result.additionalDependencyKey = qsl("residence_country_code");
|
||||||
|
|
||||||
const auto languageValue = [](const QString &countryCode) {
|
result.preferredLanguage = preferredLanguage
|
||||||
if (countryCode.isEmpty()) {
|
? std::move(preferredLanguage)
|
||||||
return QString();
|
: [](const QString &) {
|
||||||
}
|
return rpl::single(EditDocumentCountry());
|
||||||
const auto &config = ConfigInstance();
|
};
|
||||||
const auto i = config.languagesByCountryCode.find(
|
const auto languageValue = [](const QString &langCode) {
|
||||||
countryCode);
|
return Lang::GetNonDefaultValue(kLanguageNamePrefix
|
||||||
if (i == end(config.languagesByCountryCode)) {
|
+ langCode.toUtf8());
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
return Lang::GetNonDefaultValue(
|
|
||||||
kLanguageNamePrefix + i->second.toUtf8());
|
|
||||||
};
|
};
|
||||||
result.additionalHeader = [=](const QString &countryCode) {
|
result.additionalHeader = [=](const EditDocumentCountry &info) {
|
||||||
const auto language = languageValue(countryCode);
|
const auto language = languageValue(info.languageCode);
|
||||||
return language.isEmpty()
|
return language.isEmpty()
|
||||||
? tr::lng_passport_native_name_title(tr::now)
|
? tr::lng_passport_native_name_title(tr::now)
|
||||||
: tr::lng_passport_native_name_language(
|
: tr::lng_passport_native_name_language(
|
||||||
|
@ -316,32 +313,28 @@ EditDocumentScheme GetDocumentScheme(
|
||||||
lt_language,
|
lt_language,
|
||||||
language);
|
language);
|
||||||
};
|
};
|
||||||
result.additionalDescription = [=](const QString &countryCode) {
|
result.additionalDescription = [=](
|
||||||
const auto language = languageValue(countryCode);
|
const EditDocumentCountry &info) {
|
||||||
|
const auto language = languageValue(info.languageCode);
|
||||||
if (!language.isEmpty()) {
|
if (!language.isEmpty()) {
|
||||||
return tr::lng_passport_native_name_language_about(tr::now);
|
return tr::lng_passport_native_name_language_about(
|
||||||
|
tr::now);
|
||||||
}
|
}
|
||||||
const auto name = Countries::Instance().countryNameByISO2(
|
const auto name = Countries::Instance().countryNameByISO2(
|
||||||
countryCode);
|
info.countryCode);
|
||||||
Assert(!name.isEmpty());
|
Assert(!name.isEmpty());
|
||||||
return tr::lng_passport_native_name_about(
|
return tr::lng_passport_native_name_about(
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_country,
|
lt_country,
|
||||||
name);
|
name);
|
||||||
};
|
};
|
||||||
result.additionalShown = [](const QString &countryCode) {
|
result.additionalShown = [](const EditDocumentCountry &info) {
|
||||||
using Result = EditDocumentScheme::AdditionalVisibility;
|
using Result = EditDocumentScheme::AdditionalVisibility;
|
||||||
if (countryCode.isEmpty()) {
|
return (info.countryCode.isEmpty())
|
||||||
return Result::Hidden;
|
? Result::Hidden
|
||||||
}
|
: (info.languageCode == "en")
|
||||||
const auto &config = ConfigInstance();
|
? Result::OnlyIfError
|
||||||
const auto i = config.languagesByCountryCode.find(
|
: Result::Shown;
|
||||||
countryCode);
|
|
||||||
if (i != end(config.languagesByCountryCode)
|
|
||||||
&& i->second == "en") {
|
|
||||||
return Result::OnlyIfError;
|
|
||||||
}
|
|
||||||
return Result::Shown;
|
|
||||||
};
|
};
|
||||||
using Row = EditDocumentScheme::Row;
|
using Row = EditDocumentScheme::Row;
|
||||||
auto additional = std::initializer_list<Row>{
|
auto additional = std::initializer_list<Row>{
|
||||||
|
@ -1149,6 +1142,10 @@ void PanelController::startScopeEdit(
|
||||||
_form->startValueEdit(_editDocument);
|
_form->startValueEdit(_editDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto preferredLanguage = [=](const QString &countryCode) {
|
||||||
|
return _form->preferredLanguage(countryCode);
|
||||||
|
};
|
||||||
|
|
||||||
auto content = [&]() -> object_ptr<Ui::RpWidget> {
|
auto content = [&]() -> object_ptr<Ui::RpWidget> {
|
||||||
switch (_editScope->type) {
|
switch (_editScope->type) {
|
||||||
case Scope::Type::Identity:
|
case Scope::Type::Identity:
|
||||||
|
@ -1169,7 +1166,8 @@ void PanelController::startScopeEdit(
|
||||||
GetDocumentScheme(
|
GetDocumentScheme(
|
||||||
_editScope->type,
|
_editScope->type,
|
||||||
_editDocument->type,
|
_editDocument->type,
|
||||||
_editValue->nativeNames),
|
_editValue->nativeNames,
|
||||||
|
std::move(preferredLanguage)),
|
||||||
_editValue->error,
|
_editValue->error,
|
||||||
_editValue->data.parsedInEdit,
|
_editValue->data.parsedInEdit,
|
||||||
_editDocument->error,
|
_editDocument->error,
|
||||||
|
@ -1183,7 +1181,8 @@ void PanelController::startScopeEdit(
|
||||||
GetDocumentScheme(
|
GetDocumentScheme(
|
||||||
_editScope->type,
|
_editScope->type,
|
||||||
_editDocument->type,
|
_editDocument->type,
|
||||||
false),
|
false,
|
||||||
|
std::move(preferredLanguage)),
|
||||||
_editDocument->error,
|
_editDocument->error,
|
||||||
_editDocument->data.parsedInEdit,
|
_editDocument->data.parsedInEdit,
|
||||||
std::move(scans),
|
std::move(scans),
|
||||||
|
@ -1204,7 +1203,8 @@ void PanelController::startScopeEdit(
|
||||||
GetDocumentScheme(
|
GetDocumentScheme(
|
||||||
_editScope->type,
|
_editScope->type,
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
_editValue->nativeNames),
|
_editValue->nativeNames,
|
||||||
|
std::move(preferredLanguage)),
|
||||||
_editValue->error,
|
_editValue->error,
|
||||||
_editValue->data.parsedInEdit);
|
_editValue->data.parsedInEdit);
|
||||||
const auto weak = Ui::MakeWeak(result.data());
|
const auto weak = Ui::MakeWeak(result.data());
|
||||||
|
|
|
@ -20,15 +20,19 @@ namespace Passport {
|
||||||
class FormController;
|
class FormController;
|
||||||
class Panel;
|
class Panel;
|
||||||
|
|
||||||
|
struct EditDocumentCountry;
|
||||||
struct EditDocumentScheme;
|
struct EditDocumentScheme;
|
||||||
struct EditContactScheme;
|
struct EditContactScheme;
|
||||||
|
|
||||||
enum class ReadScanError;
|
enum class ReadScanError;
|
||||||
|
|
||||||
|
using preferredLangCallback =
|
||||||
|
Fn<rpl::producer<EditDocumentCountry>(const QString &)>;
|
||||||
EditDocumentScheme GetDocumentScheme(
|
EditDocumentScheme GetDocumentScheme(
|
||||||
Scope::Type type,
|
Scope::Type type,
|
||||||
std::optional<Value::Type> scansType,
|
std::optional<Value::Type> scansType,
|
||||||
bool nativeNames);
|
bool nativeNames,
|
||||||
|
preferredLangCallback &&preferredLanguage);
|
||||||
EditContactScheme GetContactScheme(Scope::Type type);
|
EditContactScheme GetContactScheme(Scope::Type type);
|
||||||
|
|
||||||
const std::map<QString, QString> &LatinToNativeMap();
|
const std::map<QString, QString> &LatinToNativeMap();
|
||||||
|
|
|
@ -425,25 +425,42 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
|
||||||
showIfError = true;
|
showIfError = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const auto shown = [=](const QString &code) {
|
const auto shown = [=](const Scheme::CountryInfo &info) {
|
||||||
using Result = Scheme::AdditionalVisibility;
|
using Result = Scheme::AdditionalVisibility;
|
||||||
const auto value = _scheme.additionalShown(code);
|
const auto value = _scheme.additionalShown(info);
|
||||||
return (value == Result::Shown)
|
return (value == Result::Shown)
|
||||||
|| (value == Result::OnlyIfError && showIfError);
|
|| (value == Result::OnlyIfError && showIfError);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto title = row->value(
|
auto langValue = row->value(
|
||||||
) | rpl::filter(
|
) | rpl::map(
|
||||||
|
_scheme.preferredLanguage
|
||||||
|
) | rpl::flatten_latest();
|
||||||
|
|
||||||
|
auto title = rpl::duplicate(langValue) | rpl::filter(
|
||||||
shown
|
shown
|
||||||
) | rpl::map([=](const QString &code) {
|
) | rpl::map([=](const Scheme::CountryInfo &info) {
|
||||||
return _scheme.additionalHeader(code);
|
return _scheme.additionalHeader(info);
|
||||||
});
|
});
|
||||||
added->add(
|
const auto headerLabel = added->add(
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
added,
|
added,
|
||||||
std::move(title),
|
rpl::duplicate(title),
|
||||||
st::passportFormHeader),
|
st::passportFormHeader),
|
||||||
st::passportNativeNameHeaderPadding);
|
st::passportNativeNameHeaderPadding);
|
||||||
|
std::move(
|
||||||
|
title
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
const auto &padding = st::passportNativeNameHeaderPadding;
|
||||||
|
const auto available = added->width()
|
||||||
|
- padding.left()
|
||||||
|
- padding.right();
|
||||||
|
headerLabel->resizeToNaturalWidth(available);
|
||||||
|
headerLabel->moveToLeft(
|
||||||
|
padding.left(),
|
||||||
|
padding.top(),
|
||||||
|
available);
|
||||||
|
}, headerLabel->lifetime());
|
||||||
|
|
||||||
enumerateRows([&](
|
enumerateRows([&](
|
||||||
int i,
|
int i,
|
||||||
|
@ -454,11 +471,10 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
auto description = row->value(
|
auto description = rpl::duplicate(langValue) | rpl::filter(
|
||||||
) | rpl::filter(
|
|
||||||
shown
|
shown
|
||||||
) | rpl::map([=](const QString &code) {
|
) | rpl::map([=](const Scheme::CountryInfo &info) {
|
||||||
return _scheme.additionalDescription(code);
|
return _scheme.additionalDescription(info);
|
||||||
});
|
});
|
||||||
added->add(
|
added->add(
|
||||||
object_ptr<Ui::DividerLabel>(
|
object_ptr<Ui::DividerLabel>(
|
||||||
|
@ -470,11 +486,10 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
|
||||||
st::passportFormLabelPadding),
|
st::passportFormLabelPadding),
|
||||||
st::passportNativeNameAboutMargin);
|
st::passportNativeNameAboutMargin);
|
||||||
|
|
||||||
wrap->toggleOn(row->value() | rpl::map(shown));
|
wrap->toggleOn(rpl::duplicate(langValue) | rpl::map(shown));
|
||||||
wrap->finishAnimating();
|
wrap->finishAnimating();
|
||||||
|
|
||||||
row->value(
|
std::move(langValue) | rpl::map(
|
||||||
) | rpl::map(
|
|
||||||
shown
|
shown
|
||||||
) | rpl::start_with_next([=](bool visible) {
|
) | rpl::start_with_next([=](bool visible) {
|
||||||
_additionalShown = visible;
|
_additionalShown = visible;
|
||||||
|
|
|
@ -39,6 +39,11 @@ class EditScans;
|
||||||
enum class FileType;
|
enum class FileType;
|
||||||
struct ScanListData;
|
struct ScanListData;
|
||||||
|
|
||||||
|
struct EditDocumentCountry {
|
||||||
|
QString countryCode;
|
||||||
|
QString languageCode;
|
||||||
|
};
|
||||||
|
|
||||||
struct EditDocumentScheme {
|
struct EditDocumentScheme {
|
||||||
enum class ValueClass {
|
enum class ValueClass {
|
||||||
Fields,
|
Fields,
|
||||||
|
@ -50,6 +55,7 @@ struct EditDocumentScheme {
|
||||||
OnlyIfError,
|
OnlyIfError,
|
||||||
Shown,
|
Shown,
|
||||||
};
|
};
|
||||||
|
using CountryInfo = EditDocumentCountry;
|
||||||
struct Row {
|
struct Row {
|
||||||
using Validator = Fn<std::optional<QString>(const QString &value)>;
|
using Validator = Fn<std::optional<QString>(const QString &value)>;
|
||||||
using Formatter = Fn<QString(const QString &value)>;
|
using Formatter = Fn<QString(const QString &value)>;
|
||||||
|
@ -69,9 +75,10 @@ struct EditDocumentScheme {
|
||||||
QString scansHeader;
|
QString scansHeader;
|
||||||
|
|
||||||
QString additionalDependencyKey;
|
QString additionalDependencyKey;
|
||||||
Fn<AdditionalVisibility(const QString &dependency)> additionalShown;
|
Fn<AdditionalVisibility(const CountryInfo &dependency)> additionalShown;
|
||||||
Fn<QString(const QString &dependency)> additionalHeader;
|
Fn<QString(const CountryInfo &dependency)> additionalHeader;
|
||||||
Fn<QString(const QString &dependency)> additionalDescription;
|
Fn<QString(const CountryInfo &dependency)> additionalDescription;
|
||||||
|
Fn<rpl::producer<CountryInfo>(const QString &)> preferredLanguage;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue