diff --git a/Localizations/de.lproj/Localizable.strings b/Localizations/de.lproj/Localizable.strings index c2af9d3..6079c06 100644 --- a/Localizations/de.lproj/Localizable.strings +++ b/Localizations/de.lproj/Localizable.strings @@ -201,6 +201,10 @@ "preferences" = "Einstellungen"; "preferences.app" = "App Einstellungen"; "preferences.app-icon" = "App Icon"; +"preferences.app.color-scheme" = "Erscheinungsbild"; +"preferences.app.color-scheme.dark" = "Dunkel"; +"preferences.app.color-scheme.light" = "Hell"; +"preferences.app.color-scheme.system" = "System"; "preferences.blocked-domains" = "Gesperrte Domains"; "preferences.blocked-users" = "Gesperrte Nutzer"; "preferences.media" = "Medien"; diff --git a/Localizations/en.lproj/Localizable.strings b/Localizations/en.lproj/Localizable.strings index 6c924cf..f7f6054 100644 --- a/Localizations/en.lproj/Localizable.strings +++ b/Localizations/en.lproj/Localizable.strings @@ -201,6 +201,10 @@ "preferences" = "Preferences"; "preferences.app" = "App Preferences"; "preferences.app-icon" = "App Icon"; +"preferences.app.color-scheme" = "Appearance"; +"preferences.app.color-scheme.dark" = "Dark"; +"preferences.app.color-scheme.light" = "Light"; +"preferences.app.color-scheme.system" = "System"; "preferences.blocked-domains" = "Blocked Domains"; "preferences.blocked-users" = "Blocked Users"; "preferences.media" = "Media"; diff --git a/Localizations/es.lproj/Localizable.strings b/Localizations/es.lproj/Localizable.strings index 0aebd56..3c3a7bf 100644 --- a/Localizations/es.lproj/Localizable.strings +++ b/Localizations/es.lproj/Localizable.strings @@ -201,6 +201,10 @@ "preferences" = "Ajustes"; "preferences.app" = "Ajustes de la App"; "preferences.app-icon" = "Icono de la App"; +"preferences.app.color-scheme" = "Appearance"; +"preferences.app.color-scheme.dark" = "Dark"; +"preferences.app.color-scheme.light" = "Light"; +"preferences.app.color-scheme.system" = "System"; "preferences.blocked-domains" = "Dominios bloqueados"; "preferences.blocked-users" = "Usuarios bloqueados"; "preferences.media" = "Multimedia"; diff --git a/Localizations/ja.lproj/Localizable.strings b/Localizations/ja.lproj/Localizable.strings index e445772..e626cda 100644 --- a/Localizations/ja.lproj/Localizable.strings +++ b/Localizations/ja.lproj/Localizable.strings @@ -201,6 +201,10 @@ "preferences" = "環境設定"; "preferences.app" = "アプリ環境設定"; "preferences.app-icon" = "アプリアイコン"; +"preferences.app.color-scheme" = "Appearance"; +"preferences.app.color-scheme.dark" = "Dark"; +"preferences.app.color-scheme.light" = "Light"; +"preferences.app.color-scheme.system" = "System"; "preferences.blocked-domains" = "ブロックしたドメイン"; "preferences.blocked-users" = "ブロックしたユーザー"; "preferences.media" = "メディア"; diff --git a/Localizations/ko.lproj/Localizable.strings b/Localizations/ko.lproj/Localizable.strings index e72de25..befb311 100644 --- a/Localizations/ko.lproj/Localizable.strings +++ b/Localizations/ko.lproj/Localizable.strings @@ -201,6 +201,10 @@ "preferences" = "설정"; "preferences.app" = "앱 설정"; "preferences.app-icon" = "앱 아이콘"; +"preferences.app.color-scheme" = "Appearance"; +"preferences.app.color-scheme.dark" = "Dark"; +"preferences.app.color-scheme.light" = "Light"; +"preferences.app.color-scheme.system" = "System"; "preferences.blocked-domains" = "차단된 도메인"; "preferences.blocked-users" = "차단된 사용자"; "preferences.media" = "미디어"; diff --git a/Localizations/pl.lproj/Localizable.strings b/Localizations/pl.lproj/Localizable.strings index e72fb3c..c17509c 100644 --- a/Localizations/pl.lproj/Localizable.strings +++ b/Localizations/pl.lproj/Localizable.strings @@ -201,6 +201,10 @@ "preferences" = "Właściwości"; "preferences.app" = "Ustawienia aplikacji"; "preferences.app-icon" = "Ikona aplikacji"; +"preferences.app.color-scheme" = "Appearance"; +"preferences.app.color-scheme.dark" = "Dark"; +"preferences.app.color-scheme.light" = "Light"; +"preferences.app.color-scheme.system" = "System"; "preferences.blocked-domains" = "Zablokowane domeny"; "preferences.blocked-users" = "Zablokowane profile"; "preferences.media" = "Media"; diff --git a/Localizations/ru.lproj/Localizable.strings b/Localizations/ru.lproj/Localizable.strings index 945cc57..582d2f5 100644 --- a/Localizations/ru.lproj/Localizable.strings +++ b/Localizations/ru.lproj/Localizable.strings @@ -201,6 +201,10 @@ "preferences" = "Настройки"; "preferences.app" = "Настройки приложения"; "preferences.app-icon" = "Значок приложения"; +"preferences.app.color-scheme" = "Appearance"; +"preferences.app.color-scheme.dark" = "Dark"; +"preferences.app.color-scheme.light" = "Light"; +"preferences.app.color-scheme.system" = "System"; "preferences.blocked-domains" = "Заблокированные домены"; "preferences.blocked-users" = "Заблокированные пользователи"; "preferences.media" = "Медиафайлы"; diff --git a/Localizations/zh-Hans.lproj/Localizable.strings b/Localizations/zh-Hans.lproj/Localizable.strings index 646958d..4df8fa9 100644 --- a/Localizations/zh-Hans.lproj/Localizable.strings +++ b/Localizations/zh-Hans.lproj/Localizable.strings @@ -201,6 +201,10 @@ "preferences" = "偏好设置"; "preferences.app" = "应用偏好设置"; "preferences.app-icon" = "应用图标"; +"preferences.app.color-scheme" = "Appearance"; +"preferences.app.color-scheme.dark" = "Dark"; +"preferences.app.color-scheme.light" = "Light"; +"preferences.app.color-scheme.system" = "System"; "preferences.blocked-domains" = "已屏蔽的域名"; "preferences.blocked-users" = "已屏蔽的用户"; "preferences.media" = "媒体"; diff --git a/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift b/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift index 50e0d42..828fa03 100644 --- a/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift +++ b/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift @@ -17,6 +17,14 @@ public struct AppPreferences { } public extension AppPreferences { + enum ColorScheme: String, CaseIterable, Identifiable { + case system + case light + case dark + + public var id: String { rawValue } + } + enum StatusWord: String, CaseIterable, Identifiable { case toot case post @@ -47,6 +55,18 @@ public extension AppPreferences { public var id: String { rawValue } } + var colorScheme: ColorScheme { + get { + if let rawValue = self[.colorScheme] as String?, + let value = ColorScheme(rawValue: rawValue) { + return value + } + + return .system + } + set { self[.colorScheme] = newValue.rawValue } + } + var statusWord: StatusWord { get { if let rawValue = self[.statusWord] as String?, @@ -185,6 +205,7 @@ public extension AppPreferences { private extension AppPreferences { enum Item: String { + case colorScheme case statusWord case requireDoubleTapToReblog case requireDoubleTapToFavorite diff --git a/Views/SwiftUI/PreferencesView.swift b/Views/SwiftUI/PreferencesView.swift index f9e68e5..296e58d 100644 --- a/Views/SwiftUI/PreferencesView.swift +++ b/Views/SwiftUI/PreferencesView.swift @@ -88,6 +88,11 @@ struct PreferencesView: View { } } } + Picker("preferences.app.color-scheme", selection: $identityContext.appPreferences.colorScheme) { + ForEach(AppPreferences.ColorScheme.allCases) { option in + Text(option.localizedStringKey).tag(option) + } + } NavigationLink("preferences.notifications", destination: NotificationPreferencesView(viewModel: viewModel)) Picker("preferences.status-word", @@ -153,6 +158,19 @@ struct PreferencesView: View { } } +extension AppPreferences.ColorScheme { + var localizedStringKey: LocalizedStringKey { + switch self { + case .system: + return "preferences.app.color-scheme.system" + case .light: + return "preferences.app.color-scheme.light" + case .dark: + return "preferences.app.color-scheme.dark" + } + } +} + extension AppPreferences.StatusWord { var localizedStringKey: LocalizedStringKey { switch self { diff --git a/Views/SwiftUI/RootView.swift b/Views/SwiftUI/RootView.swift index 904ef08..431d24a 100644 --- a/Views/SwiftUI/RootView.swift +++ b/Views/SwiftUI/RootView.swift @@ -1,6 +1,7 @@ // Copyright © 2020 Metabolist. All rights reserved. import SwiftUI +import UIKit import ViewModels struct RootView: View { @@ -13,13 +14,15 @@ struct RootView: View { .environmentObject(viewModel) .transition(.opacity) .edgesIgnoringSafeArea(.all) + .onReceive(navigationViewModel.identityContext.$appPreferences.map(\.colorScheme), + perform: setColorScheme) } else { NavigationView { AddIdentityView( viewModelClosure: { viewModel.addIdentityViewModel() }, displayWelcome: true) - .navigationBarTitleDisplayMode(.inline) - .navigationBarHidden(true) + .navigationBarTitleDisplayMode(.inline) + .navigationBarHidden(true) } .environmentObject(viewModel) .navigationViewStyle(StackNavigationViewStyle()) @@ -28,6 +31,29 @@ struct RootView: View { } } +private extension RootView { + func setColorScheme(_ colorScheme: AppPreferences.ColorScheme) { + for scene in UIApplication.shared.connectedScenes.compactMap({ $0 as? UIWindowScene }) { + for window in scene.windows { + window.overrideUserInterfaceStyle = colorScheme.uiKit + } + } + } +} + +extension AppPreferences.ColorScheme { + var uiKit: UIUserInterfaceStyle { + switch self { + case .system: + return .unspecified + case .light: + return .light + case .dark: + return .dark + } + } +} + #if DEBUG import Combine import PreviewViewModels