Add theme toggle separate from system appearance

Closes #67
This commit is contained in:
Shadowfacts 2019-12-31 00:12:18 -05:00
parent 49f58cf955
commit edb86fc503
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
4 changed files with 26 additions and 0 deletions

View File

@ -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(onUserLoggedOut), name: .userLoggedOut, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(themePrefChanged), name: .themePreferenceChanged, object: nil)
themePrefChanged()
window!.makeKeyAndVisible() window!.makeKeyAndVisible()
if let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem { if let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem {
@ -109,6 +112,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
@objc func onUserLoggedOut() { @objc func onUserLoggedOut() {
showOnboardingUI() showOnboardingUI()
} }
@objc func themePrefChanged() {
window?.overrideUserInterfaceStyle = Preferences.shared.theme
}
} }

View File

@ -10,4 +10,5 @@ import Foundation
extension Notification.Name { extension Notification.Name {
static let preferencesChanged = Notification.Name("Tusker.preferencesChanged") static let preferencesChanged = Notification.Name("Tusker.preferencesChanged")
static let themePreferenceChanged = Notification.Name("Tusker.themePreferenceChanged")
} }

View File

@ -37,6 +37,7 @@ class Preferences: Codable, ObservableObject {
required init(from decoder: Decoder) throws { required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self) 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.showRepliesInProfiles = try container.decode(Bool.self, forKey: .showRepliesInProfiles)
self.avatarStyle = try container.decode(AvatarStyle.self, forKey: .avatarStyle) self.avatarStyle = try container.decode(AvatarStyle.self, forKey: .avatarStyle)
self.hideCustomEmojiInUsernames = try container.decode(Bool.self, forKey: .hideCustomEmojiInUsernames) self.hideCustomEmojiInUsernames = try container.decode(Bool.self, forKey: .hideCustomEmojiInUsernames)
@ -59,6 +60,7 @@ class Preferences: Codable, ObservableObject {
func encode(to encoder: Encoder) throws { func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(theme, forKey: .theme)
try container.encode(showRepliesInProfiles, forKey: .showRepliesInProfiles) try container.encode(showRepliesInProfiles, forKey: .showRepliesInProfiles)
try container.encode(avatarStyle, forKey: .avatarStyle) try container.encode(avatarStyle, forKey: .avatarStyle)
try container.encode(hideCustomEmojiInUsernames, forKey: .hideCustomEmojiInUsernames) try container.encode(hideCustomEmojiInUsernames, forKey: .hideCustomEmojiInUsernames)
@ -79,6 +81,7 @@ class Preferences: Codable, ObservableObject {
} }
// MARK: - Appearance // MARK: - Appearance
@Published var theme = UIUserInterfaceStyle.unspecified
@Published var showRepliesInProfiles = false @Published var showRepliesInProfiles = false
@Published var avatarStyle = AvatarStyle.roundRect @Published var avatarStyle = AvatarStyle.roundRect
@Published var hideCustomEmojiInUsernames = false @Published var hideCustomEmojiInUsernames = false
@ -101,6 +104,7 @@ class Preferences: Codable, ObservableObject {
@Published var statusContentType: StatusContentType = .plain @Published var statusContentType: StatusContentType = .plain
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case theme
case showRepliesInProfiles case showRepliesInProfiles
case avatarStyle case avatarStyle
case hideCustomEmojiInUsernames case hideCustomEmojiInUsernames
@ -127,3 +131,5 @@ extension Preferences {
case undecided, accepted, rejected case undecided, accepted, rejected
} }
} }
extension UIUserInterfaceStyle: Codable {}

View File

@ -10,6 +10,13 @@ import SwiftUI
struct AppearancePrefsView : View { struct AppearancePrefsView : View {
@ObservedObject var preferences = Preferences.shared @ObservedObject var preferences = Preferences.shared
var theme: Binding<UIUserInterfaceStyle> = Binding(get: {
Preferences.shared.theme
}, set: {
Preferences.shared.theme = $0
NotificationCenter.default.post(name: .themePreferenceChanged, object: nil)
})
var useCircularAvatars: Binding<Bool> = Binding(get: { var useCircularAvatars: Binding<Bool> = Binding(get: {
Preferences.shared.avatarStyle == .circle Preferences.shared.avatarStyle == .circle
}) { }) {
@ -18,6 +25,11 @@ struct AppearancePrefsView : View {
var body: some View { var body: some View {
List { 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) { Toggle(isOn: $preferences.showRepliesInProfiles) {
Text("Show Replies in Profiles") Text("Show Replies in Profiles")
} }