Compare commits

...

2 Commits

Author SHA1 Message Date
c78dfbcf12 loclization update 2025-10-07 03:00:41 +03:00
19251ed52f translate to english 2025-10-07 02:42:44 +03:00
5 changed files with 843 additions and 93 deletions

View File

@ -151,7 +151,7 @@ final class AuthService {
return
}
completion(true, apiResponse.data.message)
completion(true, NSLocalizedString(apiResponse.data.message, comment: ""))
} catch {
completion(false, NSLocalizedString("Не удалось обработать ответ сервера.", comment: ""))
}
@ -280,20 +280,28 @@ final class AuthService {
case .network(let err):
return String(format: NSLocalizedString("Ошибка сети: %@", comment: ""), err.localizedDescription)
case .server(let statusCode, let data):
if let message = extractMessage(from: data) {
return message
}
let message = extractMessage(from: data)
switch statusCode {
case 401:
return NSLocalizedString("Необходимо авторизоваться заново.", comment: "")
case 403:
if let message,
Self.changePasswordForbiddenMessages.contains(message) {
return NSLocalizedString(message, comment: "")
}
return NSLocalizedString("Старый пароль указан неверно или совпадает с новым.", comment: "")
case 422:
if let message {
return message
}
return NSLocalizedString("Проверьте данные и повторите попытку.", comment: "")
case 429:
return NSLocalizedString("Слишком много попыток. Попробуйте позже.", comment: "")
default:
if let message {
return message
}
return String(format: NSLocalizedString("Ошибка сервера: %@", comment: ""), "\(statusCode)")
}
case .unauthorized:
@ -305,7 +313,8 @@ final class AuthService {
private func extractMessage(from data: Data?) -> String? {
guard let data else { return nil }
if let response = try? JSONDecoder().decode(ErrorResponse.self, from: data) {
let decoder = JSONDecoder()
if let response = try? decoder.decode(ErrorResponse.self, from: data) {
if let message = response.data?.message, !message.isEmpty {
return message
}
@ -313,7 +322,58 @@ final class AuthService {
return detail
}
}
if let jsonObject = try? JSONSerialization.jsonObject(with: data) {
if let dictionary = jsonObject as? [String: Any] {
if let detail = Self.normalizedMessage(dictionary["detail"] as? String) {
return detail
}
if let dataDict = dictionary["data"] as? [String: Any],
let message = Self.normalizedMessage(dataDict["message"] as? String) {
return message
}
if let errors = dictionary["errors"] as? [[String: Any]],
let firstMessage = errors.compactMap({ Self.normalizedMessage($0["message"] as? String) }).first {
return firstMessage
}
} else if let array = jsonObject as? [[String: Any]] {
if let firstMessage = array.compactMap({ item -> String? in
if let detail = Self.normalizedMessage(item["detail"] as? String) {
return detail
}
if let message = Self.normalizedMessage(item["message"] as? String) {
return message
}
if let msg = Self.normalizedMessage(item["msg"] as? String) {
return msg
}
return nil
}).first {
return firstMessage
}
}
}
if let string = Self.normalizedMessage(String(data: data, encoding: .utf8)) {
return string
}
return nil
}
}
private extension AuthService {
static let changePasswordForbiddenMessages: Set<String> = [
"Неверный текущий пароль",
"Пароль должен отличаться от старого",
"Пароль не удовлетворяет требованиям"
]
static func normalizedMessage(_ raw: String?) -> String? {
guard let raw = raw?.trimmingCharacters(in: .whitespacesAndNewlines), !raw.isEmpty else {
return nil
}
return raw
}
}

File diff suppressed because it is too large Load Diff

View File

@ -12,24 +12,24 @@ enum ThemeOption: String, CaseIterable, Identifiable {
var title: String {
switch self {
case .system:
return "Системная"
return NSLocalizedString("Системная", comment: "")
case .oledDark:
return "OLEG тёмный"
return NSLocalizedString("OLEG тёмный", comment: "")
case .dark:
return "Тёмная"
return NSLocalizedString("Тёмная", comment: "")
case .lightTest:
return "Светлая"
return NSLocalizedString("Светлая", comment: "")
case .custom:
return "Кастомная"
return NSLocalizedString("Кастомная", comment: "")
}
}
var note: String? {
switch self {
case .lightTest:
return "Тестовая версия"
return NSLocalizedString("Тестовая версия", comment: "")
case .dark, .custom:
return "Недоступна"
return NSLocalizedString("Недоступна", comment: "")
default:
return nil
}

View File

@ -176,7 +176,7 @@ struct ChangePasswordView: View {
.alert(item: $alertData) { data in
Alert(
title: Text(data.kind == .success
? NSLocalizedString("Пароль обновлен", comment: "")
? NSLocalizedString("Ура!", comment: "")
: NSLocalizedString("Ошибка", comment: "")),
message: Text(data.message),
dismissButton: .default(Text(NSLocalizedString("OK", comment: ""))) {

View File

@ -21,9 +21,9 @@ struct SettingsView: View {
// }
// MARK: - Безопасность
Section(header: Text("Безопасность")) {
Section(header: Text(NSLocalizedString("Безопасность", comment: ""))) {
NavigationLink(destination: ChangePasswordView()) {
Label("Сменить пароль", systemImage: "key")
Label(NSLocalizedString("Сменить пароль", comment: ""), systemImage: "key")
}
NavigationLink(destination: Text("Заглушка: Двухфакторная аутентификация")) {
Label("Двухфакторная аутентификация", systemImage: "lock.shield")