Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
a1d3105261
commit
d55271e921
@ -76,7 +76,7 @@ struct AndromidaApp: App {
|
||||
}
|
||||
}
|
||||
.modelContainer(modelContainer)
|
||||
.preferredColorScheme(.dark)
|
||||
.preferredColorScheme(settingsStore.theme.colorScheme)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ struct AppSettingsData: PersistableData {
|
||||
var hapticsEnabled: Bool = true
|
||||
var soundEnabled: Bool = true
|
||||
var remindersEnabled: Bool = false
|
||||
var theme: AppTheme = .dark
|
||||
var lastModified: Date = .now
|
||||
|
||||
/// Sync priority - uses haptics as a simple indicator of user activity
|
||||
|
||||
@ -4,7 +4,7 @@ import Bedrock
|
||||
|
||||
@MainActor
|
||||
@Observable
|
||||
final class SettingsStore: CloudSyncable {
|
||||
final class SettingsStore: CloudSyncable, ThemeProviding {
|
||||
@ObservationIgnored private let cloudSync = CloudSyncManager<AppSettingsData>()
|
||||
|
||||
/// Observable copy of last sync date, updated when sync completes.
|
||||
@ -26,6 +26,11 @@ final class SettingsStore: CloudSyncable {
|
||||
set { update { $0.soundEnabled = newValue } }
|
||||
}
|
||||
|
||||
var theme: AppTheme {
|
||||
get { cloudSync.data.theme }
|
||||
set { update { $0.theme = newValue } }
|
||||
}
|
||||
|
||||
var iCloudAvailable: Bool { cloudSync.iCloudAvailable }
|
||||
|
||||
var iCloudEnabled: Bool {
|
||||
|
||||
@ -45,6 +45,11 @@ struct SettingsView: View {
|
||||
)
|
||||
|
||||
SettingsCard(backgroundColor: AppSurface.card, borderColor: AppBorder.subtle) {
|
||||
SettingsThemePicker(
|
||||
store: store,
|
||||
accentColor: AppAccent.primary
|
||||
)
|
||||
|
||||
if let categoryStore {
|
||||
SettingsNavigationRow(
|
||||
title: String(localized: "Categories"),
|
||||
|
||||
@ -23,9 +23,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.53",
|
||||
"green" : "0.63",
|
||||
"red" : "0.95"
|
||||
"blue" : "0.40",
|
||||
"green" : "0.55",
|
||||
"red" : "0.93"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
38
Andromida/Assets.xcassets/AccentDark.colorset/Contents.json
Normal file
38
Andromida/Assets.xcassets/AccentDark.colorset/Contents.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.25",
|
||||
"green" : "0.38",
|
||||
"red" : "0.75"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.25",
|
||||
"green" : "0.38",
|
||||
"red" : "0.75"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
38
Andromida/Assets.xcassets/AccentLight.colorset/Contents.json
Normal file
38
Andromida/Assets.xcassets/AccentLight.colorset/Contents.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.55",
|
||||
"green" : "0.70",
|
||||
"red" : "0.98"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.55",
|
||||
"green" : "0.70",
|
||||
"red" : "0.98"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.80",
|
||||
"green" : "0.90",
|
||||
"red" : "0.95"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.80",
|
||||
"green" : "0.90",
|
||||
"red" : "0.95"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -23,9 +23,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.09",
|
||||
"green" : "0.10",
|
||||
"red" : "0.11"
|
||||
"blue" : "0.08",
|
||||
"green" : "0.09",
|
||||
"red" : "0.12"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
@ -23,9 +23,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.12",
|
||||
"green" : "0.14",
|
||||
"red" : "0.15"
|
||||
"blue" : "0.10",
|
||||
"green" : "0.11",
|
||||
"red" : "0.14"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.82",
|
||||
"green" : "0.87",
|
||||
"red" : "0.90"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.12",
|
||||
"green" : "0.14",
|
||||
"red" : "0.18"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -23,9 +23,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.14",
|
||||
"green" : "0.16",
|
||||
"red" : "0.17"
|
||||
"blue" : "0.11",
|
||||
"green" : "0.12",
|
||||
"red" : "0.16"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
38
Andromida/Assets.xcassets/Error.colorset/Contents.json
Normal file
38
Andromida/Assets.xcassets/Error.colorset/Contents.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.25",
|
||||
"green" : "0.25",
|
||||
"red" : "0.85"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.35",
|
||||
"green" : "0.35",
|
||||
"red" : "0.90"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
38
Andromida/Assets.xcassets/Info.colorset/Contents.json
Normal file
38
Andromida/Assets.xcassets/Info.colorset/Contents.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.85",
|
||||
"green" : "0.62",
|
||||
"red" : "0.40"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.92",
|
||||
"green" : "0.72",
|
||||
"red" : "0.55"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -5,9 +5,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.56",
|
||||
"green" : "0.62",
|
||||
"red" : "0.17"
|
||||
"blue" : "0.45",
|
||||
"green" : "0.65",
|
||||
"red" : "0.15"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
@ -23,9 +23,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.66",
|
||||
"green" : "0.72",
|
||||
"red" : "0.24"
|
||||
"blue" : "0.55",
|
||||
"green" : "0.75",
|
||||
"red" : "0.20"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.55",
|
||||
"green" : "0.60",
|
||||
"red" : "0.65"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.38",
|
||||
"green" : "0.42",
|
||||
"red" : "0.46"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -23,9 +23,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.91",
|
||||
"green" : "0.93",
|
||||
"red" : "0.95"
|
||||
"blue" : "1.0",
|
||||
"green" : "1.0",
|
||||
"red" : "1.0"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.45",
|
||||
"green" : "0.50",
|
||||
"red" : "0.55"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.55",
|
||||
"green" : "0.58",
|
||||
"red" : "0.62"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -5,9 +5,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.42",
|
||||
"green" : "0.77",
|
||||
"red" : "0.91"
|
||||
"blue" : "0.35",
|
||||
"green" : "0.70",
|
||||
"red" : "0.90"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
@ -23,8 +23,8 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.0",
|
||||
"blue" : "0.52",
|
||||
"green" : "0.82",
|
||||
"blue" : "0.45",
|
||||
"green" : "0.78",
|
||||
"red" : "0.95"
|
||||
}
|
||||
},
|
||||
|
||||
@ -3,71 +3,78 @@ import Bedrock
|
||||
|
||||
// MARK: - Rituals Surface Colors
|
||||
|
||||
/// Surface colors using Asset Catalog with light/dark variants.
|
||||
public enum RitualsSurfaceColors: SurfaceColorProvider {
|
||||
public static let primary = Color(red: 0.12, green: 0.09, blue: 0.08)
|
||||
public static let secondary = Color(red: 0.14, green: 0.11, blue: 0.10)
|
||||
public static let tertiary = Color(red: 0.18, green: 0.14, blue: 0.12)
|
||||
public static let overlay = Color(red: 0.12, green: 0.09, blue: 0.08)
|
||||
public static let card = Color(red: 0.16, green: 0.12, blue: 0.11)
|
||||
public static let groupedFill = Color(red: 0.13, green: 0.10, blue: 0.09)
|
||||
public static let sectionFill = Color(red: 0.18, green: 0.14, blue: 0.12)
|
||||
public static let primary = Color("Background")
|
||||
public static let secondary = Color("BackgroundAlt")
|
||||
public static let tertiary = Color("BackgroundTertiary")
|
||||
public static let overlay = Color("Background")
|
||||
public static let card = Color("Card")
|
||||
public static let groupedFill = Color("BackgroundAlt")
|
||||
public static let sectionFill = Color("BackgroundTertiary")
|
||||
}
|
||||
|
||||
// MARK: - Rituals Text Colors
|
||||
|
||||
/// Text colors using Asset Catalog with light/dark variants.
|
||||
public enum RitualsTextColors: TextColorProvider {
|
||||
public static let primary = Color.white
|
||||
public static let secondary = Color.white.opacity(Design.Opacity.accent)
|
||||
public static let tertiary = Color.white.opacity(Design.Opacity.medium)
|
||||
public static let disabled = Color.white.opacity(Design.Opacity.light)
|
||||
public static let placeholder = Color.white.opacity(Design.Opacity.overlay)
|
||||
public static let inverse = Color.black
|
||||
public static let primary = Color("TextPrimary")
|
||||
public static let secondary = Color("TextSecondary")
|
||||
public static let tertiary = Color("TextTertiary")
|
||||
public static let disabled = Color("TextDisabled")
|
||||
public static let placeholder = Color("TextTertiary")
|
||||
public static let inverse = Color("Background")
|
||||
}
|
||||
|
||||
// MARK: - Rituals Accent Colors
|
||||
|
||||
/// Accent colors using Asset Catalog with light/dark variants.
|
||||
public enum RitualsAccentColors: AccentColorProvider {
|
||||
public static let primary = Color(red: 0.93, green: 0.55, blue: 0.40)
|
||||
public static let light = Color(red: 0.98, green: 0.70, blue: 0.55)
|
||||
public static let dark = Color(red: 0.75, green: 0.38, blue: 0.25)
|
||||
public static let secondary = Color(red: 0.95, green: 0.90, blue: 0.80)
|
||||
public static let primary = Color("Accent")
|
||||
public static let light = Color("AccentLight")
|
||||
public static let dark = Color("AccentDark")
|
||||
public static let secondary = Color("AccentSecondary")
|
||||
}
|
||||
|
||||
// MARK: - Rituals Button Colors
|
||||
|
||||
/// Button colors using Asset Catalog with light/dark variants.
|
||||
public enum RitualsButtonColors: ButtonColorProvider {
|
||||
public static let primaryLight = Color(red: 0.98, green: 0.70, blue: 0.55)
|
||||
public static let primaryDark = Color(red: 0.75, green: 0.38, blue: 0.25)
|
||||
public static let secondary = Color.white.opacity(Design.Opacity.subtle)
|
||||
public static let destructive = Color.red.opacity(Design.Opacity.heavy)
|
||||
public static let cancelText = Color.white.opacity(Design.Opacity.strong)
|
||||
public static let primaryLight = Color("AccentLight")
|
||||
public static let primaryDark = Color("AccentDark")
|
||||
public static let secondary = Color("Divider")
|
||||
public static let destructive = Color("Error")
|
||||
public static let cancelText = Color("TextSecondary")
|
||||
}
|
||||
|
||||
// MARK: - Rituals Status Colors
|
||||
|
||||
/// Status colors using Asset Catalog with light/dark variants.
|
||||
public enum RitualsStatusColors: StatusColorProvider {
|
||||
public static let success = Color(red: 0.20, green: 0.75, blue: 0.55)
|
||||
public static let warning = Color(red: 0.95, green: 0.78, blue: 0.45)
|
||||
public static let error = Color(red: 0.90, green: 0.35, blue: 0.35)
|
||||
public static let info = Color(red: 0.55, green: 0.72, blue: 0.92)
|
||||
public static let success = Color("Success")
|
||||
public static let warning = Color("Warning")
|
||||
public static let error = Color("Error")
|
||||
public static let info = Color("Info")
|
||||
}
|
||||
|
||||
// MARK: - Rituals Border Colors
|
||||
|
||||
/// Border colors using Asset Catalog with light/dark variants.
|
||||
public enum RitualsBorderColors: BorderColorProvider {
|
||||
public static let subtle = Color.white.opacity(Design.Opacity.subtle)
|
||||
public static let standard = Color.white.opacity(Design.Opacity.hint)
|
||||
public static let emphasized = Color.white.opacity(Design.Opacity.light)
|
||||
public static let selected = RitualsAccentColors.primary.opacity(Design.Opacity.medium)
|
||||
public static let subtle = Color("Divider")
|
||||
public static let standard = Color("Divider")
|
||||
public static let emphasized = Color("TextTertiary")
|
||||
public static let selected = Color("Accent").opacity(Design.Opacity.medium)
|
||||
}
|
||||
|
||||
// MARK: - Rituals Interactive Colors
|
||||
|
||||
/// Interactive colors using Asset Catalog with light/dark variants.
|
||||
public enum RitualsInteractiveColors: InteractiveColorProvider {
|
||||
public static let selected = RitualsAccentColors.primary.opacity(Design.Opacity.selection)
|
||||
public static let hover = Color.white.opacity(Design.Opacity.subtle)
|
||||
public static let pressed = Color.white.opacity(Design.Opacity.hint)
|
||||
public static let focus = RitualsAccentColors.light
|
||||
public static let selected = Color("Accent").opacity(Design.Opacity.selection)
|
||||
public static let hover = Color("Divider")
|
||||
public static let pressed = Color("TextTertiary").opacity(Design.Opacity.hint)
|
||||
public static let focus = Color("AccentLight")
|
||||
}
|
||||
|
||||
// MARK: - Rituals Theme
|
||||
|
||||
Loading…
Reference in New Issue
Block a user