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

Fix therapy rate hour parsing; fix color

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

+ 5 - 0
Trio.xcodeproj/project.pbxproj

@@ -524,6 +524,7 @@
 		DDAA29852D2D1D9E006546A1 /* AdjustmentsRootView+TempTargets.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAA29842D2D1D98006546A1 /* AdjustmentsRootView+TempTargets.swift */; };
 		DDB37CC52D05048F00D99BF4 /* ContactImageStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB37CC42D05048F00D99BF4 /* ContactImageStorage.swift */; };
 		DDB37CC72D05127500D99BF4 /* FontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB37CC62D05127500D99BF4 /* FontExtensions.swift */; };
+		DDCAE8332D78D4A800B1BB51 /* TherapySettingsUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCAE8322D78D49C00B1BB51 /* TherapySettingsUtil.swift */; };
 		DDCE790F2D6F97FC000A4D7A /* SubmodulesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE790E2D6F97F7000A4D7A /* SubmodulesView.swift */; };
 		DDCEBF5B2CC1B76400DF4C36 /* LiveActivity+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCEBF5A2CC1B76400DF4C36 /* LiveActivity+Helper.swift */; };
 		DDD163122C4C689900CD525A /* AdjustmentsStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD163112C4C689900CD525A /* AdjustmentsStateModel.swift */; };
