learning_ai_clock/ios/ChronoMind/SiriShortcuts/TimerAppIntents.swift

168 lines
5.7 KiB
Swift

// Siri Shortcuts (App Intents)
// "Set a timer for 25 minutes", "Start Pomodoro", etc.
// iOS 17+ App Intents framework
import AppIntents
import Foundation
// MARK: - Set Timer Intent
struct SetTimerIntent: AppIntent {
static var title: LocalizedStringResource = "Set a Timer"
static var description: IntentDescription = "Creates a countdown timer for the specified duration"
static var openAppWhenRun: Bool = false
@Parameter(title: "Duration (minutes)", default: 25)
var minutes: Int
@Parameter(title: "Label", default: "Timer")
var label: String
static var parameterSummary: some ParameterSummary {
Summary("Set a \(\.$minutes) minute timer called \(\.$label)")
}
func perform() async throws -> some IntentResult & ProvidesDialog {
let now = Date()
let targetTime = now.addingTimeInterval(TimeInterval(minutes * 60))
let intervals = CascadePreset.minimal.defaultIntervals
let snapshot = TimerSnapshot(
id: UUID().uuidString,
label: label,
type: .countdown,
urgency: .standard,
state: .active,
targetTime: targetTime,
duration: TimeInterval(minutes * 60),
startedAt: now,
elapsedBeforePause: 0,
snoozeCount: 0,
category: nil,
pomodoroCurrentRound: nil,
pomodoroTotalRounds: nil,
pomodoroIsBreak: nil,
nextWarningTime: intervals.first.map { targetTime.addingTimeInterval(-Double($0) * 60) },
totalWarnings: intervals.count,
firedWarnings: 0
)
// Write to shared data
let manager = SharedTimerDataManager.shared
var timers = manager.readSnapshots()
timers.append(snapshot)
manager.writeSnapshots(timers)
manager.writeActiveTimer(nil) // Let iOS app recalculate
return .result(dialog: "Timer set for \(minutes) minutes: \(label)")
}
}
// MARK: - Start Pomodoro Intent
struct StartPomodoroIntent: AppIntent {
static var title: LocalizedStringResource = "Start Pomodoro"
static var description: IntentDescription = "Starts a 25-minute Pomodoro focus session"
static var openAppWhenRun: Bool = true
@Parameter(title: "Work Minutes", default: 25)
var workMinutes: Int
static var parameterSummary: some ParameterSummary {
Summary("Start a \(\.$workMinutes) minute Pomodoro session")
}
func perform() async throws -> some IntentResult & ProvidesDialog {
let now = Date()
let durationSeconds = TimeInterval(workMinutes * 60)
let targetTime = now.addingTimeInterval(durationSeconds)
let snapshot = TimerSnapshot(
id: UUID().uuidString,
label: "Pomodoro Focus",
type: .pomodoro,
urgency: .standard,
state: .active,
targetTime: targetTime,
duration: durationSeconds,
startedAt: now,
elapsedBeforePause: 0,
snoozeCount: 0,
category: nil,
pomodoroCurrentRound: 1,
pomodoroTotalRounds: 4,
pomodoroIsBreak: false,
nextWarningTime: targetTime.addingTimeInterval(-60),
totalWarnings: 1,
firedWarnings: 0
)
let manager = SharedTimerDataManager.shared
var timers = manager.readSnapshots()
timers.append(snapshot)
manager.writeSnapshots(timers)
return .result(dialog: "Pomodoro started: \(workMinutes) minutes of focus time!")
}
}
// MARK: - What's My Next Timer Intent
struct NextTimerInfoIntent: AppIntent {
static var title: LocalizedStringResource = "What's My Next Timer?"
static var description: IntentDescription = "Tells you about your next upcoming timer"
static var openAppWhenRun: Bool = false
func perform() async throws -> some IntentResult & ProvidesDialog {
let manager = SharedTimerDataManager.shared
guard let next = manager.readNextFiringTimer() else {
return .result(dialog: "You don't have any active timers right now.")
}
let remaining = next.remainingSeconds()
let compact = formatDurationCompact(remaining)
let timeStr = formatTime(next.targetTime)
return .result(dialog: "\(next.label) fires in \(compact), at \(timeStr).")
}
}
// MARK: - Shortcuts Provider
struct ChronoMindShortcutsProvider: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: SetTimerIntent(),
phrases: [
"Set a timer in \(.applicationName)",
"Set a \(\.$minutes) minute timer in \(.applicationName)",
"Start a \(\.$minutes) minute timer called \(\.$label) in \(.applicationName)",
],
shortTitle: "Set Timer",
systemImageName: "timer"
)
AppShortcut(
intent: StartPomodoroIntent(),
phrases: [
"Start Pomodoro in \(.applicationName)",
"Start a focus session in \(.applicationName)",
"Start a \(\.$workMinutes) minute Pomodoro in \(.applicationName)",
],
shortTitle: "Start Pomodoro",
systemImageName: "target"
)
AppShortcut(
intent: NextTimerInfoIntent(),
phrases: [
"What's my next timer in \(.applicationName)",
"When's my next alarm in \(.applicationName)",
"Next timer in \(.applicationName)",
],
shortTitle: "Next Timer",
systemImageName: "clock"
)
}
}