Procházet zdrojové kódy

Refactoring: Fix clipping and improve state encapsulation
* Add missing commands for contentMargins, widgetUrl, and keylineTint
* Introduce enum for better type safety
* Move mode related attributes to to maintain state encapsulation

Co-Authored-By: 10nas <10nas@users.noreply.github.com>

Deniz Cengiz před 1 rokem
rodič
revize
567baf02ed

+ 20 - 9
FreeAPS/Sources/Services/LiveActivity/LiveActitiyAttributes.swift

@@ -2,7 +2,14 @@ import ActivityKit
 import Foundation
 import Foundation
 
 
 struct LiveActivityAttributes: ActivityAttributes {
 struct LiveActivityAttributes: ActivityAttributes {
-    public struct ContentState: Codable, Hashable {
+    enum ItemOrder: String, Hashable, Codable, Equatable {
+        case currentGlucose
+        case iob
+        case cob
+        case updatedLabel
+    }
+
+    struct ContentState: Codable, Hashable {
         let bg: String
         let bg: String
         let direction: String?
         let direction: String?
         let change: String
         let change: String
@@ -10,18 +17,11 @@ struct LiveActivityAttributes: ActivityAttributes {
 
 
         let detailedViewState: ContentAdditionalState?
         let detailedViewState: ContentAdditionalState?
 
 
-        let showCOB: Bool
-        let showIOB: Bool
-        let showCurrentGlucose: Bool
-        let showUpdatedLabel: Bool
-
-        let itemOrder: [String]
-
         /// true for the first state that is set on the activity
         /// true for the first state that is set on the activity
         let isInitialState: Bool
         let isInitialState: Bool
     }
     }
 
 
-    public struct ContentAdditionalState: Codable, Hashable {
+    struct ContentAdditionalState: Codable, Hashable {
         let chart: [Decimal]
         let chart: [Decimal]
         let chartDate: [Date?]
         let chartDate: [Date?]
         let rotationDegrees: Double
         let rotationDegrees: Double
@@ -36,7 +36,18 @@ struct LiveActivityAttributes: ActivityAttributes {
         let overrideDate: Date
         let overrideDate: Date
         let overrideDuration: Decimal
         let overrideDuration: Decimal
         let overrideTarget: Decimal
         let overrideTarget: Decimal
+
+        let itemOrder: [ItemOrder]
+
+        let showCOB: Bool
+        let showIOB: Bool
+        let showCurrentGlucose: Bool
+        let showUpdatedLabel: Bool
     }
     }
 
 
     let startDate: Date
     let startDate: Date
 }
 }
+
+extension LiveActivityAttributes.ItemOrder {
+    static let defaultOrders: [Self] = [.currentGlucose, .iob, .cob, .updatedLabel]
+}

+ 13 - 11
FreeAPS/Sources/Services/LiveActivity/LiveActivityAttributes+Helper.swift

@@ -5,8 +5,10 @@ extension UserDefaults {
         static let liveActivityOrder = "liveActivityOrder"
         static let liveActivityOrder = "liveActivityOrder"
     }
     }
 
 
-    func loadLiveActivityOrderFromUserDefaults() -> [String]? {
-        array(forKey: Keys.liveActivityOrder) as? [String]
+    func loadLiveActivityOrderFromUserDefaults() -> [LiveActivityAttributes.ItemOrder]? {
+        stringArray(forKey: Keys.liveActivityOrder)?.map({ str in
+            LiveActivityAttributes.ItemOrder(rawValue: str)
+        }) as? [LiveActivityAttributes.ItemOrder]
     }
     }
 }
 }
 
 
