feat: better clarity for disabled reminders, continued prev commit work
This commit is contained in:
1
Gaze/Animations/ring.json
Normal file
1
Gaze/Animations/ring.json
Normal 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": [] }
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -76,9 +76,19 @@ struct BlinkSetupView: View {
|
||||
.padding()
|
||||
.glassEffect(.regular, in: .rect(cornerRadius: 12))
|
||||
|
||||
Text(
|
||||
"You will be subtly reminded every \(intervalMinutes) minutes to blink"
|
||||
)
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -93,9 +93,20 @@ struct LookAwaySetupView: View {
|
||||
.padding()
|
||||
.glassEffect(.regular, in: .rect(cornerRadius: 12))
|
||||
|
||||
Text(
|
||||
"You will be reminded every \(intervalMinutes) minutes to look in the distance for \(countdownSeconds) seconds"
|
||||
)
|
||||
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)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -76,9 +76,19 @@ struct PostureSetupView: View {
|
||||
.padding()
|
||||
.glassEffect(.regular, in: .rect(cornerRadius: 12))
|
||||
|
||||
Text(
|
||||
"You will be subtly reminded every \(intervalMinutes) minutes to check your posture"
|
||||
)
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user