feat: switch to size preset for more consistent control
This commit is contained in:
@@ -140,14 +140,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
case .blinkTriggered:
|
case .blinkTriggered:
|
||||||
let sizePercentage = settingsManager?.settings.subtleReminderSizePercentage ?? 15.0
|
let sizePercentage = settingsManager?.settings.subtleReminderSize.percentage ?? 5.0
|
||||||
contentView = AnyView(
|
contentView = AnyView(
|
||||||
BlinkReminderView(sizePercentage: sizePercentage) { [weak self] in
|
BlinkReminderView(sizePercentage: sizePercentage) { [weak self] in
|
||||||
self?.timerEngine?.dismissReminder()
|
self?.timerEngine?.dismissReminder()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
case .postureTriggered:
|
case .postureTriggered:
|
||||||
let sizePercentage = settingsManager?.settings.subtleReminderSizePercentage ?? 10.0
|
let sizePercentage = settingsManager?.settings.subtleReminderSize.percentage ?? 5.0
|
||||||
contentView = AnyView(
|
contentView = AnyView(
|
||||||
PostureReminderView(sizePercentage: sizePercentage) { [weak self] in
|
PostureReminderView(sizePercentage: sizePercentage) { [weak self] in
|
||||||
self?.timerEngine?.dismissReminder()
|
self?.timerEngine?.dismissReminder()
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import SwiftUI
|
|||||||
struct GazeApp: App {
|
struct GazeApp: App {
|
||||||
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
||||||
@StateObject private var settingsManager = SettingsManager.shared
|
@StateObject private var settingsManager = SettingsManager.shared
|
||||||
@State private var menuBarRefreshID = 0
|
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
// Onboarding window (only shown when not completed)
|
// Onboarding window (only shown when not completed)
|
||||||
@@ -48,13 +47,9 @@ struct GazeApp: App {
|
|||||||
onOpenSettings: { appDelegate.openSettings() },
|
onOpenSettings: { appDelegate.openSettings() },
|
||||||
onOpenSettingsTab: { tab in appDelegate.openSettings(tab: tab) }
|
onOpenSettingsTab: { tab in appDelegate.openSettings(tab: tab) }
|
||||||
)
|
)
|
||||||
.id(menuBarRefreshID)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.menuBarExtraStyle(.window)
|
.menuBarExtraStyle(.window)
|
||||||
.onChange(of: settingsManager.settings) { _ in
|
|
||||||
menuBarRefreshID += 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func closeAllWindows() {
|
private func closeAllWindows() {
|
||||||
|
|||||||
@@ -7,6 +7,30 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
// MARK: - Reminder Size
|
||||||
|
|
||||||
|
enum ReminderSize: String, Codable, CaseIterable {
|
||||||
|
case small
|
||||||
|
case medium
|
||||||
|
case large
|
||||||
|
|
||||||
|
var percentage: Double {
|
||||||
|
switch self {
|
||||||
|
case .small: return 1.5
|
||||||
|
case .medium: return 2.5
|
||||||
|
case .large: return 5.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var displayName: String {
|
||||||
|
switch self {
|
||||||
|
case .small: return "Small"
|
||||||
|
case .medium: return "Medium"
|
||||||
|
case .large: return "Large"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Centralized Configuration System
|
// MARK: - Centralized Configuration System
|
||||||
|
|
||||||
/// Unified configuration class that manages all app settings in a centralized way
|
/// Unified configuration class that manages all app settings in a centralized way
|
||||||
@@ -17,11 +41,9 @@ struct AppSettings: Codable, Equatable, Hashable {
|
|||||||
var blinkTimer: TimerConfiguration
|
var blinkTimer: TimerConfiguration
|
||||||
var postureTimer: TimerConfiguration
|
var postureTimer: TimerConfiguration
|
||||||
|
|
||||||
// User-defined timers (up to 3)
|
|
||||||
var userTimers: [UserTimer]
|
var userTimers: [UserTimer]
|
||||||
|
|
||||||
// UI and display settings
|
var subtleReminderSize: ReminderSize
|
||||||
var subtleReminderSizePercentage: Double // 0.5-25% of screen width
|
|
||||||
|
|
||||||
// App state and behavior
|
// App state and behavior
|
||||||
var hasCompletedOnboarding: Bool
|
var hasCompletedOnboarding: Bool
|
||||||
@@ -37,7 +59,7 @@ struct AppSettings: Codable, Equatable, Hashable {
|
|||||||
postureTimer: TimerConfiguration = TimerConfiguration(
|
postureTimer: TimerConfiguration = TimerConfiguration(
|
||||||
enabled: true, intervalSeconds: 30 * 60),
|
enabled: true, intervalSeconds: 30 * 60),
|
||||||
userTimers: [UserTimer] = [],
|
userTimers: [UserTimer] = [],
|
||||||
subtleReminderSizePercentage: Double = 5.0,
|
subtleReminderSize: ReminderSize = .large,
|
||||||
hasCompletedOnboarding: Bool = false,
|
hasCompletedOnboarding: Bool = false,
|
||||||
launchAtLogin: Bool = false,
|
launchAtLogin: Bool = false,
|
||||||
playSounds: Bool = true
|
playSounds: Bool = true
|
||||||
@@ -47,8 +69,7 @@ struct AppSettings: Codable, Equatable, Hashable {
|
|||||||
self.blinkTimer = blinkTimer
|
self.blinkTimer = blinkTimer
|
||||||
self.postureTimer = postureTimer
|
self.postureTimer = postureTimer
|
||||||
self.userTimers = userTimers
|
self.userTimers = userTimers
|
||||||
// Clamp the subtle reminder size to valid range (2-35%)
|
self.subtleReminderSize = subtleReminderSize
|
||||||
self.subtleReminderSizePercentage = max(2.0, min(35.0, subtleReminderSizePercentage))
|
|
||||||
self.hasCompletedOnboarding = hasCompletedOnboarding
|
self.hasCompletedOnboarding = hasCompletedOnboarding
|
||||||
self.launchAtLogin = launchAtLogin
|
self.launchAtLogin = launchAtLogin
|
||||||
self.playSounds = playSounds
|
self.playSounds = playSounds
|
||||||
@@ -61,7 +82,7 @@ struct AppSettings: Codable, Equatable, Hashable {
|
|||||||
blinkTimer: TimerConfiguration(enabled: false, intervalSeconds: 7 * 60),
|
blinkTimer: TimerConfiguration(enabled: false, intervalSeconds: 7 * 60),
|
||||||
postureTimer: TimerConfiguration(enabled: true, intervalSeconds: 30 * 60),
|
postureTimer: TimerConfiguration(enabled: true, intervalSeconds: 30 * 60),
|
||||||
userTimers: [],
|
userTimers: [],
|
||||||
subtleReminderSizePercentage: 5.0,
|
subtleReminderSize: .large,
|
||||||
hasCompletedOnboarding: false,
|
hasCompletedOnboarding: false,
|
||||||
launchAtLogin: false,
|
launchAtLogin: false,
|
||||||
playSounds: true
|
playSounds: true
|
||||||
@@ -73,7 +94,7 @@ struct AppSettings: Codable, Equatable, Hashable {
|
|||||||
&& lhs.lookAwayCountdownSeconds == rhs.lookAwayCountdownSeconds
|
&& lhs.lookAwayCountdownSeconds == rhs.lookAwayCountdownSeconds
|
||||||
&& lhs.blinkTimer == rhs.blinkTimer && lhs.postureTimer == rhs.postureTimer
|
&& lhs.blinkTimer == rhs.blinkTimer && lhs.postureTimer == rhs.postureTimer
|
||||||
&& lhs.userTimers == rhs.userTimers
|
&& lhs.userTimers == rhs.userTimers
|
||||||
&& lhs.subtleReminderSizePercentage == rhs.subtleReminderSizePercentage
|
&& lhs.subtleReminderSize == rhs.subtleReminderSize
|
||||||
&& lhs.hasCompletedOnboarding == rhs.hasCompletedOnboarding
|
&& lhs.hasCompletedOnboarding == rhs.hasCompletedOnboarding
|
||||||
&& lhs.launchAtLogin == rhs.launchAtLogin && lhs.playSounds == rhs.playSounds
|
&& lhs.launchAtLogin == rhs.launchAtLogin && lhs.playSounds == rhs.playSounds
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ class MigrationManager {
|
|||||||
|
|
||||||
private func setupMigrations() {
|
private func setupMigrations() {
|
||||||
migrations.append(Version101Migration())
|
migrations.append(Version101Migration())
|
||||||
|
migrations.append(Version102Migration())
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getTargetVersion() -> String {
|
private func getTargetVersion() -> String {
|
||||||
@@ -165,6 +166,35 @@ class Version101Migration: Migration {
|
|||||||
// Add any new fields with default values if they don't exist
|
// Add any new fields with default values if they don't exist
|
||||||
// Transform data structures as needed
|
// Transform data structures as needed
|
||||||
|
|
||||||
|
return migratedData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Version102Migration: Migration {
|
||||||
|
var targetVersion: String = "1.0.2"
|
||||||
|
|
||||||
|
func migrate(_ data: [String: Any]) throws -> [String: Any] {
|
||||||
|
var migratedData = data
|
||||||
|
|
||||||
|
// Migrate subtleReminderSizePercentage (Double) to subtleReminderSize (ReminderSize enum)
|
||||||
|
if let oldPercentage = migratedData["subtleReminderSizePercentage"] as? Double {
|
||||||
|
// Map old percentage values to new enum cases
|
||||||
|
let reminderSize: String
|
||||||
|
if oldPercentage <= 2.0 {
|
||||||
|
reminderSize = "small"
|
||||||
|
} else if oldPercentage <= 3.5 {
|
||||||
|
reminderSize = "medium"
|
||||||
|
} else {
|
||||||
|
reminderSize = "large"
|
||||||
|
}
|
||||||
|
|
||||||
|
migratedData["subtleReminderSize"] = reminderSize
|
||||||
|
migratedData.removeValue(forKey: "subtleReminderSizePercentage")
|
||||||
|
} else if migratedData["subtleReminderSize"] == nil {
|
||||||
|
// If neither old nor new key exists, set default
|
||||||
|
migratedData["subtleReminderSize"] = "large"
|
||||||
|
}
|
||||||
|
|
||||||
return migratedData
|
return migratedData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,38 +5,39 @@
|
|||||||
// Created by Mike Freno on 1/7/26.
|
// Created by Mike Freno on 1/7/26.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Combine
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
class SettingsManager: ObservableObject {
|
class SettingsManager: ObservableObject {
|
||||||
static let shared = SettingsManager()
|
static let shared = SettingsManager()
|
||||||
|
|
||||||
@Published var settings: AppSettings {
|
@Published var settings: AppSettings {
|
||||||
didSet {
|
didSet {
|
||||||
save()
|
save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let userDefaults = UserDefaults.standard
|
private let userDefaults = UserDefaults.standard
|
||||||
private let settingsKey = "gazeAppSettings"
|
private let settingsKey = "gazeAppSettings"
|
||||||
|
|
||||||
private init() {
|
private init() {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// Clear settings on every development build
|
// Clear settings on every development build
|
||||||
UserDefaults.standard.removeObject(forKey: "gazeAppSettings")
|
UserDefaults.standard.removeObject(forKey: "gazeAppSettings")
|
||||||
#endif
|
#endif
|
||||||
self.settings = Self.loadSettings()
|
self.settings = Self.loadSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func loadSettings() -> AppSettings {
|
private static func loadSettings() -> AppSettings {
|
||||||
guard let data = UserDefaults.standard.data(forKey: "gazeAppSettings"),
|
guard let data = UserDefaults.standard.data(forKey: "gazeAppSettings"),
|
||||||
let settings = try? JSONDecoder().decode(AppSettings.self, from: data) else {
|
let settings = try? JSONDecoder().decode(AppSettings.self, from: data)
|
||||||
|
else {
|
||||||
return .defaults
|
return .defaults
|
||||||
}
|
}
|
||||||
return settings
|
return settings
|
||||||
}
|
}
|
||||||
|
|
||||||
func save() {
|
func save() {
|
||||||
guard let data = try? JSONEncoder().encode(settings) else {
|
guard let data = try? JSONEncoder().encode(settings) else {
|
||||||
print("Failed to encode settings")
|
print("Failed to encode settings")
|
||||||
@@ -44,15 +45,15 @@ class SettingsManager: ObservableObject {
|
|||||||
}
|
}
|
||||||
userDefaults.set(data, forKey: settingsKey)
|
userDefaults.set(data, forKey: settingsKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func load() {
|
func load() {
|
||||||
settings = Self.loadSettings()
|
settings = Self.loadSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
func resetToDefaults() {
|
func resetToDefaults() {
|
||||||
settings = .defaults
|
settings = .defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
func timerConfiguration(for type: TimerType) -> TimerConfiguration {
|
func timerConfiguration(for type: TimerType) -> TimerConfiguration {
|
||||||
switch type {
|
switch type {
|
||||||
case .lookAway:
|
case .lookAway:
|
||||||
@@ -63,7 +64,7 @@ class SettingsManager: ObservableObject {
|
|||||||
return settings.postureTimer
|
return settings.postureTimer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTimerConfiguration(for type: TimerType, configuration: TimerConfiguration) {
|
func updateTimerConfiguration(for type: TimerType, configuration: TimerConfiguration) {
|
||||||
switch type {
|
switch type {
|
||||||
case .lookAway:
|
case .lookAway:
|
||||||
|
|||||||
@@ -50,9 +50,6 @@ struct MenuBarContentView: View {
|
|||||||
var onQuit: () -> Void
|
var onQuit: () -> Void
|
||||||
var onOpenSettings: () -> Void
|
var onOpenSettings: () -> Void
|
||||||
var onOpenSettingsTab: (Int) -> Void
|
var onOpenSettingsTab: (Int) -> Void
|
||||||
|
|
||||||
// Force view refresh when timer states change
|
|
||||||
@State private var refreshID = UUID()
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
@@ -170,13 +167,9 @@ struct MenuBarContentView: View {
|
|||||||
.padding(.vertical, 8)
|
.padding(.vertical, 8)
|
||||||
}
|
}
|
||||||
.frame(width: 300)
|
.frame(width: 300)
|
||||||
.id(refreshID)
|
|
||||||
.onReceive(NotificationCenter.default.publisher(for: Notification.Name("CloseMenuBarPopover"))) { _ in
|
.onReceive(NotificationCenter.default.publisher(for: Notification.Name("CloseMenuBarPopover"))) { _ in
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
.onReceive(timerEngine.$timerStates) { _ in
|
|
||||||
refreshID = UUID()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var isPaused: Bool {
|
private var isPaused: Bool {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ struct OnboardingContainerView: View {
|
|||||||
@State private var postureEnabled = true
|
@State private var postureEnabled = true
|
||||||
@State private var postureIntervalMinutes = 30
|
@State private var postureIntervalMinutes = 30
|
||||||
@State private var launchAtLogin = false
|
@State private var launchAtLogin = false
|
||||||
@State private var subtleReminderSizePercentage = 5.0
|
@State private var subtleReminderSize: ReminderSize = .large
|
||||||
@State private var isAnimatingOut = false
|
@State private var isAnimatingOut = false
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ struct OnboardingContainerView: View {
|
|||||||
|
|
||||||
SettingsOnboardingView(
|
SettingsOnboardingView(
|
||||||
launchAtLogin: $launchAtLogin,
|
launchAtLogin: $launchAtLogin,
|
||||||
subtleReminderSizePercentage: $subtleReminderSizePercentage,
|
subtleReminderSize: $subtleReminderSize,
|
||||||
isOnboarding: true
|
isOnboarding: true
|
||||||
)
|
)
|
||||||
.tag(4)
|
.tag(4)
|
||||||
@@ -162,7 +162,7 @@ struct OnboardingContainerView: View {
|
|||||||
)
|
)
|
||||||
|
|
||||||
settingsManager.settings.launchAtLogin = launchAtLogin
|
settingsManager.settings.launchAtLogin = launchAtLogin
|
||||||
settingsManager.settings.subtleReminderSizePercentage = subtleReminderSizePercentage
|
settingsManager.settings.subtleReminderSize = subtleReminderSize
|
||||||
settingsManager.settings.hasCompletedOnboarding = true
|
settingsManager.settings.hasCompletedOnboarding = true
|
||||||
|
|
||||||
// Apply launch at login setting
|
// Apply launch at login setting
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import SwiftUI
|
|||||||
|
|
||||||
struct SettingsOnboardingView: View {
|
struct SettingsOnboardingView: View {
|
||||||
@Binding var launchAtLogin: Bool
|
@Binding var launchAtLogin: Bool
|
||||||
@Binding var subtleReminderSizePercentage: Double
|
@Binding var subtleReminderSize: ReminderSize
|
||||||
var isOnboarding: Bool = true
|
var isOnboarding: Bool = true
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -62,16 +62,13 @@ struct SettingsOnboardingView: View {
|
|||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
HStack {
|
Picker("Size", selection: $subtleReminderSize) {
|
||||||
Slider(
|
ForEach(ReminderSize.allCases, id: \.self) { size in
|
||||||
value: $subtleReminderSizePercentage,
|
Text(size.displayName).tag(size)
|
||||||
in: 0.5...25,
|
}
|
||||||
step: 0.5
|
|
||||||
)
|
|
||||||
Text("\(String(format: "%.1f", subtleReminderSizePercentage))%")
|
|
||||||
.frame(width: 50, alignment: .trailing)
|
|
||||||
.monospacedDigit()
|
|
||||||
}
|
}
|
||||||
|
.pickerStyle(.segmented)
|
||||||
|
.labelsHidden()
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
.glassEffect(.regular, in: .rect(cornerRadius: 12))
|
.glassEffect(.regular, in: .rect(cornerRadius: 12))
|
||||||
@@ -166,7 +163,7 @@ struct SettingsOnboardingView: View {
|
|||||||
#Preview("Settings Onboarding - Launch Disabled") {
|
#Preview("Settings Onboarding - Launch Disabled") {
|
||||||
SettingsOnboardingView(
|
SettingsOnboardingView(
|
||||||
launchAtLogin: .constant(false),
|
launchAtLogin: .constant(false),
|
||||||
subtleReminderSizePercentage: .constant(5.0),
|
subtleReminderSize: .constant(.large),
|
||||||
isOnboarding: true
|
isOnboarding: true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -174,7 +171,7 @@ struct SettingsOnboardingView: View {
|
|||||||
#Preview("Settings Onboarding - Launch Enabled") {
|
#Preview("Settings Onboarding - Launch Enabled") {
|
||||||
SettingsOnboardingView(
|
SettingsOnboardingView(
|
||||||
launchAtLogin: .constant(true),
|
launchAtLogin: .constant(true),
|
||||||
subtleReminderSizePercentage: .constant(10.0),
|
subtleReminderSize: .constant(.medium),
|
||||||
isOnboarding: true
|
isOnboarding: true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ struct BlinkReminderView: View {
|
|||||||
private let screenWidth = NSScreen.main?.frame.width ?? 1200
|
private let screenWidth = NSScreen.main?.frame.width ?? 1200
|
||||||
|
|
||||||
private var baseSize: CGFloat {
|
private var baseSize: CGFloat {
|
||||||
screenWidth * (sizePercentage / 100.0)
|
screenWidth * (sizePercentage / 100.0) * 2.5
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -45,7 +45,7 @@ struct BlinkReminderView: View {
|
|||||||
}
|
}
|
||||||
.opacity(opacity)
|
.opacity(opacity)
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||||
.padding(.top, screenHeight * 0.1)
|
.padding(.top, screenHeight * 0.05)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
startAnimation()
|
startAnimation()
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ struct BlinkReminderView: View {
|
|||||||
opacity = 1.0
|
opacity = 1.0
|
||||||
scale = 1.0
|
scale = 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||||
shouldShowAnimation = true
|
shouldShowAnimation = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ struct PostureReminderView: View {
|
|||||||
.opacity(opacity)
|
.opacity(opacity)
|
||||||
.offset(y: yOffset)
|
.offset(y: yOffset)
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||||
.padding(.top, screenHeight * 0.1)
|
.padding(.top, screenHeight * 0.075)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
startAnimation()
|
startAnimation()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ struct SettingsWindowView: View {
|
|||||||
@State private var postureEnabled: Bool
|
@State private var postureEnabled: Bool
|
||||||
@State private var postureIntervalMinutes: Int
|
@State private var postureIntervalMinutes: Int
|
||||||
@State private var launchAtLogin: Bool
|
@State private var launchAtLogin: Bool
|
||||||
@State private var subtleReminderSizePercentage: Double
|
@State private var subtleReminderSize: ReminderSize
|
||||||
@State private var userTimers: [UserTimer]
|
@State private var userTimers: [UserTimer]
|
||||||
|
|
||||||
init(settingsManager: SettingsManager, initialTab: Int = 0) {
|
init(settingsManager: SettingsManager, initialTab: Int = 0) {
|
||||||
@@ -37,8 +37,8 @@ struct SettingsWindowView: View {
|
|||||||
_postureIntervalMinutes = State(
|
_postureIntervalMinutes = State(
|
||||||
initialValue: settingsManager.settings.postureTimer.intervalSeconds / 60)
|
initialValue: settingsManager.settings.postureTimer.intervalSeconds / 60)
|
||||||
_launchAtLogin = State(initialValue: settingsManager.settings.launchAtLogin)
|
_launchAtLogin = State(initialValue: settingsManager.settings.launchAtLogin)
|
||||||
_subtleReminderSizePercentage = State(
|
_subtleReminderSize = State(
|
||||||
initialValue: settingsManager.settings.subtleReminderSizePercentage)
|
initialValue: settingsManager.settings.subtleReminderSize)
|
||||||
_userTimers = State(initialValue: settingsManager.settings.userTimers)
|
_userTimers = State(initialValue: settingsManager.settings.userTimers)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ struct SettingsWindowView: View {
|
|||||||
|
|
||||||
SettingsOnboardingView(
|
SettingsOnboardingView(
|
||||||
launchAtLogin: $launchAtLogin,
|
launchAtLogin: $launchAtLogin,
|
||||||
subtleReminderSizePercentage: $subtleReminderSizePercentage,
|
subtleReminderSize: $subtleReminderSize,
|
||||||
isOnboarding: false
|
isOnboarding: false
|
||||||
)
|
)
|
||||||
.tag(4)
|
.tag(4)
|
||||||
@@ -137,7 +137,7 @@ struct SettingsWindowView: View {
|
|||||||
intervalSeconds: postureIntervalMinutes * 60
|
intervalSeconds: postureIntervalMinutes * 60
|
||||||
),
|
),
|
||||||
userTimers: userTimers,
|
userTimers: userTimers,
|
||||||
subtleReminderSizePercentage: subtleReminderSizePercentage,
|
subtleReminderSize: subtleReminderSize,
|
||||||
hasCompletedOnboarding: settingsManager.settings.hasCompletedOnboarding,
|
hasCompletedOnboarding: settingsManager.settings.hasCompletedOnboarding,
|
||||||
launchAtLogin: launchAtLogin,
|
launchAtLogin: launchAtLogin,
|
||||||
playSounds: settingsManager.settings.playSounds
|
playSounds: settingsManager.settings.playSounds
|
||||||
|
|||||||
Reference in New Issue
Block a user