@@ -85,6 +87,9 @@ extension LiveActivityAttributes.ContentState {
         let trendString = bg.direction?.symbol as? String
         let trendString = bg.direction?.symbol as? String
         let change = Self.calculateChange(chart: chart, units: units)
         let change = Self.calculateChange(chart: chart, units: units)
 
 
+        let itemOrder = UserDefaults.standard
+            .loadLiveActivityOrderFromUserDefaults() ?? LiveActivityAttributes.ItemOrder.defaultOrders
+
         let detailedState: LiveActivityAttributes.ContentAdditionalState?
         let detailedState: LiveActivityAttributes.ContentAdditionalState?
 
 
         switch settings.lockScreenView {
         switch settings.lockScreenView {
@@ -107,27 +112,24 @@ extension LiveActivityAttributes.ContentState {
                 overrideName: override?.overrideName ?? "Override",
                 overrideName: override?.overrideName ?? "Override",
                 overrideDate: override?.date ?? Date(),
                 overrideDate: override?.date ?? Date(),
                 overrideDuration: override?.duration ?? 0,
                 overrideDuration: override?.duration ?? 0,
-                overrideTarget: override?.target ?? 0
+                overrideTarget: override?.target ?? 0,
+                itemOrder: itemOrder,
+                showCOB: settings.showCOB,
+                showIOB: settings.showIOB,
+                showCurrentGlucose: settings.showCurrentGlucose,
+                showUpdatedLabel: settings.showUpdatedLabel
             )
             )
 
 
         case .simple:
         case .simple:
             detailedState = nil
             detailedState = nil
         }
         }
 
 
-        let itemOrder = UserDefaults.standard
-            .loadLiveActivityOrderFromUserDefaults() ?? ["currentGlucose", "iob", "cob", "updatedLabel"]
-
         self.init(
         self.init(
             bg: formattedBG,
             bg: formattedBG,
             direction: trendString,
             direction: trendString,
             change: change,
             change: change,
             date: bg.date,
             date: bg.date,
             detailedViewState: detailedState,
             detailedViewState: detailedState,
-            showCOB: settings.showCOB,
-            showIOB: settings.showIOB,
-            showCurrentGlucose: settings.showCurrentGlucose,
-            showUpdatedLabel: settings.showUpdatedLabel,
-            itemOrder: itemOrder,
             isInitialState: false
             isInitialState: false
         )
         )
     }
     }

+ 0 - 5
FreeAPS/Sources/Services/LiveActivity/LiveActivityBridge.swift

@@ -232,11 +232,6 @@ import UIKit
                         change: "--",
                         change: "--",
                         date: Date.now,
                         date: Date.now,
                         detailedViewState: nil,
                         detailedViewState: nil,
-                        showCOB: true,
-                        showIOB: true,
-                        showCurrentGlucose: true,
-                        showUpdatedLabel: true,
-                        itemOrder: ["currentGlucose", "iob", "cob", "updatedLabel"],
                         isInitialState: true
                         isInitialState: true
                     ),
                     ),
                     staleDate: Date.now.addingTimeInterval(60)
                     staleDate: Date.now.addingTimeInterval(60)

+ 107 - 50
LiveActivity/LiveActivity.swift

@@ -85,8 +85,13 @@ struct LiveActivity: Widget {
             } compactTrailing: {
             } compactTrailing: {
                 LiveActivityCompactTrailingView(context: context)
                 LiveActivityCompactTrailingView(context: context)
             } minimal: {
             } minimal: {
-                LiveActivityMinimalView(context: context).font(.system(size: 11))
+                LiveActivityMinimalView(context: context)
             }
             }
+            .widgetURL(URL(string: "Trio://"))
+            .keylineTint(Color.purple)
+            .contentMargins(.horizontal, 0, for: .minimal)
+            .contentMargins(.trailing, 0, for: .compactLeading)
+            .contentMargins(.leading, 0, for: .compactTrailing)
         }
         }
     }
     }
 }
 }
