Przeglądaj źródła

Adjust broken build; various additions/changes
* Rename and refactor boolean setting to type-based setting Glucose Color Scheme
* Add setting to User Interface settings to pick scheme style
* Various adjustments for proper display
* Add dynamic coloring to forecast chart in treatment view
* Fix broken build after merge (thanks to @polscm32)
* Misc

Deniz Cengiz 1 rok temu
rodzic
commit
d90c6e279a

+ 4 - 4
FreeAPS.xcodeproj/project.pbxproj

@@ -449,7 +449,7 @@
 		DD6B7CBB2C7FBBFA00B75029 /* ReviewInsulinActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B7CBA2C7FBBFA00B75029 /* ReviewInsulinActionView.swift */; };
 		DD6D67E42C9C253500660C9B /* ColorSchemeOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6D67E32C9C253500660C9B /* ColorSchemeOption.swift */; };
 		DD88C8E22C50420800F2D558 /* DefinitionRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD88C8E12C50420800F2D558 /* DefinitionRow.swift */; };
-		DD940BAA2CA7585D000830A5 /* GlucoseColorStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD940BA92CA7585D000830A5 /* GlucoseColorStyle.swift */; };
+		DD940BAA2CA7585D000830A5 /* GlucoseColorScheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */; };
 		DD940BAC2CA75889000830A5 /* DynamicGlucoseColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD940BAB2CA75889000830A5 /* DynamicGlucoseColor.swift */; };
 		DDD163122C4C689900CD525A /* OverrideStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD163112C4C689900CD525A /* OverrideStateModel.swift */; };
 		DDD163142C4C68D300CD525A /* OverrideProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD163132C4C68D300CD525A /* OverrideProvider.swift */; };
