Преглед изворни кода

Merge pull request #1211 from bastiaanv/feat/bolus-initiating

Feat: Bolus initiating
Deniz Cengiz пре 3 часа
родитељ
комит
4333da70b0

+ 4 - 0
Trio.xcodeproj/project.pbxproj

@@ -313,6 +313,7 @@
 		3E54EF2C2E476DA40006F54D /* MedtrumKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E54EF2B2E476DA40006F54D /* MedtrumKit.framework */; };
 		3E54EF2D2E476DA40006F54D /* MedtrumKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3E54EF2B2E476DA40006F54D /* MedtrumKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		3E62C7822F54CC1B00433237 /* BolusDisplayThreshold.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E62C7812F54CC1600433237 /* BolusDisplayThreshold.swift */; };
+		3E705AFB2FF94FAB0007F96B /* BolusStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E705AFA2FF94FAB0007F96B /* BolusStatus.swift */; };
 		3E84DA402F48D96000033608 /* EversenseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E84DA3F2F48D96000033608 /* EversenseKit.framework */; };
 		3E84DA412F48D96000033608 /* EversenseKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3E84DA3F2F48D96000033608 /* EversenseKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		3EF667132FE48509009FB31A /* BasalDeliveryState+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EF667122FE48502009FB31A /* BasalDeliveryState+Extension.swift */; };
@@ -1324,6 +1325,7 @@
 		3BF92F392D86F1AA006B545A /* iob-error-log.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "iob-error-log.json"; sourceTree = "<group>"; };
 		3E54EF2B2E476DA40006F54D /* MedtrumKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MedtrumKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		3E62C7812F54CC1600433237 /* BolusDisplayThreshold.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusDisplayThreshold.swift; sourceTree = "<group>"; };
+		3E705AFA2FF94FAB0007F96B /* BolusStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusStatus.swift; sourceTree = "<group>"; };
 		3E84DA3F2F48D96000033608 /* EversenseKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = EversenseKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		3EF667122FE48502009FB31A /* BasalDeliveryState+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BasalDeliveryState+Extension.swift"; sourceTree = "<group>"; };
 		3F60E97100041040446F44E7 /* PumpConfigStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PumpConfigStateModel.swift; sourceTree = "<group>"; };
@@ -2744,6 +2746,7 @@
 				388358C725EEF6D200E024B2 /* BasalProfileEntry.swift */,
 				38D0B3B525EBE24900CB6E88 /* Battery.swift */,
 				382C134A25F14E3700715CE1 /* BGTargets.swift */,
+				3E705AFA2FF94FAB0007F96B /* BolusStatus.swift */,
 				3870FF4225EC13F40088248F /* BloodGlucose.swift */,
 				38A9260425F012D8009E3739 /* CarbRatios.swift */,
 				38D0B3D825EC07C400CB6E88 /* CarbsEntry.swift */,
@@ -5580,6 +5583,7 @@
 				DDE1795E2C910127003CDDB7 /* PumpEventStored+CoreDataClass.swift in Sources */,
 				3BBB76AA2E01C70B0040977D /* MealCob.swift in Sources */,
 				BDDAF9EF2D00554500B34E7A /* SelectionPopoverView.swift in Sources */,
+				3E705AFB2FF94FAB0007F96B /* BolusStatus.swift in Sources */,
 				DDE1795F2C910127003CDDB7 /* PumpEventStored+CoreDataProperties.swift in Sources */,
 				DDE179602C910127003CDDB7 /* StatsData+CoreDataClass.swift in Sources */,
 				DD30BA0E2E07700000DA677C /* Profile+Autosens.swift in Sources */,

+ 9 - 3
Trio/Sources/APS/APSManager.swift