@@ -118,10 +123,10 @@ struct LiveActivityView: View {
                     }
                     }
 
 
                 HStack {
                 HStack {
-                    ForEach(Array(context.state.itemOrder.enumerated()), id: \.element) { index, item in
+                    ForEach(Array(detailedViewState.itemOrder.enumerated()), id: \.element) { index, item in
                         switch item {
                         switch item {
-                        case "currentGlucose":
-                            if context.state.showCurrentGlucose {
+                        case .currentGlucose:
+                            if detailedViewState.showCurrentGlucose {
                                 VStack {
                                 VStack {
                                     LiveActivityBGLabelView(context: context, additionalState: detailedViewState)
                                     LiveActivityBGLabelView(context: context, additionalState: detailedViewState)
                                     HStack {
                                     HStack {
@@ -132,23 +137,21 @@ struct LiveActivityView: View {
                                     }
                                     }
                                 }
                                 }
                             }
                             }
-                        case "iob":
-                            if context.state.showIOB {
+                        case .iob:
+                            if detailedViewState.showIOB {
                                 LiveActivityIOBLabelView(context: context, additionalState: detailedViewState)
                                 LiveActivityIOBLabelView(context: context, additionalState: detailedViewState)
                             }
                             }
-                        case "cob":
-                            if context.state.showCOB {
+                        case .cob:
+                            if detailedViewState.showCOB {
                                 LiveActivityCOBLabelView(context: context, additionalState: detailedViewState)
                                 LiveActivityCOBLabelView(context: context, additionalState: detailedViewState)
                             }
                             }
-                        case "updatedLabel":
-                            if context.state.showUpdatedLabel {
+                        case .updatedLabel:
+                            if detailedViewState.showUpdatedLabel {
                                 LiveActivityUpdatedLabelView(context: context, isDetailedLayout: true)
                                 LiveActivityUpdatedLabelView(context: context, isDetailedLayout: true)
                             }
                             }
-                        default:
-                            EmptyView()
                         }
                         }
 
 
-                        if index < context.state.itemOrder.count - 1 {
+                        if index < detailedViewState.itemOrder.count - 1 {
                             Divider().foregroundStyle(.primary).fontWeight(.bold).frame(width: 10)
                             Divider().foregroundStyle(.primary).fontWeight(.bold).frame(width: 10)
                         }
                         }
                     }
                     }
@@ -572,7 +575,12 @@ private extension LiveActivityAttributes.ContentState {
         overrideName: "Exercise",
         overrideName: "Exercise",
         overrideDate: Date().addingTimeInterval(-3600),
         overrideDate: Date().addingTimeInterval(-3600),
         overrideDuration: 120,
         overrideDuration: 120,
-        overrideTarget: 150
+        overrideTarget: 150,
+        itemOrder: LiveActivityAttributes.ItemOrder.defaultOrders,
+        showCOB: true,
+        showIOB: true,
+        showCurrentGlucose: true,
+        showUpdatedLabel: true
     )
     )
 
 
     // 0 is the widest digit. Use this to get an upper bound on text width.
     // 0 is the widest digit. Use this to get an upper bound on text width.
@@ -584,12 +592,7 @@ private extension LiveActivityAttributes.ContentState {
             direction: "→",
             direction: "→",
             change: "+0.0",
             change: "+0.0",
             date: Date(),
             date: Date(),
-            detailedViewState: detailedViewState,
-            showCOB: true,
-            showIOB: true,
-            showCurrentGlucose: true,
-            showUpdatedLabel: true,
-            itemOrder: ["currentGlucose", "iob", "cob", "updatedLabel"],
+            detailedViewState: nil,
             isInitialState: false
             isInitialState: false
         )
         )
     }
     }
@@ -600,12 +603,7 @@ private extension LiveActivityAttributes.ContentState {
             direction: "↑↑",
             direction: "↑↑",
             change: "+0.0",
             change: "+0.0",
             date: Date(),
             date: Date(),
-            detailedViewState: detailedViewState,
-            showCOB: true,
-            showIOB: true,
-            showCurrentGlucose: true,
-            showUpdatedLabel: true,
-            itemOrder: ["currentGlucose", "iob", "cob", "updatedLabel"],
+            detailedViewState: nil,
             isInitialState: false
             isInitialState: false
         )
         )
     }
     }
@@ -616,12 +614,7 @@ private extension LiveActivityAttributes.ContentState {
             direction: "↑↑↑",
             direction: "↑↑↑",
             change: "+0.0",
             change: "+0.0",
             date: Date(),
             date: Date(),
-            detailedViewState: detailedViewState,
-            showCOB: true,
-            showIOB: true,
-            showCurrentGlucose: true,
-            showUpdatedLabel: true,
-            itemOrder: ["currentGlucose", "iob", "cob", "updatedLabel"],
+            detailedViewState: nil,
             isInitialState: false
             isInitialState: false
         )
         )
     }
     }
