diff --git a/LoopFollow/Controllers/SpeakBGIntents.swift b/LoopFollow/Controllers/SpeakBGIntents.swift new file mode 100644 index 000000000..995df2071 --- /dev/null +++ b/LoopFollow/Controllers/SpeakBGIntents.swift @@ -0,0 +1,49 @@ +// LoopFollow +// SpeakBGIntents.swift + +import AppIntents + +struct EnableSpeakBGIntent: AppIntent { + static var title: LocalizedStringResource = "Turn On Speak BG" + static var description = IntentDescription("Turns on Speak BG so LoopFollow reads glucose values aloud.") + + @MainActor + func perform() async throws -> some IntentResult & ProvidesDialog { + try SpeakBGIntentSupport.set(true) + return .result(dialog: "Speak BG is now on.") + } +} + +struct DisableSpeakBGIntent: AppIntent { + static var title: LocalizedStringResource = "Turn Off Speak BG" + static var description = IntentDescription("Turns off Speak BG so LoopFollow stops reading glucose values aloud.") + + @MainActor + func perform() async throws -> some IntentResult & ProvidesDialog { + try SpeakBGIntentSupport.set(false) + return .result(dialog: "Speak BG is now off.") + } +} + +enum SpeakBGIntentSupport { + /// Storage writes are memory-only during a suspected before-first-unlock + /// launch, so the change would be lost on hydration. + @MainActor + static func set(_ enabled: Bool) throws { + guard !StorageReadiness.isSuppressingWrites else { + throw SpeakBGIntentError.storageUnavailable + } + Storage.shared.speakBG.value = enabled + } +} + +enum SpeakBGIntentError: Error, CustomLocalizedStringResourceConvertible { + case storageUnavailable + + var localizedStringResource: LocalizedStringResource { + switch self { + case .storageUnavailable: + return "LoopFollow can't change Speak BG until your iPhone has been unlocked once after restarting." + } + } +} diff --git a/LoopFollow/LiveActivity/RestartLiveActivityIntent.swift b/LoopFollow/LiveActivity/RestartLiveActivityIntent.swift index e92ee5778..5a25afdae 100644 --- a/LoopFollow/LiveActivity/RestartLiveActivityIntent.swift +++ b/LoopFollow/LiveActivity/RestartLiveActivityIntent.swift @@ -40,6 +40,18 @@ shortTitle: "Restart Live Activity", systemImageName: "dot.radiowaves.left.and.right" ) + AppShortcut( + intent: EnableSpeakBGIntent(), + phrases: ["Turn on Speak BG in \(.applicationName)"], + shortTitle: "Turn On Speak BG", + systemImageName: "speaker.wave.2" + ) + AppShortcut( + intent: DisableSpeakBGIntent(), + phrases: ["Turn off Speak BG in \(.applicationName)"], + shortTitle: "Turn Off Speak BG", + systemImageName: "speaker.slash" + ) } } #endif