Add a follow system colors option close #128
This commit is contained in:
parent
cd05a75ab9
commit
5321b2b8d8
|
@ -622,7 +622,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.3;
|
||||
MARKETING_VERSION = 1.0.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp.IceCubesNotifications;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -652,7 +652,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.3;
|
||||
MARKETING_VERSION = 1.0.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp.IceCubesNotifications;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -683,7 +683,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.3;
|
||||
MARKETING_VERSION = 1.0.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp.IceCubesShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -713,7 +713,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.3;
|
||||
MARKETING_VERSION = 1.0.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp.IceCubesShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -877,7 +877,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.0.3;
|
||||
MARKETING_VERSION = 1.0.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = auto;
|
||||
|
@ -929,7 +929,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.0.3;
|
||||
MARKETING_VERSION = 1.0.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = auto;
|
||||
|
|
|
@ -14,6 +14,7 @@ struct IceCubesApp: App {
|
|||
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
|
||||
|
||||
@Environment(\.scenePhase) private var scenePhase
|
||||
|
||||
@StateObject private var appAccountsManager = AppAccountsManager.shared
|
||||
@StateObject private var currentInstance = CurrentInstance.shared
|
||||
@StateObject private var currentAccount = CurrentAccount.shared
|
||||
|
@ -197,6 +198,8 @@ struct IceCubesApp: App {
|
|||
}
|
||||
|
||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
||||
let themeObserver = ThemeObserverViewController(nibName: nil, bundle: nil)
|
||||
|
||||
func application(_: UIApplication,
|
||||
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
|
||||
{
|
||||
|
@ -219,3 +222,11 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
|||
func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {}
|
||||
|
||||
}
|
||||
|
||||
class ThemeObserverViewController: UIViewController {
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
print(traitCollection.userInterfaceStyle.rawValue)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,20 @@ struct DisplaySettingsView: View {
|
|||
var body: some View {
|
||||
Form {
|
||||
Section("settings.display.section.theme") {
|
||||
Toggle("settings.display.theme.systemColor", isOn: $theme.followSystemColorScheme)
|
||||
themeSelectorButton
|
||||
ColorPicker("settings.display.theme.tint", selection: $theme.tintColor)
|
||||
.onChange(of: theme.tintColor) { newValue in
|
||||
theme.followSystemColorScheme = false
|
||||
}
|
||||
ColorPicker("settings.display.theme.background", selection: $theme.primaryBackgroundColor)
|
||||
.onChange(of: theme.primaryBackgroundColor) { newValue in
|
||||
theme.followSystemColorScheme = false
|
||||
}
|
||||
ColorPicker("settings.display.theme.secondary-background", selection: $theme.secondaryBackgroundColor)
|
||||
.onChange(of: theme.primaryBackgroundColor) { newValue in
|
||||
theme.followSystemColorScheme = false
|
||||
}
|
||||
}
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import Network
|
|||
import SwiftUI
|
||||
import Timeline
|
||||
|
||||
struct TimelineTab: View {
|
||||
struct TimelineTab: View {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
"settings.display.theme.background" = "Hintergrundfarbe";
|
||||
"settings.display.theme.secondary-background" = "Sekundäre Hintergrundfarbe";
|
||||
"settings.display.theme.tint" = "Akzentfarbe";
|
||||
"settings.display.theme.systemColor" = "Match-System";
|
||||
"settings.general.browser" = "Browser";
|
||||
"settings.general.browser.in-app" = "In-App Browser";
|
||||
"settings.general.browser.system" = "System Browser";
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
"settings.display.theme.background" = "Background color";
|
||||
"settings.display.theme.secondary-background" = "Secondary Background color";
|
||||
"settings.display.theme.tint" = "Tint color";
|
||||
"settings.display.theme.systemColor" = "Match System";
|
||||
"settings.general.browser" = "Browser";
|
||||
"settings.general.browser.in-app" = "In-App Browser";
|
||||
"settings.general.browser.system" = "System Browser";
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
"settings.display.theme.background" = "Color de fondo";
|
||||
"settings.display.theme.secondary-background" = "Color de fondo secundario";
|
||||
"settings.display.theme.tint" = "Color";
|
||||
"settings.display.theme.systemColor" = "Sistema de coincidencia";
|
||||
"settings.general.browser" = "Navegador";
|
||||
"settings.general.browser.in-app" = "Interno";
|
||||
"settings.general.browser.system" = "Sistema";
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
"settings.display.theme.background" = "Achtergrondkleur";
|
||||
"settings.display.theme.secondary-background" = "Secundaire Achtergrondkleur";
|
||||
"settings.display.theme.tint" = "Kleurtint";
|
||||
"settings.display.theme.systemColor" = "Match systeem";
|
||||
"settings.general.browser" = "Browser";
|
||||
"settings.general.browser.in-app" = "In-App Browser";
|
||||
"settings.general.browser.system" = "Systeem Browser";
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import SwiftUI
|
||||
|
||||
public let availableColorsSets: [ColorSetCouple] =
|
||||
[.init(light: IceCubeLight(), dark: IceCubeDark()),
|
||||
.init(light: DesertLight(), dark: DesertDark()),
|
||||
.init(light: NemesisLight(), dark: NemesisDark()),
|
||||
.init(light: MediumLight(), dark: MediumDark())]
|
||||
|
||||
public protocol ColorSet {
|
||||
var name: ColorSetName { get }
|
||||
var scheme: ColorScheme { get }
|
||||
|
@ -23,6 +30,15 @@ public enum ColorSetName: String {
|
|||
case mediumDark = "Medium - Dark"
|
||||
}
|
||||
|
||||
public struct ColorSetCouple: Identifiable {
|
||||
public var id: String {
|
||||
dark.name.rawValue + light.name.rawValue
|
||||
}
|
||||
|
||||
public let light: ColorSet
|
||||
public let dark: ColorSet
|
||||
}
|
||||
|
||||
public struct IceCubeDark: ColorSet {
|
||||
public var name: ColorSetName = .iceCubeDark
|
||||
public var scheme: ColorScheme = .dark
|
||||
|
|
|
@ -6,6 +6,7 @@ public class Theme: ObservableObject {
|
|||
case colorScheme, tint, label, primaryBackground, secondaryBackground
|
||||
case avatarPosition, avatarShape, statusActionsDisplay, statusDisplayStyle
|
||||
case selectedSet, selectedScheme
|
||||
case followSystemColorSchme
|
||||
}
|
||||
|
||||
public enum AvatarPosition: String, CaseIterable {
|
||||
|
@ -62,7 +63,7 @@ public class Theme: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
@AppStorage("is_previously_set") private var isSet: Bool = false
|
||||
@AppStorage("is_previously_set") public var isThemePreviouslySet: 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
|
||||
|
@ -73,6 +74,7 @@ public class Theme: ObservableObject {
|
|||
@AppStorage(ThemeKey.selectedSet.rawValue) var storedSet: ColorSetName = .iceCubeDark
|
||||
@AppStorage(ThemeKey.statusActionsDisplay.rawValue) public var statusActionsDisplay: StatusActionsDisplay = .full
|
||||
@AppStorage(ThemeKey.statusDisplayStyle.rawValue) public var statusDisplayStyle: StatusDisplayStyle = .large
|
||||
@AppStorage(ThemeKey.followSystemColorSchme.rawValue) public var followSystemColorScheme: Bool = true
|
||||
|
||||
@Published public var avatarPosition: AvatarPosition = .top
|
||||
@Published public var avatarShape: AvatarShape = .rounded
|
||||
|
@ -85,13 +87,6 @@ public class Theme: ObservableObject {
|
|||
private init() {
|
||||
selectedSet = storedSet
|
||||
|
||||
// If theme is never set before set the default store. This should only execute once after install.
|
||||
|
||||
if !isSet {
|
||||
setColor(withName: .iceCubeDark)
|
||||
isSet = true
|
||||
}
|
||||
|
||||
avatarPosition = AvatarPosition(rawValue: rawAvatarPosition) ?? .top
|
||||
avatarShape = AvatarShape(rawValue: rawAvatarShape) ?? .rounded
|
||||
|
||||
|
|
|
@ -10,43 +10,48 @@ public extension View {
|
|||
}
|
||||
|
||||
struct ThemeApplier: ViewModifier {
|
||||
@Environment(\EnvironmentValues.colorScheme) var colorScheme
|
||||
|
||||
@ObservedObject var theme: Theme
|
||||
|
||||
var actualColorScheme: SwiftUI.ColorScheme? {
|
||||
if theme.followSystemColorScheme {
|
||||
return nil
|
||||
}
|
||||
return theme.selectedScheme == ColorScheme.dark ? .dark : .light
|
||||
}
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.tint(theme.tintColor)
|
||||
.preferredColorScheme(theme.selectedScheme == ColorScheme.dark ? .dark : .light)
|
||||
.preferredColorScheme(actualColorScheme)
|
||||
#if canImport(UIKit)
|
||||
.onAppear {
|
||||
// If theme is never set before set the default store. This should only execute once after install.
|
||||
if !theme.isThemePreviouslySet {
|
||||
theme.selectedSet = colorScheme == .dark ? .iceCubeDark : .iceCubeLight
|
||||
theme.isThemePreviouslySet = true
|
||||
}
|
||||
setWindowTint(theme.tintColor)
|
||||
setWindowUserInterfaceStyle(theme.selectedScheme)
|
||||
setBarsColor(theme.primaryBackgroundColor)
|
||||
}
|
||||
.onChange(of: theme.tintColor) { newValue in
|
||||
setWindowTint(newValue)
|
||||
}
|
||||
.onChange(of: theme.selectedScheme) { newValue in
|
||||
setWindowUserInterfaceStyle(newValue)
|
||||
}
|
||||
.onChange(of: theme.primaryBackgroundColor) { newValue in
|
||||
setBarsColor(newValue)
|
||||
}
|
||||
.onChange(of: colorScheme) { newColorScheme in
|
||||
if theme.followSystemColorScheme,
|
||||
let sets = availableColorsSets
|
||||
.first(where: { $0.light.name == theme.selectedSet || $0.dark.name == theme.selectedSet }) {
|
||||
theme.selectedSet = newColorScheme == .dark ? sets.dark.name : sets.light.name
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if canImport(UIKit)
|
||||
private func setWindowUserInterfaceStyle(_ colorScheme: ColorScheme) {
|
||||
allWindows()
|
||||
.forEach {
|
||||
switch colorScheme {
|
||||
case .dark:
|
||||
$0.overrideUserInterfaceStyle = .dark
|
||||
case .light:
|
||||
$0.overrideUserInterfaceStyle = .light
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func setWindowTint(_ color: Color) {
|
||||
allWindows()
|
||||
.forEach {
|
||||
|
|
|
@ -10,21 +10,11 @@ public struct ThemePreviewView: View {
|
|||
|
||||
public var body: some View {
|
||||
ScrollView {
|
||||
HStack(spacing: gutterSpace) {
|
||||
ThemeBoxView(color: IceCubeDark())
|
||||
ThemeBoxView(color: IceCubeLight())
|
||||
}
|
||||
HStack(spacing: gutterSpace) {
|
||||
ThemeBoxView(color: DesertDark())
|
||||
ThemeBoxView(color: DesertLight())
|
||||
}
|
||||
HStack(spacing: gutterSpace) {
|
||||
ThemeBoxView(color: NemesisDark())
|
||||
ThemeBoxView(color: NemesisLight())
|
||||
}
|
||||
HStack(spacing: gutterSpace) {
|
||||
ThemeBoxView(color: MediumDark())
|
||||
ThemeBoxView(color: MediumLight())
|
||||
ForEach(availableColorsSets) { couple in
|
||||
HStack(spacing: gutterSpace) {
|
||||
ThemeBoxView(color: couple.light)
|
||||
ThemeBoxView(color: couple.dark)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(4)
|
||||
|
@ -94,6 +84,10 @@ struct ThemeBoxView: View {
|
|||
isSelected = newValue.rawValue == color.name.rawValue
|
||||
}
|
||||
.onTapGesture {
|
||||
let currentScheme = theme.selectedScheme
|
||||
if color.scheme != currentScheme {
|
||||
theme.followSystemColorScheme = false
|
||||
}
|
||||
theme.selectedSet = color.name
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue