Browse Source

add glucose bobble to lockscreen

polscm32 2 năm trước cách đây
mục cha
commit
7c03637c2e

+ 6 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -309,6 +309,8 @@
 		B9CAAEFC2AE70836000F68BC /* branch.txt in Resources */ = {isa = PBXBuildFile; fileRef = B9CAAEFB2AE70836000F68BC /* branch.txt */; };
 		BA00D96F7B2FF169A06FB530 /* CGMStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C018D1680307A31C9ED7120 /* CGMStateModel.swift */; };
 		BA90041DC8991147E5C8C3AA /* CalibrationsRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500371C09F54F89A97D65FDB /* CalibrationsRootView.swift */; };
+		BD188BEC2B1B805B00B183BF /* WidgetBobble.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD188BEB2B1B805A00B183BF /* WidgetBobble.swift */; };
+		BD188BED2B1B805B00B183BF /* WidgetBobble.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD188BEB2B1B805A00B183BF /* WidgetBobble.swift */; };
 		BD2B464E0745FBE7B79913F4 /* NightscoutConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF768BD6264FF7D71D66767 /* NightscoutConfigProvider.swift */; };
 		BF1667ADE69E4B5B111CECAE /* ManualTempBasalProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680C4420C9A345D46D90D06C /* ManualTempBasalProvider.swift */; };
 		C967DACD3B1E638F8B43BE06 /* ManualTempBasalStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFCFE0781F9074C2917890E8 /* ManualTempBasalStateModel.swift */; };
@@ -858,6 +860,7 @@
 		B9CAAEFB2AE70836000F68BC /* branch.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = branch.txt; sourceTree = SOURCE_ROOT; };
 		BA49538D56989D8DA6FCF538 /* TargetsEditorDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetsEditorDataFlow.swift; sourceTree = "<group>"; };
 		BC210C0F3CB6D3C86E5DED4E /* LibreConfigRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LibreConfigRootView.swift; sourceTree = "<group>"; };
+		BD188BEB2B1B805A00B183BF /* WidgetBobble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBobble.swift; sourceTree = "<group>"; };
 		BF8BCB0C37DEB5EC377B9612 /* BasalProfileEditorRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BasalProfileEditorRootView.swift; sourceTree = "<group>"; };
 		C19984D62EFC0035A9E9644D /* BolusProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BolusProvider.swift; sourceTree = "<group>"; };
 		C377490C77661D75E8C50649 /* ManualTempBasalRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ManualTempBasalRootView.swift; sourceTree = "<group>"; };
@@ -2013,6 +2016,7 @@
 			children = (
 				6B1A8D1D2B14D91600E76752 /* LiveActivityBundle.swift */,
 				6B1A8D1F2B14D91600E76752 /* LiveActivity.swift */,
+				BD188BEB2B1B805A00B183BF /* WidgetBobble.swift */,
 				6B1A8D232B14D91700E76752 /* Assets.xcassets */,
 				6B1A8D252B14D91700E76752 /* Info.plist */,
 			);
@@ -2808,6 +2812,7 @@
 				38FEF3FA2737E42000574A46 /* BaseStateModel.swift in Sources */,
 				CC6C406E2ACDD69E009B8058 /* RawFetchedProfile.swift in Sources */,
 				385CEA8225F23DFD002D6D5B /* NightscoutStatus.swift in Sources */,
+				BD188BEC2B1B805B00B183BF /* WidgetBobble.swift in Sources */,
 				F90692AA274B7AAE0037068D /* HealthKitManager.swift in Sources */,
 				38887CCE25F5725200944304 /* IOBEntry.swift in Sources */,
 				38E98A2425F52C9300C0CED0 /* Logger.swift in Sources */,
@@ -2957,6 +2962,7 @@
 				6BCF84DE2B16843A003AD46E /* LiveActitiyShared.swift in Sources */,
 				6B1A8D1E2B14D91600E76752 /* LiveActivityBundle.swift in Sources */,
 				6B1A8D202B14D91600E76752 /* LiveActivity.swift in Sources */,