@@ -633,12 +626,7 @@ private extension LiveActivityAttributes.ContentState {
             direction: "↑",
             direction: "↑",
             change: "+0",
             change: "+0",
             date: Date(),
             date: Date(),
-            detailedViewState: detailedViewState,
-            showCOB: true,
-            showIOB: true,
-            showCurrentGlucose: true,
-            showUpdatedLabel: true,
-            itemOrder: ["currentGlucose", "iob", "cob", "updatedLabel"],
+            detailedViewState: nil,
             isInitialState: false
             isInitialState: false
         )
         )
     }
     }
@@ -649,12 +637,7 @@ private extension LiveActivityAttributes.ContentState {
             direction: "↗︎",
             direction: "↗︎",
             change: "+00",
             change: "+00",
             date: Date(),
             date: Date(),
-            detailedViewState: detailedViewState,
-            showCOB: true,
-            showIOB: true,
-            showCurrentGlucose: true,
-            showUpdatedLabel: true,
-            itemOrder: ["currentGlucose", "iob", "cob", "updatedLabel"],
+            detailedViewState: nil,
             isInitialState: false
             isInitialState: false
         )
         )
     }
     }
@@ -665,19 +648,81 @@ private extension LiveActivityAttributes.ContentState {
             direction: nil,
             direction: nil,
             change: "--",
             change: "--",
             date: Date().addingTimeInterval(-60 * 60),
             date: Date().addingTimeInterval(-60 * 60),
+            detailedViewState: nil,
+            isInitialState: false
+        )
+    }
+
+    static var testWideDetailed: LiveActivityAttributes.ContentState {
+        LiveActivityAttributes.ContentState(
+            bg: "00.0",
+            direction: "→",
+            change: "+0.0",
+            date: Date(),
+            detailedViewState: detailedViewState,
+            isInitialState: false
+        )
+    }
+
+    static var testVeryWideDetailed: LiveActivityAttributes.ContentState {
+        LiveActivityAttributes.ContentState(
+            bg: "00.0",
+            direction: "↑↑",
+            change: "+0.0",
+            date: Date(),
+            detailedViewState: detailedViewState,
+            isInitialState: false
+        )
+    }
+
+    static var testSuperWideDetailed: LiveActivityAttributes.ContentState {
+        LiveActivityAttributes.ContentState(
+            bg: "00.0",
+            direction: "↑↑↑",
+            change: "+0.0",
+            date: Date(),
+            detailedViewState: detailedViewState,
+            isInitialState: false
+        )
+    }
+
+    // 2 characters for BG, 1 character for change is the minimum that will be shown
+    static var testNarrowDetailed: LiveActivityAttributes.ContentState {
+        LiveActivityAttributes.ContentState(
+            bg: "00",
+            direction: "↑",
+            change: "+0",
+            date: Date(),
+            detailedViewState: detailedViewState,
+            isInitialState: false
+        )
+    }
+
+    static var testMediumDetailed: LiveActivityAttributes.ContentState {
+        LiveActivityAttributes.ContentState(
+            bg: "000",
+            direction: "↗︎",
+            change: "+00",
+            date: Date(),
+            detailedViewState: detailedViewState,
+            isInitialState: false
+        )
+    }
+
+    static var testExpiredDetailed: LiveActivityAttributes.ContentState {
+        LiveActivityAttributes.ContentState(
+            bg: "--",
+            direction: nil,
+            change: "--",
+            date: Date().addingTimeInterval(-60 * 60),
             detailedViewState: detailedViewState,
             detailedViewState: detailedViewState,
-            showCOB: true,
-            showIOB: true,
-            showCurrentGlucose: true,
-            showUpdatedLabel: true,
-            itemOrder: ["currentGlucose", "iob", "cob", "updatedLabel"],
             isInitialState: false
             isInitialState: false
         )
         )
     }
     }
 }
 }
 
 
 @available(iOS 17.0, iOSApplicationExtension 17.0, *)
 @available(iOS 17.0, iOSApplicationExtension 17.0, *)
