فهرست منبع

Add conditional mmol/L parsing for tags in Loop stauts HUD

Deniz Cengiz 1 سال پیش
والد
کامیت
7fed876eb9
2فایلهای تغییر یافته به همراه154 افزوده شده و 13 حذف شده
  1. 47 2
      FreeAPS/Sources/Modules/Home/View/HomeRootView.swift
  2. 107 11
      FreeAPS/Sources/Views/TagCloudView.swift

+ 47 - 2
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -915,6 +915,44 @@ extension Home {
             }
         }
 
+        private func parseReasonConclusion(_ reasonConclusion: String, isMmolL: Bool) -> String {
+            var updatedConclusion = reasonConclusion
+
+            // Handle "minGuardBG x<y" pattern
+            if let range = updatedConclusion.range(of: "minGuardBG\\s*-?\\d+<\\d+", options: .regularExpression) {
+                let matchedString = updatedConclusion[range]
+                let parts = matchedString.components(separatedBy: "<")
+
+                if let firstValue = Double(parts[0].components(separatedBy: CharacterSet.decimalDigits.inverted).joined()),
+                   let secondValue = Double(parts[1])
+                {
+                    let formattedFirstValue = isMmolL ? Double(firstValue.asMmolL) : firstValue
+                    let formattedSecondValue = isMmolL ? Double(secondValue.asMmolL) : secondValue
+
+                    let formattedString = "minGuardBG \(formattedFirstValue)<\(formattedSecondValue)"
+                    updatedConclusion = updatedConclusion.replacingOccurrences(of: matchedString, with: formattedString)
+                }
+            }
+
+            // Handle "Eventual BG x >= target" pattern
+            if let range = updatedConclusion.range(of: "Eventual BG\\s*\\d+\\s*>?=\\s*\\d+", options: .regularExpression) {
+                let matchedString = updatedConclusion[range]
+                let parts = matchedString.components(separatedBy: " >= ")
+
+                if let firstValue = Double(parts[0].components(separatedBy: CharacterSet.decimalDigits.inverted).joined()),
+                   let secondValue = Double(parts[1])
+                {
+                    let formattedFirstValue = isMmolL ? Double(firstValue.asMmolL) : firstValue
+                    let formattedSecondValue = isMmolL ? Double(secondValue.asMmolL) : secondValue
+
+                    let formattedString = "Eventual BG \(formattedFirstValue) >= \(formattedSecondValue)"
+                    updatedConclusion = updatedConclusion.replacingOccurrences(of: matchedString, with: formattedString)
+                }
+            }
+
+            return updatedConclusion.capitalizingFirstLetter()
+        }
+
         private var popup: some View {
             VStack(alignment: .leading, spacing: 4) {
                 Text(statusTitle).font(.headline).foregroundColor(.white)
@@ -924,9 +962,16 @@ extension Home {
                         Text("Invalid CGM reading (HIGH).").font(.callout).bold().foregroundColor(.loopRed).padding(.top, 8)
                         Text("SMBs and High Temps Disabled.").font(.caption).foregroundColor(.white).padding(.bottom, 4)
                     } else {
-                        TagCloudView(tags: determination.reasonParts).animation(.none, value: false)
+                        TagCloudView(tags: determination.reasonParts, shouldParseToMmolL: state.units == .mmolL)
+                            .animation(.none, value: false)
 
-                        Text(determination.reasonConclusion.capitalizingFirstLetter()).font(.caption).foregroundColor(.white)
+                        Text(
+                            self
+                                .parseReasonConclusion(
+                                    determination.reasonConclusion,
+                                    isMmolL: state.units == .mmolL
+                                )
+                        ).font(.caption).foregroundColor(.white)
                     }
                 } else {
                     Text("No determination found").font(.body).foregroundColor(.white)

+ 107 - 11
FreeAPS/Sources/Views/TagCloudView.swift

@@ -5,6 +5,7 @@ import Swinject
 
 struct TagCloudView: View {
     var tags: [String]
+    var shouldParseToMmolL: Bool
 
     @State private var totalHeight
 //          = CGFloat.zero       // << variant for ScrollView/List
@@ -25,7 +26,7 @@ struct TagCloudView: View {
 
         return ZStack(alignment: .topLeading) {
             ForEach(self.tags, id: \.self) { tag in
-                self.item(for: tag)
+                self.item(for: tag, isMmolL: shouldParseToMmolL)
                     .padding([.horizontal, .vertical], 2)
                     .alignmentGuide(.leading, computeValue: { d in
                         if abs(width - d.width) > g.size.width
@@ -52,7 +53,41 @@ struct TagCloudView: View {
         }.background(viewHeightReader($totalHeight))
     }
 
-    private func item(for textTag: String) -> some View {
+//    private func item(for textTag: String) -> some View {
+//        var colorOfTag: Color {
+//            switch textTag {
+//            case textTag where textTag.contains("SMB Delivery Ratio:"):
+//                return .uam
+//            case textTag where textTag.contains("Bolus"):
+//                return .green
+//            case textTag where textTag.contains("TDD:"),
+//                 textTag where textTag.contains("tdd_factor"),
+//                 textTag where textTag.contains("Sigmoid function"),
+//                 textTag where textTag.contains("Logarithmic formula"),
+//                 textTag where textTag.contains("AF:"),
+//                 textTag where textTag.contains("Autosens/Dynamic Limit:"),
+//                 textTag where textTag.contains("Dynamic ISF/CR"),
+//                 textTag where textTag.contains("Basal ratio"),
+//                 textTag where textTag.contains("SMB Ratio"):
+//                return .zt
+//            case textTag where textTag.contains("Middleware:"):
+//                return .red
+//            case textTag where textTag.contains("SMB Ratio"):
+//                return .orange
+//            default:
+//                return .insulin
+//            }
+//        }
+//
+//        return ZStack { Text(textTag)
+//            .padding(.vertical, 2)
+//            .padding(.horizontal, 4)
+//            .font(.subheadline)
+//            .background(colorOfTag.opacity(0.8))
+//            .foregroundColor(Color.white)
+//            .cornerRadius(2) }
+//    }
+    private func item(for textTag: String, isMmolL: Bool) -> some View {
         var colorOfTag: Color {
             switch textTag {
             case textTag where textTag.contains("SMB Delivery Ratio:"):
@@ -78,13 +113,71 @@ struct TagCloudView: View {
             }
         }
 
-        return ZStack { Text(textTag)
-            .padding(.vertical, 2)
-            .padding(.horizontal, 4)
-            .font(.subheadline)
-            .background(colorOfTag.opacity(0.8))
-            .foregroundColor(Color.white)
-            .cornerRadius(2) }
+        func formattedTextTag(for tag: String) -> String {
+            // List of glucose-related tags
+            let glucoseTags = ["ISF:", "Target:", "minPredBG", "minGuardBG", "IOBpredBG", "COBpredBG", "UAMpredBG", "Dev:"]
+
+            var updatedTag = tag
+
+            // Apply conversion if necessary
+            for glucoseTag in glucoseTags {
+                if glucoseTag == "ISF:" {
+                    // Handle the special ISF case with the arrow
+                    if let range = updatedTag.range(of: "\(glucoseTag)\\s*\\d+→\\d+", options: .regularExpression) {
+                        let glucoseValueString = updatedTag[range]
+                        let values = glucoseValueString.components(separatedBy: "→")
+
+                        if let firstValue = Double(
+                            values[0]
+                                .components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
+                        ),
+                            let secondValue = Double(
+                                values[1]
+                                    .components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
+                            )
+                        {
+                            let formattedFirstValue = isMmolL ? Double(firstValue.asMmolL) : firstValue
+                            let formattedSecondValue = isMmolL ? Double(secondValue.asMmolL) : secondValue
+
+                            let formattedGlucoseValueString =
+                                "\(glucoseTag) \(formattedFirstValue)→\(formattedSecondValue)"
+                            updatedTag = updatedTag.replacingOccurrences(
+                                of: glucoseValueString,
+                                with: formattedGlucoseValueString
+                            )
+                        }
+                    }
+                } else {
+                    // General case for other glucose tags
+                    if let range = updatedTag.range(of: "\(glucoseTag)\\s*\\d+", options: .regularExpression) {
+                        let glucoseValueString = updatedTag[range]
+                        if let glucoseValue = Double(
+                            glucoseValueString
+                                .components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
+                        ) {
+                            let formattedValue = isMmolL ? Double(glucoseValue.asMmolL) : glucoseValue
+                            updatedTag = updatedTag.replacingOccurrences(
+                                of: glucoseValueString,
+                                with: "\(glucoseTag) \(formattedValue)"
+                            )
+                        }
+                    }
+                }
+            }
+            return updatedTag
+        }
+
+        let formattedTextTag = formattedTextTag(for: textTag)
+
+        return ZStack {
+            Text(formattedTextTag)
+                .padding(.vertical, 2)
+                .padding(.horizontal, 4)
+                .font(.subheadline)
+                .background(colorOfTag.opacity(0.8))
+                .foregroundColor(Color.white)
+                .cornerRadius(2)
+        }
     }
 
     private func viewHeightReader(_ binding: Binding<CGFloat>) -> some View {
@@ -102,11 +195,14 @@ struct TestTagCloudView: View {
     var body: some View {
         VStack {
             Text("Header").font(.largeTitle)
-            TagCloudView(tags: ["Ninetendo", "XBox", "PlayStation", "PlayStation 2", "PlayStation 3", "PlayStation 4"])
+            TagCloudView(
+                tags: ["Ninetendo", "XBox", "PlayStation", "PlayStation 2", "PlayStation 3", "PlayStation 4"],
+                shouldParseToMmolL: false
+            )
             Text("Some other text")
             Divider()
             Text("Some other cloud")
-            TagCloudView(tags: ["Apple", "Google", "Amazon", "Microsoft", "Oracle", "Facebook"])
+            TagCloudView(tags: ["Apple", "Google", "Amazon", "Microsoft", "Oracle", "Facebook"], shouldParseToMmolL: false)
         }
     }
 }