From 17af6743871f63ea0ee0715261ec194a9260efa7 Mon Sep 17 00:00:00 2001 From: prajeet Date: Mon, 2 Jan 2023 22:03:16 +0545 Subject: [PATCH] Removed toggle for selecting themes and replaced with picker. (#19) * Removed toggle for selecting themes and replaced with picker. * Synced stored and inmemory themeset. * fixed default theme state * Added desert dark and light theme * fixed navigation bar background not changing in setttings tab after theme change. * nemesis theme added --- IceCubesApp/App/IceCubesApp.swift | 2 +- .../App/Tabs/Settings/SettingsTab.swift | 19 ++--- .../Sources/DesignSystem/ColorSet.swift | 71 +++++++++++++++- .../Sources/DesignSystem/Theme.swift | 82 ++++++++++++------- 4 files changed, 126 insertions(+), 48 deletions(-) diff --git a/IceCubesApp/App/IceCubesApp.swift b/IceCubesApp/App/IceCubesApp.swift index e8c00546..e22d55e2 100644 --- a/IceCubesApp/App/IceCubesApp.swift +++ b/IceCubesApp/App/IceCubesApp.swift @@ -49,7 +49,7 @@ struct IceCubesApp: App { setNewClientsInEnv(client: appAccountsManager.currentClient) setBarsColor(color: theme.primaryBackgroundColor) } - .preferredColorScheme(theme.colorScheme == "dark" ? .dark : .light) + .preferredColorScheme(theme.selectedScheme == ColorScheme.dark ? .dark : .light) .environmentObject(appAccountsManager) .environmentObject(appAccountsManager.currentClient) .environmentObject(quickLook) diff --git a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift index c8893ba9..b8d0c969 100644 --- a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift +++ b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift @@ -28,6 +28,7 @@ struct SettingsTabs: View { .background(theme.secondaryBackgroundColor) .navigationTitle(Text("Settings")) .navigationBarTitleDisplayMode(.inline) + .toolbarBackground(theme.primaryBackgroundColor, for: .navigationBar) } .onAppear { routeurPath.client = client @@ -64,15 +65,11 @@ struct SettingsTabs: View { private var themeSection: some View { Section("Theme") { - Toggle("Prefer dark color scheme", isOn: .init(get: { - theme.colorScheme == "dark" - }, set: { newValue in - if newValue { - theme.colorScheme = "dark" - } else { - theme.colorScheme = "light" + Picker("Theme", selection: $theme.selectedSet) { + ForEach(Theme.allColorSet, id: \.name.rawValue) { set in + Text(set.name.rawValue).tag(set.name) } - })) + } ColorPicker("Tint color", selection: $theme.tintColor) ColorPicker("Background color", selection: $theme.primaryBackgroundColor) ColorPicker("Secondary Background color", selection: $theme.secondaryBackgroundColor) @@ -82,11 +79,7 @@ struct SettingsTabs: View { } } Button { - theme.colorScheme = "dark" - theme.tintColor = .brand - theme.primaryBackgroundColor = .primaryBackground - theme.secondaryBackgroundColor = .secondaryBackground - theme.avatarPosition = .top + theme.selectedSet = .iceCubeDark } label: { Text("Restore default") } diff --git a/Packages/DesignSystem/Sources/DesignSystem/ColorSet.swift b/Packages/DesignSystem/Sources/DesignSystem/ColorSet.swift index 8a3813fe..62e324fd 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/ColorSet.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/ColorSet.swift @@ -1,13 +1,29 @@ import SwiftUI - public protocol ColorSet { + var name: ColorSetName { get } + var scheme: ColorScheme { get } var tintColor: Color { get set } var primaryBackgroundColor: Color { get set } var secondaryBackgroundColor: Color { get set } var labelColor: Color { get set } } -public struct DarkSet: ColorSet { +public enum ColorScheme: String { + case dark, light +} + +public enum ColorSetName: String { + case iceCubeDark = "Ice Cube - Dark" + case iceCubeLight = "Ice Cube - Light" + case desertDark = "Desert - Dark" + case desertLight = "Desert - Light" + case nemesisDark = "Nemesis - Dark" + case nemesisLight = "Nemesis - Light" +} + +public struct IceCubeDark: ColorSet { + public var name: ColorSetName = .iceCubeDark + public var scheme: ColorScheme = .dark public var tintColor: Color = Color(red: 187/255, green: 59/255, blue: 226/255) public var primaryBackgroundColor: Color = Color(red: 16/255, green: 21/255, blue: 35/255) public var secondaryBackgroundColor: Color = Color(red: 30/255, green: 35/255, blue: 62/255) @@ -16,7 +32,9 @@ public struct DarkSet: ColorSet { public init() {} } -public struct LightSet: ColorSet { +public struct IceCubeLight: ColorSet { + public var name: ColorSetName = .iceCubeLight + public var scheme: ColorScheme = .light public var tintColor: Color = Color(red: 187/255, green: 59/255, blue: 226/255) public var primaryBackgroundColor: Color = .white public var secondaryBackgroundColor: Color = Color(hex:0xF0F1F2) @@ -24,3 +42,50 @@ public struct LightSet: ColorSet { public init() {} } + +public struct DesertDark: ColorSet { + public var name: ColorSetName = .desertDark + public var scheme: ColorScheme = .dark + public var tintColor: Color = Color(hex: 0xdf915e) + public var primaryBackgroundColor: Color = Color(hex: 0x433744) + public var secondaryBackgroundColor: Color = Color(hex:0x654868) + public var labelColor: Color = .black + + public init() {} +} + +public struct DesertLight: ColorSet { + public var name: ColorSetName = .desertLight + public var scheme: ColorScheme = .light + public var tintColor: Color = Color(hex: 0xdf915e) + public var primaryBackgroundColor: Color = Color(hex: 0xfcf2eb) + public var secondaryBackgroundColor: Color = Color(hex:0xeeede7) + public var labelColor: Color = .black + + public init() {} +} + +public struct NemesisDark: ColorSet { + public var name: ColorSetName = .nemesisDark + public var scheme: ColorScheme = .dark + public var tintColor: Color = Color(hex: 0x17a2f2) + public var primaryBackgroundColor: Color = Color(hex: 0x000000) + public var secondaryBackgroundColor: Color = Color(hex:0x151e2b) + public var labelColor: Color = .black + + public init() {} +} + +public struct NemesisLight: ColorSet { + public var name: ColorSetName = .nemesisLight + public var scheme: ColorScheme = .light + public var tintColor: Color = Color(hex: 0x17a2f2) + public var primaryBackgroundColor: Color = Color(hex: 0xffffff) + public var secondaryBackgroundColor: Color = Color(hex:0xe8ecef) + public var labelColor: Color = .black + + public init() {} +} + + + diff --git a/Packages/DesignSystem/Sources/DesignSystem/Theme.swift b/Packages/DesignSystem/Sources/DesignSystem/Theme.swift index 2e558066..33c429ae 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Theme.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Theme.swift @@ -3,51 +3,49 @@ import SwiftUI public class Theme: ObservableObject { enum ThemeKey: String { - case colorScheme, tint, label, primaryBackground, secondaryBackground - case avatarPosition + case colorScheme, tint, label, primaryBackground, secondaryBackground + case avatarPosition + case selectedSet, selectedScheme } - + public enum AvatarPosition: String, CaseIterable { case leading, top - + public var description: LocalizedStringKey { switch self { - case .leading: - return "Leading" - case .top: - return "Top" - } - } - } - - @AppStorage("is_previously_set") var isSet: Bool = false - @AppStorage(ThemeKey.colorScheme.rawValue) public var colorScheme: String = "dark" { - didSet { - if colorScheme == "dark" { - setColor(set: DarkSet()) - } else { - setColor(set: LightSet()) + case .leading: + return "Leading" + case .top: + return "Top" } } } + + @AppStorage("is_previously_set") private var isSet: Bool = false + @AppStorage(ThemeKey.selectedScheme.rawValue) public var selectedScheme: ColorScheme = .dark @AppStorage(ThemeKey.tint.rawValue) public var tintColor: Color = .black @AppStorage(ThemeKey.primaryBackground.rawValue) public var primaryBackgroundColor: Color = .white @AppStorage(ThemeKey.secondaryBackground.rawValue) public var secondaryBackgroundColor: Color = .gray @AppStorage(ThemeKey.label.rawValue) public var labelColor: Color = .black @AppStorage(ThemeKey.avatarPosition.rawValue) var rawAvatarPosition: String = AvatarPosition.top.rawValue - + @AppStorage(ThemeKey.selectedSet.rawValue) var storedSet: ColorSetName = .iceCubeDark @Published public var avatarPosition: AvatarPosition = .top - + @Published public var selectedSet: ColorSetName = .iceCubeDark + private var cancellables = Set() - + public init() { + selectedSet = storedSet + + // If theme is never set before set the default store. This should only execute once after install. + if !isSet { - setColor(set: DarkSet()) - isSet.toggle() + setColor(withName: .iceCubeDark) + isSet = true } - + avatarPosition = AvatarPosition(rawValue: rawAvatarPosition) ?? .top - + $avatarPosition .dropFirst() .map(\.rawValue) @@ -55,12 +53,34 @@ public class Theme: ObservableObject { self?.rawAvatarPosition = position } .store(in: &cancellables) + + // Workaround, since @AppStorage can't be directly observed + $selectedSet + .dropFirst() + .sink { [weak self] colorSetName in + self?.setColor(withName: colorSetName) + } + .store(in: &cancellables) } - public func setColor(set: ColorSet) { - self.tintColor = set.tintColor - self.primaryBackgroundColor = set.primaryBackgroundColor - self.secondaryBackgroundColor = set.secondaryBackgroundColor - self.labelColor = set.labelColor + public static var allColorSet: [ColorSet] { + [ + IceCubeDark(), + IceCubeLight(), + DesertDark(), + DesertLight(), + NemesisDark(), + NemesisLight() + ] + } + + public func setColor(withName name: ColorSetName) { + let colorSet = Theme.allColorSet.filter { $0.name == name }.first ?? IceCubeDark() + self.selectedScheme = colorSet.scheme + self.tintColor = colorSet.tintColor + self.primaryBackgroundColor = colorSet.primaryBackgroundColor + self.secondaryBackgroundColor = colorSet.secondaryBackgroundColor + self.labelColor = colorSet.labelColor + self.storedSet = name } }