diff --git a/CHANGELOG.md b/CHANGELOG.md index 41b789d..574d363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to GeoShift are documented here. +## 1.5.2 — 2026-07-21 + +### Added + +- A compact English/Russian language switch in the main window header. +- Apple emoji flags in both the main-window and Settings language controls. + +### Changed + +- The default window height now fits the collapsed interface instead of leaving + a large empty area below Diagnostics. +- Expanded diagnostics remain bounded inside their own scrolling log panel, and + the main window can still be resized vertically. + ## 1.5.1 — 2026-07-21 ### Fixed diff --git a/README.md b/README.md index acb4d88..978c1b5 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

CI - Version 1.5.1 + Version 1.5.2 macOS 14+ Swift 6.2 MIT License diff --git a/Sources/GeoShift/AppLanguage.swift b/Sources/GeoShift/AppLanguage.swift index 16ac661..054b932 100644 --- a/Sources/GeoShift/AppLanguage.swift +++ b/Sources/GeoShift/AppLanguage.swift @@ -15,6 +15,15 @@ enum AppLanguage: String, CaseIterable, Identifiable, Sendable { } } + var selectionLabel: String { + switch self { + case .english: + "🇬🇧 \(displayName)" + case .russian: + "🇷🇺 \(displayName)" + } + } + var locale: Locale { Locale(identifier: rawValue) } diff --git a/Sources/GeoShift/ContentView.swift b/Sources/GeoShift/ContentView.swift index 4c8446f..0ee48e0 100644 --- a/Sources/GeoShift/ContentView.swift +++ b/Sources/GeoShift/ContentView.swift @@ -42,6 +42,9 @@ struct ContentView: View { .sheet(isPresented: $isSettingsPresented) { SettingsView(controller: controller) } + .onChange(of: localization.language) { + controller.languageDidChange() + } } private func showCityPicker() { diff --git a/Sources/GeoShift/GeoShiftApp.swift b/Sources/GeoShift/GeoShiftApp.swift index b7191e3..abec8f5 100644 --- a/Sources/GeoShift/GeoShiftApp.swift +++ b/Sources/GeoShift/GeoShiftApp.swift @@ -23,7 +23,7 @@ struct GeoShiftApp: App { controller.startMonitoring() } } - .defaultSize(width: 760, height: 820) + .defaultSize(width: 760, height: 680) .windowResizability(.contentMinSize) } } diff --git a/Sources/GeoShift/HeaderView.swift b/Sources/GeoShift/HeaderView.swift index c739baf..beb9162 100644 --- a/Sources/GeoShift/HeaderView.swift +++ b/Sources/GeoShift/HeaderView.swift @@ -16,11 +16,15 @@ struct HeaderView: View { Spacer() - Button( - localization.text("header.settings"), - systemImage: "gearshape", - action: settingsAction - ) + HStack { + LanguagePicker(controlSize: .small) + + Button( + localization.text("header.settings"), + systemImage: "gearshape", + action: settingsAction + ) + } } } } diff --git a/Sources/GeoShift/LanguagePicker.swift b/Sources/GeoShift/LanguagePicker.swift new file mode 100644 index 0000000..3f3b356 --- /dev/null +++ b/Sources/GeoShift/LanguagePicker.swift @@ -0,0 +1,24 @@ +import SwiftUI + +struct LanguagePicker: View { + var controlSize: ControlSize = .regular + @Environment(LocalizationStore.self) private var localization + + var body: some View { + @Bindable var localization = localization + + Picker( + localization.text("settings.language"), + selection: $localization.language + ) { + ForEach(AppLanguage.allCases) { language in + Text(language.selectionLabel).tag(language) + } + } + .pickerStyle(.segmented) + .labelsHidden() + .controlSize(controlSize) + .fixedSize() + .accessibilityLabel(localization.text("settings.language")) + } +} diff --git a/Sources/GeoShift/SettingsView.swift b/Sources/GeoShift/SettingsView.swift index 93666da..eb6340e 100644 --- a/Sources/GeoShift/SettingsView.swift +++ b/Sources/GeoShift/SettingsView.swift @@ -6,20 +6,12 @@ struct SettingsView: View { @Environment(LocalizationStore.self) private var localization var body: some View { - @Bindable var localization = localization - NavigationStack { Form { Section(localization.text("settings.languageSection")) { - Picker( - localization.text("settings.language"), - selection: $localization.language - ) { - ForEach(AppLanguage.allCases) { language in - Text(language.displayName).tag(language) - } + LabeledContent(localization.text("settings.language")) { + LanguagePicker() } - .pickerStyle(.segmented) } Section(localization.text("settings.timings")) { @@ -78,9 +70,6 @@ struct SettingsView: View { .onChange(of: controller.locationRefreshSeconds) { controller.applySettings() } - .onChange(of: localization.language) { - controller.languageDidChange() - } } private func durationOption(_ seconds: Int) -> some View { diff --git a/Tests/GeoShiftTests/LocalizationTests.swift b/Tests/GeoShiftTests/LocalizationTests.swift index bbb4c89..12deb99 100644 --- a/Tests/GeoShiftTests/LocalizationTests.swift +++ b/Tests/GeoShiftTests/LocalizationTests.swift @@ -38,10 +38,12 @@ struct LocalizationTests { localization.language = .english #expect(localization.text("header.subtitle") == "Control iPhone GPS simulation from your Mac") #expect(localization.text("settings.language") == "App language") + #expect(AppLanguage.english.selectionLabel == "🇬🇧 English") localization.language = .russian #expect(localization.text("header.subtitle").contains("симуляцией GPS")) #expect(localization.text("settings.language") == "Язык приложения") + #expect(AppLanguage.russian.selectionLabel == "🇷🇺 Русский") #expect(KeeperError.commandFailed("The command timed out after 5 seconds.") .description(using: localization) == "Команда завершилась с ошибкой.") } diff --git a/version.env b/version.env index e5556a8..ca3b362 100644 --- a/version.env +++ b/version.env @@ -1,2 +1,2 @@ -MARKETING_VERSION=1.5.1 -BUILD_NUMBER=8 +MARKETING_VERSION=1.5.2 +BUILD_NUMBER=9