Add preference to override color scheme / appearance (#142)

* Add color scheme / appearance switcher

* Refactoring

* Refactoring

Co-authored-by: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com>
This commit is contained in:
Thomas 2022-11-13 21:03:19 +01:00 committed by GitHub
parent 436cf0a045
commit 5d7d28dbe5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 99 additions and 2 deletions

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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" = "メディア";

View file

@ -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" = "미디어";

View file

@ -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";

View file

@ -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" = "Медиафайлы";

View file

@ -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" = "媒体";

View file

@ -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

View file

@ -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 {

View file

@ -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