polscm32 aka Marvout пре 1 година
родитељ
комит
112dae054f

+ 7 - 0
FreeAPS/Sources/APS/DeviceDataManager.swift

@@ -389,6 +389,9 @@ extension BaseDeviceDataManager: PumpManagerDelegate {
     func pumpManagerWillDeactivate(_: PumpManager) {
         dispatchPrecondition(condition: .onQueue(processQueue))
         pumpManager = nil
+        broadcaster.notify(PumpDeactivatedObserver.self, on: processQueue) {
+            $0.pumpDeactivatedDidChange()
+        }
     }
 
     func pumpManager(_: PumpManager, didUpdatePumpRecordsBasalProfileStartEvents _: Bool) {}
@@ -626,3 +629,7 @@ protocol PumpBatteryObserver {
 protocol PumpTimeZoneObserver {
     func pumpTimeZoneDidChange(_ timezone: TimeZone)
 }
+
+protocol PumpDeactivatedObserver {
+    func pumpDeactivatedDidChange()
+}

+ 28 - 1
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -80,6 +80,7 @@ extension Home {
         @Published var overrideRunStored: [OverrideRunStored] = []
         @Published var isOverrideCancelled: Bool = false
         @Published var preprocessedData: [(id: UUID, forecast: Forecast, forecastValue: ForecastValue)] = []
+        @Published var pumpStatusHighlightMessage: String? = nil
 
         let context = CoreDataStack.shared.newTaskContext()
         let viewContext = CoreDataStack.shared.persistentContainer.viewContext
@@ -130,6 +131,7 @@ extension Home {
             broadcaster.register(BasalProfileObserver.self, observer: self)
             broadcaster.register(TempTargetsObserver.self, observer: self)
             broadcaster.register(PumpReservoirObserver.self, observer: self)
+            broadcaster.register(PumpDeactivatedObserver.self, observer: self)
 
             animatedBackground = settingsManager.settings.animatedBackground
 
@@ -191,6 +193,7 @@ extension Home {
                         self.setupPump = false
                     } else {
                         self.setupReservoir()
+                        self.displayPumpStatusHighlightMessage()
                     }
                 }
                 .store(in: &lifetime)
@@ -208,6 +211,8 @@ extension Home {
                             setupDelegate: self
                         ).asAny()
                         self.router.mainSecondaryModalView.send(view)
+                    } else if show {
+                        self.router.mainSecondaryModalView.send(self.router.view(for: .pumpConfigDirect))
                     } else {
                         self.router.mainSecondaryModalView.send(nil)
                     }
@@ -215,6 +220,22 @@ extension Home {
                 .store(in: &lifetime)
         }
 
+        /// Display the eventual status message provided by the manager of the pump
+        /// Only display if state is warning or critical message else return nil
+        private func displayPumpStatusHighlightMessage(_ didDeactivate: Bool = false) {
+            DispatchQueue.main.async { [weak self] in
+                guard let self = self else { return }
+                if let statusHighlight = self.provider.deviceManager.pumpManager?.pumpStatusHighlight,
+                   statusHighlight.state == .warning || statusHighlight.state == .critical, !didDeactivate
+                {
+                    pumpStatusHighlightMessage = (statusHighlight.state == .warning ? "⚠️\n" : "‼️\n") + statusHighlight
+                        .localizedMessage
+                } else {
+                    pumpStatusHighlightMessage = nil
+                }
+            }
+        }
+
         func runLoop() {
             provider.heartbeatNow()
         }
@@ -375,7 +396,8 @@ extension Home.StateModel:
     BasalProfileObserver,
     TempTargetsObserver,
     PumpReservoirObserver,
-    PumpTimeZoneObserver
+    PumpTimeZoneObserver,
+    PumpDeactivatedObserver
 {
     func glucoseDidUpdate(_: [BloodGlucose]) {
 //        setupGlucose()
@@ -425,6 +447,10 @@ extension Home.StateModel:
     func pumpTimeZoneDidChange(_: TimeZone) {
         setupCurrentPumpTimezone()
     }
+
+    func pumpDeactivatedDidChange() {
+        displayPumpStatusHighlightMessage(true)
+    }
 }
 
 extension Home.StateModel: CompletionDelegate {
@@ -533,6 +559,7 @@ extension Home.StateModel {
             if !insulinUpdates.isEmpty {
                 self.setupInsulinArray()
                 self.setupLastBolus()
+                self.displayPumpStatusHighlightMessage()
             }
             if !batteryUpdates.isEmpty {
                 self.setupBatteryArray()

+ 58 - 33
FreeAPS/Sources/Modules/Home/View/Header/PumpView.swift

@@ -7,6 +7,7 @@ struct PumpView: View {
     @Binding var expiresAtDate: Date?
     @Binding var timerDate: Date
     @Binding var timeZone: TimeZone?
+    @Binding var pumpStatusHighlightMessage: String?
     var battery: [OpenAPS_Battery]
 
     @Environment(\.colorScheme) var colorScheme
@@ -38,47 +39,71 @@ struct PumpView: View {
     }
 
     var body: some View {
-        VStack(alignment: .leading, spacing: 20) {
-            if let reservoir = reservoir {
-                HStack {
-                    Image(systemName: "cross.vial.fill")
-                        .font(.system(size: 16))
-                        .foregroundColor(reservoirColor)
-                    if reservoir == 0xDEAD_BEEF {
-                        Text("50+ " + NSLocalizedString("U", comment: "Insulin unit")).font(.system(size: 15, design: .rounded))
-                    } else {
-                        Text(
-                            reservoirFormatter
-                                .string(from: reservoir as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit")
-                        )
-                        .font(.system(size: 16, design: .rounded))
+        if let pumpStatusHighlightMessage = pumpStatusHighlightMessage { // display message instead pump info
+            VStack(alignment: .center) {
+                Text(pumpStatusHighlightMessage).font(.footnote).fontWeight(.bold)
+                    .multilineTextAlignment(.center).frame(maxWidth: /*@START_MENU_TOKEN@*/ .infinity/*@END_MENU_TOKEN@*/)
+            }.frame(width: 100)
+        } else {
+            VStack(alignment: .leading, spacing: 20) {
+                if reservoir == nil && battery.isEmpty {
+                    VStack(alignment: .center, spacing: 12) {
+                        HStack {
+                            Image(systemName: "keyboard.onehanded.left")
+                                .font(.body)
+                                .imageScale(.large)
+                        }
+                        HStack {
+                            Text("Add pump")
+                                .font(.caption)
+                                .bold()
+                        }
                     }
+                    .frame(alignment: .top)
                 }
+                if let reservoir = reservoir {
+                    HStack {
+                        Image(systemName: "cross.vial.fill")
+                            .font(.system(size: 16))
+                            .foregroundColor(reservoirColor)
+                        if reservoir == 0xDEAD_BEEF {
+                            Text("50+ " + NSLocalizedString("U", comment: "Insulin unit"))
+                                .font(.system(size: 15, design: .rounded))
+                        } else {
+                            Text(
+                                reservoirFormatter
+                                    .string(from: reservoir as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit")
+                            )
+                            .font(.system(size: 16, design: .rounded))
+                        }
+                    }
 
-                if let timeZone = timeZone, timeZone.secondsFromGMT() != TimeZone.current.secondsFromGMT() {
-                    Image(systemName: "clock.badge.exclamationmark.fill")
-                        .font(.system(size: 16))
-                        .symbolRenderingMode(.palette)
-                        .foregroundStyle(.red, Color(.warning))
+                    if let timeZone = timeZone, timeZone.secondsFromGMT() != TimeZone.current.secondsFromGMT() {
+                        Image(systemName: "clock.badge.exclamationmark.fill")
+                            .font(.system(size: 16))
+                            .symbolRenderingMode(.palette)
+                            .foregroundStyle(.red, Color(.warning))
+                    }
                 }
-            }
 
-            if (battery.first?.display) != nil, expiresAtDate == nil {
-                HStack {
-                    Image(systemName: "battery.100")
-                        .font(.system(size: 16))
-                        .foregroundColor(batteryColor)
-                    Text("\(Int(battery.first?.percent ?? 100)) %").font(.system(size: 16, design: .rounded))
+                if (battery.first?.display) != nil, expiresAtDate == nil {
+                    HStack {
+                        Image(systemName: "battery.100")
+                            .font(.system(size: 16))
+                            .foregroundColor(batteryColor)
+                        Text("\(Int(battery.first?.percent ?? 100)) %").font(.system(size: 16, design: .rounded))
+                    }
                 }
-            }
 
-            if let date = expiresAtDate {
-                HStack {
-                    Image(systemName: "stopwatch.fill")
-                        .font(.system(size: 16))
-                        .foregroundColor(timerColor)
+                if let date = expiresAtDate {
+                    HStack {
+                        Image(systemName: "stopwatch.fill")
+                            .font(.system(size: 16))
+                            .foregroundColor(timerColor)
 
-                    Text(remainingTimeString(time: date.timeIntervalSince(timerDate))).font(.system(size: 16, design: .rounded))
+                        Text(remainingTimeString(time: date.timeIntervalSince(timerDate)))
+                            .font(.system(size: 16, design: .rounded))
+                    }
                 }
             }
         }

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

@@ -168,7 +168,9 @@ extension Home {
                 name: $state.pumpName,
                 expiresAtDate: $state.pumpExpiresAtDate,
                 timerDate: $state.timerDate,
-                timeZone: $state.timeZone, battery: state.batteryFromPersistence
+                timeZone: $state.timeZone,
+                pumpStatusHighlightMessage: $state.pumpStatusHighlightMessage,
+                battery: state.batteryFromPersistence
             ).onTapGesture {
                 if state.pumpDisplayState != nil {
                     state.setupPump = true

+ 2 - 0
FreeAPS/Sources/Modules/PumpConfig/View/PumpConfigRootView.swift

@@ -4,6 +4,7 @@ import Swinject
 extension PumpConfig {
     struct RootView: BaseView {
         let resolver: Resolver
+        let displayClose: Bool
         @StateObject var state = StateModel()
 
         @Environment(\.colorScheme) var colorScheme
@@ -53,6 +54,7 @@ extension PumpConfig {
                 .onAppear(perform: configureView)
                 .navigationTitle("Pump config")
                 .navigationBarTitleDisplayMode(.automatic)
+                .navigationBarItems(leading: displayClose ? Button("Close", action: state.hideModal) : nil)
                 .sheet(isPresented: $state.setupPump) {
                     if let pumpManager = state.provider.apsManager.pumpManager {
                         PumpSettingsView(

+ 4 - 1
FreeAPS/Sources/Router/Screen.swift

@@ -8,6 +8,7 @@ enum Screen: Identifiable, Hashable {
     case configEditor(file: String)
     case nighscoutConfig
     case pumpConfig
+    case pumpConfigDirect
     case pumpSettingsEditor
     case basalProfileEditor
     case isfEditor
@@ -51,7 +52,9 @@ extension Screen {
         case .nighscoutConfig:
             NightscoutConfig.RootView(resolver: resolver)
         case .pumpConfig:
-            PumpConfig.RootView(resolver: resolver)
+            PumpConfig.RootView(resolver: resolver, displayClose: false)
+        case .pumpConfigDirect:
+            PumpConfig.RootView(resolver: resolver, displayClose: true)
         case .pumpSettingsEditor:
             PumpSettingsEditor.RootView(resolver: resolver)
         case .basalProfileEditor: