Skip to content

Commit 5c36239

Browse files
authored
feat(demo): [SDK-4217] add Live Activities demp example (#1933)
1 parent d7866a6 commit 5c36239

File tree

14 files changed

+458
-614
lines changed

14 files changed

+458
-614
lines changed

examples/demo/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ONESIGNAL_API_KEY=your_rest_api_key

examples/demo/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Environment
2+
.env
3+
14
# OSX
25
#
36
.DS_Store

examples/demo/App.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ function App() {
8484
OneSignal.setConsentGiven(privacyConsent);
8585
OneSignal.initialize(appId);
8686

87+
OneSignal.LiveActivities.setupDefault({
88+
enablePushToStart: true,
89+
enablePushToUpdate: true,
90+
});
91+
8792
OneSignal.InAppMessages.setPaused(iamPaused);
8893
OneSignal.Location.setShared(locationShared);
8994

examples/demo/babel.config.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
module.exports = {
22
presets: ['module:@react-native/babel-preset'],
3+
plugins: [
4+
[
5+
'module:react-native-dotenv',
6+
{
7+
envName: 'APP_ENV',
8+
moduleName: '@env',
9+
path: '.env',
10+
safe: false,
11+
allowUndefined: true,
12+
},
13+
],
14+
],
315
};

examples/demo/bun.lock

Lines changed: 13 additions & 587 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/demo/ios/OneSignalWidget/OneSignalWidgetLiveActivity.swift

Lines changed: 118 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,140 @@ import WidgetKit
33
import SwiftUI
44
import 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
}

examples/demo/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,7 +1446,7 @@ PODS:
14461446
- React-RCTFBReactNativeSpec
14471447
- ReactCommon/turbomodule/core
14481448
- ReactNativeDependencies
1449-
- react-native-onesignal (5.4.0):
1449+
- react-native-onesignal (5.4.1):
14501450
- hermes-engine
14511451
- OneSignalXCFramework (= 5.5.0)
14521452
- RCTRequired
@@ -2349,7 +2349,7 @@ SPEC CHECKSUMS:
23492349
React-logger: 9e51e01455f15cb3ef87a09a1ec773cdb22d56c1
23502350
React-Mapbuffer: 92b99e450e8ff598b27d6e4db3a75e04fd45e9a9
23512351
React-microtasksnativemodule: 2fe0f2bd2840dedbd66c0ac249c64f977f39cc18
2352-
react-native-onesignal: 95e69fd48dbdd28700ee6ebe6a5548c107127bf3
2352+
react-native-onesignal: 21bb718c560cd7e6e763594ace7a4599606d0452
23532353
react-native-safe-area-context: 37e680fc4cace3c0030ee46e8987d24f5d3bdab2
23542354
React-NativeModulesApple: 44a9474594566cd03659f92e38f42599c6b9dee4
23552355
React-networking: db73d91466cb134fcbdaaa579fb2de14e2c2ea01

examples/demo/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@react-native/typescript-config": "0.84.0",
3838
"@types/react": "^19.2.0",
3939
"@types/react-native-vector-icons": "^6.4.18",
40+
"react-native-dotenv": "^3.4.11",
4041
"react-native-svg-transformer": "^1.5.3",
4142
"typescript": "^5.8.3"
4243
},

0 commit comments

Comments
 (0)