@@ -3,44 +3,140 @@ import WidgetKit
33import SwiftUI
44import OneSignalLiveActivities
55
6- struct OneSignalWidgetAttributes : OneSignalLiveActivityAttributes {
7- public struct ContentState : OneSignalLiveActivityContentState {
8- var emoji : String
9- var onesignal : OneSignalLiveActivityContentStateData ?
6+ @available ( iOS 16 . 2 , * )
7+ struct OneSignalWidgetLiveActivity : Widget {
8+
9+ private func statusIcon( for status: String ) -> String {
10+ switch status {
11+ case " on_the_way " : return " box.truck.fill "
12+ case " delivered " : return " checkmark.circle.fill "
13+ default : return " bag.fill "
14+ }
15+ }
16+
17+ private func statusColor( for status: String ) -> Color {
18+ switch status {
19+ case " on_the_way " : return . blue
20+ case " delivered " : return . green
21+ default : return . orange
22+ }
23+ }
24+
25+ private func statusLabel( for status: String ) -> String {
26+ switch status {
27+ case " on_the_way " : return " On the Way "
28+ case " delivered " : return " Delivered "
29+ default : return " Preparing "
30+ }
1031 }
11- var name : String
12- var onesignal : OneSignalLiveActivityAttributeData
13- }
1432
15- struct OneSignalWidgetLiveActivity : Widget {
1633 var body : some WidgetConfiguration {
17- ActivityConfiguration ( for: OneSignalWidgetAttributes . self) { context in
18- VStack {
19- Text ( " Hello \( context. attributes. name) \( context. state. emoji) " )
34+ ActivityConfiguration ( for: DefaultLiveActivityAttributes . self) { context in
35+ let orderNumber = context. attributes. data [ " orderNumber " ] ? . asString ( ) ?? " Order "
36+ let status = context. state. data [ " status " ] ? . asString ( ) ?? " preparing "
37+ let message = context. state. data [ " message " ] ? . asString ( ) ?? " Your order is being prepared "
38+ let eta = context. state. data [ " estimatedTime " ] ? . asString ( ) ?? " "
39+
40+ VStack ( spacing: 10 ) {
41+ HStack {
42+ Text ( orderNumber)
43+ . font ( . caption)
44+ . foregroundColor ( . gray)
45+ Spacer ( )
46+ if !eta. isEmpty {
47+ Text ( eta)
48+ . font ( . caption)
49+ . foregroundColor ( . white. opacity ( 0.7 ) )
50+ }
51+ }
52+
53+ HStack ( spacing: 12 ) {
54+ Image ( systemName: statusIcon ( for: status) )
55+ . font ( . title2)
56+ . foregroundColor ( statusColor ( for: status) )
57+
58+ VStack ( alignment: . leading, spacing: 2 ) {
59+ Text ( statusLabel ( for: status) )
60+ . font ( . headline)
61+ . foregroundColor ( . white)
62+ Text ( message)
63+ . font ( . subheadline)
64+ . foregroundColor ( . white. opacity ( 0.8 ) )
65+ . lineLimit ( 1 )
66+ }
67+ Spacer ( )
68+ }
69+
70+ DeliveryProgressBar ( status: status)
2071 }
21- . activityBackgroundTint ( Color . cyan)
22- . activitySystemActionForegroundColor ( Color . black)
72+ . padding ( )
73+ . activityBackgroundTint ( Color ( red: 0.11 , green: 0.13 , blue: 0.19 ) )
74+ . activitySystemActionForegroundColor ( . white)
2375
2476 } dynamicIsland: { context in
25- DynamicIsland {
77+ let status = context. state. data [ " status " ] ? . asString ( ) ?? " preparing "
78+ let message = context. state. data [ " message " ] ? . asString ( ) ?? " Preparing "
79+ let eta = context. state. data [ " estimatedTime " ] ? . asString ( ) ?? " "
80+
81+ return DynamicIsland {
2682 DynamicIslandExpandedRegion ( . leading) {
27- Text ( " Leading " )
83+ Image ( systemName: statusIcon ( for: status) )
84+ . font ( . title2)
85+ . foregroundColor ( statusColor ( for: status) )
86+ }
87+ DynamicIslandExpandedRegion ( . center) {
88+ Text ( statusLabel ( for: status) )
89+ . font ( . headline)
2890 }
2991 DynamicIslandExpandedRegion ( . trailing) {
30- Text ( " Trailing " )
92+ if !eta. isEmpty {
93+ Text ( eta)
94+ . font ( . caption)
95+ . foregroundColor ( . secondary)
96+ }
3197 }
3298 DynamicIslandExpandedRegion ( . bottom) {
33- Text ( " Bottom \( context. state. emoji) " )
99+ Text ( message)
100+ . font ( . caption)
101+ . foregroundColor ( . secondary)
34102 }
35103 } compactLeading: {
36- Text ( " L " )
104+ Image ( systemName: statusIcon ( for: status) )
105+ . foregroundColor ( statusColor ( for: status) )
37106 } compactTrailing: {
38- Text ( " T \( context. state. emoji) " )
107+ Text ( statusLabel ( for: status) )
108+ . font ( . caption)
39109 } minimal: {
40- Text ( context. state. emoji)
110+ Image ( systemName: statusIcon ( for: status) )
111+ . foregroundColor ( statusColor ( for: status) )
112+ }
113+ }
114+ }
115+ }
116+
117+ @available ( iOS 16 . 2 , * )
118+ struct DeliveryProgressBar : View {
119+ let status : String
120+
121+ private var progress : CGFloat {
122+ switch status {
123+ case " on_the_way " : return 0.6
124+ case " delivered " : return 1.0
125+ default : return 0.25
126+ }
127+ }
128+
129+ var body : some View {
130+ GeometryReader { geo in
131+ ZStack ( alignment: . leading) {
132+ RoundedRectangle ( cornerRadius: 3 )
133+ . fill ( Color . white. opacity ( 0.2 ) )
134+ . frame ( height: 6 )
135+ RoundedRectangle ( cornerRadius: 3 )
136+ . fill ( progress >= 1.0 ? Color . green : Color . blue)
137+ . frame ( width: geo. size. width * progress, height: 6 )
41138 }
42- . widgetURL ( URL ( string: " http://www.apple.com " ) )
43- . keylineTint ( Color . red)
44139 }
140+ . frame ( height: 6 )
45141 }
46142}
0 commit comments