expo-widgets 57.0.11 → 57.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,25 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 57.0.13 — 2026-08-26
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
17
+ ## 57.0.12 — 2026-08-24
18
+
19
+ ### 🎉 New features
20
+
21
+ - [iOS] Expose ActivityKit's `staleDate` on `LiveActivity.start()` and `LiveActivity.update()`. ([#46343](https://github.com/expo/expo/pull/46343) by [@KyleAsaff](https://github.com/KyleAsaff))
22
+ - [iOS] Expose ActivityKit's `isStale` on `LiveActivityEnvironment`. ([#48303](https://github.com/expo/expo/pull/48303) by [@dirkpostma](https://github.com/dirkpostma))
23
+ - [iOS] Expose stable ActivityKit identifiers on Live Activity instances. ([#48589](https://github.com/expo/expo/pull/48589) by [@developwithJB](https://github.com/developwithJB))
24
+
25
+ ### 🐛 Bug fixes
26
+
27
+ - [iOS] Fix XCFramework precompilation failing on the unguarded `ActivityViewContext` parameter of `getLiveActivityEnvironment`, which requires iOS 16.1. ([#49076](https://github.com/expo/expo/pull/49076) by [@brentvatne](https://github.com/brentvatne))
28
+ - [iOS] Fix `LiveActivityFactory.getInstances()` returning live activities that belong to other factories or that have already ended. ([#48489](https://github.com/expo/expo/pull/48489) by [@huextrat](https://github.com/huextrat))
29
+ - [iOS] Deliver the Live Activity `start()` URL to the Lock Screen banner, and scope it to the activity that set it instead of storing it globally per factory name. ([#48489](https://github.com/expo/expo/pull/48489) by [@huextrat](https://github.com/huextrat))
30
+ - [iOS] Restore push token observation when retrieving existing Live Activities. ([#48589](https://github.com/expo/expo/pull/48589) by [@developwithJB](https://github.com/developwithJB))
31
+
13
32
  ## 57.0.11 — 2026-08-20
14
33
 
15
34
  ### 🐛 Bug fixes
@@ -13,7 +13,7 @@ apply plugin: 'expo-module-gradle-plugin'
13
13
  apply plugin: 'org.jetbrains.kotlin.plugin.compose'
14
14
 
15
15
  group = 'expo.modules.widgets'
16
- version = '57.0.11'
16
+ version = '57.0.13'
17
17
 
18
18
  expoModule {
19
19
  canBePublished false
@@ -23,7 +23,7 @@ android {
23
23
  namespace "expo.modules.widgets"
24
24
  defaultConfig {
25
25
  versionCode 1
26
- versionName '57.0.11'
26
+ versionName '57.0.13'
27
27
  }
28
28
 
29
29
  buildFeatures {
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoWidgets.d.ts","sourceRoot":"","sources":["../src/ExpoWidgets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAEV,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAyCzB,QAAA,MAAM,iBAAiB;;wBAED,IAAI;YACF,OAAO,kBAAkB;yBACC,OAAO,yBAAyB;kBAC9C,OAAO,kBAAkB;gBAC/C,SAAS,SAAS,MAAM,iBAAiB,cACvC,SAAS,aACV,iBAAiB,CAAC,SAAS,CAAC,GACtC,iBAAiB;CAGrB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"ExpoWidgets.d.ts","sourceRoot":"","sources":["../src/ExpoWidgets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAEV,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AA4CzB,QAAA,MAAM,iBAAiB;;wBAED,IAAI;YACF,OAAO,kBAAkB;yBACC,OAAO,yBAAyB;kBAC9C,OAAO,kBAAkB;gBAC/C,SAAS,SAAS,MAAM,iBAAiB,cACvC,SAAS,aACV,iBAAiB,CAAC,SAAS,CAAC,GACtC,iBAAiB;CAGrB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -9,6 +9,9 @@ class WidgetStub {
9
9
  }
10
10
  }
11
11
  class LiveActivityStub {
12
+ getId() {
13
+ return '';
14
+ }
12
15
  async update(_props) { }
13
16
  async end(_dismissalPolicy, _afterDate, _state, _contentDate) { }
14
17
  async getPushToken() {
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoWidgets.js","sourceRoot":"","sources":["../src/ExpoWidgets.ts"],"names":[],"mappings":"AAUA,MAAM,gBAAgB,GAAsB,EAAE,MAAM,KAAI,CAAC,EAAE,CAAC;AAE5D,MAAM,UAAU;IACd,qEAAqE;IACrE,YAAY,KAAa,EAAE,OAAe,IAAG,CAAC;IAC9C,MAAM,KAAU,CAAC;IACjB,cAAc,CAAC,QAA6B,IAAS,CAAC;IACtD,KAAK,CAAC,WAAW;QACf,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,MAAM,gBAAgB;IACpB,KAAK,CAAC,MAAM,CAAC,MAAc,IAAkB,CAAC;IAC9C,KAAK,CAAC,GAAG,CACP,gBAAyB,EACzB,UAAmB,EACnB,MAAe,EACf,YAAqB,IACL,CAAC;IACnB,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,WAAW,CAAC,UAAkB,EAAE,SAAuC;QACrE,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,uBAAuB;IAC3B,qEAAqE;IACrE,YAAY,KAAa,EAAE,OAAe,IAAG,CAAC;IAC9C,KAAK,CAAC,MAAc,EAAE,IAAa;QACjC,OAAO,IAAI,gBAAgB,EAAwB,CAAC;IACtD,CAAC;IACD,YAAY;QACV,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,MAAM,iBAAiB,GAAG;IACxB,gBAAgB,EAAE,EAAE;IACpB,gBAAgB,KAAU,CAAC;IAC3B,MAAM,EAAE,UAAuC;IAC/C,mBAAmB,EAAE,uBAA2D;IAChF,YAAY,EAAE,gBAA6C;IAC3D,WAAW,CACT,UAAqB,EACrB,SAAuC;QAEvC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF,CAAC;AAEF,eAAe,iBAAiB,CAAC","sourcesContent":["import type { EventSubscription } from 'expo-modules-core';\n\nimport type {\n ExpoTimelineEntry,\n ExpoWidgetsEvents,\n NativeLiveActivity,\n NativeLiveActivityFactory,\n NativeWidgetObject,\n} from './Widgets.types';\n\nconst noopSubscription: EventSubscription = { remove() {} };\n\nclass WidgetStub {\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(_name: string, _layout: string) {}\n reload(): void {}\n updateTimeline(_entries: ExpoTimelineEntry[]): void {}\n async getTimeline(): Promise<ExpoTimelineEntry[]> {\n return [];\n }\n}\n\nclass LiveActivityStub {\n async update(_props: string): Promise<void> {}\n async end(\n _dismissalPolicy?: string,\n _afterDate?: number,\n _state?: string,\n _contentDate?: number\n ): Promise<void> {}\n async getPushToken(): Promise<string | null> {\n return null;\n }\n addListener(_eventName: string, _listener: (...args: unknown[]) => void): EventSubscription {\n return noopSubscription;\n }\n}\n\nclass LiveActivityFactoryStub {\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(_name: string, _layout: string) {}\n start(_props: string, _url?: string): NativeLiveActivity {\n return new LiveActivityStub() as NativeLiveActivity;\n }\n getInstances(): NativeLiveActivity[] {\n return [];\n }\n}\n\nconst ExpoWidgetsModule = {\n widgetsDirectory: '',\n reloadAllWidgets(): void {},\n Widget: WidgetStub as typeof NativeWidgetObject,\n LiveActivityFactory: LiveActivityFactoryStub as typeof NativeLiveActivityFactory,\n LiveActivity: LiveActivityStub as typeof NativeLiveActivity,\n addListener<EventName extends keyof ExpoWidgetsEvents>(\n _eventName: EventName,\n _listener: ExpoWidgetsEvents[EventName]\n ): EventSubscription {\n return noopSubscription;\n },\n};\n\nexport default ExpoWidgetsModule;\n"]}
1
+ {"version":3,"file":"ExpoWidgets.js","sourceRoot":"","sources":["../src/ExpoWidgets.ts"],"names":[],"mappings":"AAUA,MAAM,gBAAgB,GAAsB,EAAE,MAAM,KAAI,CAAC,EAAE,CAAC;AAE5D,MAAM,UAAU;IACd,qEAAqE;IACrE,YAAY,KAAa,EAAE,OAAe,IAAG,CAAC;IAC9C,MAAM,KAAU,CAAC;IACjB,cAAc,CAAC,QAA6B,IAAS,CAAC;IACtD,KAAK,CAAC,WAAW;QACf,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,MAAM,gBAAgB;IACpB,KAAK;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,MAAc,IAAkB,CAAC;IAC9C,KAAK,CAAC,GAAG,CACP,gBAAyB,EACzB,UAAmB,EACnB,MAAe,EACf,YAAqB,IACL,CAAC;IACnB,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,WAAW,CAAC,UAAkB,EAAE,SAAuC;QACrE,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,uBAAuB;IAC3B,qEAAqE;IACrE,YAAY,KAAa,EAAE,OAAe,IAAG,CAAC;IAC9C,KAAK,CAAC,MAAc,EAAE,IAAa;QACjC,OAAO,IAAI,gBAAgB,EAAwB,CAAC;IACtD,CAAC;IACD,YAAY;QACV,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,MAAM,iBAAiB,GAAG;IACxB,gBAAgB,EAAE,EAAE;IACpB,gBAAgB,KAAU,CAAC;IAC3B,MAAM,EAAE,UAAuC;IAC/C,mBAAmB,EAAE,uBAA2D;IAChF,YAAY,EAAE,gBAA6C;IAC3D,WAAW,CACT,UAAqB,EACrB,SAAuC;QAEvC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF,CAAC;AAEF,eAAe,iBAAiB,CAAC","sourcesContent":["import type { EventSubscription } from 'expo-modules-core';\n\nimport type {\n ExpoTimelineEntry,\n ExpoWidgetsEvents,\n NativeLiveActivity,\n NativeLiveActivityFactory,\n NativeWidgetObject,\n} from './Widgets.types';\n\nconst noopSubscription: EventSubscription = { remove() {} };\n\nclass WidgetStub {\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(_name: string, _layout: string) {}\n reload(): void {}\n updateTimeline(_entries: ExpoTimelineEntry[]): void {}\n async getTimeline(): Promise<ExpoTimelineEntry[]> {\n return [];\n }\n}\n\nclass LiveActivityStub {\n getId(): string {\n return '';\n }\n async update(_props: string): Promise<void> {}\n async end(\n _dismissalPolicy?: string,\n _afterDate?: number,\n _state?: string,\n _contentDate?: number\n ): Promise<void> {}\n async getPushToken(): Promise<string | null> {\n return null;\n }\n addListener(_eventName: string, _listener: (...args: unknown[]) => void): EventSubscription {\n return noopSubscription;\n }\n}\n\nclass LiveActivityFactoryStub {\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(_name: string, _layout: string) {}\n start(_props: string, _url?: string): NativeLiveActivity {\n return new LiveActivityStub() as NativeLiveActivity;\n }\n getInstances(): NativeLiveActivity[] {\n return [];\n }\n}\n\nconst ExpoWidgetsModule = {\n widgetsDirectory: '',\n reloadAllWidgets(): void {},\n Widget: WidgetStub as typeof NativeWidgetObject,\n LiveActivityFactory: LiveActivityFactoryStub as typeof NativeLiveActivityFactory,\n LiveActivity: LiveActivityStub as typeof NativeLiveActivity,\n addListener<EventName extends keyof ExpoWidgetsEvents>(\n _eventName: EventName,\n _listener: ExpoWidgetsEvents[EventName]\n ): EventSubscription {\n return noopSubscription;\n },\n};\n\nexport default ExpoWidgetsModule;\n"]}
@@ -33,11 +33,16 @@ export declare class LiveActivity<T extends object = object> {
33
33
  /** @hidden */
34
34
  private nativeLiveActivity;
35
35
  constructor(nativeLiveActivity: NativeLiveActivity);
36
+ /**
37
+ * Returns the stable ActivityKit identifier for this Live Activity.
38
+ */
39
+ getId(): string;
36
40
  /**
37
41
  * Updates the Live Activity's content. The UI reflects the new properties immediately.
38
42
  * @param props The updated content properties.
43
+ * @param staleDate When set, the system may de-emphasize the activity after this date if content has not been refreshed.
39
44
  */
40
- update(props: T): Promise<void>;
45
+ update(props: T, staleDate?: Date): Promise<void>;
41
46
  /**
42
47
  * Ends the Live Activity.
43
48
  * @param dismissalPolicy Controls when the Live Activity is removed from the Lock Screen after ending.
@@ -70,9 +75,10 @@ export declare class LiveActivityFactory<T extends object = object> {
70
75
  * Starts a new Live Activity with the given properties.
71
76
  * @param props The initial content properties for the Live Activity.
72
77
  * @param url An optional URL to associate with the Live Activity, used for deep linking.
78
+ * @param staleDate When set, the system may de-emphasize the activity after this date if content has not been refreshed.
73
79
  * @returns The new Live Activity instance.
74
80
  */
75
- start(props: T, url?: string): LiveActivity<T>;
81
+ start(props: T, url?: string, staleDate?: Date): LiveActivity<T>;
76
82
  /**
77
83
  * Returns all currently active instances of this Live Activity type.
78
84
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.d.ts","sourceRoot":"","sources":["../src/Widgets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Widgets.d.ts","sourceRoot":"","sources":["../src/Widgets.ts"],"names":[],"mappings":"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"}
package/build/Widgets.js CHANGED
@@ -47,12 +47,19 @@ export class LiveActivity {
47
47
  constructor(nativeLiveActivity) {
48
48
  this.nativeLiveActivity = nativeLiveActivity;
49
49
  }
50
+ /**
51
+ * Returns the stable ActivityKit identifier for this Live Activity.
52
+ */
53
+ getId() {
54
+ return this.nativeLiveActivity.getId();
55
+ }
50
56
  /**
51
57
  * Updates the Live Activity's content. The UI reflects the new properties immediately.
52
58
  * @param props The updated content properties.
59
+ * @param staleDate When set, the system may de-emphasize the activity after this date if content has not been refreshed.
53
60
  */
54
- update(props) {
55
- return this.nativeLiveActivity.update(JSON.stringify(props));
61
+ update(props, staleDate) {
62
+ return this.nativeLiveActivity.update(JSON.stringify(props), staleDate?.getTime());
56
63
  }
57
64
  /**
58
65
  * Ends the Live Activity.
@@ -100,10 +107,11 @@ export class LiveActivityFactory {
100
107
  * Starts a new Live Activity with the given properties.
101
108
  * @param props The initial content properties for the Live Activity.
102
109
  * @param url An optional URL to associate with the Live Activity, used for deep linking.
110
+ * @param staleDate When set, the system may de-emphasize the activity after this date if content has not been refreshed.
103
111
  * @returns The new Live Activity instance.
104
112
  */
105
- start(props, url) {
106
- return new LiveActivity(this.nativeLiveActivityFactory.start(JSON.stringify(props), url));
113
+ start(props, url, staleDate) {
114
+ return new LiveActivity(this.nativeLiveActivityFactory.start(JSON.stringify(props), url, staleDate?.getTime()));
107
115
  }
108
116
  /**
109
117
  * Returns all currently active instances of this Live Activity type.
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.js","sourceRoot":"","sources":["../src/Widgets.ts"],"names":[],"mappings":"AAEA,OAAO,iBAAiB,MAAM,eAAe,CAAC;AAa9C;;GAEG;AACH,MAAM,OAAO,MAAM;IAIjB,cAAc;IACN,kBAAkB,CAAqB;IAC/C,YACE,IAAY,EACZ,MAGsB;QAEtB,IAAI,CAAC,kBAAkB,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,MAA2B,CAAC,CAAC;IAC5F,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,OAAyC;QACtD,IAAI,CAAC,kBAAkB,CAAC,cAAc,CACpC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAClF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,KAAgB;QAC7B,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,OAAO,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACnE,IAAI,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YAC/B,KAAK,EAAE,KAAK,CAAC,KAAkB;SAChC,CAAC,CAAC,CAAC;IACN,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,YAAY;IACvB,cAAc;IACN,kBAAkB,CAAqB;IAC/C,YAAY,kBAAsC;QAChD,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAQ;QACb,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,eAA6C,EAAE,KAAS,EAAE,WAAkB;QAC9E,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClE,IACE,OAAO,eAAe,KAAK,QAAQ;YACnC,eAAe,KAAK,IAAI;YACxB,OAAO,IAAI,eAAe,EAC1B,CAAC;YACD,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAChC,OAAO,EACP,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,EAChC,eAAe,EACf,WAAW,EAAE,OAAO,EAAE,CACvB,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAChC,eAAe,EACf,SAAS,EACT,eAAe,EACf,WAAW,EAAE,OAAO,EAAE,CACvB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,oBAAoB,CAAC,QAAyC;QAC5D,OAAO,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,4BAA4B,EAAE,QAAQ,CAAC,CAAC;IACrF,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,mBAAmB;IAC9B,cAAc;IACN,yBAAyB,CAA4B;IAC7D,YAAY,IAAY,EAAE,MAAgC;QACxD,IAAI,CAAC,yBAAyB,GAAG,IAAI,iBAAiB,CAAC,mBAAmB,CACxE,IAAI,EACJ,MAA2B,CAC5B,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAQ,EAAE,GAAY;QAC1B,OAAO,IAAI,YAAY,CAAI,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/F,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,yBAAyB;aAClC,YAAY,EAAE;aACd,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,YAAY,CAAI,QAAQ,CAAC,CAAC,CAAC;IACtD,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,IAAU;IAC9B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAI1B,IAAY,EACZ,MAA8F;IAE9F,OAAO,IAAI,MAAM,CAA+B,IAAI,EAAE,MAAM,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,YAAsC;IAEtC,OAAO,IAAI,mBAAmB,CAAI,IAAI,EAAE,YAAY,CAAC,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAA2D;IAE3D,OAAO,iBAAiB,CAAC,WAAW,CAAC,8BAA8B,EAAE,QAAQ,CAAC,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CACzC,QAAoE;IAEpE,OAAO,iBAAiB,CAAC,WAAW,CAAC,uCAAuC,EAAE,QAAQ,CAAC,CAAC;AAC1F,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,gBAAgB,CAAC","sourcesContent":["import type { EventSubscription } from 'expo-modules-core';\n\nimport ExpoWidgetsModule from './ExpoWidgets';\nimport type {\n ExpoWidgetsEvents,\n LiveActivityComponent,\n LiveActivityDismissalPolicy,\n NativeLiveActivity,\n NativeLiveActivityFactory,\n NativeWidgetObject,\n PushTokenEvent,\n WidgetEnvironment,\n WidgetTimelineEntry,\n} from './Widgets.types';\n\n/**\n * Represents a widget instance. Provides methods to manage the widget's timeline.\n */\nexport class Widget<\n PropsType extends object = object,\n ConfigurationType extends object | undefined = undefined,\n> {\n /** @hidden */\n private nativeWidgetObject: NativeWidgetObject;\n constructor(\n name: string,\n layout: (\n props: PropsType,\n environment: WidgetEnvironment<ConfigurationType>\n ) => React.JSX.Element\n ) {\n this.nativeWidgetObject = new ExpoWidgetsModule.Widget(name, layout as unknown as string);\n }\n\n /**\n * Force reloads the widget, causing it to refresh its content and timeline.\n */\n reload() {\n this.nativeWidgetObject.reload();\n }\n\n /**\n * Schedules a series of updates for the widget's content and reloads the widget.\n * @param entries Timeline entries, each specifying a date and the props to display at that time.\n */\n updateTimeline(entries: WidgetTimelineEntry<PropsType>[]) {\n this.nativeWidgetObject.updateTimeline(\n entries.map((entry) => ({ timestamp: entry.date.getTime(), props: entry.props }))\n );\n }\n\n /**\n * Sets the widget's content to the given props immediately, without scheduling a timeline.\n * @param props The properties to display in the widget.\n */\n updateSnapshot(props: PropsType) {\n this.nativeWidgetObject.updateTimeline([{ timestamp: Date.now(), props }]);\n }\n\n /**\n * Returns the current timeline entries for the widget, including past and future entries.\n */\n async getTimeline(): Promise<WidgetTimelineEntry<PropsType>[]> {\n return (await this.nativeWidgetObject.getTimeline()).map((entry) => ({\n date: new Date(entry.timestamp),\n props: entry.props as PropsType,\n }));\n }\n}\n\n/**\n * Represents a Live Activity instance. Provides methods to update its content and end it.\n */\nexport class LiveActivity<T extends object = object> {\n /** @hidden */\n private nativeLiveActivity: NativeLiveActivity;\n constructor(nativeLiveActivity: NativeLiveActivity) {\n this.nativeLiveActivity = nativeLiveActivity;\n }\n\n /**\n * Updates the Live Activity's content. The UI reflects the new properties immediately.\n * @param props The updated content properties.\n */\n update(props: T): Promise<void> {\n return this.nativeLiveActivity.update(JSON.stringify(props));\n }\n\n /**\n * Ends the Live Activity.\n * @param dismissalPolicy Controls when the Live Activity is removed from the Lock Screen after ending.\n * Can be `'default'`, `'immediate'`, or `after(date)`.\n * @param props Final content properties to update after the activity ends.\n * @param contentDate The time the data in the payload was generated. If this is older than a previous update or push payload, the system ignores this update.\n */\n end(dismissalPolicy?: LiveActivityDismissalPolicy, props?: T, contentDate?: Date): Promise<void> {\n const serializedProps = props ? JSON.stringify(props) : undefined;\n if (\n typeof dismissalPolicy === 'object' &&\n dismissalPolicy !== null &&\n 'after' in dismissalPolicy\n ) {\n return this.nativeLiveActivity.end(\n 'after',\n dismissalPolicy.after?.getTime(),\n serializedProps,\n contentDate?.getTime()\n );\n }\n return this.nativeLiveActivity.end(\n dismissalPolicy,\n undefined,\n serializedProps,\n contentDate?.getTime()\n );\n }\n\n /**\n * Returns the push token for this Live Activity, used to send push notification updates via APNs.\n * Returns `null` if push notifications are not enabled or the token is not yet available.\n */\n getPushToken(): Promise<string | null> {\n return this.nativeLiveActivity.getPushToken();\n }\n\n /**\n * Adds a listener for push token update events on this Live Activity instance.\n * The token can be used to send content updates to this specific activity via APNs.\n * @param listener Callback invoked when a new push token is available.\n * @returns An event subscription that can be used to remove the listener.\n */\n addPushTokenListener(listener: (event: PushTokenEvent) => void): EventSubscription {\n return this.nativeLiveActivity.addListener('onExpoWidgetsTokenReceived', listener);\n }\n}\n\n/**\n * Manages Live Activity instances of a specific type. Use it to start new activities and retrieve currently active ones.\n */\nexport class LiveActivityFactory<T extends object = object> {\n /** @hidden */\n private nativeLiveActivityFactory: NativeLiveActivityFactory;\n constructor(name: string, layout: LiveActivityComponent<T>) {\n this.nativeLiveActivityFactory = new ExpoWidgetsModule.LiveActivityFactory(\n name,\n layout as unknown as string\n );\n }\n\n /**\n * Starts a new Live Activity with the given properties.\n * @param props The initial content properties for the Live Activity.\n * @param url An optional URL to associate with the Live Activity, used for deep linking.\n * @returns The new Live Activity instance.\n */\n start(props: T, url?: string) {\n return new LiveActivity<T>(this.nativeLiveActivityFactory.start(JSON.stringify(props), url));\n }\n\n /**\n * Returns all currently active instances of this Live Activity type.\n */\n getInstances() {\n return this.nativeLiveActivityFactory\n .getInstances()\n .map((instance) => new LiveActivity<T>(instance));\n }\n}\n\n/**\n * Creates a dismissal policy that removes the Live Activity at the specified time within a four-hour window.\n * @param date The date after which the Live Activity should be removed from the Lock Screen.\n * @hidden\n */\nexport function after(date: Date): { after: Date } {\n return { after: date };\n}\n\n/**\n * Creates a Widget instance.\n * @param name The widget name. Must match the `'name'` field in your widget configuration in the app config.\n * @param widget The widget component, marked with the `'widget'` directive.\n */\nexport function createWidget<\n PropsType extends object = object,\n ConfigurationType extends object | undefined = undefined,\n>(\n name: string,\n widget: (props: PropsType, context: WidgetEnvironment<ConfigurationType>) => React.JSX.Element\n): Widget<PropsType, ConfigurationType> {\n return new Widget<PropsType, ConfigurationType>(name, widget);\n}\n\n/**\n * Creates a Live Activity Factory for managing Live Activities of a specific type.\n * @param name The Live Activity name. Must match the `'name'` field in your widget configuration in the app config.\n * @param liveActivity The Live Activity component, marked with the `'widget'` directive.\n */\nexport function createLiveActivity<T extends object = object>(\n name: string,\n liveActivity: LiveActivityComponent<T>\n): LiveActivityFactory<T> {\n return new LiveActivityFactory<T>(name, liveActivity);\n}\n\n/**\n * Adds a listener for widget interaction events (for example, button taps).\n * @param listener Callback function to handle user interaction events.\n * @return An event subscription that can be used to remove the listener.\n */\nexport function addUserInteractionListener(\n listener: ExpoWidgetsEvents['onExpoWidgetsUserInteraction']\n): EventSubscription {\n return ExpoWidgetsModule.addListener('onExpoWidgetsUserInteraction', listener);\n}\n\n/**\n * Adds a listener for push-to-start token events.\n * This token can be used to start live activities remotely via APNs.\n * @param listener Callback function to handle push-to-start token events.\n * @return An event subscription that can be used to remove the listener.\n */\nexport function addPushToStartTokenListener(\n listener: ExpoWidgetsEvents['onExpoWidgetsPushToStartTokenReceived']\n): EventSubscription {\n return ExpoWidgetsModule.addListener('onExpoWidgetsPushToStartTokenReceived', listener);\n}\n\n/**\n * A directory that can be used to store shared images for widgets.\n * The contents of this directory are accessible by both the main app and widgets.\n */\nexport const widgetsDirectory = ExpoWidgetsModule.widgetsDirectory;\n"]}
1
+ {"version":3,"file":"Widgets.js","sourceRoot":"","sources":["../src/Widgets.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EventSubscription } from 'expo-modules-core';\n\nimport ExpoWidgetsModule from './ExpoWidgets';\nimport type {\n ExpoWidgetsEvents,\n LiveActivityComponent,\n LiveActivityDismissalPolicy,\n NativeLiveActivity,\n NativeLiveActivityFactory,\n NativeWidgetObject,\n PushTokenEvent,\n WidgetEnvironment,\n WidgetTimelineEntry,\n} from './Widgets.types';\n\n/**\n * Represents a widget instance. Provides methods to manage the widget's timeline.\n */\nexport class Widget<\n PropsType extends object = object,\n ConfigurationType extends object | undefined = undefined,\n> {\n /** @hidden */\n private nativeWidgetObject: NativeWidgetObject;\n constructor(\n name: string,\n layout: (\n props: PropsType,\n environment: WidgetEnvironment<ConfigurationType>\n ) => React.JSX.Element\n ) {\n this.nativeWidgetObject = new ExpoWidgetsModule.Widget(name, layout as unknown as string);\n }\n\n /**\n * Force reloads the widget, causing it to refresh its content and timeline.\n */\n reload() {\n this.nativeWidgetObject.reload();\n }\n\n /**\n * Schedules a series of updates for the widget's content and reloads the widget.\n * @param entries Timeline entries, each specifying a date and the props to display at that time.\n */\n updateTimeline(entries: WidgetTimelineEntry<PropsType>[]) {\n this.nativeWidgetObject.updateTimeline(\n entries.map((entry) => ({ timestamp: entry.date.getTime(), props: entry.props }))\n );\n }\n\n /**\n * Sets the widget's content to the given props immediately, without scheduling a timeline.\n * @param props The properties to display in the widget.\n */\n updateSnapshot(props: PropsType) {\n this.nativeWidgetObject.updateTimeline([{ timestamp: Date.now(), props }]);\n }\n\n /**\n * Returns the current timeline entries for the widget, including past and future entries.\n */\n async getTimeline(): Promise<WidgetTimelineEntry<PropsType>[]> {\n return (await this.nativeWidgetObject.getTimeline()).map((entry) => ({\n date: new Date(entry.timestamp),\n props: entry.props as PropsType,\n }));\n }\n}\n\n/**\n * Represents a Live Activity instance. Provides methods to update its content and end it.\n */\nexport class LiveActivity<T extends object = object> {\n /** @hidden */\n private nativeLiveActivity: NativeLiveActivity;\n constructor(nativeLiveActivity: NativeLiveActivity) {\n this.nativeLiveActivity = nativeLiveActivity;\n }\n\n /**\n * Returns the stable ActivityKit identifier for this Live Activity.\n */\n getId(): string {\n return this.nativeLiveActivity.getId();\n }\n\n /**\n * Updates the Live Activity's content. The UI reflects the new properties immediately.\n * @param props The updated content properties.\n * @param staleDate When set, the system may de-emphasize the activity after this date if content has not been refreshed.\n */\n update(props: T, staleDate?: Date): Promise<void> {\n return this.nativeLiveActivity.update(JSON.stringify(props), staleDate?.getTime());\n }\n\n /**\n * Ends the Live Activity.\n * @param dismissalPolicy Controls when the Live Activity is removed from the Lock Screen after ending.\n * Can be `'default'`, `'immediate'`, or `after(date)`.\n * @param props Final content properties to update after the activity ends.\n * @param contentDate The time the data in the payload was generated. If this is older than a previous update or push payload, the system ignores this update.\n */\n end(dismissalPolicy?: LiveActivityDismissalPolicy, props?: T, contentDate?: Date): Promise<void> {\n const serializedProps = props ? JSON.stringify(props) : undefined;\n if (\n typeof dismissalPolicy === 'object' &&\n dismissalPolicy !== null &&\n 'after' in dismissalPolicy\n ) {\n return this.nativeLiveActivity.end(\n 'after',\n dismissalPolicy.after?.getTime(),\n serializedProps,\n contentDate?.getTime()\n );\n }\n return this.nativeLiveActivity.end(\n dismissalPolicy,\n undefined,\n serializedProps,\n contentDate?.getTime()\n );\n }\n\n /**\n * Returns the push token for this Live Activity, used to send push notification updates via APNs.\n * Returns `null` if push notifications are not enabled or the token is not yet available.\n */\n getPushToken(): Promise<string | null> {\n return this.nativeLiveActivity.getPushToken();\n }\n\n /**\n * Adds a listener for push token update events on this Live Activity instance.\n * The token can be used to send content updates to this specific activity via APNs.\n * @param listener Callback invoked when a new push token is available.\n * @returns An event subscription that can be used to remove the listener.\n */\n addPushTokenListener(listener: (event: PushTokenEvent) => void): EventSubscription {\n return this.nativeLiveActivity.addListener('onExpoWidgetsTokenReceived', listener);\n }\n}\n\n/**\n * Manages Live Activity instances of a specific type. Use it to start new activities and retrieve currently active ones.\n */\nexport class LiveActivityFactory<T extends object = object> {\n /** @hidden */\n private nativeLiveActivityFactory: NativeLiveActivityFactory;\n constructor(name: string, layout: LiveActivityComponent<T>) {\n this.nativeLiveActivityFactory = new ExpoWidgetsModule.LiveActivityFactory(\n name,\n layout as unknown as string\n );\n }\n\n /**\n * Starts a new Live Activity with the given properties.\n * @param props The initial content properties for the Live Activity.\n * @param url An optional URL to associate with the Live Activity, used for deep linking.\n * @param staleDate When set, the system may de-emphasize the activity after this date if content has not been refreshed.\n * @returns The new Live Activity instance.\n */\n start(props: T, url?: string, staleDate?: Date) {\n return new LiveActivity<T>(\n this.nativeLiveActivityFactory.start(JSON.stringify(props), url, staleDate?.getTime())\n );\n }\n\n /**\n * Returns all currently active instances of this Live Activity type.\n */\n getInstances() {\n return this.nativeLiveActivityFactory\n .getInstances()\n .map((instance) => new LiveActivity<T>(instance));\n }\n}\n\n/**\n * Creates a dismissal policy that removes the Live Activity at the specified time within a four-hour window.\n * @param date The date after which the Live Activity should be removed from the Lock Screen.\n * @hidden\n */\nexport function after(date: Date): { after: Date } {\n return { after: date };\n}\n\n/**\n * Creates a Widget instance.\n * @param name The widget name. Must match the `'name'` field in your widget configuration in the app config.\n * @param widget The widget component, marked with the `'widget'` directive.\n */\nexport function createWidget<\n PropsType extends object = object,\n ConfigurationType extends object | undefined = undefined,\n>(\n name: string,\n widget: (props: PropsType, context: WidgetEnvironment<ConfigurationType>) => React.JSX.Element\n): Widget<PropsType, ConfigurationType> {\n return new Widget<PropsType, ConfigurationType>(name, widget);\n}\n\n/**\n * Creates a Live Activity Factory for managing Live Activities of a specific type.\n * @param name The Live Activity name. Must match the `'name'` field in your widget configuration in the app config.\n * @param liveActivity The Live Activity component, marked with the `'widget'` directive.\n */\nexport function createLiveActivity<T extends object = object>(\n name: string,\n liveActivity: LiveActivityComponent<T>\n): LiveActivityFactory<T> {\n return new LiveActivityFactory<T>(name, liveActivity);\n}\n\n/**\n * Adds a listener for widget interaction events (for example, button taps).\n * @param listener Callback function to handle user interaction events.\n * @return An event subscription that can be used to remove the listener.\n */\nexport function addUserInteractionListener(\n listener: ExpoWidgetsEvents['onExpoWidgetsUserInteraction']\n): EventSubscription {\n return ExpoWidgetsModule.addListener('onExpoWidgetsUserInteraction', listener);\n}\n\n/**\n * Adds a listener for push-to-start token events.\n * This token can be used to start live activities remotely via APNs.\n * @param listener Callback function to handle push-to-start token events.\n * @return An event subscription that can be used to remove the listener.\n */\nexport function addPushToStartTokenListener(\n listener: ExpoWidgetsEvents['onExpoWidgetsPushToStartTokenReceived']\n): EventSubscription {\n return ExpoWidgetsModule.addListener('onExpoWidgetsPushToStartTokenReceived', listener);\n}\n\n/**\n * A directory that can be used to store shared images for widgets.\n * The contents of this directory are accessible by both the main app and widgets.\n */\nexport const widgetsDirectory = ExpoWidgetsModule.widgetsDirectory;\n"]}
@@ -100,6 +100,15 @@ export type LiveActivityEnvironment = {
100
100
  * @platform iOS 16.1+
101
101
  */
102
102
  isActivityFullscreen?: boolean;
103
+ /**
104
+ * Whether the activity's content is out of date, based on the `staleDate` passed to
105
+ * `LiveActivityFactory.start()` or `LiveActivity.update()`.
106
+ *
107
+ * Use it to de-emphasize content the system can no longer vouch for. It becomes `true`
108
+ * without the app running, so a Live Activity can degrade while the app is suspended.
109
+ * @platform iOS 16.2+
110
+ */
111
+ isStale?: boolean;
103
112
  /**
104
113
  * A Boolean value that indicates whether the Live Activity update synchronization rate is reduced.
105
114
  * @platform iOS 18+
@@ -252,11 +261,12 @@ export declare class NativeWidgetObject extends SharedObject {
252
261
  }
253
262
  export declare class NativeLiveActivityFactory extends SharedObject {
254
263
  constructor(name: string, layout: string);
255
- start(props: string, url?: string): NativeLiveActivity;
264
+ start(props: string, url?: string, staleDate?: number): NativeLiveActivity;
256
265
  getInstances(): NativeLiveActivity[];
257
266
  }
258
267
  export declare class NativeLiveActivity extends SharedObject<LiveActivityEvents> {
259
- update(props: string): Promise<void>;
268
+ getId(): string;
269
+ update(props: string, staleDate?: number): Promise<void>;
260
270
  end(dismissalPolicy?: string, afterDate?: number, state?: string, contentDate?: number): Promise<void>;
261
271
  getPushToken(): Promise<string | null>;
262
272
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.types.d.ts","sourceRoot":"","sources":["../src/Widgets.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,SAAS,CAAC;AAErD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhD;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,cAAc,GACd,aAAa,GACb,kBAAkB,GAClB,mBAAmB,GACnB,sBAAsB,GACtB,iBAAiB,CAAC;AAEtB,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS,IAAI;IACxE;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC;IAC3B;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,oBAAoB,CAAC,EAAE;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;OAGG;IACH,aAAa,EAAE,CAAC,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,WAAW,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAC3D;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;OAEG;IACH,MAAM,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B;;OAEG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B;;OAEG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,CAC7D,KAAK,EAAE,CAAC,EACR,WAAW,EAAE,uBAAuB,KACjC,kBAAkB,CAAC;AAExB;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,IAAI,EAAE,4BAA4B,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,wBAAwB,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AAE7F,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,4BAA4B,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACpE;;;OAGG;IACH,qCAAqC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC/E,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;OAGG;IACH,0BAA0B,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CAC7D,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,YAAY;gBAC9C,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACxC,MAAM,IAAI,IAAI;IACd,cAAc,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAClD,WAAW,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAC5C;AAED,MAAM,CAAC,OAAO,OAAO,yBAA0B,SAAQ,YAAY;gBACrD,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACxC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,kBAAkB;IACtD,YAAY,IAAI,kBAAkB,EAAE;CACrC;AAED,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAC9E,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACpC,GAAG,CACD,eAAe,CAAC,EAAE,MAAM,EACxB,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAChB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CACvC"}
1
+ {"version":3,"file":"Widgets.types.d.ts","sourceRoot":"","sources":["../src/Widgets.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.types.js","sourceRoot":"","sources":["../src/Widgets.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC","sourcesContent":["import { SharedObject } from 'expo';\nimport type { ReactNode } from 'react';\n\nimport type { after } from './Widgets';\n\n/**\n * The rendering mode of the widget as provided by WidgetKit.\n * - `fullColor` — Home screen widgets (default).\n * - `accented` — Tinted widgets (iOS 18+) and watchOS.\n * - `vibrant` — Lock screen widgets.\n */\nexport type WidgetRenderingMode = 'fullColor' | 'accented' | 'vibrant';\n\n/**\n * The level of detail the view is recommended to have.\n * The system can update the levelOfDetail value based on user proximity or other system specific factors and allow content customization adapting to show different levels of details.\n * - `simplified` — The system recommends showing a simplified view with less details.\n * - `default` — The system has no specific recommendation for the level of detail.\n * @platform iOS 26+\n */\nexport type LevelOfDetail = 'simplified' | 'default';\n\n/**\n * The size family of the current Live Activity.\n * A Live Activity you initiate on one device can also appear on a remote device that renders the Live Activity in a different family size. As a result, it renders for a specific family, depending on both the device and the location in which it appears.\n * @platform iOS 18+\n */\nexport type ActivityFamily = 'small' | 'medium';\n\n/**\n * The widget family (size).\n * - `systemSmall` - Small square widget (2x2 grid).\n * - `systemMedium` - Medium widget (4x2 grid).\n * - `systemLarge` - Large widget (4x4 grid).\n * - `systemExtraLarge` - Extra large widget (iPad only, 6x4 grid).\n * - `accessoryCircular` - Circular accessory widget for the Lock Screen.\n * - `accessoryRectangular` - Rectangular accessory widget for the Lock Screen.\n * - `accessoryInline` - Inline accessory widget for the Lock Screen.\n */\nexport type WidgetFamily =\n | 'systemSmall'\n | 'systemMedium'\n | 'systemLarge'\n | 'systemExtraLarge'\n | 'accessoryCircular'\n | 'accessoryRectangular'\n | 'accessoryInline';\n\nexport type WidgetEnvironment<T extends object | undefined = undefined> = {\n /**\n * The date of this timeline entry.\n */\n date: Date;\n /**\n * The widget family.\n */\n widgetFamily: WidgetFamily;\n /**\n * The color scheme of the widget's environment.\n */\n colorScheme?: 'light' | 'dark';\n /**\n * A Boolean value that indicates whether the display or environment currently requires reduced luminance.\n *\n * When you detect this condition, lower the overall brightness of your view.\n * For example, you can change large, filled shapes to be stroked, and choose less bright colors.\n * @platform iOS 16+\n */\n isLuminanceReduced?: boolean;\n /**\n * The widget's rendering mode, based on where the system is displaying it.\n * @platform iOS 16+\n */\n widgetRenderingMode?: WidgetRenderingMode;\n /**\n * A Boolean value that indicates whether an accessory family widget can display an accessory label.\n * @platform iOS 16+\n */\n showsWidgetLabel?: boolean;\n /**\n * The content margins for the widget.\n * @platform iOS 17+\n */\n widgetContentMargins?: {\n top: number;\n bottom: number;\n leading: number;\n trailing: number;\n };\n /**\n * The level of detail the view is recommended to have.\n * @platform iOS 26+\n */\n levelOfDetail?: LevelOfDetail;\n /**\n * Widget configuration parameters.\n * @platform iOS 17+\n */\n configuration: T;\n};\n\nexport type LiveActivityEnvironment = {\n /**\n * The color scheme of the activity's environment.\n */\n colorScheme: 'light' | 'dark';\n /**\n * Whether the activity is displayed in a context with reduced luminance.\n * @platform iOS 16+\n */\n isLuminanceReduced?: boolean;\n /**\n * Whether the activity is currently displayed in fullscreen.\n * @platform iOS 16.1+\n */\n isActivityFullscreen?: boolean;\n /**\n * A Boolean value that indicates whether the Live Activity update synchronization rate is reduced.\n * @platform iOS 18+\n */\n isActivityUpdateReduced?: boolean;\n /**\n * The size family of the current Live Activity.\n * @platform iOS 18+\n */\n activityFamily?: ActivityFamily;\n /**\n * The level of detail the view is recommended to have.\n * @platform iOS 26+\n */\n levelOfDetail?: LevelOfDetail;\n};\n\nexport type WidgetTimelineEntry<T extends object = object> = {\n /**\n * Date when widget should update.\n */\n date: Date;\n /**\n * Props to be passed to the widget.\n */\n props: T;\n};\n\nexport type ExpoTimelineEntry = {\n timestamp: number;\n props: Record<string, any>;\n};\n\n/**\n * Defines the layout sections for an iOS Live Activity.\n */\nexport type LiveActivityLayout = {\n /**\n * The main banner content displayed in Notifications Center.\n */\n banner: ReactNode;\n /**\n * The small banner content displayed in CarPlay and WatchOS. Falls back to `banner` if not provided.\n */\n bannerSmall?: ReactNode;\n /**\n * The leading content in the compact Dynamic Island presentation.\n */\n compactLeading?: ReactNode;\n /**\n * The trailing content in the compact Dynamic Island presentation.\n */\n compactTrailing?: ReactNode;\n /**\n * The minimal content shown when the Dynamic Island is in its smallest form.\n */\n minimal?: ReactNode;\n /**\n * The center content in the expanded Dynamic Island presentation.\n */\n expandedCenter?: ReactNode;\n /**\n * The leading content in the expanded Dynamic Island presentation.\n */\n expandedLeading?: ReactNode;\n /**\n * The trailing content in the expanded Dynamic Island presentation.\n */\n expandedTrailing?: ReactNode;\n /**\n * The bottom content in the expanded Dynamic Island presentation.\n */\n expandedBottom?: ReactNode;\n};\n\n/**\n * A function that returns the layout for a Live Activity.\n */\nexport type LiveActivityComponent<T extends object = object> = (\n props: T,\n environment: LiveActivityEnvironment\n) => LiveActivityLayout;\n\n/**\n * Event emitted when a user interacts with a widget.\n */\nexport type UserInteractionEvent = {\n /**\n * Widget that triggered the interaction.\n */\n source: string;\n /**\n * Button/toggle that was pressed.\n */\n target: string;\n /**\n * Timestamp of the event.\n */\n timestamp: number;\n /**\n * The event type identifier.\n */\n type: 'ExpoWidgetsUserInteraction';\n};\n\n/**\n * Event emitted when a push token is received for a live activity.\n */\nexport type PushTokenEvent = {\n /**\n * The ID of the live activity.\n */\n activityId: string;\n /**\n * The push token for the live activity.\n */\n pushToken: string;\n};\n\n/**\n * Event emitted when a push-to-start token is received.\n */\nexport type PushToStartTokenEvent = {\n /**\n * The push-to-start token for starting live activities remotely.\n */\n activityPushToStartToken: string;\n};\n\n/**\n * Dismissal policy for ending a live activity.\n * - `'default'` - The system’s default dismissal policy for the Live Activity.\n * - `'immediate'` - The system immediately removes the Live Activity that ended.\n * - `after(date)` - The system removes the Live Activity that ended at the specified time within a four-hour window.\n */\nexport type LiveActivityDismissalPolicy = 'default' | 'immediate' | ReturnType<typeof after>;\n\nexport type ExpoWidgetsEvents = {\n /**\n * Function that is invoked when user interacts with a widget.\n * @param event Interaction event details.\n */\n onExpoWidgetsUserInteraction: (event: UserInteractionEvent) => void;\n /**\n * Function that is invoked when a push-to-start token is received.\n * @param event Token event details.\n */\n onExpoWidgetsPushToStartTokenReceived: (event: PushToStartTokenEvent) => void;\n};\n\nexport type LiveActivityEvents = {\n /**\n * Function that is invoked when a push token is received for a live activity.\n * @param event Token event details.\n */\n onExpoWidgetsTokenReceived: (event: PushTokenEvent) => void;\n};\n\nexport declare class NativeWidgetObject extends SharedObject {\n constructor(name: string, layout: string);\n reload(): void;\n updateTimeline(entries: ExpoTimelineEntry[]): void;\n getTimeline(): Promise<ExpoTimelineEntry[]>;\n}\n\nexport declare class NativeLiveActivityFactory extends SharedObject {\n constructor(name: string, layout: string);\n start(props: string, url?: string): NativeLiveActivity;\n getInstances(): NativeLiveActivity[];\n}\n\nexport declare class NativeLiveActivity extends SharedObject<LiveActivityEvents> {\n update(props: string): Promise<void>;\n end(\n dismissalPolicy?: string,\n afterDate?: number,\n state?: string,\n contentDate?: number\n ): Promise<void>;\n getPushToken(): Promise<string | null>;\n}\n"]}
1
+ {"version":3,"file":"Widgets.types.js","sourceRoot":"","sources":["../src/Widgets.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC","sourcesContent":["import { SharedObject } from 'expo';\nimport type { ReactNode } from 'react';\n\nimport type { after } from './Widgets';\n\n/**\n * The rendering mode of the widget as provided by WidgetKit.\n * - `fullColor` — Home screen widgets (default).\n * - `accented` — Tinted widgets (iOS 18+) and watchOS.\n * - `vibrant` — Lock screen widgets.\n */\nexport type WidgetRenderingMode = 'fullColor' | 'accented' | 'vibrant';\n\n/**\n * The level of detail the view is recommended to have.\n * The system can update the levelOfDetail value based on user proximity or other system specific factors and allow content customization adapting to show different levels of details.\n * - `simplified` — The system recommends showing a simplified view with less details.\n * - `default` — The system has no specific recommendation for the level of detail.\n * @platform iOS 26+\n */\nexport type LevelOfDetail = 'simplified' | 'default';\n\n/**\n * The size family of the current Live Activity.\n * A Live Activity you initiate on one device can also appear on a remote device that renders the Live Activity in a different family size. As a result, it renders for a specific family, depending on both the device and the location in which it appears.\n * @platform iOS 18+\n */\nexport type ActivityFamily = 'small' | 'medium';\n\n/**\n * The widget family (size).\n * - `systemSmall` - Small square widget (2x2 grid).\n * - `systemMedium` - Medium widget (4x2 grid).\n * - `systemLarge` - Large widget (4x4 grid).\n * - `systemExtraLarge` - Extra large widget (iPad only, 6x4 grid).\n * - `accessoryCircular` - Circular accessory widget for the Lock Screen.\n * - `accessoryRectangular` - Rectangular accessory widget for the Lock Screen.\n * - `accessoryInline` - Inline accessory widget for the Lock Screen.\n */\nexport type WidgetFamily =\n | 'systemSmall'\n | 'systemMedium'\n | 'systemLarge'\n | 'systemExtraLarge'\n | 'accessoryCircular'\n | 'accessoryRectangular'\n | 'accessoryInline';\n\nexport type WidgetEnvironment<T extends object | undefined = undefined> = {\n /**\n * The date of this timeline entry.\n */\n date: Date;\n /**\n * The widget family.\n */\n widgetFamily: WidgetFamily;\n /**\n * The color scheme of the widget's environment.\n */\n colorScheme?: 'light' | 'dark';\n /**\n * A Boolean value that indicates whether the display or environment currently requires reduced luminance.\n *\n * When you detect this condition, lower the overall brightness of your view.\n * For example, you can change large, filled shapes to be stroked, and choose less bright colors.\n * @platform iOS 16+\n */\n isLuminanceReduced?: boolean;\n /**\n * The widget's rendering mode, based on where the system is displaying it.\n * @platform iOS 16+\n */\n widgetRenderingMode?: WidgetRenderingMode;\n /**\n * A Boolean value that indicates whether an accessory family widget can display an accessory label.\n * @platform iOS 16+\n */\n showsWidgetLabel?: boolean;\n /**\n * The content margins for the widget.\n * @platform iOS 17+\n */\n widgetContentMargins?: {\n top: number;\n bottom: number;\n leading: number;\n trailing: number;\n };\n /**\n * The level of detail the view is recommended to have.\n * @platform iOS 26+\n */\n levelOfDetail?: LevelOfDetail;\n /**\n * Widget configuration parameters.\n * @platform iOS 17+\n */\n configuration: T;\n};\n\nexport type LiveActivityEnvironment = {\n /**\n * The color scheme of the activity's environment.\n */\n colorScheme: 'light' | 'dark';\n /**\n * Whether the activity is displayed in a context with reduced luminance.\n * @platform iOS 16+\n */\n isLuminanceReduced?: boolean;\n /**\n * Whether the activity is currently displayed in fullscreen.\n * @platform iOS 16.1+\n */\n isActivityFullscreen?: boolean;\n /**\n * Whether the activity's content is out of date, based on the `staleDate` passed to\n * `LiveActivityFactory.start()` or `LiveActivity.update()`.\n *\n * Use it to de-emphasize content the system can no longer vouch for. It becomes `true`\n * without the app running, so a Live Activity can degrade while the app is suspended.\n * @platform iOS 16.2+\n */\n isStale?: boolean;\n /**\n * A Boolean value that indicates whether the Live Activity update synchronization rate is reduced.\n * @platform iOS 18+\n */\n isActivityUpdateReduced?: boolean;\n /**\n * The size family of the current Live Activity.\n * @platform iOS 18+\n */\n activityFamily?: ActivityFamily;\n /**\n * The level of detail the view is recommended to have.\n * @platform iOS 26+\n */\n levelOfDetail?: LevelOfDetail;\n};\n\nexport type WidgetTimelineEntry<T extends object = object> = {\n /**\n * Date when widget should update.\n */\n date: Date;\n /**\n * Props to be passed to the widget.\n */\n props: T;\n};\n\nexport type ExpoTimelineEntry = {\n timestamp: number;\n props: Record<string, any>;\n};\n\n/**\n * Defines the layout sections for an iOS Live Activity.\n */\nexport type LiveActivityLayout = {\n /**\n * The main banner content displayed in Notifications Center.\n */\n banner: ReactNode;\n /**\n * The small banner content displayed in CarPlay and WatchOS. Falls back to `banner` if not provided.\n */\n bannerSmall?: ReactNode;\n /**\n * The leading content in the compact Dynamic Island presentation.\n */\n compactLeading?: ReactNode;\n /**\n * The trailing content in the compact Dynamic Island presentation.\n */\n compactTrailing?: ReactNode;\n /**\n * The minimal content shown when the Dynamic Island is in its smallest form.\n */\n minimal?: ReactNode;\n /**\n * The center content in the expanded Dynamic Island presentation.\n */\n expandedCenter?: ReactNode;\n /**\n * The leading content in the expanded Dynamic Island presentation.\n */\n expandedLeading?: ReactNode;\n /**\n * The trailing content in the expanded Dynamic Island presentation.\n */\n expandedTrailing?: ReactNode;\n /**\n * The bottom content in the expanded Dynamic Island presentation.\n */\n expandedBottom?: ReactNode;\n};\n\n/**\n * A function that returns the layout for a Live Activity.\n */\nexport type LiveActivityComponent<T extends object = object> = (\n props: T,\n environment: LiveActivityEnvironment\n) => LiveActivityLayout;\n\n/**\n * Event emitted when a user interacts with a widget.\n */\nexport type UserInteractionEvent = {\n /**\n * Widget that triggered the interaction.\n */\n source: string;\n /**\n * Button/toggle that was pressed.\n */\n target: string;\n /**\n * Timestamp of the event.\n */\n timestamp: number;\n /**\n * The event type identifier.\n */\n type: 'ExpoWidgetsUserInteraction';\n};\n\n/**\n * Event emitted when a push token is received for a live activity.\n */\nexport type PushTokenEvent = {\n /**\n * The ID of the live activity.\n */\n activityId: string;\n /**\n * The push token for the live activity.\n */\n pushToken: string;\n};\n\n/**\n * Event emitted when a push-to-start token is received.\n */\nexport type PushToStartTokenEvent = {\n /**\n * The push-to-start token for starting live activities remotely.\n */\n activityPushToStartToken: string;\n};\n\n/**\n * Dismissal policy for ending a live activity.\n * - `'default'` - The system’s default dismissal policy for the Live Activity.\n * - `'immediate'` - The system immediately removes the Live Activity that ended.\n * - `after(date)` - The system removes the Live Activity that ended at the specified time within a four-hour window.\n */\nexport type LiveActivityDismissalPolicy = 'default' | 'immediate' | ReturnType<typeof after>;\n\nexport type ExpoWidgetsEvents = {\n /**\n * Function that is invoked when user interacts with a widget.\n * @param event Interaction event details.\n */\n onExpoWidgetsUserInteraction: (event: UserInteractionEvent) => void;\n /**\n * Function that is invoked when a push-to-start token is received.\n * @param event Token event details.\n */\n onExpoWidgetsPushToStartTokenReceived: (event: PushToStartTokenEvent) => void;\n};\n\nexport type LiveActivityEvents = {\n /**\n * Function that is invoked when a push token is received for a live activity.\n * @param event Token event details.\n */\n onExpoWidgetsTokenReceived: (event: PushTokenEvent) => void;\n};\n\nexport declare class NativeWidgetObject extends SharedObject {\n constructor(name: string, layout: string);\n reload(): void;\n updateTimeline(entries: ExpoTimelineEntry[]): void;\n getTimeline(): Promise<ExpoTimelineEntry[]>;\n}\n\nexport declare class NativeLiveActivityFactory extends SharedObject {\n constructor(name: string, layout: string);\n start(props: string, url?: string, staleDate?: number): NativeLiveActivity;\n getInstances(): NativeLiveActivity[];\n}\n\nexport declare class NativeLiveActivity extends SharedObject<LiveActivityEvents> {\n getId(): string;\n update(props: string, staleDate?: number): Promise<void>;\n end(\n dismissalPolicy?: string,\n afterDate?: number,\n state?: string,\n contentDate?: number\n ): Promise<void>;\n getPushToken(): Promise<string | null>;\n}\n"]}
@@ -12,7 +12,7 @@ final class LiveActivity: SharedObject {
12
12
  super.init()
13
13
  }
14
14
 
15
- func update(props: String) async throws {
15
+ func update(props: String, staleDate: Date?) async throws {
16
16
  guard #available(iOS 16.2, *) else { throw LiveActivitiesNotSupportedException() }
17
17
 
18
18
  guard let activity = Activity<LiveActivityAttributes>.activities.first(where: { $0.id == id }) else {
@@ -20,7 +20,7 @@ final class LiveActivity: SharedObject {
20
20
  }
21
21
 
22
22
  let newState = LiveActivityAttributes.ContentState(name: name, props: props)
23
- await activity.update(ActivityContent(state: newState, staleDate: nil))
23
+ await activity.update(ActivityContent(state: newState, staleDate: staleDate))
24
24
  }
25
25
 
26
26
  func end(dismissalPolicy: LiveActivityDismissalPolicy?, afterDate: Date?, props: String?, contentDate: Date?) async throws {
@@ -62,7 +62,10 @@ final class LiveActivity: SharedObject {
62
62
  return
63
63
  }
64
64
 
65
- pushTokenObserverTask?.cancel()
65
+ guard pushTokenObserverTask == nil else {
66
+ return
67
+ }
68
+
66
69
  pushTokenObserverTask = Task {
67
70
  for await data in activity.pushTokenUpdates {
68
71
  let token = data.reduce("") { $0 + String(format: "%02x", $1) }
@@ -3,6 +3,7 @@ import ActivityKit
3
3
 
4
4
  final class LiveActivityFactory: SharedObject {
5
5
  let name: String
6
+ private var instances: [String: LiveActivity] = [:]
6
7
 
7
8
  static var pushNotificationsEnabled: Bool {
8
9
  Bundle.main.object(forInfoDictionaryKey: pushNotificationsEnabledKey) as? Bool ?? false
@@ -13,26 +14,23 @@ final class LiveActivityFactory: SharedObject {
13
14
  WidgetsStorage.set(layout, forKey: "__expo_widgets_live_activity_\(name)_layout")
14
15
  }
15
16
 
16
- func start(props: String, url: URL?) throws -> LiveActivity {
17
+ func start(props: String, url: URL?, staleDate: Date?) throws -> LiveActivity {
17
18
  guard #available(iOS 16.2, *) else { throw LiveActivitiesNotSupportedException() }
18
19
  guard ActivityAuthorizationInfo().areActivitiesEnabled else {
19
20
  throw LiveActivitiesNotSupportedException()
20
21
  }
21
22
 
22
- if let url {
23
- WidgetsStorage.set(url.absoluteString, forKey: "__expo_widgets_live_activity_\(name)_url")
24
- }
25
-
26
23
  do {
27
24
  let initialState = LiveActivityAttributes.ContentState(name: name, props: props)
28
25
  let activity = try Activity.request(
29
- attributes: LiveActivityAttributes(),
30
- content: .init(state: initialState, staleDate: nil),
26
+ attributes: LiveActivityAttributes(url: url?.absoluteString),
27
+ content: .init(state: initialState, staleDate: staleDate),
31
28
  pushType: LiveActivityFactory.pushNotificationsEnabled ? .token : nil
32
29
  )
33
30
 
34
31
  let instance = LiveActivity(id: activity.id, name: name)
35
32
  instance.observePushTokenUpdates(for: activity, pushNotificationsEnabled: LiveActivityFactory.pushNotificationsEnabled)
33
+ instances[activity.id] = instance
36
34
  return instance
37
35
  } catch {
38
36
  throw StartLiveActivityException(error.localizedDescription)
@@ -40,10 +38,31 @@ final class LiveActivityFactory: SharedObject {
40
38
  }
41
39
 
42
40
  func getInstances() throws -> [LiveActivity] {
43
- guard #available(iOS 16.1, *) else { throw LiveActivitiesNotSupportedException() }
41
+ guard #available(iOS 16.2, *) else { throw LiveActivitiesNotSupportedException() }
42
+
43
+ let activities = Activity<LiveActivityAttributes>.activities
44
+ // Filter LiveActivity instances for activities that don't match the factory's name.
45
+ .filter { $0.content.state.name == name }
46
+ // A stale activity is still visible and updatable; only ended/dismissed ones are gone.
47
+ .filter { $0.activityState == .active || $0.activityState == .stale }
48
+
49
+ let activeIDs = Set(activities.map(\.id))
50
+ instances = instances.filter { activeIDs.contains($0.key) }
51
+
52
+ return activities.map { activity in
53
+ if let instance = instances[activity.id] {
54
+ instance.observePushTokenUpdates(for: activity, pushNotificationsEnabled: Self.pushNotificationsEnabled)
55
+ return instance
56
+ }
44
57
 
45
- return Activity<LiveActivityAttributes>.activities.map { activity in
46
- LiveActivity(id: activity.id, name: name)
58
+ let instance = LiveActivity(id: activity.id, name: name)
59
+ instance.observePushTokenUpdates(for: activity, pushNotificationsEnabled: Self.pushNotificationsEnabled)
60
+ instances[activity.id] = instance
61
+ return instance
47
62
  }
48
63
  }
64
+
65
+ override func sharedObjectWillRelease() {
66
+ instances.removeAll()
67
+ }
49
68
  }
@@ -56,13 +56,6 @@ func getLiveActivityNodes(forName name: String, props: String = "{}", environmen
56
56
  }
57
57
  }
58
58
 
59
- func getLiveActivityUrl(forName name: String) -> URL? {
60
- guard let urlString = WidgetsStorage.getString(forKey: "__expo_widgets_live_activity_\(name)_url") else {
61
- return nil
62
- }
63
- return URL(string: urlString)
64
- }
65
-
66
59
  public func getWidgetEnvironment(environment: EnvironmentValues) -> [String: Any] {
67
60
  var env: [String: Any] = [
68
61
  "showsContainerBackground": environment.showsWidgetContainerBackground,
@@ -89,16 +82,19 @@ public func getWidgetEnvironment(environment: EnvironmentValues) -> [String: Any
89
82
  return env
90
83
  }
91
84
 
92
- func getLiveActivityEnvironment(environment: EnvironmentValues) -> [String: Any] {
85
+ // ActivityViewContext requires iOS 16.1. Without the availability attribute, precompiling
86
+ // this package fails: the SwiftPM prebuild targets iOS 16.0 (spm.config.json), unlike the
87
+ // podspec (16.4). Both callers live in @available(iOS 16.1, *) views.
88
+ @available(iOS 16.1, *)
89
+ func getLiveActivityEnvironment(for environment: EnvironmentValues, in context: ActivityViewContext<LiveActivityAttributes>) -> [String: Any] {
93
90
  var env: [String: Any] = [
94
91
  "colorScheme": "\(environment.colorScheme)"
95
92
  ]
96
93
 
97
- if #available(iOS 16.0, *) {
98
- env["isLuminanceReduced"] = environment.isLuminanceReduced
99
- }
100
- if #available(iOS 16.1, *) {
101
- env["isActivityFullscreen"] = environment.isActivityFullscreen
94
+ env["isLuminanceReduced"] = environment.isLuminanceReduced
95
+ env["isActivityFullscreen"] = environment.isActivityFullscreen
96
+ if #available(iOS 16.2, *) {
97
+ env["isStale"] = context.isStale
102
98
  }
103
99
  if #available(iOS 18.0, *) {
104
100
  env["isActivityUpdateReduced"] = environment.isActivityUpdateReduced
@@ -4,10 +4,18 @@ import ExpoModulesCore
4
4
  import ActivityKit
5
5
 
6
6
  struct LiveActivityAttributes: ActivityAttributes {
7
+ // The deep link URL passed to start(). Stored in the static attributes so it is
8
+ // scoped to this activity and survives content updates, unlike ContentState.
9
+ var url: String?
10
+
7
11
  public struct ContentState: Codable, Hashable {
8
12
  var name: String
9
13
  var props: String
10
14
  }
15
+
16
+ init(url: String? = nil) {
17
+ self.url = url
18
+ }
11
19
  }
12
20
 
13
21
  @available(iOS 16.1, *)
@@ -15,10 +23,6 @@ public struct WidgetLiveActivity: Widget {
15
23
  @Environment(\.self) var env
16
24
 
17
25
  let widgetContext: AppContext = AppContext()
18
-
19
- var environment: [String: Any] {
20
- return getLiveActivityEnvironment(environment: env)
21
- }
22
26
 
23
27
  public init() {}
24
28
 
@@ -27,16 +31,24 @@ public struct WidgetLiveActivity: Widget {
27
31
  let nodes = getLiveActivityNodes(
28
32
  forName: context.state.name,
29
33
  props: context.state.props,
30
- environment: environment
34
+ environment: getLiveActivityEnvironment(for: env, in: context)
31
35
  )
32
- LiveActivityBannerView(context: context, nodes: nodes)
36
+ // Only apply widgetURL when the activity has one: a hierarchy with more than one
37
+ // widgetURL modifier is undefined behavior, and layouts can set their own through
38
+ // the widgetURL modifier from @expo/ui.
39
+ let banner = LiveActivityBannerView(context: context, nodes: nodes)
40
+ if let url = context.attributes.url.flatMap(URL.init(string:)) {
41
+ banner.widgetURL(url)
42
+ } else {
43
+ banner
44
+ }
33
45
  } dynamicIsland: { context in
34
46
  let nodes = getLiveActivityNodes(
35
47
  forName: context.state.name,
36
48
  props: context.state.props,
37
- environment: environment
49
+ environment: getLiveActivityEnvironment(for: env, in: context)
38
50
  )
39
- return DynamicIsland {
51
+ let island = DynamicIsland {
40
52
  DynamicIslandExpandedRegion(.center) {
41
53
  LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedCenter")
42
54
  }
@@ -56,7 +68,10 @@ public struct WidgetLiveActivity: Widget {
56
68
  } minimal: {
57
69
  LiveActivitySectionView(context: context, nodes: nodes, sectionName: "minimal")
58
70
  }
59
- .widgetURL(getLiveActivityUrl(forName: context.state.name))
71
+ if let url = context.attributes.url.flatMap(URL.init(string:)) {
72
+ return island.widgetURL(url)
73
+ }
74
+ return island
60
75
  }
61
76
  .supplementalActivityFamiliesIfAvailable()
62
77
  }
@@ -86,8 +86,8 @@ public final class WidgetsModule: Module {
86
86
  LiveActivityFactory(name: name, layout: layout)
87
87
  }
88
88
 
89
- Function("start") { (liveActivity: LiveActivityFactory, props: String, url: URL?) in
90
- try liveActivity.start(props: props, url: url)
89
+ Function("start") { (liveActivity: LiveActivityFactory, props: String, url: URL?, staleDate: Date?) in
90
+ return try liveActivity.start(props: props, url: url, staleDate: staleDate)
91
91
  }
92
92
 
93
93
  Function("getInstances") { (liveActivity: LiveActivityFactory) in
@@ -96,8 +96,12 @@ public final class WidgetsModule: Module {
96
96
  }
97
97
 
98
98
  Class("LiveActivity", LiveActivity.self) {
99
- AsyncFunction("update") { (instance: LiveActivity, props: String) in
100
- try await instance.update(props: props)
99
+ Function("getId") { (instance: LiveActivity) in
100
+ instance.id
101
+ }
102
+
103
+ AsyncFunction("update") { (instance: LiveActivity, props: String, staleDate: Date?) in
104
+ try await instance.update(props: props, staleDate: staleDate)
101
105
  }
102
106
 
103
107
  AsyncFunction("end") { (instance: LiveActivity, dismissalPolicy: LiveActivityDismissalPolicy?, afterDate: Date?, props: String?, contentDate: Date?) in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-widgets",
3
- "version": "57.0.11",
3
+ "version": "57.0.13",
4
4
  "description": "Widgets.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -22,15 +22,15 @@
22
22
  "homepage": "https://docs.expo.dev/versions/latest/sdk/widgets/",
23
23
  "dependencies": {
24
24
  "@expo/plist": "^0.8.1",
25
- "@expo/ui": "~57.0.12"
25
+ "@expo/ui": "~57.0.14"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@expo/spawn-async": "^1.8.0",
29
29
  "@types/node": "^22.14.0",
30
30
  "@types/react": "~19.2.0",
31
- "react-native": "0.86.2",
31
+ "react-native": "0.86.3",
32
32
  "resolve-workspace-root": "^2.0.0",
33
- "expo": "57.0.15",
33
+ "expo": "57.0.17",
34
34
  "expo-module-scripts": "56.0.3"
35
35
  },
36
36
  "peerDependencies": {
@@ -44,7 +44,7 @@
44
44
  "./scripts/xcode-build-bundle.sh"
45
45
  ]
46
46
  },
47
- "gitHead": "499024a441d67293aa60afcbe02051999a54f1bb",
47
+ "gitHead": "c300d2cc60c9e684e64f48d9bc90ea18a571d01d",
48
48
  "scripts": {
49
49
  "build": "expo-module build",
50
50
  "build:plugin": "expo-module build plugin",
@@ -21,6 +21,9 @@ class WidgetStub {
21
21
  }
22
22
 
23
23
  class LiveActivityStub {
24
+ getId(): string {
25
+ return '';
26
+ }
24
27
  async update(_props: string): Promise<void> {}
25
28
  async end(
26
29
  _dismissalPolicy?: string,
package/src/Widgets.ts CHANGED
@@ -78,12 +78,20 @@ export class LiveActivity<T extends object = object> {
78
78
  this.nativeLiveActivity = nativeLiveActivity;
79
79
  }
80
80
 
81
+ /**
82
+ * Returns the stable ActivityKit identifier for this Live Activity.
83
+ */
84
+ getId(): string {
85
+ return this.nativeLiveActivity.getId();
86
+ }
87
+
81
88
  /**
82
89
  * Updates the Live Activity's content. The UI reflects the new properties immediately.
83
90
  * @param props The updated content properties.
91
+ * @param staleDate When set, the system may de-emphasize the activity after this date if content has not been refreshed.
84
92
  */
85
- update(props: T): Promise<void> {
86
- return this.nativeLiveActivity.update(JSON.stringify(props));
93
+ update(props: T, staleDate?: Date): Promise<void> {
94
+ return this.nativeLiveActivity.update(JSON.stringify(props), staleDate?.getTime());
87
95
  }
88
96
 
89
97
  /**
@@ -151,10 +159,13 @@ export class LiveActivityFactory<T extends object = object> {
151
159
  * Starts a new Live Activity with the given properties.
152
160
  * @param props The initial content properties for the Live Activity.
153
161
  * @param url An optional URL to associate with the Live Activity, used for deep linking.
162
+ * @param staleDate When set, the system may de-emphasize the activity after this date if content has not been refreshed.
154
163
  * @returns The new Live Activity instance.
155
164
  */
156
- start(props: T, url?: string) {
157
- return new LiveActivity<T>(this.nativeLiveActivityFactory.start(JSON.stringify(props), url));
165
+ start(props: T, url?: string, staleDate?: Date) {
166
+ return new LiveActivity<T>(
167
+ this.nativeLiveActivityFactory.start(JSON.stringify(props), url, staleDate?.getTime())
168
+ );
158
169
  }
159
170
 
160
171
  /**
@@ -114,6 +114,15 @@ export type LiveActivityEnvironment = {
114
114
  * @platform iOS 16.1+
115
115
  */
116
116
  isActivityFullscreen?: boolean;
117
+ /**
118
+ * Whether the activity's content is out of date, based on the `staleDate` passed to
119
+ * `LiveActivityFactory.start()` or `LiveActivity.update()`.
120
+ *
121
+ * Use it to de-emphasize content the system can no longer vouch for. It becomes `true`
122
+ * without the app running, so a Live Activity can degrade while the app is suspended.
123
+ * @platform iOS 16.2+
124
+ */
125
+ isStale?: boolean;
117
126
  /**
118
127
  * A Boolean value that indicates whether the Live Activity update synchronization rate is reduced.
119
128
  * @platform iOS 18+
@@ -281,12 +290,13 @@ export declare class NativeWidgetObject extends SharedObject {
281
290
 
282
291
  export declare class NativeLiveActivityFactory extends SharedObject {
283
292
  constructor(name: string, layout: string);
284
- start(props: string, url?: string): NativeLiveActivity;
293
+ start(props: string, url?: string, staleDate?: number): NativeLiveActivity;
285
294
  getInstances(): NativeLiveActivity[];
286
295
  }
287
296
 
288
297
  export declare class NativeLiveActivity extends SharedObject<LiveActivityEvents> {
289
- update(props: string): Promise<void>;
298
+ getId(): string;
299
+ update(props: string, staleDate?: number): Promise<void>;
290
300
  end(
291
301
  dismissalPolicy?: string,
292
302
  afterDate?: number,