general: continued refinements
This commit is contained in:
@@ -34,7 +34,7 @@ struct LookAwaySetupView: View {
|
||||
|
||||
// Vertically centered content
|
||||
Spacer()
|
||||
|
||||
|
||||
VStack(spacing: 30) {
|
||||
// InfoBox with link functionality
|
||||
HStack(spacing: 12) {
|
||||
@@ -74,7 +74,7 @@ struct LookAwaySetupView: View {
|
||||
value: Binding(
|
||||
get: { Double(intervalMinutes) },
|
||||
set: { intervalMinutes = Int($0) }
|
||||
), in: 5...60, step: 5)
|
||||
), in: 5...90, step: 5)
|
||||
|
||||
Text("\(intervalMinutes) min")
|
||||
.frame(width: 60, alignment: .trailing)
|
||||
@@ -117,7 +117,7 @@ struct LookAwaySetupView: View {
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
|
||||
@@ -138,7 +138,7 @@ struct OnboardingContainerView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(minWidth: 1000, minHeight: 750)
|
||||
.frame(minWidth: 1000, minHeight: 800)
|
||||
.opacity(isAnimatingOut ? 0 : 1)
|
||||
.scaleEffect(isAnimatingOut ? 0.3 : 1.0)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ struct SettingsOnboardingView: View {
|
||||
.padding(.top, 20)
|
||||
.padding(.bottom, 30)
|
||||
|
||||
// Vertically centered content
|
||||
Spacer()
|
||||
VStack(spacing: 30) {
|
||||
Text("Configure app preferences and support the project")
|
||||
@@ -34,7 +33,6 @@ struct SettingsOnboardingView: View {
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
VStack(spacing: 20) {
|
||||
// Launch at Login Toggle
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Launch at Login")
|
||||
@@ -62,13 +60,41 @@ struct SettingsOnboardingView: View {
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
Picker("Size", selection: $subtleReminderSize) {
|
||||
HStack(spacing: 12) {
|
||||
ForEach(ReminderSize.allCases, id: \.self) { size in
|
||||
Text(size.displayName).tag(size)
|
||||
Button(action: {
|
||||
subtleReminderSize = size
|
||||
}) {
|
||||
VStack(spacing: 8) {
|
||||
Circle()
|
||||
.fill(
|
||||
subtleReminderSize == size
|
||||
? Color.accentColor
|
||||
: Color.secondary.opacity(0.3)
|
||||
)
|
||||
.frame(
|
||||
width: iconSize(for: size),
|
||||
height: iconSize(for: size))
|
||||
|
||||
Text(size.displayName)
|
||||
.font(.caption)
|
||||
.fontWeight(
|
||||
subtleReminderSize == size ? .semibold : .regular
|
||||
)
|
||||
.foregroundColor(
|
||||
subtleReminderSize == size ? .primary : .secondary)
|
||||
}
|
||||
.frame(maxWidth: .infinity, minHeight: 60)
|
||||
.padding(.vertical, 12)
|
||||
}
|
||||
.glassEffect(
|
||||
subtleReminderSize == size
|
||||
? .regular.tint(.accentColor.opacity(0.3))
|
||||
: .regular,
|
||||
in: .rect(cornerRadius: 10)
|
||||
)
|
||||
}
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
.labelsHidden()
|
||||
}
|
||||
.padding()
|
||||
.glassEffect(.regular, in: .rect(cornerRadius: 12))
|
||||
@@ -158,6 +184,14 @@ struct SettingsOnboardingView: View {
|
||||
print("Failed to set launch at login: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func iconSize(for size: ReminderSize) -> CGFloat {
|
||||
switch size {
|
||||
case .small: return 20
|
||||
case .medium: return 32
|
||||
case .large: return 48
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Settings Onboarding - Launch Disabled") {
|
||||
|
||||
@@ -74,7 +74,8 @@ struct UserTimersView: View {
|
||||
} else {
|
||||
ScrollView {
|
||||
VStack(spacing: 8) {
|
||||
ForEach(Array(userTimers.enumerated()), id: \.element.id) { index, timer in
|
||||
ForEach(Array(userTimers.enumerated()), id: \.element.id) {
|
||||
index, timer in
|
||||
UserTimerRow(
|
||||
timer: $userTimers[index],
|
||||
onEdit: {
|
||||
@@ -144,7 +145,7 @@ struct UserTimerRow: View {
|
||||
Circle()
|
||||
.fill(timer.color)
|
||||
.frame(width: 12, height: 12)
|
||||
|
||||
|
||||
Image(systemName: timer.type == .subtle ? "eye.circle" : "rectangle.on.rectangle")
|
||||
.foregroundColor(timer.color)
|
||||
.frame(width: 24)
|
||||
@@ -166,7 +167,7 @@ struct UserTimerRow: View {
|
||||
.labelsHidden()
|
||||
.toggleStyle(.switch)
|
||||
.controlSize(.small)
|
||||
|
||||
|
||||
Button(action: onEdit) {
|
||||
Image(systemName: "pencil.circle.fill")
|
||||
.font(.title3)
|
||||
@@ -216,11 +217,14 @@ struct UserTimerEditSheet: View {
|
||||
self.onSave = onSave
|
||||
self.onCancel = onCancel
|
||||
|
||||
_title = State(initialValue: timer?.title ?? UserTimer.generateTitle(for: existingTimersCount))
|
||||
_title = State(
|
||||
initialValue: timer?.title ?? UserTimer.generateTitle(for: existingTimersCount))
|
||||
_message = State(initialValue: timer?.message ?? "")
|
||||
_type = State(initialValue: timer?.type ?? .subtle)
|
||||
_timeOnScreen = State(initialValue: timer?.timeOnScreenSeconds ?? 30)
|
||||
_selectedColorHex = State(initialValue: timer?.colorHex ?? UserTimer.defaultColors[existingTimersCount % UserTimer.defaultColors.count])
|
||||
_selectedColorHex = State(
|
||||
initialValue: timer?.colorHex
|
||||
?? UserTimer.defaultColors[existingTimersCount % UserTimer.defaultColors.count])
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@@ -239,12 +243,15 @@ struct UserTimerEditSheet: View {
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Color")
|
||||
.font(.headline)
|
||||
|
||||
LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 12), count: 8), spacing: 12) {
|
||||
|
||||
LazyVGrid(
|
||||
columns: Array(repeating: GridItem(.flexible(), spacing: 12), count: 8),
|
||||
spacing: 12
|
||||
) {
|
||||
ForEach(UserTimer.defaultColors, id: \.self) { colorHex in
|
||||
Button(action: {
|
||||
selectedColorHex = colorHex
|
||||
@@ -254,9 +261,13 @@ struct UserTimerEditSheet: View {
|
||||
.frame(width: 32, height: 32)
|
||||
.overlay(
|
||||
Circle()
|
||||
.strokeBorder(Color.white, lineWidth: selectedColorHex == colorHex ? 3 : 0)
|
||||
.strokeBorder(
|
||||
Color.white,
|
||||
lineWidth: selectedColorHex == colorHex ? 3 : 0)
|
||||
)
|
||||
.shadow(color: selectedColorHex == colorHex ? .accentColor : .clear, radius: 4)
|
||||
.shadow(
|
||||
color: selectedColorHex == colorHex ? .accentColor : .clear,
|
||||
radius: 4)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
@@ -264,9 +275,6 @@ struct UserTimerEditSheet: View {
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Display Type")
|
||||
.font(.headline)
|
||||
|
||||
Picker("Display Type", selection: $type) {
|
||||
ForEach(UserTimerType.allCases) { timerType in
|
||||
Text(timerType.displayName).tag(timerType)
|
||||
@@ -276,28 +284,30 @@ struct UserTimerEditSheet: View {
|
||||
|
||||
Text(
|
||||
type == .subtle
|
||||
? "Small reminder in corner of screen"
|
||||
? "Small reminder at top of screen"
|
||||
: "Full screen reminder with animation"
|
||||
)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Duration on Screen")
|
||||
.font(.headline)
|
||||
HStack {
|
||||
Slider(
|
||||
value: Binding(
|
||||
get: { Double(timeOnScreen) },
|
||||
set: { timeOnScreen = Int($0) }
|
||||
),
|
||||
in: 5...120,
|
||||
step: 5
|
||||
)
|
||||
Text("\(timeOnScreen)s")
|
||||
.frame(width: 50, alignment: .trailing)
|
||||
.monospacedDigit()
|
||||
if type == .overlay {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Duration on Screen")
|
||||
.font(.headline)
|
||||
HStack {
|
||||
Slider(
|
||||
value: Binding(
|
||||
get: { Double(timeOnScreen) },
|
||||
set: { timeOnScreen = Int($0) }
|
||||
),
|
||||
in: 5...30,
|
||||
step: 1
|
||||
)
|
||||
Text("\(timeOnScreen)s")
|
||||
.frame(width: 50, alignment: .trailing)
|
||||
.monospacedDigit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +357,8 @@ struct UserTimerEditSheet: View {
|
||||
UserTimersView(
|
||||
userTimers: .constant([
|
||||
UserTimer(
|
||||
id: "1", title: "User Reminder 1", type: .subtle, timeOnScreenSeconds: 30, message: "Take a break", colorHex: "9B59B6"),
|
||||
id: "1", title: "User Reminder 1", type: .subtle, timeOnScreenSeconds: 30,
|
||||
message: "Take a break", colorHex: "9B59B6"),
|
||||
UserTimer(
|
||||
id: "2", title: "User Reminder 2", type: .overlay, timeOnScreenSeconds: 60,
|
||||
message: "Stretch your legs", colorHex: "3498DB"),
|
||||
|
||||
@@ -109,7 +109,7 @@ struct SettingsWindowView: View {
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.frame(minWidth: 700, minHeight: 750)
|
||||
.frame(minWidth: 750, minHeight: 800)
|
||||
.onReceive(
|
||||
NotificationCenter.default.publisher(for: Notification.Name("SwitchToSettingsTab"))
|
||||
) { notification in
|
||||
|
||||
Reference in New Issue
Block a user