Kaynağa Gözat

Bolus cancellation

Ivan Valkou 5 yıl önce
ebeveyn
işleme
92a64b647d

+ 36 - 0
FreeAPS/Sources/APS/APSManager.swift

@@ -22,6 +22,7 @@ protocol APSManager {
     func determineBasal() -> AnyPublisher<Bool, Never>
     func roundBolus(amount: Decimal) -> Decimal
     var lastError: CurrentValueSubject<Error?, Never> { get }
+    func cancelBolus()
 }
 
 enum APSError: LocalizedError {
@@ -286,6 +287,8 @@ final class BaseAPSManager: APSManager, Injectable {
 
         let roundedAmout = pump.roundToSupportedBolusVolume(units: amount)
 
+        debug(.apsManager, "Enact bolus \(roundedAmout), manual \(!isSMB)")
+
         pump.enactBolus(units: roundedAmout, automatic: isSMB).sink { completion in
             if case let .failure(error) = completion {
                 debug(.apsManager, "Bolus failed with error: \(error.localizedDescription)")
@@ -300,8 +303,27 @@ final class BaseAPSManager: APSManager, Injectable {
             .store(in: &lifetime)
     }
 
+    func cancelBolus() {
+        guard let pump = pumpManager else { return }
+        debug(.apsManager, "Cancel bolus")
+        pump.cancelBolus().sink { completion in
+            if case let .failure(error) = completion {
+                debug(.apsManager, "Bolus cancellation failed with error: \(error.localizedDescription)")
+                self.processError(APSError.pumpError(error))
+            } else {
+                debug(.apsManager, "Bolus cancelled")
+            }
+
+            self.bolusReporter?.removeObserver(self)
+            self.bolusReporter = nil
+            self.bolusProgress.send(nil)
+        } receiveValue: { _ in }
+            .store(in: &lifetime)
+    }
+
     func enactTempBasal(rate: Double, duration: TimeInterval) {
         guard let pump = pumpManager, verifyStatus() else { return }
+        debug(.apsManager, "Enact temp basal \(rate) - \(duration)")
 
         let roundedAmout = pump.roundToSupportedBasalRate(unitsPerHour: rate)
         pump.enactTempBasal(unitsPerHour: roundedAmout, for: duration) { result in
@@ -538,6 +560,20 @@ private extension PumpManager {
         }.eraseToAnyPublisher()
     }
 
+    func cancelBolus() -> AnyPublisher<DoseEntry?, Error> {
+        Future { promise in
+            self.cancelBolus { result in
+                switch result {
+                case let .success(dose):
+                    promise(.success(dose))
+                case let .failure(error):
+                    promise(.failure(error))
+                }
+            }
+        }
+        .eraseToAnyPublisher()
+    }
+
     func suspendDelivery() -> AnyPublisher<Void, Error> {
         Future { promise in
             self.suspendDelivery { error in

+ 4 - 0
FreeAPS/Sources/Modules/Home/HomeViewModel.swift

@@ -125,6 +125,10 @@ extension Home {
             provider.heartbeatNow()
         }
 
+        func cancelBolus() {
+            apsManager.cancelBolus()
+        }
+
         private func setupGlucose() {
             DispatchQueue.main.async {
                 self.glucose = self.provider.filteredGlucose(hours: self.filteredHours)

+ 3 - 0
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -142,6 +142,9 @@ extension Home {
                     ProgressView(value: Double(progress))
                         .progressViewStyle(BolusProgressViewStyle())
                         .padding(.trailing, 8)
+                        .onTapGesture {
+                            viewModel.cancelBolus()
+                        }
                 }
             }
             .frame(maxWidth: .infinity, maxHeight: 30)

+ 7 - 4
FreeAPS/Sources/Views/BolusProgressViewStyle.swift

@@ -4,17 +4,20 @@ public struct BolusProgressViewStyle: ProgressViewStyle {
     public func makeBody(configuration: LinearProgressViewStyle.Configuration) -> some View {
         ZStack {
             Circle()
-                .stroke(lineWidth: 6.0)
+                .stroke(lineWidth: 4.0)
                 .opacity(0.3)
                 .foregroundColor(.secondary)
-                .frame(width: 16, height: 16)
+                .frame(width: 22, height: 22)
+
+            Rectangle().fill(Color.insulin)
+                .frame(width: 8, height: 8)
 
             Circle()
                 .trim(from: 0.0, to: CGFloat(configuration.fractionCompleted ?? 0))
-                .stroke(style: StrokeStyle(lineWidth: 6.0, lineCap: .butt, lineJoin: .round))
+                .stroke(style: StrokeStyle(lineWidth: 4.0, lineCap: .butt, lineJoin: .round))
                 .foregroundColor(.insulin)
                 .rotationEffect(Angle(degrees: -90))
-                .frame(width: 16, height: 16)
+                .frame(width: 22, height: 22)
         }.frame(width: 30, height: 30)
     }
 }