Files
Nextcloud-Cookbook-iOS/Nextcloud Cookbook iOS Client/Data/UserSettings.swift
Hendrik Hogertz 02118e3d7a Add dark mode support with appearance picker and fix hardcoded colors
Add user-facing appearance setting (System/Light/Dark) wired via
preferredColorScheme at the app root. Replace hardcoded .black tints
and foreground styles with .primary so toolbar buttons and text remain
visible in dark mode. Remove profile picture from settings and
SwiftSoup from acknowledgements.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 06:31:14 +01:00

197 lines
6.9 KiB
Swift

//
// UserSettings.swift
// Nextcloud Cookbook iOS Client
//
// Created by Vincent Meilinger on 15.09.23.
//
import Foundation
import Combine
class UserSettings: ObservableObject {
static let shared = UserSettings()
@Published var username: String {
didSet {
UserDefaults.standard.set(username, forKey: "username")
}
}
@Published var token: String {
didSet {
UserDefaults.standard.set(token, forKey: "token")
}
}
@Published var authString: String {
didSet {
UserDefaults.standard.set(authString, forKey: "authString")
}
}
@Published var serverAddress: String {
didSet {
UserDefaults.standard.set(serverAddress, forKey: "serverAddress")
}
}
@Published var serverProtocol: String {
didSet {
UserDefaults.standard.set(serverProtocol, forKey: "serverProtocol")
}
}
@Published var cookbookApiVersion: CookbookApiVersion {
didSet {
UserDefaults.standard.set(cookbookApiVersion, forKey: "cookbookApiVersion")
}
}
@Published var onboarding: Bool {
didSet {
UserDefaults.standard.set(onboarding, forKey: "onboarding")
}
}
@Published var defaultCategory: String {
didSet {
UserDefaults.standard.set(defaultCategory, forKey: "defaultCategory")
}
}
@Published var language: String {
didSet {
UserDefaults.standard.set(language, forKey: "language")
}
}
@Published var storeRecipes: Bool {
didSet {
UserDefaults.standard.set(storeRecipes, forKey: "storeRecipes")
}
}
@Published var storeImages: Bool {
didSet {
UserDefaults.standard.set(storeImages, forKey: "storeImages")
}
}
@Published var storeThumb: Bool {
didSet {
UserDefaults.standard.set(storeThumb, forKey: "storeThumb")
}
}
@Published var lastUpdate: Date {
didSet {
UserDefaults.standard.set(lastUpdate, forKey: "lastUpdate")
}
}
@Published var expandNutritionSection: Bool {
didSet {
UserDefaults.standard.set(expandNutritionSection, forKey: "expandNutritionSection")
}
}
@Published var expandKeywordSection: Bool {
didSet {
UserDefaults.standard.set(expandKeywordSection, forKey: "expandKeywordSection")
}
}
@Published var expandInfoSection: Bool {
didSet {
UserDefaults.standard.set(expandInfoSection, forKey: "expandInfoSection")
}
}
@Published var keepScreenAwake: Bool {
didSet {
UserDefaults.standard.set(keepScreenAwake, forKey: "keepScreenAwake")
}
}
@Published var decimalNumberSeparator: String {
didSet {
UserDefaults.standard.set(decimalNumberSeparator, forKey: "decimalNumberSeparator")
}
}
@Published var groceryListMode: String {
didSet {
UserDefaults.standard.set(groceryListMode, forKey: "groceryListMode")
}
}
@Published var remindersListIdentifier: String {
didSet {
UserDefaults.standard.set(remindersListIdentifier, forKey: "remindersListIdentifier")
}
}
@Published var grocerySyncEnabled: Bool {
didSet {
UserDefaults.standard.set(grocerySyncEnabled, forKey: "grocerySyncEnabled")
}
}
@Published var mealPlanSyncEnabled: Bool {
didSet {
UserDefaults.standard.set(mealPlanSyncEnabled, forKey: "mealPlanSyncEnabled")
}
}
@Published var appearanceMode: String {
didSet {
UserDefaults.standard.set(appearanceMode, forKey: "appearanceMode")
}
}
init() {
self.username = UserDefaults.standard.object(forKey: "username") as? String ?? ""
self.token = UserDefaults.standard.object(forKey: "token") as? String ?? ""
self.authString = UserDefaults.standard.object(forKey: "authString") as? String ?? ""
self.serverAddress = UserDefaults.standard.object(forKey: "serverAddress") as? String ?? ""
self.serverProtocol = UserDefaults.standard.object(forKey: "serverProtocol") as? String ?? "https://"
self.cookbookApiVersion = UserDefaults.standard.object(forKey: "cookbookApiVersion") as? CookbookApiVersion ?? .v1
self.onboarding = UserDefaults.standard.object(forKey: "onboarding") as? Bool ?? true
self.defaultCategory = UserDefaults.standard.object(forKey: "defaultCategory") as? String ?? ""
self.language = UserDefaults.standard.object(forKey: "language") as? String ?? SupportedLanguage.DEVICE.rawValue
self.storeRecipes = UserDefaults.standard.object(forKey: "storeRecipes") as? Bool ?? true
self.storeImages = UserDefaults.standard.object(forKey: "storeImages") as? Bool ?? true
self.storeThumb = UserDefaults.standard.object(forKey: "storeThumb") as? Bool ?? true
self.lastUpdate = UserDefaults.standard.object(forKey: "lastUpdate") as? Date ?? Date.distantPast
self.expandNutritionSection = UserDefaults.standard.object(forKey: "expandNutritionSection") as? Bool ?? false
self.expandKeywordSection = UserDefaults.standard.object(forKey: "expandKeywordSection") as? Bool ?? false
self.expandInfoSection = UserDefaults.standard.object(forKey: "expandInfoSection") as? Bool ?? false
self.keepScreenAwake = UserDefaults.standard.object(forKey: "keepScreenAwake") as? Bool ?? true
self.decimalNumberSeparator = UserDefaults.standard.object(forKey: "decimalNumberSeparator") as? String ?? "."
self.groceryListMode = UserDefaults.standard.object(forKey: "groceryListMode") as? String ?? GroceryListMode.inApp.rawValue
self.remindersListIdentifier = UserDefaults.standard.object(forKey: "remindersListIdentifier") as? String ?? ""
self.grocerySyncEnabled = UserDefaults.standard.object(forKey: "grocerySyncEnabled") as? Bool ?? true
self.mealPlanSyncEnabled = UserDefaults.standard.object(forKey: "mealPlanSyncEnabled") as? Bool ?? true
self.appearanceMode = UserDefaults.standard.object(forKey: "appearanceMode") as? String ?? AppearanceMode.system.rawValue
if authString == "" {
if token != "" && username != "" {
let loginString = "\(self.username):\(self.token)"
let loginData = loginString.data(using: String.Encoding.utf8)!
authString = loginData.base64EncodedString()
}
}
}
func setAuthString() {
if token != "" && username != "" {
let loginString = "\(self.username):\(self.token)"
let loginData = loginString.data(using: String.Encoding.utf8)!
self.authString = loginData.base64EncodedString()
}
}
}