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

show hint in views when BLE access is not given

polscm32 1 год назад
Родитель
Сommit
a6e4bb8a0b

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

@@ -47686,6 +47686,9 @@
         }
       }
     },
+    "Bluetooth Access Required" : {
+
+    },
     "Bluetooth is used to communicate with insulin pump and continuous glucose monitor devices." : {
       "localizations" : {
         "bg" : {
@@ -87584,6 +87587,9 @@
         }
       }
     },
+    "Enable Bluetooth in Settings" : {
+
+    },
     "Enable device connectivity" : {
       "localizations" : {
         "bg" : {

+ 1 - 0
Trio/Sources/Modules/CGMSettings/CGMSettingsStateModel.swift

@@ -42,6 +42,7 @@ extension CGMSettings {
         @Injected() var pluginCGMManager: PluginManager!
         @Injected() var broadcaster: Broadcaster!
         @Injected() var nightscoutManager: NightscoutManager!
+        @Injected() var bluetoothManager: BluetoothStateManager!
 
         @Published var units: GlucoseUnits = .mgdL
         @Published var shouldDisplayCGMSetupSheet: Bool = false

+ 56 - 38
Trio/Sources/Modules/CGMSettings/View/CGMRootView.swift

@@ -6,14 +6,14 @@ extension CGMSettings {
     struct RootView: BaseView {
         let resolver: Resolver
         let displayClose: Bool
+        let bluetoothManager: BluetoothStateManager
         @StateObject var state = StateModel()
-
         @State private var shouldDisplayHint: Bool = false
         @State var hintDetent = PresentationDetent.large
         @State var selectedVerboseHint: AnyView?
         @State var hintLabel: String?
         @State private var decimalPlaceholder: Decimal = 0.0
-        @State private var booleanPlaceholder: Bool = false
+        @State private var booleanPlaceholdre: Bool = false
         @State var showCGMSelection: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
@@ -35,48 +35,66 @@ extension CGMSettings {
                     Section(
                         header: Text("CGM Integration to Trio"),
                         content: {
-                            let cgmState = state.cgmCurrent
-                            if cgmState.type != .none {
-                                Button {
-                                    state.shouldDisplayCGMSetupSheet = true
-                                } label: {
-                                    HStack {
-                                        Image(systemName: "sensor.tag.radiowaves.forward.fill")
-                                        Text(cgmState.displayName)
+                            if bluetoothManager.bluetoothAuthorization != .authorized {
+                                HStack {
+                                    Image(systemName: "exclamationmark.triangle.fill")
+                                        .foregroundStyle(.red)
+                                    Text("Bluetooth Access Required")
+                                        .foregroundColor(.red)
+                                    Spacer()
+                                    Button(action: {
+                                        if let url = URL(string: UIApplication.openSettingsURLString) {
+                                            UIApplication.shared.open(url)
+                                        }
+                                    }) {
+                                        Text("Enable")
+                                            .foregroundColor(.blue)
                                     }
-                                    .frame(maxWidth: .infinity, minHeight: 50, alignment: .center)
-                                    .font(.title2)
-                                }.padding()
+                                }
                             } else {
-                                VStack {
+                                let cgmState = state.cgmCurrent
+                                if cgmState.type != .none {
                                     Button {
-                                        showCGMSelection.toggle()
+                                        state.shouldDisplayCGMSetupSheet = true
                                     } label: {
-                                        Text("Add CGM")
-                                            .font(.title3) }
-                                        .frame(maxWidth: .infinity, alignment: .center)
-                                        .buttonStyle(.bordered)
+                                        HStack {
+                                            Image(systemName: "sensor.tag.radiowaves.forward.fill")
+                                            Text(cgmState.displayName)
+                                        }
+                                        .frame(maxWidth: .infinity, minHeight: 50, alignment: .center)
+                                        .font(.title2)
+                                    }.padding()
+                                } else {
+                                    VStack {
+                                        Button {
+                                            showCGMSelection.toggle()
+                                        } label: {
+                                            Text("Add CGM")
+                                                .font(.title3) }
+                                            .frame(maxWidth: .infinity, alignment: .center)
+                                            .buttonStyle(.bordered)
 
-                                    HStack(alignment: .center) {
-                                        Text(
-                                            "Pair your CGM with Trio. See hint for compatible devices."
-                                        )
-                                        .font(.footnote)
-                                        .foregroundColor(.secondary)
-                                        .lineLimit(nil)
-                                        Spacer()
-                                        Button(
-                                            action: {
-                                                shouldDisplayHint.toggle()
-                                            },
-                                            label: {
-                                                HStack {
-                                                    Image(systemName: "questionmark.circle")
+                                        HStack(alignment: .center) {
+                                            Text(
+                                                "Pair your CGM with Trio. See hint for compatible devices."
+                                            )
+                                            .font(.footnote)
+                                            .foregroundColor(.secondary)
+                                            .lineLimit(nil)
+                                            Spacer()
+                                            Button(
+                                                action: {
+                                                    shouldDisplayHint.toggle()
+                                                },
+                                                label: {
+                                                    HStack {
+                                                        Image(systemName: "questionmark.circle")
+                                                    }
                                                 }
-                                            }
-                                        ).buttonStyle(BorderlessButtonStyle())
-                                    }.padding(.top)
-                                }.padding(.vertical)
+                                            ).buttonStyle(BorderlessButtonStyle())
+                                        }.padding(.top)
+                                    }.padding(.vertical)
+                                }
                             }
                         }
                     )

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

@@ -19,6 +19,7 @@ extension Home {
         @ObservationIgnored @Injected() var carbsStorage: CarbsStorage!
         @ObservationIgnored @Injected() var tempTargetStorage: TempTargetsStorage!
         @ObservationIgnored @Injected() var overrideStorage: OverrideStorage!
+        @ObservationIgnored @Injected() var bluetoothManager: BluetoothStateManager!
 
         var cgmStateModel: CGMSettings.StateModel {
             CGMSettings.StateModel.shared

+ 21 - 2
Trio/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift

@@ -11,7 +11,7 @@ struct CurrentGlucoseView: View {
     var currentGlucoseTarget: Decimal
     let glucoseColorScheme: GlucoseColorScheme
     let glucose: [GlucoseStored] // This contains the last two glucose values, no matter if its manual or a cgm reading
-
+    let bluetoothManager: BluetoothStateManager
     @State private var rotationDegrees: Double = 0.0
     @State private var angularGradient = AngularGradient(colors: [
         Color(red: 0.7215686275, green: 0.3411764706, blue: 1),
@@ -42,7 +42,26 @@ struct CurrentGlucoseView: View {
     var body: some View {
         let triangleColor = Color(red: 0.262745098, green: 0.7333333333, blue: 0.9137254902)
 
-        if cgmAvailable {
+        if bluetoothManager.bluetoothAuthorization != .authorized {
+            VStack(alignment: .center, spacing: 12) {
+                HStack {
+                    Image(systemName: "exclamationmark.triangle.fill")
+                        .foregroundStyle(.red)
+                        .font(.system(size: 20))
+                    Text("Bluetooth Access Required")
+                        .font(.caption)
+                        .bold()
+                }
+                Text("Enable Bluetooth in Settings")
+                    .font(.caption)
+                    .foregroundColor(.secondary)
+            }
+            .onTapGesture {
+                if let url = URL(string: UIApplication.openSettingsURLString) {
+                    UIApplication.shared.open(url)
+                }
+            }
+        } else if cgmAvailable {
             ZStack {
                 TrendShape(gradient: angularGradient, color: triangleColor)
                     .rotationEffect(.degrees(rotationDegrees))

+ 21 - 2
Trio/Sources/Modules/Home/View/Header/PumpView.swift

@@ -8,7 +8,7 @@ struct PumpView: View {
     let timerDate: Date
     let pumpStatusHighlightMessage: String?
     let battery: [OpenAPS_Battery]
-
+    let bluetoothManager: BluetoothStateManager
     @Environment(\.colorScheme) var colorScheme
 
     private var batteryFormatter: NumberFormatter {
@@ -18,7 +18,26 @@ struct PumpView: View {
     }
 
     var body: some View {
-        if let pumpStatusHighlightMessage = pumpStatusHighlightMessage { // display message instead pump info
+        if bluetoothManager.bluetoothAuthorization != .authorized {
+            VStack(alignment: .center, spacing: 12) {
+                HStack {
+                    Image(systemName: "exclamationmark.triangle.fill")
+                        .foregroundStyle(.red)
+                        .font(.system(size: 20))
+                    Text("Bluetooth Access Required")
+                        .font(.caption)
+                        .bold()
+                }
+                Text("Enable Bluetooth in Settings")
+                    .font(.caption)
+                    .foregroundColor(.secondary)
+            }
+            .onTapGesture {
+                if let url = URL(string: UIApplication.openSettingsURLString) {
+                    UIApplication.shared.open(url)
+                }
+            }
+        } else 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@*/)

+ 4 - 2
Trio/Sources/Modules/Home/View/HomeRootView.swift

@@ -126,7 +126,8 @@ extension Home {
                 cgmAvailable: state.cgmAvailable,
                 currentGlucoseTarget: state.currentGlucoseTarget,
                 glucoseColorScheme: state.glucoseColorScheme,
-                glucose: state.latestTwoGlucoseValues
+                glucose: state.latestTwoGlucoseValues,
+                bluetoothManager: state.bluetoothManager
             ).scaleEffect(0.9)
                 .onTapGesture {
                     if !state.cgmAvailable {
@@ -149,7 +150,8 @@ extension Home {
                 expiresAtDate: state.pumpExpiresAtDate,
                 timerDate: state.timerDate,
                 pumpStatusHighlightMessage: state.pumpStatusHighlightMessage,
-                battery: state.batteryFromPersistence
+                battery: state.batteryFromPersistence,
+                bluetoothManager: state.bluetoothManager
             )
             .onTapGesture {
                 if state.pumpDisplayState == nil {

+ 1 - 0
Trio/Sources/Modules/PumpConfig/PumpConfigStateModel.swift

@@ -10,6 +10,7 @@ extension PumpConfig {
         @Published var pumpState: PumpDisplayState?
         private(set) var initialSettings: PumpInitialSettings = .default
         @Published var alertNotAck: Bool = false
+        @Injected() var bluetoothManager: BluetoothStateManager!
 
         override func subscribe() {
             provider.pumpDisplayState

+ 18 - 2
Trio/Sources/Modules/PumpConfig/View/PumpConfigRootView.swift

@@ -5,8 +5,8 @@ extension PumpConfig {
     struct RootView: BaseView {
         let resolver: Resolver
         let displayClose: Bool
+        let bluetoothManager: BluetoothStateManager
         @StateObject var state = StateModel()
-
         @State private var shouldDisplayHint: Bool = false
         @State var hintDetent = PresentationDetent.large
         @State var selectedVerboseHint: AnyView?
@@ -24,7 +24,23 @@ extension PumpConfig {
                     Section(
                         header: Text("Pump Integration to Trio"),
                         content: {
-                            if let pumpState = state.pumpState {
+                            if bluetoothManager.bluetoothAuthorization != .authorize d{
+                                HStack {
+                                    Image(systemName: "exclamationmark.triangle.fill")
+                                        .foregroundStyle(.red)
+                                    Text("Bluetooth Access Required")
+                                        .foregroundColor(.red)
+                                    Spacer()
+                                    Button(action: {
+                                        if let url = URL(string: UIApplication.openSettingsURLString) {
+                                            UIApplication.shared.open(url)
+                                        }
+                                    }) {
+                                        Text("Enable")
+                                            .foregroundColor(.blue)
+                                    }
+                                }
+                            } else if let pumpState = state.pumpState {
                                 Button {
                                     state.setupPump = true
                                 } label: {

+ 12 - 1
Trio/Sources/Services/Bluetooth/BluetoothStateManager.swift

@@ -3,13 +3,24 @@ import LoopKit
 import LoopKitUI
 import Swinject
 
-protocol BluetoothStateManager: BluetoothProvider {}
+protocol BluetoothStateManager: BluetoothProvider {
+//    var isBluetoothAuthorized: Bool { get }
+//    var isBluetoothDenied: Bool { get }
+}
 
 public class BaseBluetoothStateManager: NSObject, BluetoothStateManager, Injectable {
     private var completion: ((BluetoothAuthorization) -> Void)?
     private var centralManager: CBCentralManager?
     private var bluetoothObservers = WeakSynchronizedSet<BluetoothObserver>()
 
+//    public var isBluetoothAuthorized: Bool {
+//        bluetoothAuthorization == .authorized
+//    }
+//
+//    public var isBluetoothDenied: Bool {
+//        bluetoothAuthorization == .denied || bluetoothAuthorization == .restricted
+//    }
+
     init(resolver: Resolver) {
         super.init()
         injectServices(resolver)