learning_ai_clock/ios/ChronoMindMac/Views/CreateTimerSheet.swift
saravanakumardb1 d179c4c624 feat(watch,mac): complete watchOS + macOS companion targets
- watchOS: add WatchSessionManager (WCSession bridge), WatchNotificationHandler
  (snooze/dismiss actions), recommendations() for AppIntentTimelineProvider
- watchOS: WatchTimerStore tick loop with cascade haptics, App Group sync
- macOS: CreateTimerSheet (countdown/alarm/pomodoro), launch-at-login toggle
- macOS: MenuBarState showCreateSheet, MacSettingsView data tab
- Xcode project updated with new file references
2026-03-27 11:28:13 -07:00

167 lines
5.4 KiB
Swift

// Sheet for creating a new timer from the macOS menu bar popover
import SwiftUI
struct CreateTimerSheet: View {
@EnvironmentObject var store: MacTimerStore
@Environment(\.dismiss) private var dismiss
@State private var label = ""
@State private var timerType: CMTimerType = .countdown
@State private var hours: Int = 0
@State private var minutes: Int = 25
@State private var alarmTime = Date().addingTimeInterval(3600)
@State private var pomodoroRounds: Int = 4
@State private var workMinutes: Int = 25
@State private var breakMinutes: Int = 5
@State private var urgency: UrgencyLevel = .standard
@State private var cascadePreset: CascadePreset = .standard
var body: some View {
VStack(spacing: 0) {
// Header
HStack {
Text("New Timer")
.font(CMFonts.display(size: 16))
.foregroundStyle(CMColors.text)
Spacer()
Button {
dismiss()
} label: {
Image(systemName: "xmark.circle.fill")
.font(.title3)
.foregroundStyle(CMColors.textMuted)
}
.buttonStyle(.plain)
}
.padding(.horizontal, 16)
.padding(.vertical, 12)
Divider().background(CMColors.border)
// Form
Form {
TextField("Timer Label", text: $label)
.textFieldStyle(.roundedBorder)
Picker("Type", selection: $timerType) {
Text("Countdown").tag(CMTimerType.countdown)
Text("Alarm").tag(CMTimerType.alarm)
Text("Pomodoro").tag(CMTimerType.pomodoro)
}
switch timerType {
case .countdown:
countdownFields
case .alarm:
alarmFields
case .pomodoro:
pomodoroFields
default:
EmptyView()
}
Picker("Urgency", selection: $urgency) {
ForEach(UrgencyLevel.allCases) { level in
HStack {
Circle()
.fill(CMColors.urgencyColor(level))
.frame(width: 8, height: 8)
Text(getUrgencyConfig(level).label)
}
.tag(level)
}
}
if timerType != .pomodoro {
Picker("Cascade", selection: $cascadePreset) {
ForEach(CascadePreset.allCases.filter { $0 != .custom }) { preset in
Text(preset.label).tag(preset)
}
}
}
}
.formStyle(.grouped)
.scrollContentBackground(.hidden)
.background(CMColors.bg)
Divider().background(CMColors.border)
// Actions
HStack {
Button("Cancel") {
dismiss()
}
.keyboardShortcut(.cancelAction)
Spacer()
Button("Create") {
createTimer()
dismiss()
}
.keyboardShortcut(.defaultAction)
.disabled(label.isEmpty && timerType != .pomodoro)
}
.padding(.horizontal, 16)
.padding(.vertical, 10)
}
.frame(width: 360, height: 420)
.background(CMColors.bg)
}
// MARK: - Type-Specific Fields
private var countdownFields: some View {
HStack {
Stepper("Hours: \(hours)", value: $hours, in: 0...23)
Stepper("Minutes: \(minutes)", value: $minutes, in: 0...59)
}
}
private var alarmFields: some View {
DatePicker("Target Time", selection: $alarmTime, displayedComponents: [.date, .hourAndMinute])
}
private var pomodoroFields: some View {
Group {
Stepper("Rounds: \(pomodoroRounds)", value: $pomodoroRounds, in: 1...12)
Stepper("Work: \(workMinutes)m", value: $workMinutes, in: 5...60, step: 5)
Stepper("Break: \(breakMinutes)m", value: $breakMinutes, in: 1...30)
}
}
// MARK: - Create
private func createTimer() {
let timerLabel = label.isEmpty ? "Focus Session" : label
switch timerType {
case .countdown:
let totalSeconds = TimeInterval((hours * 3600) + (minutes * 60))
guard totalSeconds > 0 else { return }
store.addCountdown(label: timerLabel, durationSeconds: totalSeconds)
case .alarm:
store.addAlarm(label: timerLabel, targetTime: alarmTime, urgency: urgency)
case .pomodoro:
let config = PomodoroConfig(
workMinutes: workMinutes,
breakMinutes: breakMinutes,
longBreakMinutes: breakMinutes * 3,
rounds: pomodoroRounds
)
let timer = createPomodoro(CreatePomodoroParams(
label: timerLabel,
config: config,
urgency: urgency
))
store.timers.append(timer)
default:
break
}
}
}