diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 344c9508..eda4fa4b 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -12,7 +12,14 @@ } }, "**Thank you so much for your support.** Feel free to leave another tip in the future if you’re feeling generous." : { - + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "**Grazie mille per il tuo supporto.** Sentiti libero di lasciare un altro suggerimento in futuro se ti senti generoso." + } + } + } }, "%@" : { @@ -169,6 +176,16 @@ } } }, + "%@ Solstice" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ Solstice" + } + } + } + }, "%@ Time Travel" : { "localizations" : { "it" : { @@ -239,6 +256,16 @@ } } }, + "a specific time" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "un momento specifico" + } + } + } + }, "About Solstice" : { "localizations" : { "it" : { @@ -454,7 +481,7 @@ "it" : { "stringUnit" : { "state" : "translated", - "value" : "Customise notification content" + "value" : "Personalizza il contenuto delle notifiche" } } } @@ -489,6 +516,16 @@ } } }, + "Daylight gain/loss" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Guadagno/perdita di luce diurna" + } + } + } + }, "Daylight in %@" : { "localizations" : { "it" : { @@ -529,6 +566,16 @@ } } }, + "December" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dicembre" + } + } + } + }, "Delete Location" : { "localizations" : { "it" : { @@ -699,6 +746,16 @@ } } }, + "Graphical" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Grafico" + } + } + } + }, "Imagery Source: [NASA Visible Earth Catalog](https://visibleearth.nasa.gov/collection/1484/blue-marble)" : { "localizations" : { "it" : { @@ -729,6 +786,16 @@ } } }, + "June" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Giugno" + } + } + } + }, "Learn more about the equinox and solstice" : { "localizations" : { "it" : { @@ -850,6 +917,16 @@ } } }, + "March" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Marzo" + } + } + } + }, "more" : { "comment" : "More daylight middle of sentence", "localizations" : { @@ -871,6 +948,36 @@ } } }, + "my location" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "mia posizione" + } + } + } + }, + "My Location" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La mia posizione" + } + } + } + }, + "My Location %@" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "La mia posizione %@" + } + } + } + }, "Nautical Sunrise" : { "localizations" : { "it" : { @@ -921,6 +1028,16 @@ } } }, + "No change" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nessun cambiamento" + } + } + } + }, "No daylight left today. The sun set %@ ago." : { "localizations" : { "it" : { @@ -1052,6 +1169,16 @@ } } }, + "Remove daylight gain/loss" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rimuovere il guadagno/perdita della luce diurna" + } + } + } + }, "Reset" : { "localizations" : { "it" : { @@ -1132,6 +1259,16 @@ } } }, + "September" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Settembre" + } + } + } + }, "Set Up Location Access" : { "localizations" : { "it" : { @@ -1202,6 +1339,16 @@ } } }, + "Simple" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Semplice" + } + } + } + }, "Solar Chart" : { "localizations" : { "it" : { @@ -1223,7 +1370,14 @@ } }, "Solstice" : { - + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Solstizio" + } + } + } }, "Solstice on Apple Watch requires location access in order to show local sunrise and sunset times. For custom and saved locations, use Solstice on iPhone, iPad, or Mac." : { "localizations" : { @@ -1295,6 +1449,16 @@ } } }, + "Sunrise/sunset times" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Orari di alba/tramonto" + } + } + } + }, "Sunset" : { "localizations" : { "it" : { @@ -1325,6 +1489,16 @@ } } }, + "Suppress notifications altogether" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Elimina del tutto le notifiche" + } + } + } + }, "The equinox and solstice define the transitions between the seasons of the astronomical calendar and are a key part of the Earth’s orbit around the Sun." : { "localizations" : { "it" : { @@ -1385,6 +1559,16 @@ } } }, + "Time until next solstice" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tempo fino al prossimo solstizio" + } + } + } + }, "Timezone" : { "localizations" : { "it" : { diff --git a/Solstice.xcodeproj/xcshareddata/xcschemes/iOS Widget Extension.xcscheme b/Solstice.xcodeproj/xcshareddata/xcschemes/iOS Widget Extension.xcscheme index d49ba9a6..e37315b1 100644 --- a/Solstice.xcodeproj/xcshareddata/xcschemes/iOS Widget Extension.xcscheme +++ b/Solstice.xcodeproj/xcshareddata/xcschemes/iOS Widget Extension.xcscheme @@ -57,8 +57,18 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" launchAutomaticallySubstyle = "2"> - + + + + + - + : View { #if !os(watchOS) .contextMenu { if let chartRenderedAsImage { + var locationTitle: Text { + guard let title = location.title else { + return Text("my location") + } + + return Text(title) + } + ShareLink( item: chartRenderedAsImage, - preview: SharePreview("Daylight in \(location.title ?? "my location")", image: chartRenderedAsImage) + preview: SharePreview("Daylight in \(locationTitle)", image: chartRenderedAsImage) ) } Picker(selection: $chartAppearance.animation()) { ForEach(DaylightChart.Appearance.allCases, id: \.self) { appearance in - Text(appearance.rawValue) + Text(appearance.description) } } label: { Label("Appearance", systemImage: "paintpalette") @@ -167,8 +175,14 @@ extension DailyOverview { HStack { VStack(alignment: .leading) { - Text(location.title ?? "My Location") - .font(.headline) + Group { + if let title = location.title { + Text(title) + } else { + Text("My Location") + } + } + .font(.headline) let duration = solar.daylightDuration.localizedString Text("\(duration) of daylight") diff --git a/Solstice/Detail View/DetailView.swift b/Solstice/Detail View/DetailView.swift index 2da308a9..17ce4650 100644 --- a/Solstice/Detail View/DetailView.swift +++ b/Solstice/Detail View/DetailView.swift @@ -27,6 +27,14 @@ struct DetailView: View { @AppStorage(Preferences.detailViewChartAppearance) private var chartAppearance @SceneStorage("selectedLocation") private var selectedLocation: String? + var navBarTitleText: Text { + guard let title = location.title else { + return location is CurrentLocation ? Text("My Location") : Text(verbatim: "Solstice") + } + + return Text(title) + } + var body: some View { ScrollViewReader { scrollProxy in Form { @@ -53,7 +61,7 @@ struct DetailView: View { AnnualOverview(location: location) } .formStyle(.grouped) - .navigationTitle(location.title ?? (location is CurrentLocation ? "My Location" : "Solstice")) + .navigationTitle(navBarTitleText) .toolbar { toolbarItems } diff --git a/Solstice/Equinox and Solstice Info View/EquinoxAndSolsticeInfoView.swift b/Solstice/Equinox and Solstice Info View/EquinoxAndSolsticeInfoView.swift index 2beb2944..34c9d322 100644 --- a/Solstice/Equinox and Solstice Info View/EquinoxAndSolsticeInfoView.swift +++ b/Solstice/Equinox and Solstice Info View/EquinoxAndSolsticeInfoView.swift @@ -21,16 +21,43 @@ fileprivate struct Selection: Codable, Hashable { var equinoxMonth: EquinoxMonth = .march var solsticeMonth: SolsticeMonth = .june - enum Event: String, CaseIterable, Codable { - case equinox = "Equinox", solstice = "Solstice" + enum Event: CaseIterable, Codable { + case equinox, solstice + + var description: LocalizedStringKey { + switch self { + case .equinox: + return "Equinox" + case .solstice: + return "Solstice" + } + } } - enum EquinoxMonth: String, CaseIterable, Codable { - case march = "March", september = "September" + enum EquinoxMonth: CaseIterable, Codable { + case march, september + + var description: LocalizedStringKey { + switch self { + case .march: + return "March" + case .september: + return "September" + } + } } - enum SolsticeMonth: String, CaseIterable, Codable { - case june = "June", december = "December" + enum SolsticeMonth: CaseIterable, Codable { + case june, december + + var description: LocalizedStringKey { + switch self { + case .june: + return "June" + case .december: + return "December" + } + } } var sunAngle: CGFloat { @@ -82,7 +109,7 @@ struct EquinoxAndSolsticeInfoView: View { Picker(selection: $selection.event.animation()) { ForEach(Selection.Event.allCases, id: \.self) { eventType in - Text(eventType.rawValue) + Text(eventType.description) } } label: { Text("View event:") @@ -94,18 +121,20 @@ struct EquinoxAndSolsticeInfoView: View { case .equinox: Picker(selection: $selection.equinoxMonth) { ForEach(Selection.EquinoxMonth.allCases, id: \.self) { eventType in - Text(eventType.rawValue) + Text(eventType.description) } } label: { Text("At month:") + .id("monthSelector") } case .solstice: Picker(selection: $selection.solsticeMonth) { ForEach(Selection.SolsticeMonth.allCases, id: \.self) { eventType in - Text(eventType.rawValue) + Text(eventType.description) } } label: { Text("At month:") + .id("monthSelector") } } } diff --git a/Solstice/Extensions/AppStorage++.swift b/Solstice/Extensions/AppStorage++.swift index 0afd46df..87fd0617 100644 --- a/Solstice/Extensions/AppStorage++.swift +++ b/Solstice/Extensions/AppStorage++.swift @@ -133,6 +133,17 @@ extension Preferences { case none = "No change" case removeDifference = "Remove daylight gain/loss" case suppressNotifications = "Suppress notifications altogether" + + var description: LocalizedStringKey { + switch self { + case .none: + return "No change" + case .removeDifference: + return "Remove daylight gain/loss" + case .suppressNotifications: + return "Suppress notifications altogether" + } + } } } @@ -140,7 +151,7 @@ extension Preferences.NotificationSettings { enum ScheduleType: String, RawRepresentable, CaseIterable { case specificTime, sunset, sunrise - var description: String { + var description: LocalizedStringKey { switch self { case .specificTime: return "a specific time" diff --git a/Solstice/List View/SidebarListView.swift b/Solstice/List View/SidebarListView.swift index 34fa3a03..ecff3f0e 100644 --- a/Solstice/List View/SidebarListView.swift +++ b/Solstice/List View/SidebarListView.swift @@ -94,7 +94,7 @@ struct SidebarListView: View { Label("Locations", systemImage: "map") } } - .navigationTitle("Solstice") + .navigationTitle(Text(verbatim: "Solstice")) .navigationSplitViewColumnWidth(ideal: 300) .searchable(text: $locationSearchService.queryFragment, prompt: "Search locations") diff --git a/Solstice/LocationPermissionScreenerView.swift b/Solstice/LocationPermissionScreenerView.swift index 211e316d..1bbe6661 100644 --- a/Solstice/LocationPermissionScreenerView.swift +++ b/Solstice/LocationPermissionScreenerView.swift @@ -31,7 +31,7 @@ struct LocationPermissionScreenerView: View { } footer: { Text("Set up location services to see sunrise and sunset times for your current location in the app, widgets, and notifications") } - .navigationTitle("Solstice") + .navigationTitle(Text(verbatim: "Solstice")) } } diff --git a/Solstice/Settings/NotificationSettings.swift b/Solstice/Settings/NotificationSettings.swift index ae9d8483..59f78fce 100644 --- a/Solstice/Settings/NotificationSettings.swift +++ b/Solstice/Settings/NotificationSettings.swift @@ -115,7 +115,7 @@ struct NotificationSettings: View { case let x where x > 0: Text("\(Duration.seconds(timeInterval).formatted(.units(maximumUnitCount: 2))) after") default: - Text("at \(scheduleType.description)") + Text("at \(Text(scheduleType.description))") } } } label: { @@ -126,7 +126,7 @@ struct NotificationSettings: View { DisclosureGroup { ForEach(notificationFragments, id: \.label) { fragment in - Toggle(fragment.label, isOn: fragment.value) + Toggle(LocalizedStringKey(fragment.label), isOn: fragment.value) } VStack(alignment: .leading) { diff --git a/Widget/Helpers/WidgetLocationHeadingView.swift b/Widget/Helpers/WidgetLocationHeadingView.swift index 6975d9f5..3b137efc 100644 --- a/Widget/Helpers/WidgetLocationHeadingView.swift +++ b/Widget/Helpers/WidgetLocationHeadingView.swift @@ -11,25 +11,24 @@ import WidgetKit struct WidgetLocationView: View { var location: SolsticeWidgetLocation - var locationName: String? { - (location.isRealLocation ? location.title ?? "My Location" : location.title) + var locationName: Text { + guard let title = location.title else { + switch location.isRealLocation { + case true: + return Text("My Location \(Image(systemName: "location"))") + case false: + return Text("\(Image("Solstice.SFSymbol")) Solstice") + } + } + + return Text(title) } var body: some View { - Group { - if let locationName { - if location.isRealLocation { - Text("\(locationName) \(Image(systemName: "location"))") - } else { - Text(locationName) - } - } else { - Label("Solstice", image: "Solstice.SFSymbol") - } - } - .font(.footnote.weight(.semibold)) - .symbolVariant(.fill) - .imageScale(.small) + locationName + .font(.footnote.weight(.semibold)) + .symbolVariant(.fill) + .imageScale(.small) } } diff --git a/Widget/Helpers/WidgetMissingLocationView.swift b/Widget/Helpers/WidgetMissingLocationView.swift index e8d7ebdc..3d89c81f 100644 --- a/Widget/Helpers/WidgetMissingLocationView.swift +++ b/Widget/Helpers/WidgetMissingLocationView.swift @@ -10,16 +10,18 @@ import SwiftUI struct WidgetMissingLocationView: View { @Environment(\.widgetFamily) var family + var locationMissingIcon = Image("location.slash") + var body: some View { switch family { #if !os(macOS) case .accessoryCorner: - Image("location.slash") + locationMissingIcon .widgetLabel { Text("Location required") } case .accessoryCircular: - Image("location.slash") + locationMissingIcon .widgetLabel { Text("Location required") } @@ -27,10 +29,11 @@ struct WidgetMissingLocationView: View { Label("Location required", systemImage: "location.slash") #endif default: - VStack { - Text("Location required") + VStack(alignment: .leading) { + Text("\(locationMissingIcon) Location required") .font(.headline) Text("Enable location services for Solstice, or choose a location by configuring the widget") + .foregroundStyle(.secondary) } } } diff --git a/Widget/Solar Chart Widget/SolarChartWidgetView.swift b/Widget/Solar Chart Widget/SolarChartWidgetView.swift index 21a0eee5..79cc4f0b 100644 --- a/Widget/Solar Chart Widget/SolarChartWidgetView.swift +++ b/Widget/Solar Chart Widget/SolarChartWidgetView.swift @@ -26,11 +26,19 @@ struct SolarChartWidgetView: View { let location { VStack { HStack { - Label("\(solar.safeSunrise.withTimeZoneAdjustment(for: location.timeZone), style: .time)", systemImage: "sunrise") + Label { + Text(solar.safeSunrise.withTimeZoneAdjustment(for: location.timeZone), style: .time) + } icon: { + Image(systemName: "sunrise") + } Spacer() - Label("\(solar.safeSunset.withTimeZoneAdjustment(for: location.timeZone), style: .time)", systemImage: "sunset") + Label { + Text(solar.safeSunset.withTimeZoneAdjustment(for: location.timeZone), style: .time) + } icon: { + Image(systemName: "sunset") + } } .symbolVariant(.fill) .imageScale(.small) diff --git a/watchOS/ContentView.swift b/watchOS/ContentView.swift index ca1ff1c5..cf53bac1 100644 --- a/watchOS/ContentView.swift +++ b/watchOS/ContentView.swift @@ -28,7 +28,7 @@ struct ContentView: View { } } .environmentObject(timeMachine) - .navigationTitle("Solstice") + .navigationTitle(Text(verbatim: "Solstice")) .onChange(of: scenePhase) { _ in timeMachine.referenceDate = Date() if currentLocation.isAuthorized, diff --git a/watchOS/LocationPermissionScreenerView.swift b/watchOS/LocationPermissionScreenerView.swift index 7e81205f..e4bbe73e 100644 --- a/watchOS/LocationPermissionScreenerView.swift +++ b/watchOS/LocationPermissionScreenerView.swift @@ -26,7 +26,7 @@ struct LocationPermissionScreenerView: View { Label("Location Permission", systemImage: "location") } } - .navigationTitle("Solstice") + .navigationTitle(Text(verbatim: "Solstice")) } }