Move diagnostics into settings, remove the app-local notification module, unify the global theme switcher, refine privacy copy and the instance detail experience, and rebuild the app icon.
57 lines
1.2 KiB
Swift
57 lines
1.2 KiB
Swift
import Foundation
|
|
import SwiftUI
|
|
|
|
public enum ThemeMode: String, CaseIterable, Identifiable, Codable, Sendable {
|
|
case system
|
|
case light
|
|
case dark
|
|
|
|
public var id: String { rawValue }
|
|
|
|
public var label: String {
|
|
switch self {
|
|
case .system: return "跟随系统"
|
|
case .light: return "浅色"
|
|
case .dark: return "深色"
|
|
}
|
|
}
|
|
|
|
public var systemImage: String {
|
|
switch self {
|
|
case .system: return "circle.lefthalf.filled"
|
|
case .light: return "sun.max"
|
|
case .dark: return "moon.stars"
|
|
}
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
final class ThemeStore: ObservableObject {
|
|
static let shared = ThemeStore()
|
|
|
|
@Published private(set) var mode: ThemeMode
|
|
private let defaults: UserDefaults
|
|
private static let storageKey = "aiThemeMode"
|
|
|
|
init(defaults: UserDefaults = .standard) {
|
|
self.defaults = defaults
|
|
mode = ThemeMode(rawValue: defaults.string(forKey: Self.storageKey) ?? "") ?? .system
|
|
}
|
|
|
|
func set(_ newMode: ThemeMode) {
|
|
guard newMode != mode else { return }
|
|
mode = newMode
|
|
defaults.set(newMode.rawValue, forKey: Self.storageKey)
|
|
}
|
|
}
|
|
|
|
extension ThemeMode {
|
|
var colorScheme: ColorScheme? {
|
|
switch self {
|
|
case .system: return nil
|
|
case .light: return .light
|
|
case .dark: return .dark
|
|
}
|
|
}
|
|
}
|