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

Add dynamic glucose color to contact trick WIP

Deniz Cengiz 1 год назад
Родитель
Сommit
eeaf12de19

+ 2 - 2
FreeAPS/Sources/Modules/ContactTrick/View/AddContactTrickSheet.swift

@@ -12,8 +12,8 @@ struct AddContactTrickSheet: View {
     @State private var ringGap: ContactTrickEntry.RingGap = .small
     @State private var layout: ContactTrickLayout = .single
     @State private var primary: ContactTrickValue = .glucose
-    @State private var top: ContactTrickValue = .delta
-    @State private var bottom: ContactTrickValue = .none
+    @State private var top: ContactTrickValue = .none
+    @State private var bottom: ContactTrickValue = .trend
     @State private var ring: ContactTrickLargeRing = .none
     @State private var fontSize: ContactTrickEntry.FontSize = .regular
     @State private var secondaryFontSize: ContactTrickEntry.FontSize = .small

+ 62 - 0
FreeAPS/Sources/Services/ContactTrick/ContactTrickManager.swift

@@ -16,6 +16,7 @@ final class BaseContactTrickManager: NSObject, ContactTrickManager, Injectable {
     @Injected() private var glucoseStorage: GlucoseStorage!
     @Injected() private var contactTrickStorage: ContactTrickStorage!
     @Injected() private var settingsManager: SettingsManager!
+    @Injected() private var fileStorage: FileStorage!
 
     private let contactStore = CNContactStore()
 
@@ -127,6 +128,55 @@ final class BaseContactTrickManager: NSObject, ContactTrickManager, Injectable {
         }
     }
 
+    private func getCurrentGlucoseTarget() async -> Decimal? {
+        let now = Date()
+        let calendar = Calendar.current
+        let dateFormatter = DateFormatter()
+        dateFormatter.dateFormat = "HH:mm"
+        dateFormatter.timeZone = TimeZone.current
+
+        let bgTargets = await fileStorage.retrieveAsync(OpenAPS.Settings.bgTargets, as: BGTargets.self)
+            ?? BGTargets(from: OpenAPS.defaults(for: OpenAPS.Settings.bgTargets))
+            ?? BGTargets(units: .mgdL, userPreferredUnits: .mgdL, targets: [])
+        let entries: [(start: String, value: Decimal)] = bgTargets.targets.map { ($0.start, $0.low) }
+
+        for (index, entry) in entries.enumerated() {
+            guard let entryTime = dateFormatter.date(from: entry.start) else {
+                print("Invalid entry start time: \(entry.start)")
+                continue
+            }
+
+            let entryComponents = calendar.dateComponents([.hour, .minute, .second], from: entryTime)
+            let entryStartTime = calendar.date(
+                bySettingHour: entryComponents.hour!,
+                minute: entryComponents.minute!,
+                second: entryComponents.second!,
+                of: now
+            )!
+
+            let entryEndTime: Date
+            if index < entries.count - 1,
+               let nextEntryTime = dateFormatter.date(from: entries[index + 1].start)
+            {
+                let nextEntryComponents = calendar.dateComponents([.hour, .minute, .second], from: nextEntryTime)
+                entryEndTime = calendar.date(
+                    bySettingHour: nextEntryComponents.hour!,
+                    minute: nextEntryComponents.minute!,
+                    second: nextEntryComponents.second!,
+                    of: now
+                )!
+            } else {
+                entryEndTime = calendar.date(byAdding: .day, value: 1, to: entryStartTime)!
+            }
+
+            if now >= entryStartTime, now < entryEndTime {
+                return entry.value
+            }
+        }
+
+        return nil
+    }
+
     // MARK: - Configure ContactTrickState in order to update ContactTrickImage
 
     /// Updates the `ContactTrickState` with the latest data from Core Data.
@@ -176,6 +226,18 @@ final class BaseContactTrickManager: NSObject, ContactTrickManager, Injectable {
             let eventualBGAsString = Formatter.decimalFormatterWithOneFractionDigit.string(from: eventualBG)
             state.eventualBG = eventualBGAsString.map { "⇢ " + $0 }
         }
+
+        // TODO: workaround for now: set low value to 55, to have dynamic color shades between 55 and user-set low (approx. 70); same for high glucose
+        let hardCodedLow = Decimal(55)
+        let hardCodedHigh = Decimal(220)
+        let isDynamicColorScheme = settingsManager.settings.glucoseColorScheme == .dynamicColor
+
+        state.highGlucoseColorValue = isDynamicColorScheme ? hardCodedHigh : settingsManager.settings.highGlucose
+        state.lowGlucoseColorValue = isDynamicColorScheme ? hardCodedLow : settingsManager.settings.lowGlucose
+        state
+            .targetGlucose = await getCurrentGlucoseTarget() ??
+            (settingsManager.settings.units == .mgdL ? Decimal(100) : 100.asMmolL)
+        state.glucoseColorScheme = settingsManager.settings.glucoseColorScheme
     }
 
     // MARK: - Interactions with CNContactStore API

+ 16 - 2
FreeAPS/Sources/Services/ContactTrick/ContactTrickPicture.swift

@@ -261,9 +261,23 @@ struct ContactPicture: View {
         default: nil
         }
 
+        let glucoseValue = Decimal(string: state.glucose ?? "100") ?? 100
+
+        let dynamicColor: Color = FreeAPS.getDynamicGlucoseColor(
+            glucoseValue: glucoseValue,
+            highGlucoseColorValue: state.highGlucoseColorValue,
+            lowGlucoseColorValue: state.lowGlucoseColorValue,
+            targetGlucose: state.targetGlucose,
+            glucoseColorScheme: state.glucoseColorScheme
+        )
+
         let textColor: Color = switch value {
-        case .cob: .loopYellow
-        default: color
+        case .cob:
+            .loopYellow
+        case .glucose:
+            dynamicColor
+        default:
+            color
         }
 
         if let text = text {

+ 4 - 0
FreeAPS/Sources/Services/ContactTrick/ContactTrickState.swift

@@ -12,4 +12,8 @@ struct ContactTrickState: Codable {
     var eventualBG: String?
     var maxIOB: Decimal = 10.0
     var maxCOB: Decimal = 120.0
+    var highGlucoseColorValue: Decimal = 180.0
+    var lowGlucoseColorValue: Decimal = 70.0
+    var glucoseColorScheme: GlucoseColorScheme = .staticColor
+    var targetGlucose: Decimal = 100.0
 }