BolusIntent.swift 2.9 KB

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