BolusIntent.swift 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import AppIntents
  2. import Foundation
  3. import Intents
  4. import Swinject
  5. @available(iOS 16.0,*) struct BolusIntent: AppIntent {
  6. // Title of the action in the Shortcuts app
  7. static var title = LocalizedStringResource("Enact Bolus", table: "ShortcutsDetail")
  8. // Description of the action in the Shortcuts app
  9. static var description = IntentDescription(.init("Allow to send a bolus to the app", table: "ShortcutsDetail"))
  10. @Parameter(
  11. title: LocalizedStringResource("Amount", table: "ShortcutsDetail"),
  12. description: LocalizedStringResource("Bolus amount in U", table: "ShortcutsDetail"),
  13. controlStyle: .field,
  14. /// The 200 upperBound does nothing here, the true max is set based on pump max
  15. /// An upperBound is specificed so that we can usethe lowerBound of 0, which ensures no negatives are allowed
  16. /// A preferred approach would be to just block negatives and not specify an upperBound here, since it is implemented elsewhere
  17. inclusiveRange: (lowerBound: 0, upperBound: 200),
  18. requestValueDialog: IntentDialog(LocalizedStringResource(
  19. "Bolus amount (units of insulin)?",
  20. table: "ShortcutsDetail"
  21. ))
  22. ) var bolusQuantity: Double
  23. @Parameter(
  24. title: LocalizedStringResource("Confirm Before applying", table: "ShortcutsDetail"),
  25. description: LocalizedStringResource("If toggled, you will need to confirm before applying.", table: "ShortcutsDetail"),
  26. default: true
  27. ) var confirmBeforeApplying: Bool
  28. static var parameterSummary: some ParameterSummary {
  29. When(\.$confirmBeforeApplying, .equalTo, true, {
  30. Summary("Applying \(\.$bolusQuantity) U", table: "ShortcutsDetail") {
  31. \.$confirmBeforeApplying
  32. }
  33. }, otherwise: {
  34. Summary("Immediately applying \(\.$bolusQuantity) U", table: "ShortcutsDetail") {
  35. \.$confirmBeforeApplying
  36. }
  37. })
  38. }
  39. @MainActor func perform() async throws -> some ProvidesDialog {
  40. do {
  41. let amount: Double = bolusQuantity
  42. let bolusFormatted = amount.formatted()
  43. if confirmBeforeApplying {
  44. try await requestConfirmation(
  45. result: .result(
  46. dialog: IntentDialog(LocalizedStringResource(
  47. "Are you sure you want to bolus \(bolusFormatted) U of insulin?",
  48. table: "ShortcutsDetail"
  49. ))
  50. )
  51. )
  52. }
  53. let finalBolusDisplay = try await BolusIntentRequest().bolus(amount)
  54. return .result(
  55. dialog: IntentDialog(finalBolusDisplay)
  56. )
  57. } catch {
  58. throw error
  59. }
  60. }
  61. }