Просмотр исходного кода

Improve CGM display on home screen

- add a icon when no CGM selected
- display the CGM config when tap
- display the link to NS if available in CGM config
- display the link to NS if available in NS config

(cherry picked from commit 8b3e7d44dd71395cf0e940b82e4e02b0a3affd8f)
Pierre L 2 лет назад
Родитель
Сommit
a6143b6e91

+ 19 - 0
FreeAPS/Sources/Modules/CGM/CGMStateModel.swift

@@ -23,6 +23,8 @@ extension CGM {
         @Injected() var cgmManager: FetchGlucoseManager!
         @Injected() var calendarManager: CalendarManager!
         @Injected() var pluginCGMManager: PluginManager!
+        @Injected() private var broadcaster: Broadcaster!
+        @Injected() var nightscoutManager: NightscoutManager!
 
         @Published var setupCGM: Bool = false
         @Published var cgmCurrent = cgmDefaultName
@@ -33,6 +35,7 @@ extension CGM {
         @Persisted(key: "CalendarManager.currentCalendarID") var storedCalendarID: String? = nil
         @Published var cgmTransmitterDeviceAddress: String? = nil
         @Published var listOfCGM: [cgmName] = []
+        @Published var url: URL?
 
         override func subscribe() {
             // collect the list of CGM available with plugins and CGMType defined manually
@@ -65,6 +68,17 @@ extension CGM {
                 )
             }
 
+            url = nightscoutManager.cgmURL
+            switch url?.absoluteString {
+            case "http://127.0.0.1:1979":
+                url = URL(string: "spikeapp://")!
+            case "http://127.0.0.1:17580":
+                url = URL(string: "diabox://")!
+            //            case CGMType.libreTransmitter.appURL?.absoluteString:
+            //                showModal(for: .libreConfig)
+            default: break
+            }
+
             currentCalendarID = storedCalendarID ?? ""
             calendarIDs = calendarManager.calendarIDs()
             cgmTransmitterDeviceAddress = UserDefaults.standard.cgmTransmitterDeviceAddress
@@ -139,6 +153,11 @@ extension CGM.StateModel: CompletionDelegate {
         settingsManager.settings.uploadGlucose = cgmManager.shouldSyncToRemoteService
 
         // update if required the Glucose source
+        DispatchQueue.main.async {
+            self.broadcaster.notify(GlucoseObserver.self, on: .main) {
+                $0.glucoseDidUpdate([])
+            }
+        }
     }
 }
 

+ 13 - 0
FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift

@@ -5,6 +5,7 @@ import Swinject
 extension CGM {
     struct RootView: BaseView {
         let resolver: Resolver
+        let displayClose: Bool
         @StateObject var state = StateModel()
         @State private var setupCGM = false
 
@@ -50,6 +51,17 @@ extension CGM {
                     if state.cgmCurrent.type == .plugin && state.cgmCurrent.id.contains("Libre") {
                         Section(header: Text("Calibrations")) {
                             Text("Calibrations").navigationLink(to: .calibrations, from: self)
+                    
+
+                    if state.cgmCurrent.type == .nightscout {
+                        Section(header: Text("Nightscout")) {
+                            if state.url != nil {
+                                Button(state.url!.absoluteString) {
+                                    UIApplication.shared.open(state.url!, options: [:], completionHandler: nil)
+                                }
+                            } else {
+                                Text("You need to configure Nightscout URL")
+                            }
                         }
                     }
 
@@ -72,6 +84,7 @@ extension CGM {
                 .onAppear(perform: configureView)
                 .navigationTitle("CGM")
                 .navigationBarTitleDisplayMode(.automatic)
+                .navigationBarItems(leading: displayClose ? Button("Close", action: state.hideModal) : nil)
                 .sheet(isPresented: $setupCGM) {
                     if let cgmFetchManager = state.cgmManager,
                        let cgmManager = cgmFetchManager.cgmManager,

+ 5 - 13
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -8,7 +8,8 @@ extension Home {
     final class StateModel: BaseStateModel<Provider> {
         @Injected() var broadcaster: Broadcaster!
         @Injected() var apsManager: APSManager!
-        @Injected() var nightscoutManager: NightscoutManager!
+        @Injected() var fetchGlucoseManager: FetchGlucoseManager!
+
         private let timer = DispatchTimer(timeInterval: 5)
         private(set) var filteredHours = 24
         @Published var glucose: [BloodGlucose] = []
@@ -58,6 +59,7 @@ extension Home {
         @Published var displayXgridLines: Bool = false
         @Published var displayYgridLines: Bool = false
         @Published var thresholdLines: Bool = false
+        @Published var cgmAvailable: Bool = false
 
         let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
 
@@ -224,6 +226,7 @@ extension Home {
                     self.glucoseDelta = nil
                 }
                 self.alarm = self.provider.glucoseStorage.alarm
+                cgmAvailable = (fetchGlucoseManager.cgmGlucoseSourceType != CGMType.none)
             }
         }
 
@@ -350,18 +353,7 @@ extension Home {
         }
 
         func openCGM() {
-            guard var url = nightscoutManager.cgmURL else { return }
-
-            switch url.absoluteString {
-            case "http://127.0.0.1:1979":
-                url = URL(string: "spikeapp://")!
-            case "http://127.0.0.1:17580":
-                url = URL(string: "diabox://")!
-//            case CGMType.libreTransmitter.appURL?.absoluteString:
-//                showModal(for: .libreConfig)
-            default: break
-            }
-            UIApplication.shared.open(url, options: [:], completionHandler: nil)
+            showModal(for: .cgmDirect)
         }
 
         func infoPanelTTPercentage(_ hbt_: Double, _ target: Decimal) -> Decimal {

+ 43 - 29
FreeAPS/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift

@@ -8,6 +8,7 @@ struct CurrentGlucoseView: View {
     @Binding var alarm: GlucoseAlarm?
     @Binding var lowGlucose: Decimal
     @Binding var highGlucose: Decimal
+    @Binding var cgmAvailable: Bool
 
     private var glucoseFormatter: NumberFormatter {
         let formatter = NumberFormatter()
@@ -45,38 +46,51 @@ struct CurrentGlucoseView: View {
     }
 
     var body: some View {
-        VStack(alignment: .center) {
-            HStack {
-                Text(
-                    (recentGlucose?.glucose ?? 100) == 400 ? "HIGH" : recentGlucose?.glucose
-                        .map {
-                            glucoseFormatter
-                                .string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! }
-                        ?? "--"
-                )
-                .font(.title).fontWeight(.bold)
-                .foregroundColor(alarm == nil ? colorOfGlucose : .loopRed)
+        if cgmAvailable {
+            VStack(alignment: .center) {
+                HStack {
+                    Text(
+                        (recentGlucose?.glucose ?? 100) == 400 ? "HIGH" : recentGlucose?.glucose
+                            .map {
+                                glucoseFormatter
+                                    .string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! }
+                            ?? "--"
+                    )
+                    .font(.title).fontWeight(.bold)
+                    .foregroundColor(alarm == nil ? colorOfGlucose : .loopRed)
 
-                image
-            }
-            HStack {
-                let minutesAgo = -1 * (recentGlucose?.dateString.timeIntervalSinceNow ?? 0) / 60
-                let text = timaAgoFormatter.string(for: Double(minutesAgo)) ?? ""
-                Text(
-                    minutesAgo <= 1 ? "< 1 " + NSLocalizedString("min", comment: "Short form for minutes") : (
-                        text + " " +
-                            NSLocalizedString("min", comment: "Short form for minutes") + " "
+                    image
+                }
+                HStack {
+                    let minutesAgo = -1 * (recentGlucose?.dateString.timeIntervalSinceNow ?? 0) / 60
+                    let text = timaAgoFormatter.string(for: Double(minutesAgo)) ?? ""
+                    Text(
+                        minutesAgo <= 1 ? "< 1 " + NSLocalizedString("min", comment: "Short form for minutes") : (
+                            text + " " +
+                                NSLocalizedString("min", comment: "Short form for minutes") + " "
+                        )
                     )
-                )
-                .font(.caption2).foregroundColor(.secondary)
+                    .font(.caption2).foregroundColor(.secondary)
 
-                Text(
-                    delta
-                        .map {
-                            deltaFormatter.string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)!
-                        } ?? "--"
-                )
-                .font(.caption2).foregroundColor(.secondary)
+                    Text(
+                        delta
+                            .map {
+                                deltaFormatter.string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)!
+                            } ?? "--"
+                    )
+                    .font(.caption2).foregroundColor(.secondary)
+                }.frame(alignment: .top)
+            }
+        } else {
+            VStack(alignment: .center, spacing: 12) {
+                HStack
+                    {
+                        // no cgm defined so display a generic CGM
+                        Image(systemName: "sensor.tag.radiowaves.forward.fill").font(.body).imageScale(.large)
+                    }
+                HStack {
+                    Text("Add CGM").font(.caption).bold()
+                }
             }.frame(alignment: .top)
         }
     }

+ 4 - 11
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -127,23 +127,16 @@ extension Home {
                 units: $state.units,
                 alarm: $state.alarm,
                 lowGlucose: $state.lowGlucose,
-                highGlucose: $state.highGlucose
+                highGlucose: $state.highGlucose,
+                cgmAvailable: $state.cgmAvailable
             )
             .onTapGesture {
-                if state.alarm == nil {
-                    state.openCGM()
-                } else {
-                    state.showModal(for: .snooze)
-                }
+                state.openCGM()
             }
             .onLongPressGesture {
                 let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
                 impactHeavy.impactOccurred()
-                if state.alarm == nil {
-                    state.showModal(for: .snooze)
-                } else {
-                    state.openCGM()
-                }
+                state.showModal(for: .snooze)
             }
         }
 

+ 7 - 0
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift

@@ -55,6 +55,13 @@ extension NightscoutConfig {
                 }
 
                 Section {
+                    Button("Open Nighstcout") {
+                        UIApplication.shared.open(URL(string: state.url)!, options: [:], completionHandler: nil)
+                    }
+                    .disabled(state.url.isEmpty || state.connecting)
+                }
+
+                Section {
                     Toggle("Upload", isOn: $state.isUploadEnabled)
                     if state.isUploadEnabled {
                         Toggle("Statistics", isOn: $state.uploadStats)

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

@@ -21,6 +21,7 @@ enum Screen: Identifiable, Hashable {
     case autotuneConfig
     case dataTable
     case cgm
+    case cgmDirect
     case healthkit
     case notificationsConfig
     case fpuConfig
@@ -75,7 +76,9 @@ extension Screen {
         case .dataTable:
             DataTable.RootView(resolver: resolver)
         case .cgm:
-            CGM.RootView(resolver: resolver)
+            CGM.RootView(resolver: resolver, displayClose: false)
+        case .cgmDirect:
+            CGM.RootView(resolver: resolver, displayClose: true)
         case .healthkit:
             AppleHealthKit.RootView(resolver: resolver)
         case .notificationsConfig: