feat: better clarity for disabled reminders, continued prev commit work

This commit is contained in:
Michael Freno
2026-01-09 13:13:07 -05:00
parent b8f995b2e9
commit 63dde81b97
10 changed files with 99 additions and 15 deletions

View File

@@ -0,0 +1 @@
{ "v": "5.7.4", "fr": 30, "ip": 0, "op": 60, "w": 200, "h": 200, "nm": "Ring Animation", "ddd": 0, "assets": [], "date": "2026-01-09T00:00:00Z", "layers": [ { "ddd": 0, "ind": 1, "ty": 4, "nm": "Ring", "sr": 1, "ks": { "o": { "a": 0, "k": 100 }, "r": { "a": 1, "k": [ { "t": 0, "s": [0], "e": [360] }, { "t": 30, "s": [360], "e": [0] } ] }, "p": { "a": 0, "k": [100, 100, 0] }, "a": { "a": 0, "k": [0, 0, 0] }, "s": { "a": 0, "k": [100, 100, 100] } }, "ao": 0, "shapes": [ { "ty": "gr", "it": [ { "ty": "el", "p": { "a": 0, "k": [0, 0] }, "s": { "a": 0, "k": [80, 80] }, "nm": "Ring Ellipse" }, { "ty": "st", "c": { "a": 0, "k": [0.9, 0.3, 0.1, 1] }, "o": { "a": 0, "k": 100 }, "w": { "a": 0, "k": 6 }, "lc": 1, "lj": 2, "nm": "Stroke" }, { "ty": "tr", "p": { "a": 0, "k": [0, 0] }, "a": { "a": 0, "k": [0, 0] }, "s": { "a": 0, "k": [100, 100] }, "r": { "a": 0, "k": 0 }, "o": { "a": 0, "k": 100 } } ], "nm": "Ring Shape" } ], "ip": 0, "op": 60, "st": 0, "bm": 0 } ], "markers": [] }

View File

@@ -11,6 +11,7 @@ enum AnimationAsset: String {
case blink = "blink"
case lookAway = "look-away"
case posture = "posture"
case ring = "ring"
var fileName: String {
return self.rawValue

View File

@@ -28,6 +28,29 @@ struct AppSettings: Codable, Equatable {
var launchAtLogin: Bool
var playSounds: Bool
init(
lookAwayTimer: TimerConfiguration = TimerConfiguration(enabled: true, intervalSeconds: 20 * 60),
lookAwayCountdownSeconds: Int = 20,
blinkTimer: TimerConfiguration = TimerConfiguration(enabled: false, intervalSeconds: 7 * 60),
postureTimer: TimerConfiguration = TimerConfiguration(enabled: true, intervalSeconds: 30 * 60),
userTimers: [UserTimer] = [],
subtleReminderSizePercentage: Double = 5.0,
hasCompletedOnboarding: Bool = false,
launchAtLogin: Bool = false,
playSounds: Bool = true
) {
self.lookAwayTimer = lookAwayTimer
self.lookAwayCountdownSeconds = lookAwayCountdownSeconds
self.blinkTimer = blinkTimer
self.postureTimer = postureTimer
self.userTimers = userTimers
// Clamp the subtle reminder size to valid range (2-35%)
self.subtleReminderSizePercentage = max(2.0, min(35.0, subtleReminderSizePercentage))
self.hasCompletedOnboarding = hasCompletedOnboarding
self.launchAtLogin = launchAtLogin
self.playSounds = playSounds
}
static var defaults: AppSettings {
AppSettings(
lookAwayTimer: TimerConfiguration(enabled: true, intervalSeconds: 20 * 60),

View File

@@ -30,7 +30,7 @@ struct MenuBarHoverButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.glassEffect(
isHovered ? .regular.tint(.accentColor).interactive() : .regular,
isHovered ? .regular.tint(.accentColor.opacity(0.5)).interactive() : .regular,
in: .rect(cornerRadius: 6)
)
.contentShape(Rectangle())

View File

@@ -76,9 +76,19 @@ struct BlinkSetupView: View {
.padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12))
if enabled {
Text(
"You will be subtly reminded every \(intervalMinutes) minutes to blink"
)
.font(.subheadline)
.foregroundColor(.secondary)
} else {
Text(
"Blink reminders are currently disabled."
)
.font(.caption)
.foregroundColor(.secondary)
}
Spacer()
}

View File

@@ -56,6 +56,15 @@ struct CompletionView: View {
.font(.subheadline)
}
.padding(.horizontal)
HStack(spacing: 16) {
Image(systemName: "plus.circle")
.foregroundColor(.accentColor)
.frame(width: 30)
Text("Create custom timers in Settings for additional reminders")
.font(.subheadline)
}
.padding(.horizontal)
}
.padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12))

View File

@@ -93,9 +93,20 @@ struct LookAwaySetupView: View {
.padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12))
if enabled {
Text(
"You will be reminded every \(intervalMinutes) minutes to look in the distance for \(countdownSeconds) seconds"
)
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
} else {
Text(
"Look away reminders are currently disabled."
)
.font(.caption)
.foregroundColor(.secondary)
}
Spacer()
}
@@ -112,4 +123,3 @@ struct LookAwaySetupView: View {
countdownSeconds: .constant(20)
)
}

View File

@@ -76,9 +76,19 @@ struct PostureSetupView: View {
.padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12))
if enabled {
Text(
"You will be subtly reminded every \(intervalMinutes) minutes to check your posture"
)
.font(.subheadline)
.foregroundColor(.secondary)
} else {
Text(
"Posture reminders are currently disabled."
)
.font(.caption)
.foregroundColor(.secondary)
}
Spacer()
}

View File

@@ -24,9 +24,18 @@ struct WelcomeView: View {
.foregroundColor(.secondary)
VStack(alignment: .leading, spacing: 16) {
FeatureRow(icon: "eye.circle", title: "Reduce Eye Strain", description: "Regular breaks help prevent digital eye strain")
FeatureRow(icon: "eye.trianglebadge.exclamationmark", title: "Remember to Blink", description: "We blink less when focused on screens")
FeatureRow(icon: "figure.stand", title: "Maintain Good Posture", description: "Gentle reminders to sit up straight")
FeatureRow(
icon: "eye.trianglebadge.exclamationmark", title: "Reduce Eye Strain",
description: "Regular breaks help prevent digital eye strain")
FeatureRow(
icon: "eye.circle", title: "Remember to Blink",
description: "We blink less when focused on screens")
FeatureRow(
icon: "figure.stand", title: "Maintain Good Posture",
description: "Gentle reminders to sit up straight")
FeatureRow(
icon: "plus.circle", title: "Custom Timers",
description: "Create your own timers for specific needs")
}
.padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12))
@@ -44,11 +53,20 @@ struct FeatureRow: View {
let title: String
let description: String
private var iconColor: Color {
switch icon {
case "eye.trianglebadge.exclamationmark": return .accentColor
case "eye.circle": return .green
case "figure.stand": return .orange
default: return .primary
}
}
var body: some View {
HStack(alignment: .top, spacing: 16) {
Image(systemName: icon)
.font(.title2)
.foregroundColor(.accentColor)
.foregroundColor(iconColor)
.frame(width: 30)
VStack(alignment: .leading, spacing: 4) {

View File

@@ -17,6 +17,8 @@ struct BlinkReminderView: View {
private let screenHeight = NSScreen.main?.frame.height ?? 800
private let screenWidth = NSScreen.main?.frame.width ?? 1200
// For now, we'll use hardcoded size but leave framework for configuration
// In a real implementation, this would be passed in from SettingsManager
var body: some View {
VStack {
LottieView(