+				BD188BED2B1B805B00B183BF /* WidgetBobble.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 10 - 6
LiveActivity/LiveActivity.swift

@@ -27,7 +27,7 @@ struct LiveActivity: Widget {
         if context.isStale {
             Text("--")
         } else {
-            Text(context.state.bg)
+            Text(context.state.bg).fontWeight(.bold)
         }
     }
 
@@ -84,17 +84,21 @@ struct LiveActivity: Widget {
             HStack(spacing: 2) {
                 VStack {
                     chart(context: context).frame(width: UIScreen.main.bounds.width / 1.7)
-                }.padding()
+                }
                 Divider()
                 VStack {
                     ZStack {
-                        Circle().fill(Color.green.opacity(0.7))
-                            .frame(width: UIScreen.main.bounds.width / 5, height: UIScreen.main.bounds.height / 5).clipped()
+//                        Circle().fill(Color.green.opacity(0.7))
+//                            .frame(width: UIScreen.main.bounds.width / 5, height: UIScreen.main.bounds.height / 5).clipped()
+                        WidgetBobble()
+                            .scaleEffect(0.6)
+                            .clipped()
                         VStack {
-                            bgAndTrend(context: context).imageScale(.small).font(.title2)
+//                            bgAndTrend(context: context).imageScale(.small).font(.title2)
+                            bgLabel(context: context).font(.title2).imageScale(.small)
                             changeLabel(context: context).font(.callout)
                         }
-                    }.padding()
+                    }
                     updatedLabel(context: context).font(.caption)
                 }
             }

+ 125 - 0
LiveActivity/WidgetBobble.swift

@@ -0,0 +1,125 @@
+import SwiftUI
+
+struct WidgetBobble: View {
+    @State private var rotationDegrees: Double = 0.0
+    @State private var angularGradient = AngularGradient(colors: [
+        // 184, 87, 255
+        // 159, 108, 250
+        // 124, 139, 243
+        // 87, 170, 236
+        // 67, 187, 233
+        Color(red: 0.7215686275, green: 0.3411764706, blue: 1),
+        Color(red: 0.6235294118, green: 0.4235294118, blue: 0.9803921569),
+        Color(red: 0.4862745098, green: 0.5450980392, blue: 0.9529411765),
+        Color(red: 0.3411764706, green: 0.6666666667, blue: 0.9254901961),
+        Color(red: 0.262745098, green: 0.7333333333, blue: 0.9137254902),
+        Color(red: 0.7215686275, green: 0.3411764706, blue: 1)
+    ], center: .center, startAngle: .degrees(270), endAngle: .degrees(-90))
+
+    @Environment(\.colorScheme) var colorScheme
+
+    var body: some View {
+        let triangleColor = Color(red: 0.262745098, green: 0.7333333333, blue: 0.9137254902)
+
+        TrendShape(gradient: angularGradient, color: triangleColor)
+            .rotationEffect(.degrees(rotationDegrees))
+
+//            .onChange(of: context.state.bg) { newDirection in
+//            withAnimation {
+//                switch newDirection {
+//                case .doubleUp,
+//                     .singleUp,
+//                     .tripleUp:
+//                    rotationDegrees = -90
+//
+//                case .fortyFiveUp:
+//                    rotationDegrees = -45
+//
+//                case .flat:
+//                    rotationDegrees = 0
+//
+//                case .fortyFiveDown:
+//                    rotationDegrees = 45
+//
+//                case .doubleDown,
+//                     .singleDown,
+//                     .tripleDown:
+//                    rotationDegrees = 90
+//
+//                case .none,
+//                     .notComputable,
+//                     .rateOutOfRange:
+//                    rotationDegrees = 0
+//
+//                @unknown default:
+//                    rotationDegrees = 0
+//                }
+//            }
+//        }
+    }
+}
+
+struct Triangle: Shape {
+    func path(in rect: CGRect) -> Path {
+        var path = Path()
+
+        let cornerRadius: CGFloat = 8
+
+        path.move(to: CGPoint(x: rect.midX, y: rect.minY))
+        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - cornerRadius))
+        path.addQuadCurve(to: CGPoint(x: rect.minX, y: rect.maxY - cornerRadius), control: CGPoint(x: rect.midX, y: rect.maxY))
+        path.closeSubpath()
+
+        return path
+    }
+}
+
+struct TrendShape: View {
+    @Environment(\.colorScheme) var colorScheme
+
+    let gradient: AngularGradient
+    let color: Color
+
+    var body: some View {
+        HStack(alignment: .center) {
+            ZStack {
+                Group {
+                    CircleShape(gradient: gradient)
+                    TriangleShape(color: color)
+                }.shadow(color: Color.black.opacity(colorScheme == .dark ? 0.75 : 0.33), radius: colorScheme == .dark ? 5 : 3)
+                CircleShape(gradient: gradient)
+            }
+        }
+    }
+}
+
+struct CircleShape: View {
+    @Environment(\.colorScheme) var colorScheme
+
+    let gradient: AngularGradient
+
+    var body: some View {
+        let colorBackground: Color = colorScheme == .dark ? Color(
+            red: 0.05490196078,
+            green: 0.05490196078,
+            blue: 0.05490196078
+        ) : .white
+
+        Circle()
+            .stroke(gradient, lineWidth: 6)
+            .background(Circle().fill(colorBackground))
+            .frame(width: 130, height: 130)
+    }
+}
+
+struct TriangleShape: View {
+    let color: Color
+
+    var body: some View {
+        Triangle()
+            .fill(color)
+            .frame(width: 35, height: 35)
+            .rotationEffect(.degrees(90))
+            .offset(x: 70)
+    }
+}