@@ -213,10 +213,12 @@ final class BaseAPSManager: APSManager, Injectable {
 
         deviceDataManager.bolusTrigger
             .receive(on: processQueue)
-            .sink { [weak self] bolusing in
-                if bolusing {
+            .sink { [weak self] bolusState in
+                switch bolusState {
+                case .initiating,
+                     .inProgress:
                     self?.createBolusReporter()
-                } else {
+                case .noBolus:
                     self?.clearBolusReporter()
                 }
             }
@@ -1347,6 +1349,10 @@ final class BaseAPSManager: APSManager, Injectable {
     /// Mutations are dispatched onto the queue regardless, so a future
     /// caller from another context (e.g. `cancelBolus`) stays safe.
     private func createBolusReporter() {
+        if bolusReporter != nil {
+            return
+        }
+
         processQueue.async {
             self.bolusReporter = self.pumpManager?.createBolusProgressReporter(reportingOn: self.processQueue)
             self.bolusReporter?.addObserver(self)

+ 9 - 6
Trio/Sources/APS/DeviceDataManager.swift

@@ -21,7 +21,7 @@ protocol DeviceDataManager: GlucoseSource {
     var loopInProgress: Bool { get set }
     var pumpDisplayState: CurrentValueSubject<PumpDisplayState?, Never> { get }
     var recommendsLoop: PassthroughSubject<Void, Never> { get }
-    var bolusTrigger: PassthroughSubject<Bool, Never> { get }
+    var bolusTrigger: PassthroughSubject<BolusStatus, Never> { get }
     var manualTempBasal: PassthroughSubject<Bool, Never> { get }
     var scheduledBasal: PassthroughSubject<Bool?, Never> { get }
     var suspended: PassthroughSubject<Bool, Never> { get }
@@ -69,7 +69,7 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
         .distantPast
 
     let recommendsLoop = PassthroughSubject<Void, Never>()
-    let bolusTrigger = PassthroughSubject<Bool, Never>()
+    let bolusTrigger = PassthroughSubject<BolusStatus, Never>()
     let errorSubject = PassthroughSubject<Error, Never>()
     let pumpNewStatus = PassthroughSubject<Void, Never>()
     let manualTempBasal = PassthroughSubject<Bool, Never>()
@@ -470,10 +470,13 @@ extension BaseDeviceDataManager: PumpManagerDelegate {
         debug(.deviceManager, "New pump status Bolus: \(status.bolusState)")
         debug(.deviceManager, "New pump status Basal: \(String(describing: status.basalDeliveryState))")
 
-        if case .inProgress = status.bolusState {
-            bolusTrigger.send(true)
-        } else {
-            bolusTrigger.send(false)
+        switch status.bolusState {
+        case .initiating:
+            bolusTrigger.send(.initiating)
+        case let .inProgress(dose):
+            bolusTrigger.send(.inProgress)
+        default:
+            bolusTrigger.send(.noBolus)
         }
 
         switch status.basalDeliveryState {

+ 4 - 0
Trio/Sources/Localizations/Main/Localizable.xcstrings

@@ -145816,6 +145816,10 @@
         }
       }
     },
+    "Initiating…" : {
+      "comment" : "A label displayed when the pump is waiting to start bolusing.",
+      "isCommentAutoGenerated" : true
+    },
     "Insert Cannula" : {
       "extractionState" : "manual",
       "localizations" : {

+ 7 - 0
Trio/Sources/Models/BolusStatus.swift

@@ -0,0 +1,7 @@
+import LoopKit
+
+enum BolusStatus {
+    case noBolus
+    case initiating
+    case inProgress
+}

+ 9 - 0
Trio/Sources/Modules/Home/HomeStateModel.swift

@@ -100,6 +100,7 @@ extension Home {
         var tempBasals: [PumpEventStored] = []
         var suspendAndResumeEvents: [PumpEventStored] = []
         var batteryFromPersistence: [OpenAPS_Battery] = []
+        var bolusStatus: BolusStatus = .noBolus
         var lastPumpBolus: PumpEventStored?
         var overrides: [OverrideStored] = []
         var overrideRunStored: [OverrideRunStored] = []
@@ -262,6 +263,14 @@ extension Home {
                     self.setupFPUsArray()
                 }
                 .store(in: &subscriptions)
+
+            provider.deviceManager.bolusTrigger
+                .receive(on: queue)
+                .sink { [weak self] state in
+                    guard let self = self else { return }
+                    self.bolusStatus = state
+                }
+                .store(in: &subscriptions)
         }
 
         private func registerHandlers() {

+ 13 - 7
Trio/Sources/Modules/Home/View/HomeRootView.swift

@@ -792,6 +792,8 @@ extension Home {
                         + String(localized: " of ", comment: "Bolus string partial message: 'x U of y U' in home view") +
                         (Formatter.decimalFormatterWithThreeFractionDigits.string(from: bolusTotal as NSNumber) ?? "0")
                         + String(localized: " U", comment: "Insulin unit")
+                let bolusLabel = state
+                    .bolusStatus == .inProgress ? String(localized: "Bolusing") : String(localized: "Initiating…")
 
                 ZStack {
                     /// rectangle as background
@@ -817,7 +819,7 @@ extension Home {
                         Spacer()
 
                         VStack {
-                            Text("Bolusing")
+                            Text(bolusLabel)
                                 .font(.subheadline)
                                 .frame(maxWidth: .infinity, alignment: .leading)
                             Text(bolusString)
@@ -827,12 +829,16 @@ extension Home {
 
                         Spacer()
 
-                        Button {
-                            state.showProgressView()
-                            state.cancelBolus()
-                        } label: {
-                            Image(systemName: "xmark.app")
-                                .font(.system(size: 25))
+                        if state.bolusStatus == .inProgress {
+                            Button {
+                                state.showProgressView()
+                                state.cancelBolus()
+                            } label: {
+                                Image(systemName: "xmark.app")
+                                    .font(.system(size: 25))
+                            }
+                        } else if state.bolusStatus == .initiating {
+                            ProgressView()
                         }
                     }.padding(.horizontal, 10)
                         .padding(.trailing, 8)

+ 6 - 1
Trio/Sources/Modules/Treatments/TreatmentsStateModel.swift

@@ -139,7 +139,7 @@ extension Treatments {
         typealias PumpEvent = PumpEventStored.EventType
 
         var bolusProgress: Decimal?
-        var isBolusInProgress: Bool { bolusProgress != nil }
+        var bolusStatus: BolusStatus = .noBolus
         var lastPumpBolus: PumpEventStored?
 
         func unsubscribe() {
@@ -221,6 +221,11 @@ extension Treatments {
                 .receive(on: DispatchQueue.main)
                 .weakAssign(to: \.bolusProgress, on: self)
                 .store(in: &lifetime)
+
+            provider.deviceManager.bolusTrigger
+                .receive(on: DispatchQueue.main)
+                .weakAssign(to: \.bolusStatus, on: self)
+                .store(in: &lifetime)
         }
 
         func cancelBolus() {

+ 14 - 9
Trio/Sources/Modules/Treatments/View/TreatmentsRootView.swift

@@ -492,7 +492,7 @@ extension Treatments {
         }
 
         var treatmentButton: some View {
-            let shouldDisplayBolusProgress = state.isBolusInProgress && state.amount > 0 &&
+            let shouldDisplayBolusProgress = state.bolusStatus != .noBolus && state.amount > 0 &&
                 !state.externalInsulin && (state.carbs == 0 || state.fat == 0 || state.protein == 0)
 
             var treatmentButtonBackground = Color(.systemBlue)
@@ -568,6 +568,7 @@ extension Treatments {
                     + (Formatter.decimalFormatterWithThreeFractionDigits.string(from: bolusTotal as NSNumber) ?? "0")
                     + String(localized: " U", comment: "Insulin unit")
             }()
+            let bolusLabel = state.bolusStatus == .inProgress ? String(localized: "Bolusing") : String(localized: "Initiating…")
 
             ZStack {
                 // background card
@@ -593,7 +594,7 @@ extension Treatments {
                     Spacer()
 
                     VStack {
-                        Text("Bolusing")
+                        Text(bolusLabel)
                             .font(.subheadline)
                             .frame(maxWidth: .infinity, alignment: .leading)
                         Text(bolusString)
@@ -604,12 +605,16 @@ extension Treatments {
 
                     Spacer()
 
-                    Button { state.cancelBolus() } label: {
-                        Image(systemName: "xmark.app")
-                            .font(.system(size: 25))
-                    }.tint(Color.tabBar)
-                        .buttonStyle(.borderless)
-                        .accessibilityLabel("Cancel bolus")
+                    if state.bolusStatus == .inProgress {
+                        Button { state.cancelBolus() } label: {
+                            Image(systemName: "xmark.app")
+                                .font(.system(size: 25))
+                        }.tint(Color.tabBar)
+                            .buttonStyle(.borderless)
+                            .accessibilityLabel("Cancel bolus")
+                    } else if state.bolusStatus == .initiating {
+                        ProgressView()
+                    }
                 }
                 .padding(.horizontal, 10)
                 .padding(.trailing, 8)
@@ -690,7 +695,7 @@ extension Treatments {
 
         private var disableTaskButton: Bool {
             (
-                state.isBolusInProgress && state
+                state.bolusStatus != .noBolus && state
                     .amount > 0 && !state.externalInsulin && (state.carbs == 0 || state.fat == 0 || state.protein == 0)
             ) || state
                 .addButtonPressed || limitExceeded