-#Preview("Notification", as: .content, using: LiveActivityAttributes.preview) {
+#Preview("Simple", as: .content, using: LiveActivityAttributes.preview) {
     LiveActivity()
     LiveActivity()
 } contentStates: {
 } contentStates: {
     LiveActivityAttributes.ContentState.testSuperWide
     LiveActivityAttributes.ContentState.testSuperWide
@@ -687,3 +732,15 @@ private extension LiveActivityAttributes.ContentState {
     LiveActivityAttributes.ContentState.testNarrow
     LiveActivityAttributes.ContentState.testNarrow
     LiveActivityAttributes.ContentState.testExpired
     LiveActivityAttributes.ContentState.testExpired
 }
 }
+
+@available(iOS 17.0, iOSApplicationExtension 17.0, *)
+#Preview("Detailed", as: .content, using: LiveActivityAttributes.preview) {
+    LiveActivity()
+} contentStates: {
+    LiveActivityAttributes.ContentState.testSuperWideDetailed
+    LiveActivityAttributes.ContentState.testVeryWideDetailed
+    LiveActivityAttributes.ContentState.testWideDetailed
+    LiveActivityAttributes.ContentState.testMediumDetailed
+    LiveActivityAttributes.ContentState.testNarrowDetailed
+    LiveActivityAttributes.ContentState.testExpiredDetailed
+}

+ 55 - 1
Trio.xcworkspace/xcshareddata/swiftpm/Package.resolved

@@ -1,5 +1,5 @@
 {
 {
-  "originHash" : "cef813f4bbb01679d4ac9bf4a9f82c1a0a61e44dc839643e81aa92e4d00642bc",
+  "originHash" : "f5c836c216c4ca7d356e3777e58d6d4f9502b03f3974891349eb775f4c4cf750",
   "pins" : [
   "pins" : [
     {
     {
       "identity" : "cryptoswift",
       "identity" : "cryptoswift",
@@ -11,6 +11,15 @@
       }
       }
     },
     },
     {
     {
+      "identity" : "mkringprogressview",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/maxkonovalov/MKRingProgressView.git",
+      "state" : {
+        "branch" : "master",
+        "revision" : "660888aab1d2ab0ed7eb9eb53caec12af4955fa7"
+      }
+    },
+    {
       "identity" : "slidebutton",
       "identity" : "slidebutton",
       "kind" : "remoteSourceControl",
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/no-comment/SlideButton",
       "location" : "https://github.com/no-comment/SlideButton",
@@ -20,6 +29,24 @@
       }
       }
     },
     },
     {
     {
+      "identity" : "swift-algorithms",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-algorithms",
+      "state" : {
+        "revision" : "2327673b0e9c7e90e6b1826376526ec3627210e4",
+        "version" : "0.2.1"
+      }
+    },
+    {
+      "identity" : "swift-numerics",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-numerics",
+      "state" : {
+        "revision" : "6583ac70c326c3ee080c1d42d9ca3361dca816cd",
+        "version" : "0.1.0"
+      }
+    },
+    {
       "identity" : "swiftcharts",
       "identity" : "swiftcharts",
       "kind" : "remoteSourceControl",
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/ivanschuetz/SwiftCharts",
       "location" : "https://github.com/ivanschuetz/SwiftCharts",
@@ -29,6 +56,33 @@
       }
       }
     },
     },
     {
     {
+      "identity" : "swiftdate",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/malcommac/SwiftDate",
+      "state" : {
+        "revision" : "6190d0cefff3013e77ed567e6b074f324e5c5bf5",
+        "version" : "6.3.1"
+      }
+    },
+    {
+      "identity" : "swiftmessages",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/SwiftKickMobile/SwiftMessages",
+      "state" : {
+        "revision" : "62e12e138fc3eedf88c7553dd5d98712aa119f40",
+        "version" : "9.0.9"
+      }
+    },
+    {
+      "identity" : "swinject",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/Swinject/Swinject",
+      "state" : {
+        "revision" : "be9dbcc7b86811bc131539a20c6f9c2d3e56919f",
+        "version" : "2.9.1"
+      }
+    },
+    {
       "identity" : "tidepoolkit",
       "identity" : "tidepoolkit",
       "kind" : "remoteSourceControl",
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/tidepool-org/TidepoolKit",
       "location" : "https://github.com/tidepool-org/TidepoolKit",