@@ -1235,6 +1236,7 @@
 		DDB37CC32D05044D00D99BF4 /* ContactTrickEntryStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ContactTrickEntryStored+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDB37CC42D05048F00D99BF4 /* ContactImageStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactImageStorage.swift; sourceTree = "<group>"; };
 		DDB37CC62D05127500D99BF4 /* FontExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontExtensions.swift; sourceTree = "<group>"; };
+		DDCAE8322D78D49C00B1BB51 /* TherapySettingsUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TherapySettingsUtil.swift; sourceTree = "<group>"; };
 		DDCE790E2D6F97F7000A4D7A /* SubmodulesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubmodulesView.swift; sourceTree = "<group>"; };
 		DDCEBF5A2CC1B76400DF4C36 /* LiveActivity+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LiveActivity+Helper.swift"; sourceTree = "<group>"; };
 		DDD163112C4C689900CD525A /* AdjustmentsStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdjustmentsStateModel.swift; sourceTree = "<group>"; };
@@ -2121,6 +2123,8 @@
 		388E5A5A25B6F05F0019842D /* Helpers */ = {
 			isa = PBXGroup;
 			children = (
+				DDCAE8322D78D49C00B1BB51 /* TherapySettingsUtil.swift */,
+				DD73FA0E2D74F57300D19D1E /* BackgroundTask+Helper.swift */,
 				CEF1ED6A2D58FB4600FAF41E /* CGMOptions.swift */,
 				C2A0A42E2CE0312C003B98E8 /* ConstantValues.swift */,
 				DD940BAB2CA75889000830A5 /* DynamicGlucoseColor.swift */,
@@ -3893,6 +3897,7 @@
 				DD9ECB712CA9A0BA00AA7C45 /* RemoteControlConfigProvider.swift in Sources */,
 				63E890B4D951EAA91C071D5C /* BasalProfileEditorStateModel.swift in Sources */,
 				38FEF3FA2737E42000574A46 /* BaseStateModel.swift in Sources */,
+				DDCAE8332D78D4A800B1BB51 /* TherapySettingsUtil.swift in Sources */,
 				BDA25EFD2D261C0000035F34 /* WatchState.swift in Sources */,
 				CC6C406E2ACDD69E009B8058 /* RawFetchedProfile.swift in Sources */,
 				385CEA8225F23DFD002D6D5B /* NightscoutStatus.swift in Sources */,

+ 22 - 0
Trio/Sources/Helpers/TherapySettingsUtil.swift

@@ -0,0 +1,22 @@
+import Foundation
+
+enum TherapySettingsUtil {
+    
+    /// Parses a time string of therapy setting entry into a `Date` object using either "HH:mm:ss" or "HH:mm" formats.
+    /// This function ensures compatibility with time strings that may include or exclude seconds.
+    ///
+    /// - Parameter timeString: A string representing the time in "HH:mm:ss" or "HH:mm" format.
+    /// - Returns: A `Date` object set to today’s date with the extracted time, or `nil` if parsing fails.
+    static func parseTime(_ timeString: String) -> Date? {
+        let formats = ["HH:mm:ss", "HH:mm"]
+        for format in formats {
+            let formatter = DateFormatter()
+            formatter.dateFormat = format
+            formatter.timeZone = TimeZone.current
+            if let date = formatter.date(from: timeString) {
+                return date
+            }
+        }
+        return nil
+    }
+}

+ 3 - 6
Trio/Sources/Modules/Home/HomeStateModel.swift

@@ -600,15 +600,12 @@ extension Home {
         private func getCurrentGlucoseTarget() async {
             let now = Date()
             let calendar = Calendar.current
-            let dateFormatter = DateFormatter()
-            dateFormatter.dateFormat = "HH:mm"
-            dateFormatter.timeZone = TimeZone.current
 
             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)")
+                guard let entryTime = TherapySettingsUtil.parseTime(entry.start) else {
+                    debug(.default, "Invalid entry start time: \(entry.start)")
                     continue
                 }
 
@@ -622,7 +619,7 @@ extension Home {
 
                 let entryEndTime: Date
                 if index < entries.count - 1,
-                   let nextEntryTime = dateFormatter.date(from: entries[index + 1].start)
+                   let nextEntryTime = TherapySettingsUtil.parseTime(entries[index + 1].start)
                 {
                     let nextEntryComponents = calendar.dateComponents([.hour, .minute, .second], from: nextEntryTime)
                     entryEndTime = calendar.date(

+ 3 - 22
Trio/Sources/Modules/Treatments/TreatmentsStateModel.swift

@@ -286,11 +286,6 @@ extension Treatments {
         private func getCurrentSettingValue(for type: SettingType) async {
             let now = Date()
             let calendar = Calendar.current
-            let dateFormatter = DateFormatter()
-            dateFormatter.timeZone = TimeZone.current
-
-            let regexWithSeconds = #"^\d{2}:\d{2}:\d{2}$"#
-
             let entries: [(start: String, value: Decimal)]
 
             switch type {
@@ -309,15 +304,8 @@ extension Treatments {
             }
 
             for (index, entry) in entries.enumerated() {
-                // Dynamically set the format based on whether it matches the regex
-                if entry.start.range(of: regexWithSeconds, options: .regularExpression) != nil {
-                    dateFormatter.dateFormat = "HH:mm:ss"
-                } else {
-                    dateFormatter.dateFormat = "HH:mm"
-                }
-
-                guard let entryTime = dateFormatter.date(from: entry.start) else {
-                    print("Invalid entry start time: \(entry.start)")
+                guard let entryTime = TherapySettingsUtil.parseTime(entry.start) else {
+                    debug(.default, "Invalid entry start time: \(entry.start)")
                     continue
                 }
 
@@ -331,14 +319,7 @@ extension Treatments {
 
                 let entryEndTime: Date
                 if index < entries.count - 1 {
-                    // Dynamically set the format again for the next element
-                    if entries[index + 1].start.range(of: regexWithSeconds, options: .regularExpression) != nil {
-                        dateFormatter.dateFormat = "HH:mm:ss"
-                    } else {
-                        dateFormatter.dateFormat = "HH:mm"
-                    }
-
-                    if let nextEntryTime = dateFormatter.date(from: entries[index + 1].start) {
+                    if let nextEntryTime = TherapySettingsUtil.parseTime(entries[index + 1].start) {
                         let nextEntryComponents = calendar.dateComponents([.hour, .minute, .second], from: nextEntryTime)
                         entryEndTime = calendar.date(
                             bySettingHour: nextEntryComponents.hour!,

+ 5 - 24
Trio/Sources/Services/BolusCalculator/BolusCalculationManager.swift

@@ -71,11 +71,6 @@ final class BaseBolusCalculationManager: BolusCalculationManager, Injectable {
     private func getCurrentSettingValue(for type: SettingType) async -> Decimal {
         let now = Date()
         let calendar = Calendar.current
-        let dateFormatter = DateFormatter()
-        dateFormatter.timeZone = TimeZone.current
-
-        let regexWithSeconds = #"^\d{2}:\d{2}:\d{2}$"#
-
         let entries: [(start: String, value: Decimal)]
 
         switch type {
@@ -94,17 +89,10 @@ final class BaseBolusCalculationManager: BolusCalculationManager, Injectable {
         }
 
         for (index, entry) in entries.enumerated() {
-            // Dynamically set the format based on whether it matches the regex
-            if entry.start.range(of: regexWithSeconds, options: .regularExpression) != nil {
-                dateFormatter.dateFormat = "HH:mm:ss"
-            } else {
-                dateFormatter.dateFormat = "HH:mm"
-            }
-
-            guard let entryTime = dateFormatter.date(from: entry.start) else {
-                print("Invalid entry start time: \(entry.start)")
-                continue
-            }
+            guard let entryTime = TherapySettingsUtil.parseTime(entry.start) else {
+                                debug(.default, "Invalid entry start time: \(entry.start)")
+                                continue
+                            }
 
             let entryComponents = calendar.dateComponents([.hour, .minute, .second], from: entryTime)
             let entryStartTime = calendar.date(
@@ -116,14 +104,7 @@ final class BaseBolusCalculationManager: BolusCalculationManager, Injectable {
 
             let entryEndTime: Date
             if index < entries.count - 1 {
-                // Dynamically set the format again for the next element
-                if entries[index + 1].start.range(of: regexWithSeconds, options: .regularExpression) != nil {
-                    dateFormatter.dateFormat = "HH:mm:ss"
-                } else {
-                    dateFormatter.dateFormat = "HH:mm"
-                }
-
-                if let nextEntryTime = dateFormatter.date(from: entries[index + 1].start) {
+                if let nextEntryTime = TherapySettingsUtil.parseTime(entries[index + 1].start) {
                     let nextEntryComponents = calendar.dateComponents([.hour, .minute, .second], from: nextEntryTime)
                     entryEndTime = calendar.date(
                         bySettingHour: nextEntryComponents.hour!,

+ 9 - 14
Trio/Sources/Services/ContactImage/ContactImageManager.swift

@@ -129,33 +129,29 @@ final class BaseContactImageManager: NSObject, ContactImageManager, 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) }
+        let entries: [(start: String, value: Decimal)] = bgTargets.targets
+            .map { ($0.start.trimmingCharacters(in: .whitespacesAndNewlines), $0.low) }
 
         for (index, entry) in entries.enumerated() {
-            guard let entryTime = dateFormatter.date(from: entry.start) else {
-                print("Invalid entry start time: \(entry.start)")
+            guard let entryTime = TherapySettingsUtil.parseTime(entry.start) else {
+                debug(.default, "Invalid entry start time: \(entry.start)")
                 continue
             }
 
             let entryComponents = calendar.dateComponents([.hour, .minute, .second], from: entryTime)
-            let entryStartTime = calendar.date(
+            guard let entryStartTime = calendar.date(
                 bySettingHour: entryComponents.hour!,
                 minute: entryComponents.minute!,
                 second: entryComponents.second!,
                 of: now
-            )!
+            ) else { continue }
 
             let entryEndTime: Date
-            if index < entries.count - 1,
-               let nextEntryTime = dateFormatter.date(from: entries[index + 1].start)
-            {
+            if index < entries.count - 1, let nextEntryTime = TherapySettingsUtil.parseTime(entries[index + 1].start) {
                 let nextEntryComponents = calendar.dateComponents([.hour, .minute, .second], from: nextEntryTime)
                 entryEndTime = calendar.date(
                     bySettingHour: nextEntryComponents.hour!,
@@ -239,12 +235,11 @@ final class BaseContactImageManager: NSObject, ContactImageManager, Injectable {
             let isDynamicColorScheme = settingsManager.settings.glucoseColorScheme == .dynamicColor
             let highGlucoseColorValue = isDynamicColorScheme ? hardCodedHigh : settingsManager.settings.highGlucose
             let lowGlucoseColorValue = isDynamicColorScheme ? hardCodedLow : settingsManager.settings.lowGlucose
+            let fetchedTarget = await getCurrentGlucoseTarget() // ⚠️ this value is mg/dL
 
             state.highGlucoseColorValue = units == .mgdL ? highGlucoseColorValue : highGlucoseColorValue.asMmolL
             state.lowGlucoseColorValue = units == .mgdL ? lowGlucoseColorValue : lowGlucoseColorValue.asMmolL
-            state
-                .targetGlucose = await getCurrentGlucoseTarget() ??
-                (settingsManager.settings.units == .mgdL ? Decimal(100) : 100.asMmolL)
+            state.targetGlucose = units == .mgdL ? fetchedTarget ?? Decimal(100) : fetchedTarget?.asMmolL ?? 100.asMmolL
             state.glucoseColorScheme = settingsManager.settings.glucoseColorScheme
 
             // Notify delegate about state update on main thread

+ 5 - 9
Trio/Sources/Services/Network/TidepoolManager.swift

@@ -540,9 +540,6 @@ extension BaseTidepoolManager {
     private func getCurrentBasalRate() -> BasalProfileEntry? {
         let now = Date()
         let calendar = Calendar.current
-        let dateFormatter = DateFormatter()
-        dateFormatter.dateFormat = "HH:mm"
-        dateFormatter.timeZone = TimeZone.current
 
         let basalEntries = storage.retrieve(OpenAPS.Settings.basalProfile, as: [BasalProfileEntry].self)
             ?? [BasalProfileEntry](from: OpenAPS.defaults(for: OpenAPS.Settings.basalProfile))
@@ -551,10 +548,10 @@ extension BaseTidepoolManager {
         var currentRate: BasalProfileEntry = basalEntries[0]
 
         for (index, entry) in basalEntries.enumerated() {
-            guard let entryTime = dateFormatter.date(from: entry.start) else {
-                print("Invalid entry start time: \(entry.start)")
-                continue
-            }
+            guard let entryTime = TherapySettingsUtil.parseTime(entry.start) else {
+                                debug(.default, "Invalid entry start time: \(entry.start)")
+                                continue
+                            }
 
             let entryComponents = calendar.dateComponents([.hour, .minute, .second], from: entryTime)
             let entryStartTime = calendar.date(
@@ -566,8 +563,7 @@ extension BaseTidepoolManager {
 
             let entryEndTime: Date
             if index < basalEntries.count - 1,
-               let nextEntryTime = dateFormatter.date(from: basalEntries[index + 1].start)
-            {
+               let nextEntryTime = TherapySettingsUtil.parseTime(basalEntries[index + 1].start) {
                 let nextEntryComponents = calendar.dateComponents([.hour, .minute, .second], from: nextEntryTime)
                 entryEndTime = calendar.date(
                     bySettingHour: nextEntryComponents.hour!,

+ 6 - 9
Trio/Sources/Services/WatchManager/AppleWatchManager.swift

@@ -1043,9 +1043,6 @@ extension BaseWatchManager {
     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))
@@ -1053,22 +1050,22 @@ extension BaseWatchManager {
         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
-            }
+            guard let entryTime = TherapySettingsUtil.parseTime(entry.start) else {
+                                debug(.default, "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!,
+                second: entryComponents.secgiond!,
                 of: now
             )!
 
             let entryEndTime: Date
             if index < entries.count - 1,
-               let nextEntryTime = dateFormatter.date(from: entries[index + 1].start)
+               let nextEntryTime = TherapySettingsUtil.parseTime(entries[index + 1].start)
             {
                 let nextEntryComponents = calendar.dateComponents([.hour, .minute, .second], from: nextEntryTime)
                 entryEndTime = calendar.date(