@@ -1114,7 +1114,7 @@
 		DD6B7CBA2C7FBBFA00B75029 /* ReviewInsulinActionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewInsulinActionView.swift; sourceTree = "<group>"; };
 		DD6D67E32C9C253500660C9B /* ColorSchemeOption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorSchemeOption.swift; sourceTree = "<group>"; };
 		DD88C8E12C50420800F2D558 /* DefinitionRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefinitionRow.swift; sourceTree = "<group>"; };
-		DD940BA92CA7585D000830A5 /* GlucoseColorStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseColorStyle.swift; sourceTree = "<group>"; };
+		DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseColorScheme.swift; sourceTree = "<group>"; };
 		DD940BAB2CA75889000830A5 /* DynamicGlucoseColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicGlucoseColor.swift; sourceTree = "<group>"; };
 		DDD163112C4C689900CD525A /* OverrideStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverrideStateModel.swift; sourceTree = "<group>"; };
 		DDD163132C4C68D300CD525A /* OverrideProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverrideProvider.swift; sourceTree = "<group>"; };
@@ -1916,7 +1916,7 @@
 		388E5A5925B6F0250019842D /* Models */ = {
 			isa = PBXGroup;
 			children = (
-				DD940BA92CA7585D000830A5 /* GlucoseColorStyle.swift */,
+				DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */,
 				DD6D67E32C9C253500660C9B /* ColorSchemeOption.swift */,
 				385CEAC025F2EA52002D6D5B /* Announcement.swift */,
 				388E5A5F25B6F2310019842D /* Autosens.swift */,
@@ -3334,7 +3334,7 @@
 				CEB434E728B9053300B70274 /* LoopUIColorPalette+Default.swift in Sources */,
 				19F95FF329F10FBC00314DDC /* StatDataFlow.swift in Sources */,
 				582DF97B2C8CE209001F516D /* CarbView.swift in Sources */,
-				DD940BAA2CA7585D000830A5 /* GlucoseColorStyle.swift in Sources */,
+				DD940BAA2CA7585D000830A5 /* GlucoseColorScheme.swift in Sources */,
 				3811DE2225C9D48300A708ED /* MainProvider.swift in Sources */,
 				3811DE0C25C9D32F00A708ED /* BaseProvider.swift in Sources */,
 				CE95BF5A2BA62E4A00DC3DE3 /* PluginSource.swift in Sources */,

+ 1 - 1
FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json

@@ -37,7 +37,7 @@
   "high" : 180,
   "low" : 70,
   "hours" : 6,
-  "glucoseColorStyle" : "staticColor",
+  "glucoseColorScheme" : "staticColor",
   "xGridLines" : true,
   "yGridLines" : true,
   "oneDimensionalGraph" : false,

+ 8 - 8
FreeAPS/Sources/Helpers/DynamicGlucoseColor.swift

@@ -7,28 +7,28 @@ public func getDynamicGlucoseColor(
     highGlucoseColorValue: Decimal,
     lowGlucoseColorValue: Decimal,
     targetGlucose: Decimal,
-    glucoseColorStyle: GlucoseColorStyle,
+    glucoseColorScheme: GlucoseColorScheme,
     offset: Decimal
 ) -> Color {
     // Convert Decimal to Int for high and low glucose values
-    let lowGlucose = lowGlucoseColorValue - offset
-    let highGlucose = highGlucoseColorValue + (offset * 1.75)
+    let lowGlucose = lowGlucoseColorValue
+    let highGlucose = highGlucoseColorValue
     let targetGlucose = targetGlucose
 
     // Only use calculateHueBasedGlucoseColor if the setting is enabled in preferences
-    if GlucoseColorStyle == .dynamicColor {
+    if glucoseColorScheme == .dynamicColor {
         return calculateHueBasedGlucoseColor(
             glucoseValue: glucoseValue,
-            highGlucose: highGlucose,
-            lowGlucose: lowGlucose,
+            highGlucose: highGlucose + (offset * 1.75),
+            lowGlucose: lowGlucose - offset,
             targetGlucose: targetGlucose
         )
     }
     // Otheriwse, use static (orange = high, red = low, green = range)
     else {
-        if glucoseValue > highGlucose {
+        if glucoseValue >= highGlucose {
             return Color.orange
-        } else if glucoseValue < lowGlucose {
+        } else if glucoseValue <= lowGlucose {
             return Color.red
         } else {
             return Color.green

+ 3 - 3
FreeAPS/Sources/Models/FreeAPSSettings.swift

@@ -53,7 +53,7 @@ struct FreeAPSSettings: JSON, Equatable {
     var high: Decimal = 180
     var low: Decimal = 70
     var hours: Int = 6
-    var glucoseColorStyle: GlucoseColorStyle = .staticColor
+    var glucoseColorScheme: GlucoseColorScheme = .staticColor
     var xGridLines: Bool = true
     var yGridLines: Bool = true
     var oneDimensionalGraph: Bool = false
@@ -251,8 +251,8 @@ extension FreeAPSSettings: Decodable {
             settings.hours = hours
         }
 
-        if let glucoseColorStyle = try? container.decode(GlucoseColorStyle.self, forKey: .glucoseColorStyle) {
-            settings.glucoseColorStyle = glucoseColorStyle
+        if let glucoseColorScheme = try? container.decode(GlucoseColorScheme.self, forKey: .glucoseColorScheme) {
+            settings.glucoseColorScheme = glucoseColorScheme
         }
 
         if let xGridLines = try? container.decode(Bool.self, forKey: .xGridLines) {

+ 3 - 3
FreeAPS/Sources/Models/GlucoseColorStyle.swift

@@ -1,13 +1,13 @@
 //
-//  GlucoseColorStyle.swift
+//  GlucoseColorScheme.swift
 //  FreeAPS
 //
 //  Created by Cengiz Deniz on 27.09.24.
 //
 import Foundation
 
-enum GlucoseColorStyle: String, JSON, CaseIterable, Identifiable, Codable, Hashable {
-    var id: String { rawValue }
+public enum GlucoseColorScheme: String, JSON, CaseIterable, Identifiable, Codable, Hashable {
+    public var id: String { rawValue }
     case staticColor
     case dynamicColor
 

+ 2 - 0
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -20,6 +20,7 @@ extension Bolus {
 
         @Published var lowGlucose: Decimal = 70
         @Published var highGlucose: Decimal = 180
+        @Published var glucoseColorScheme: GlucoseColorScheme = .staticColor
 
         @Published var predictions: Predictions?
         @Published var amount: Decimal = 0
@@ -234,6 +235,7 @@ extension Bolus {
             maxProtein = settings.settings.maxProtein
             useFPUconversion = settingsManager.settings.useFPUconversion
             isSmoothingEnabled = settingsManager.settings.smoothGlucose
+            glucoseColorScheme = settingsManager.settings.glucoseColorScheme
         }
 
         private func getCurrentSettingValue(for type: SettingType) async {

+ 8 - 3
FreeAPS/Sources/Modules/Bolus/View/ForeCastChart.swift

@@ -122,9 +122,14 @@ struct ForeCastChart: View {
     private func drawGlucose() -> some ChartContent {
         ForEach(state.glucoseFromPersistence) { item in
             let glucoseToDisplay = state.units == .mgdL ? Decimal(item.glucose) : Decimal(item.glucose).asMmolL
-            let pointMarkColor: Color = glucoseToDisplay > state.highGlucose ? Color.orange :
-                glucoseToDisplay < state.lowGlucose ? Color.red :
-                Color.green
+            let pointMarkColor = FreeAPS.getDynamicGlucoseColor(
+                glucoseValue: glucoseToDisplay,
+                highGlucoseColorValue: state.highGlucose,
+                lowGlucoseColorValue: state.lowGlucose,
+                targetGlucose: (state.determination.first?.currentTarget ?? state.currentBGTarget as NSDecimalNumber) as Decimal,
+                glucoseColorScheme: state.glucoseColorScheme,
+                offset: units == .mgdL ? 20 : 20.asMmolL
+            )
 
             if !state.isSmoothingEnabled {
                 PointMark(

+ 3 - 2
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -51,7 +51,7 @@ extension Home {
         @Published var highGlucose: Decimal = 180
         @Published var currentGlucoseTarget: Decimal = 100
         @Published var overrideUnit: Bool = false
-        @Published var glucoseColorStyle: GlucoseColorStyle = .staticColor
+        @Published var glucoseColorScheme: GlucoseColorScheme = .staticColor
         @Published var displayXgridLines: Bool = false
         @Published var displayYgridLines: Bool = false
         @Published var thresholdLines: Bool = false
@@ -328,6 +328,7 @@ extension Home {
             manualTempBasal = apsManager.isManualTempBasal
             setupCurrentTempTarget()
             isSmoothingEnabled = settingsManager.settings.smoothGlucose
+            glucoseColorScheme = settingsManager.settings.glucoseColorScheme
             maxValue = settingsManager.preferences.autosensMax
             lowGlucose = units == .mgdL ? settingsManager.settings.low : settingsManager.settings.low.asMmolL
             highGlucose = units == .mgdL ? settingsManager.settings.high : settingsManager.settings.high.asMmolL
@@ -588,7 +589,7 @@ extension Home.StateModel:
             await getCurrentGlucoseTarget()
         }
         overrideUnit = settingsManager.settings.overrideHbA1cUnit
-        glucoseColorStyle = settingsManager.settings.glucoseColorStyle
+        glucoseColorScheme = settingsManager.settings.glucoseColorScheme
         displayXgridLines = settingsManager.settings.xGridLines
         displayYgridLines = settingsManager.settings.yGridLines
         thresholdLines = settingsManager.settings.rulerMarks

+ 6 - 4
FreeAPS/Sources/Modules/Home/View/Chart/DummyCharts.swift

@@ -13,7 +13,7 @@ extension MainChartView {
                     highGlucoseColorValue: highGlucose,
                     lowGlucoseColorValue: highGlucose,
                     targetGlucose: currentGlucoseTarget,
-                    glucoseColorStyle: glucoseColorStyle,
+                    glucoseColorScheme: glucoseColorScheme,
                     offset: units == .mgdL ? 20 : 20.asMmolL
                 )
                 let lowColor = FreeAPS.getDynamicGlucoseColor(
@@ -21,13 +21,15 @@ extension MainChartView {
                     highGlucoseColorValue: highGlucose,
                     lowGlucoseColorValue: lowGlucose,
                     targetGlucose: currentGlucoseTarget,
-                    glucoseColorStyle: glucoseColorStyle,
+                    glucoseColorScheme: glucoseColorScheme,
                     offset: units == .mgdL ? 20 : 20.asMmolL
                 )
 
-                RuleMark(y: .value("High", highGlucose)).foregroundStyle(highColor)
+                RuleMark(y: .value("High", highGlucose))
+                    .foregroundStyle(highColor)
                     .lineStyle(.init(lineWidth: 1, dash: [5]))
-                RuleMark(y: .value("Low", lowGlucose)).foregroundStyle(lowColor)
+                RuleMark(y: .value("Low", lowGlucose))
+                    .foregroundStyle(lowColor)
                     .lineStyle(.init(lineWidth: 1, dash: [5]))
             }
         }

+ 2 - 2
FreeAPS/Sources/Modules/Home/View/Chart/GlucoseChartView.swift

@@ -9,7 +9,7 @@ struct GlucoseChartView: ChartContent {
     let lowGlucose: Decimal
     let currentGlucoseTarget: Decimal
     let isSmoothingEnabled: Bool
-    let glucoseColorStyle: GlucoseColorStyle
+    let glucoseColorScheme: GlucoseColorScheme
 
     var body: some ChartContent {
         drawGlucoseChart()
@@ -24,7 +24,7 @@ struct GlucoseChartView: ChartContent {
                 highGlucoseColorValue: highGlucose,
                 lowGlucoseColorValue: lowGlucose,
                 targetGlucose: currentGlucoseTarget,
-                glucoseColorStyle: glucoseColorStyle,
+                glucoseColorScheme: glucoseColorScheme,
                 offset: units == .mgdL ? 20 : 20.asMmolL
             )
 

+ 3 - 3
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -14,7 +14,7 @@ struct MainChartView: View {
     @Binding var lowGlucose: Decimal
     @Binding var currentGlucoseTarget: Decimal
     @Binding var screenHours: Int16
-    @Binding var glucoseColorStyle: GlucoseColorStyle
+    @Binding var glucoseColorScheme: GlucoseColorScheme
     @Binding var displayXgridLines: Bool
     @Binding var displayYgridLines: Bool
     @Binding var thresholdLines: Bool
@@ -145,7 +145,7 @@ extension MainChartView {
                     lowGlucose: state.lowGlucose,
                     currentGlucoseTarget: state.currentGlucoseTarget,
                     isSmoothingEnabled: state.isSmoothingEnabled,
-                    glucoseColorStyle: state.glucoseColorStyle
+                    glucoseColorScheme: state.glucoseColorScheme
                 )
 
                 InsulinView(
@@ -257,7 +257,7 @@ extension MainChartView {
                     highGlucoseColorValue: highGlucose,
                     lowGlucoseColorValue: lowGlucose,
                     targetGlucose: currentGlucoseTarget,
-                    glucoseColorStyle: glucoseColorStyle,
+                    glucoseColorScheme: glucoseColorScheme,
                     offset: units == .mgdL ? 20 : 20.asMmolL
                 )
                 HStack {

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

@@ -343,7 +343,7 @@ extension Home {
                     lowGlucose: $state.lowGlucose,
                     currentGlucoseTarget: $state.currentGlucoseTarget,
                     screenHours: $state.hours,
-                    glucoseColorStyle: $state.glucoseColorStyle,
+                    glucoseColorScheme: $state.glucoseColorScheme,
                     displayXgridLines: $state.displayXgridLines,
                     displayYgridLines: $state.displayYgridLines,
                     thresholdLines: $state.thresholdLines,

+ 2 - 2
FreeAPS/Sources/Modules/UserInterfaceSettings/UserInterfaceSettingsStateModel.swift

@@ -14,7 +14,7 @@ extension UserInterfaceSettings {
         @Published var totalInsulinDisplayType: TotalInsulinDisplayType = .totalDailyDose
         @Published var showCarbsRequiredBadge: Bool = true
         @Published var carbsRequiredThreshold: Decimal = 0
-        @Published var glucoseColorStyle: GlucoseColorStyle = .staticColor
+        @Published var glucoseColorScheme: GlucoseColorScheme = .staticColor
 
         var units: GlucoseUnits = .mgdL
 
@@ -43,7 +43,7 @@ extension UserInterfaceSettings {
                 on: $carbsRequiredThreshold
             ) { carbsRequiredThreshold = $0 }
 
-            subscribeSetting(\.glucoseColorStyle, on: $glucoseColorStyle) { glucoseColorStyle = $0 }
+            subscribeSetting(\.glucoseColorScheme, on: $glucoseColorScheme) { glucoseColorScheme = $0 }
         }
     }
 }

+ 36 - 0
FreeAPS/Sources/Modules/UserInterfaceSettings/View/UserInterfaceSettingsRootView.swift

@@ -93,6 +93,42 @@ extension UserInterfaceSettings {
                     }
                 ).listRowBackground(Color.chart)
 
+                Section {
+                    VStack {
+                        Picker(
+                            selection: $state.glucoseColorScheme,
+                            label: Text("Glucose Color Scheme")
+                        ) {
+                            ForEach(GlucoseColorScheme.allCases) { selection in
+                                Text(selection.displayName).tag(selection)
+                            }
+                        }.padding(.top)
+
+                        HStack(alignment: .top) {
+                            Text(
+                                "Glucose Scheme Preference ... dynamic or static ... Lorem ipsum dolor"
+                            )
+                            .font(.footnote)
+                            .foregroundColor(.secondary)
+                            .lineLimit(nil)
+                            Spacer()
+                            Button(
+                                action: {
+                                    hintLabel = "Glucose Scheme Preference"
+                                    selectedVerboseHint =
+                                        "Glucose Scheme Preference... Lorem ipsum dolor sit amet, consetetur sadipscing elitr."
+                                    shouldDisplayHint.toggle()
+                                },
+                                label: {
+                                    HStack {
+                                        Image(systemName: "questionmark.circle")
+                                    }
+                                }
+                            ).buttonStyle(BorderlessButtonStyle())
+                        }.padding(.top)
+                    }.padding(.bottom)
+                }.listRowBackground(Color.chart)
+
                 Section(
                     header: Text("Home View Settings"),
                     content: {

+ 1 - 1
FreeAPS/Sources/Services/LiveActivity/LiveActitiyAttributes.swift

@@ -20,7 +20,7 @@ struct LiveActivityAttributes: ActivityAttributes {
         let rotationDegrees: Double
         let highGlucose: Decimal
         let lowGlucose: Decimal
-        let glucoseColorStyle: String
+        let glucoseColorScheme: String
         let cob: Decimal
         let iob: Decimal
         let unit: String

+ 1 - 1
FreeAPS/Sources/Services/LiveActivity/LiveActivityAttributes+Helper.swift

@@ -89,7 +89,7 @@ extension LiveActivityAttributes.ContentState {
                 rotationDegrees: rotationDegrees,
                 highGlucose: settings.high,
                 lowGlucose: settings.low,
-                glucoseColorStyle: settings.glucoseColorStyle.rawValue,
+                glucoseColorScheme: settings.glucoseColorScheme.rawValue,
                 cob: Decimal(determination?.cob ?? 0),
                 iob: determination?.iob ?? 0 as Decimal,
                 unit: settings.units.rawValue,

+ 10 - 8
LiveActivity/LiveActivity.swift

@@ -17,9 +17,9 @@ enum GlucoseUnits: String, Equatable {
     static let exchangeRate: Decimal = 0.0555
 }
 
-enum GlucoseColorStyle: String, Equatable {
-    case staticColor = "staticColor"
-    case dynamicColor = "dynamicColor"
+enum GlucoseColorScheme: String, Equatable {
+    case staticColor
+    case dynamicColor
 }
 
 // Helper function to decide how to pick the glucose color
@@ -28,16 +28,17 @@ func getDynamicGlucoseColor(
     highGlucoseColorValue: Decimal,
     lowGlucoseColorValue: Decimal,
     targetGlucose: Decimal,
-    glucoseColorStyle: GlucoseColorStyle,
+    glucoseColorScheme: String,
     offset: Decimal
 ) -> Color {
+    let colorStyle = GlucoseColorScheme(rawValue: glucoseColorScheme) ?? .staticColor
     // Convert Decimal to Int for high and low glucose values
     let lowGlucose = lowGlucoseColorValue - offset
     let highGlucose = highGlucoseColorValue + (offset * 1.75)
     let targetGlucose = targetGlucose
 
     // Only use calculateHueBasedGlucoseColor if the setting is enabled in preferences
-    if glucoseColorStyle == .dynamicColor {
+    if glucoseColorScheme == "dynamicColor" {
         return calculateHueBasedGlucoseColor(
             glucoseValue: glucoseValue,
             highGlucose: highGlucose,
@@ -372,7 +373,7 @@ struct LiveActivity: Widget {
                         highGlucoseColorValue: additionalState.highGlucose,
                         lowGlucoseColorValue: additionalState.lowGlucose,
                         targetGlucose: 90,
-                        glucoseColorStyle: additionalState.glucoseColorStyle ?? "staticColor",
+                        glucoseColorScheme: additionalState.glucoseColorScheme ?? "staticColor",
                         offset: additionalState.unit == "mg/dL" ? Decimal(20) : Decimal(20).asMmolL
                     )
 
@@ -421,7 +422,7 @@ struct LiveActivity: Widget {
                     highGlucoseColorValue: context.state.detailedViewState?.highGlucose ?? 180,
                     lowGlucoseColorValue: context.state.detailedViewState?.lowGlucose ?? 70,
                     targetGlucose: 90,
-                    glucoseColorStyle: context.state.detailedViewState?.glucoseColorStyle ?? "staticColor",
+                    glucoseColorScheme: context.state.detailedViewState?.glucoseColorScheme ?? "staticColor",
                     offset: context.state.detailedViewState?.unit == "mg/dL" ? Decimal(20) : Decimal(20).asMmolL
                 )
 
@@ -467,7 +468,7 @@ struct LiveActivity: Widget {
             highGlucoseColorValue: highGlucose,
             lowGlucoseColorValue: lowGlucose,
             targetGlucose: 90,
-            glucoseColorStyle: context.state.detailedViewState?.glucoseColorStyle ?? "staticColor",
+            glucoseColorScheme: context.state.detailedViewState?.glucoseColorScheme ?? "staticColor",
             offset: context.state.detailedViewState?.unit == "mg/dL" ? Decimal(20) : Decimal(20).asMmolL
         )
 
@@ -525,6 +526,7 @@ struct LiveActivity: Widget {
         ActivityConfiguration(for: LiveActivityAttributes.self, content: self.content, dynamicIsland: self.dynamicIsland)
     }
 }
+
 private extension LiveActivityAttributes {
     static var preview: LiveActivityAttributes {
         LiveActivityAttributes(startDate: Date())