// // AppSettings.swift // IceGlass // // Copyright 2026 Rouslan Zenetl. All Rights Reserved. // import Foundation #if os(macOS) import ServiceManagement #endif class AppSettings: @unchecked Sendable { private let logger = IceGlassLogger( subsystem: Bundle.main.bundleIdentifier ?? "dev.rzen.indie.IceGlass", category: "AppSettings" ) static let shared = AppSettings() private enum UserDefaultsKey { static let launchAtLogin = "launchAtLogin" static let displayOption = "displayOption" static let statusBarOption = "statusBarOption" } /// Controls which days are shown in the menu enum DisplayOption: String, CaseIterable { case yesterdayTodayTomorrow = "yesterdayTodayTomorrow" case todayTomorrow = "todayTomorrow" case todayOnly = "todayOnly" var title: String { switch self { case .yesterdayTodayTomorrow: return "Yesterday / Today / Tomorrow" case .todayTomorrow: return "Today / Tomorrow" case .todayOnly: return "Today" } } func includedDates() -> Set { switch self { case .yesterdayTodayTomorrow: return [Date.yesterdayET, Date.todayET, Date.tomorrowET] case .todayTomorrow: return [Date.todayET, Date.tomorrowET] case .todayOnly: return [Date.todayET] } } } /// Controls what number shows next to the menu bar icon enum StatusBarOption: String, CaseIterable { case gameCount = "gameCount" case gamesPlayed = "gamesPlayed" case gamesPlayedTotal = "gamesPlayedTotal" var title: String { switch self { case .gameCount: return "Game Count" case .gamesPlayed: return "Games Played" case .gamesPlayedTotal: return "Games Played / Total" } } } // Launch at login var launchAtLogin: Bool { get { UserDefaults.standard.bool(forKey: UserDefaultsKey.launchAtLogin) } set { UserDefaults.standard.set(newValue, forKey: UserDefaultsKey.launchAtLogin) } } // Display option var displayOption: DisplayOption { get { if let rawValue = UserDefaults.standard.string(forKey: UserDefaultsKey.displayOption), let option = DisplayOption(rawValue: rawValue) { return option } return .yesterdayTodayTomorrow } set { UserDefaults.standard.set(newValue.rawValue, forKey: UserDefaultsKey.displayOption) } } // Status bar option var statusBarOption: StatusBarOption { get { if let rawValue = UserDefaults.standard.string(forKey: UserDefaultsKey.statusBarOption), let option = StatusBarOption(rawValue: rawValue) { return option } return .gameCount } set { UserDefaults.standard.set(newValue.rawValue, forKey: UserDefaultsKey.statusBarOption) } } func updateLoginItem(enabled: Bool) { #if os(macOS) do { if enabled { try SMAppService.mainApp.register() } else { try SMAppService.mainApp.unregister() } } catch { logger.error("Failed to \(enabled ? "enable" : "disable") launch at login: \(error.localizedDescription)") } #endif } private init() {} }