diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp index 72ea2be1a4..d829a3486b 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp @@ -831,7 +831,6 @@ void FormController::decryptValues() { } void FormController::fillErrors() { - // #TODO passport filter by flags const auto find = [&](const MTPSecureValueType &type) -> Value* { const auto converted = ConvertType(type); const auto i = _form.values.find(ConvertType(type)); @@ -841,25 +840,36 @@ void FormController::fillErrors() { LOG(("API Error: Value not found for error type.")); return nullptr; }; - const auto scan = [&](Value &value, bytes::const_span hash) -> File* { - const auto i = ranges::find_if(value.scans, [&](const File &scan) { + using List = std::vector<File>; + const auto findScan = [&](List &list, bytes::const_span hash) -> File* { + const auto i = ranges::find_if(list, [&](const File &scan) { return !bytes::compare(hash, scan.hash); }); - if (i != end(value.scans)) { + if (i != end(list)) { return &*i; } + return nullptr; + }; + const auto scan = [&](Value &value, bytes::const_span hash) -> File* { + if (const auto translation = findScan(value.translations, hash)) { + return translation; + } else if (const auto scan = findScan(value.scans, hash)) { + return scan; + } LOG(("API Error: File not found for error value.")); return nullptr; }; const auto setSpecialScanError = [&](SpecialFile type, auto &&data) { if (const auto value = find(data.vtype)) { - const auto i = value->specialScans.find(type); - if (i != value->specialScans.end()) { - i->second.error = qs(data.vtext); - } else { - LOG(("API Error: " - "Special scan %1 not found for error value." - ).arg(int(type))); + if (value->requiresSpecialScan(type)) { + const auto i = value->specialScans.find(type); + if (i != value->specialScans.end()) { + i->second.error = qs(data.vtext); + } else { + LOG(("API Error: " + "Special scan %1 not found for error value." + ).arg(int(type))); + } } } }; @@ -871,7 +881,9 @@ void FormController::fillErrors() { }, [&](const MTPDsecureValueErrorData &data) { if (const auto value = find(data.vtype)) { const auto key = qs(data.vfield); - value->data.parsed.fields[key].error = qs(data.vtext); + if (!SkipFieldCheck(value, key)) { + value->data.parsed.fields[key].error = qs(data.vtext); + } } }, [&](const MTPDsecureValueErrorFile &data) { const auto hash = bytes::make_span(data.vfile_hash.v); @@ -887,13 +899,17 @@ void FormController::fillErrors() { }, [&](const MTPDsecureValueErrorTranslationFile &data) { const auto hash = bytes::make_span(data.vfile_hash.v); if (const auto value = find(data.vtype)) { - if (const auto file = scan(*value, hash)) { // #TODO passport - file->error = qs(data.vtext); + if (value->translationRequired) { + if (const auto file = scan(*value, hash)) { + file->error = qs(data.vtext); + } } } }, [&](const MTPDsecureValueErrorTranslationFiles &data) { if (const auto value = find(data.vtype)) { - value->translationMissingError = qs(data.vtext); + if (value->translationRequired) { + value->translationMissingError = qs(data.vtext); + } } }, [&](const MTPDsecureValueErrorFrontSide &data) { setSpecialScanError(SpecialFile::FrontSide, data); diff --git a/Telegram/SourceFiles/passport/passport_panel_controller.cpp b/Telegram/SourceFiles/passport/passport_panel_controller.cpp index 5895895cf7..d532496fd3 100644 --- a/Telegram/SourceFiles/passport/passport_panel_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_panel_controller.cpp @@ -324,6 +324,34 @@ EditContactScheme GetContactScheme(Scope::Type type) { Unexpected("Type in GetContactScheme()."); } +const std::map<QString, QString> &NativeNameKeys() { + static const auto result = std::map<QString, QString> { + { qsl("first_name"), qsl("first_name_native") }, + { qsl("last_name"), qsl("last_name_native") }, + { qsl("middle_name"), qsl("middle_name_native") }, + }; + return result; +} + +const std::map<QString, QString> &LatinNameKeys() { + static const auto result = std::map<QString, QString> { + { qsl("first_name_native"), qsl("first_name") }, + { qsl("last_name_native"), qsl("last_name") }, + { qsl("_nativemiddle_name"), qsl("middle_name") }, + }; + return result; +} + +bool SkipFieldCheck(not_null<const Value*> value, const QString &key) { + if (value->type != Value::Type::PersonalDetails) { + return false; + } + const auto &namesMap = value->nativeNames + ? NativeNameKeys() + : LatinNameKeys(); + return namesMap.find(key) == end(namesMap); +} + BoxPointer::BoxPointer(QPointer<BoxContent> value) : _value(value) { } @@ -636,15 +664,19 @@ ScanInfo PanelController::collectScanInfo(const EditFile &file) const { std::vector<ScopeError> PanelController::collectErrors( not_null<const Value*> value) const { + using General = ScopeError::General; + auto result = std::vector<ScopeError>(); if (!value->error.isEmpty()) { - result.push_back({ FileKey(), value->error }); + result.push_back({ General::WholeValue, value->error }); } if (!value->scanMissingError.isEmpty()) { - result.push_back({ FileKey(), value->scanMissingError }); + result.push_back({ General::ScanMissing, value->scanMissingError }); } if (!value->translationMissingError.isEmpty()) { - result.push_back({ FileKey(), value->translationMissingError }); + result.push_back({ + General::TranslationMissing, + value->translationMissingError }); } const auto addFileError = [&](const EditFile &file) { if (!file.fields.error.isEmpty()) { diff --git a/Telegram/SourceFiles/passport/passport_panel_controller.h b/Telegram/SourceFiles/passport/passport_panel_controller.h index b13d031522..7aef43d96b 100644 --- a/Telegram/SourceFiles/passport/passport_panel_controller.h +++ b/Telegram/SourceFiles/passport/passport_panel_controller.h @@ -25,6 +25,10 @@ EditDocumentScheme GetDocumentScheme( base::optional<Value::Type> scansType = base::none); EditContactScheme GetContactScheme(Scope::Type type); +const std::map<QString, QString> &NativeNameKeys(); +const std::map<QString, QString> &LatinNameKeys(); +bool SkipFieldCheck(not_null<const Value*> value, const QString &key); + struct ScanInfo { FileKey key; QString status; @@ -36,12 +40,17 @@ struct ScanInfo { }; struct ScopeError { - // FileKey:id != 0 - file_hash error (bad scan / selfie) - // FileKey:id == 0 - vector<file_hash> error (scan missing) - // QString - data_hash with such key error (bad value) - base::variant<FileKey, QString> key; - QString text; + enum class General { + WholeValue, + ScanMissing, + TranslationMissing, + }; + // FileKey - file_hash error (bad scan / selfie / translation) + // General - general value error (or scan / translation missing) + // QString - data_hash with such key error (bad value) + base::variant<FileKey, General, QString> key; + QString text; }; class BoxPointer {