forked from kay/RouterOS
.environment(\.locale) + Localizable.xcstrings schaltete Text(LocalizedStringKey)
live nachweislich nicht um. Ersetzt durch Core/Localization/L10n.swift
(Dictionary-Lookup je AppStorage("appLanguage")), Umschalt-Button in der Toolbar.
Vollständig übersetzt: alle Tab-Namen, alle Menü-Kategorien, kompletter
Experte-Tab inkl. Firewall-Formulare. 60 Tests grün, live bestätigt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
70 lines
4.2 KiB
Swift
70 lines
4.2 KiB
Swift
import Foundation
|
|
|
|
/// Manual in-app language switch. Not built on `.environment(\.locale)` + a String Catalog:
|
|
/// that combination only redirects Calendar/DateFormatter-style locale-aware APIs — confirmed
|
|
/// live that toggling the environment override had no effect on `Text(LocalizedStringKey)`
|
|
/// content, which resolves against the bundle's own preferred-localizations negotiation fixed
|
|
/// at launch, not a runtime environment value. This does the substitution directly: `L10n.t`
|
|
/// looks up an English string in a plain dictionary keyed by the German source text, returning
|
|
/// the German text itself when untranslated or when `language == "de"`. Every call site passes
|
|
/// its own observed `appLanguage` so SwiftUI's diffing sees the dependency and re-renders on toggle.
|
|
enum L10n {
|
|
static func t(_ german: String, _ language: String) -> String {
|
|
guard language == "en" else { return german }
|
|
return translations[german] ?? german
|
|
}
|
|
|
|
private static let translations: [String: String] = [
|
|
"Verbinden": "Connect",
|
|
"Einrichten": "Setup",
|
|
"Übersicht": "Topology",
|
|
"Geräte": "Devices",
|
|
"Experte": "Expert",
|
|
"Sicherungen": "Backups",
|
|
"Firewall: Filter-Regeln": "Firewall: Filter Rules",
|
|
"Firewall: NAT (Portweiterleitung etc.)": "Firewall: NAT (port forwarding etc.)",
|
|
"Firewall: Mangle (Markierung/QoS-Vorbereitung)": "Firewall: Mangle (marking/QoS prep)",
|
|
"Firewall: Raw (vor Connection-Tracking)": "Firewall: Raw (before connection tracking)",
|
|
"Firewall: Adress-Listen": "Firewall: Address Lists",
|
|
"Interfaces (Bridge, VLAN, VPN-Tunnel...)": "Interfaces (bridge, VLAN, VPN tunnel...)",
|
|
"IP-Adressierung & Dienste": "IP Addressing & Services",
|
|
"Routing": "Routing",
|
|
"VPN-Server/Clients": "VPN Servers/Clients",
|
|
"WLAN / CAPsMAN": "Wi-Fi / CAPsMAN",
|
|
"Queues / Bandbreiten-Steuerung": "Queues / Bandwidth Control",
|
|
"System": "System",
|
|
"Werkzeuge & Überwachung": "Tools & Monitoring",
|
|
"Nicht verbunden": "Not connected",
|
|
"Verbinde dich zuerst im Tab \"Verbinden\" mit deinem Router.": "Connect to your router first in the \"Connect\" tab.",
|
|
"Eigener Menüpfad": "Custom Menu Path",
|
|
"Jeder RouterOS-Menüpfad ist erreichbar, auch wenn er oben nicht gelistet ist — die Felder erscheinen dann generisch (Schlüssel/Wert), ohne kuratierte Erklärung.":
|
|
"Any RouterOS menu path is reachable, even if it's not listed above — fields then appear generically (key/value), without a curated explanation.",
|
|
"Menüpfad, z.B. /ip firewall filter": "Menu path, e.g. /ip firewall filter",
|
|
"Der RouterOS-CLI-Pfad, z.B. \"/interface wireguard\" oder \"/routing ospf instance\".":
|
|
"The RouterOS CLI path, e.g. \"/interface wireguard\" or \"/routing ospf instance\".",
|
|
"REST-Pfad, z.B. ip/firewall/filter": "REST path, e.g. ip/firewall/filter",
|
|
"Derselbe Pfad in REST-API-Schreibweise: führende \"/\" weg, Leerzeichen zu \"/\".":
|
|
"The same path in REST API notation: drop the leading \"/\", turn spaces into \"/\".",
|
|
"Öffnen": "Open",
|
|
"Kein Menü ausgewählt": "No menu selected",
|
|
"Wähle links einen RouterOS-Bereich aus.": "Select a RouterOS area on the left.",
|
|
"Eintrag löschen": "Delete entry",
|
|
"Einstellungen": "Settings",
|
|
"Einträge": "Entries",
|
|
"Neu hinzufügen": "Add new",
|
|
"Eintrag wirklich löschen?": "Really delete this entry?",
|
|
"Löschen": "Delete",
|
|
"Abbrechen": "Cancel",
|
|
"Weitere Parameter (frei)": "Additional Parameters (free-form)",
|
|
"Für alles, was oben nicht als eigenes Feld aufgeführt ist — RouterOS-Parametername genau wie in der Dokumentation.":
|
|
"For anything not listed as its own field above — use the exact RouterOS parameter name as in the documentation.",
|
|
"Parameter": "Parameter",
|
|
"Wert": "Value",
|
|
"Parameter hinzufügen": "Add parameter",
|
|
"Wird ausgeführt": "About to run",
|
|
"Anlegen": "Create",
|
|
"Speichern": "Save",
|
|
"Jetzt am Router anwenden?": "Apply on the router now?"
|
|
]
|
|
}
|