From edb86fc503377ec303ae449608aa3be4f5acab94 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Tue, 31 Dec 2019 00:12:18 -0500 Subject: [PATCH] Add theme toggle separate from system appearance Closes #67 --- Tusker/AppDelegate.swift | 7 +++++++ Tusker/Preferences/Preferences+Notification.swift | 1 + Tusker/Preferences/Preferences.swift | 6 ++++++ Tusker/Screens/Preferences/AppearancePrefsView.swift | 12 ++++++++++++ 4 files changed, 26 insertions(+) diff --git a/Tusker/AppDelegate.swift b/Tusker/AppDelegate.swift index ffadcea0..68e6c4a8 100644 --- a/Tusker/AppDelegate.swift +++ b/Tusker/AppDelegate.swift @@ -26,6 +26,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { NotificationCenter.default.addObserver(self, selector: #selector(onUserLoggedOut), name: .userLoggedOut, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(themePrefChanged), name: .themePreferenceChanged, object: nil) + themePrefChanged() + window!.makeKeyAndVisible() if let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem { @@ -109,6 +112,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { @objc func onUserLoggedOut() { showOnboardingUI() } + + @objc func themePrefChanged() { + window?.overrideUserInterfaceStyle = Preferences.shared.theme + } } diff --git a/Tusker/Preferences/Preferences+Notification.swift b/Tusker/Preferences/Preferences+Notification.swift index a890d4f9..a6ac020c 100644 --- a/Tusker/Preferences/Preferences+Notification.swift +++ b/Tusker/Preferences/Preferences+Notification.swift @@ -10,4 +10,5 @@ import Foundation extension Notification.Name { static let preferencesChanged = Notification.Name("Tusker.preferencesChanged") + static let themePreferenceChanged = Notification.Name("Tusker.themePreferenceChanged") } diff --git a/Tusker/Preferences/Preferences.swift b/Tusker/Preferences/Preferences.swift index cdb1a8e9..a0e50b46 100644 --- a/Tusker/Preferences/Preferences.swift +++ b/Tusker/Preferences/Preferences.swift @@ -37,6 +37,7 @@ class Preferences: Codable, ObservableObject { required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) + self.theme = try container.decode(UIUserInterfaceStyle.self, forKey: .theme) self.showRepliesInProfiles = try container.decode(Bool.self, forKey: .showRepliesInProfiles) self.avatarStyle = try container.decode(AvatarStyle.self, forKey: .avatarStyle) self.hideCustomEmojiInUsernames = try container.decode(Bool.self, forKey: .hideCustomEmojiInUsernames) @@ -59,6 +60,7 @@ class Preferences: Codable, ObservableObject { func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(theme, forKey: .theme) try container.encode(showRepliesInProfiles, forKey: .showRepliesInProfiles) try container.encode(avatarStyle, forKey: .avatarStyle) try container.encode(hideCustomEmojiInUsernames, forKey: .hideCustomEmojiInUsernames) @@ -79,6 +81,7 @@ class Preferences: Codable, ObservableObject { } // MARK: - Appearance + @Published var theme = UIUserInterfaceStyle.unspecified @Published var showRepliesInProfiles = false @Published var avatarStyle = AvatarStyle.roundRect @Published var hideCustomEmojiInUsernames = false @@ -101,6 +104,7 @@ class Preferences: Codable, ObservableObject { @Published var statusContentType: StatusContentType = .plain enum CodingKeys: String, CodingKey { + case theme case showRepliesInProfiles case avatarStyle case hideCustomEmojiInUsernames @@ -127,3 +131,5 @@ extension Preferences { case undecided, accepted, rejected } } + +extension UIUserInterfaceStyle: Codable {} diff --git a/Tusker/Screens/Preferences/AppearancePrefsView.swift b/Tusker/Screens/Preferences/AppearancePrefsView.swift index e05afe3c..96e68531 100644 --- a/Tusker/Screens/Preferences/AppearancePrefsView.swift +++ b/Tusker/Screens/Preferences/AppearancePrefsView.swift @@ -10,6 +10,13 @@ import SwiftUI struct AppearancePrefsView : View { @ObservedObject var preferences = Preferences.shared + var theme: Binding = Binding(get: { + Preferences.shared.theme + }, set: { + Preferences.shared.theme = $0 + NotificationCenter.default.post(name: .themePreferenceChanged, object: nil) + }) + var useCircularAvatars: Binding = Binding(get: { Preferences.shared.avatarStyle == .circle }) { @@ -18,6 +25,11 @@ struct AppearancePrefsView : View { var body: some View { List { + Picker(selection: theme, label: Text("Theme")) { + Text("Use System Theme").tag(UIUserInterfaceStyle.unspecified) + Text("Light").tag(UIUserInterfaceStyle.light) + Text("Dark").tag(UIUserInterfaceStyle.dark) + } Toggle(isOn: $preferences.showRepliesInProfiles) { Text("Show Replies in Profiles") }