Skip to content

Commit 387d1a9

Browse files
author
Iakov Senatov
committed
feat: add Language picker to Settings > General
1 parent e49bd58 commit 387d1a9

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

GUI/Sources/Settings/SettingsPanes.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,41 @@ private struct StubPane: View {
6868
// MARK: General
6969
// MARK: - ════════════════════════════════════════════
7070

71+
// MARK: - Supported App Languages
72+
enum AppLanguage: String, CaseIterable, Identifiable {
73+
case system = "system"
74+
case en = "en"
75+
case de = "de"
76+
case ru = "ru"
77+
var id: String { rawValue }
78+
var displayName: String {
79+
switch self {
80+
case .system: return "System Default"
81+
case .en: return "English"
82+
case .de: return "Deutsch"
83+
case .ru: return "Русский"
84+
}
85+
}
86+
/// Apply language override to UserDefaults (takes effect on next launch)
87+
static func apply(_ language: AppLanguage) {
88+
if language == .system {
89+
UserDefaults.standard.removeObject(forKey: "AppleLanguages")
90+
} else {
91+
UserDefaults.standard.set([language.rawValue], forKey: "AppleLanguages")
92+
}
93+
log.info("[Settings] Language set to '\(language.displayName)' — restart required")
94+
}
95+
/// Read current setting from UserDefaults
96+
static func current() -> AppLanguage {
97+
guard let langs = UserDefaults.standard.array(forKey: "AppleLanguages") as? [String],
98+
let first = langs.first,
99+
let lang = AppLanguage(rawValue: first) else {
100+
return .system
101+
}
102+
return lang
103+
}
104+
}
105+
// MARK: - SettingsGeneralPane
71106
struct SettingsGeneralPane: View {
72107

73108
@AppStorage("settings.appearance") private var appearance: String = "system"
@@ -76,6 +111,8 @@ struct SettingsGeneralPane: View {
76111
@AppStorage("settings.showHiddenFiles") private var showHiddenFiles: Bool = false
77112
@AppStorage("settings.showExtensions") private var showExtensions: Bool = true
78113
@AppStorage("settings.startupPath") private var startupPath: String = "home"
114+
@State private var selectedLanguage: AppLanguage = AppLanguage.current()
115+
@State private var showRestartHint: Bool = false
79116

80117
var body: some View {
81118
VStack(alignment: .leading, spacing: 20) {
@@ -96,6 +133,32 @@ struct SettingsGeneralPane: View {
96133
}
97134
}
98135

136+
// ── Language ──
137+
SettingsGroupBox {
138+
VStack(spacing: 0) {
139+
SettingsRow(label: "Language:", help: "UI language for menus, labels and dialogs") {
140+
HStack(spacing: 12) {
141+
Picker("", selection: $selectedLanguage) {
142+
ForEach(AppLanguage.allCases) { lang in
143+
Text(lang.displayName).tag(lang)
144+
}
145+
}
146+
.labelsHidden()
147+
.frame(width: 180)
148+
.onChange(of: selectedLanguage) { _, newLang in
149+
AppLanguage.apply(newLang)
150+
showRestartHint = newLang != .system
151+
}
152+
if showRestartHint {
153+
Label("Restart app to apply", systemImage: "arrow.clockwise")
154+
.font(.system(size: 11))
155+
.foregroundStyle(.orange)
156+
}
157+
}
158+
}
159+
}
160+
}
161+
99162
// ── Text & Icons ──
100163
SettingsGroupBox {
101164
VStack(spacing: 0) {

0 commit comments

Comments
 (0)