authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-10-03 10:24:23-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-03 10:24:23-07:00
log77823bd102ae50430d4acda9a553e5743d2aa5ba
tree9115820c6aecfce185cbcfecdbefc76a3997218b
parent65731f986ba2175063b0182deb6a143f8f323b74
signature Signed by PGP key B5690EEEBB952194

fix(mobile): an expired Live Activity no longer leaves a second card (#15254)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

2 files changed, 28 insertions(+), 9 deletions(-)

patches/expo-widgets@58.0.11.patch+24-5
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1diff --git a/build/Widgets.types.d.ts b/build/Widgets.types.d.ts1diff --git a/build/Widgets.types.d.ts b/build/Widgets.types.d.ts
2index c9f4dfe..dc0792e 1006442index c9f4dfe1f10a3a65ab72bd7e639f6f6d148e5f95..dc0792e1cd7b6762394de5e3fefa0863a253f70c 100644
3--- a/build/Widgets.types.d.ts3--- a/build/Widgets.types.d.ts
4+++ b/build/Widgets.types.d.ts4+++ b/build/Widgets.types.d.ts
5@@ -93,6 +93,10 @@ export type LiveActivityEnvironment = {5@@ -93,6 +93,10 @@ export type LiveActivityEnvironment = {
...@@ -13,8 +13,27 @@ index c9f4dfe..dc0792e 100644...@@ -13,8 +13,27 @@ index c9f4dfe..dc0792e 100644
13 /**13 /**
14 * Whether the activity is displayed in a context with reduced luminance.14 * Whether the activity is displayed in a context with reduced luminance.
15 * @platform iOS 16+15 * @platform iOS 16+
16diff --git a/ios/LiveActivityFactory.swift b/ios/LiveActivityFactory.swift
17index 29e4f1566d188665e301d32bc1ad85640f83e68c..7143f9a1c06245d16649b981d7f5cde1d8868217 100644
18--- a/ios/LiveActivityFactory.swift
19+++ b/ios/LiveActivityFactory.swift
20@@ -19,6 +19,14 @@ final class LiveActivityFactory: SharedObject {
21 throw LiveActivitiesNotSupportedException()
22 }
23
24+ // iOS ends an activity after 8 hours but leaves it frozen on the Lock Screen for up to
25+ // 4 more. getInstances() can't see it, so a caller starting a replacement would leave
26+ // both cards visible. Dismiss the ended ones now.
27+ for activity in Activity<LiveActivityAttributes>.activities
28+ where activity.content.state.name == name && activity.activityState == .ended {
29+ Task { await activity.end(nil, dismissalPolicy: .immediate) }
30+ }
31+
32 do {
33 let initialState = LiveActivityAttributes.ContentState(name: name, props: props)
34 let activity = try Activity.request(
16diff --git a/ios/Widgets/Utils.swift b/ios/Widgets/Utils.swift35diff --git a/ios/Widgets/Utils.swift b/ios/Widgets/Utils.swift
17index 76b2199..6cb52c3 10064436index 76b2199c2d3f879463fed5d2bd49038b0428a2e7..6cb52c3de4ad9696bc0c51ad62401cce96f405e7 100644
18--- a/ios/Widgets/Utils.swift37--- a/ios/Widgets/Utils.swift
19+++ b/ios/Widgets/Utils.swift38+++ b/ios/Widgets/Utils.swift
20@@ -125,6 +125,10 @@ func getLiveActivityEnvironment(for environment: EnvironmentValues, in context:39@@ -125,6 +125,10 @@ func getLiveActivityEnvironment(for environment: EnvironmentValues, in context:
...@@ -29,7 +48,7 @@ index 76b2199..6cb52c3 100644...@@ -29,7 +48,7 @@ index 76b2199..6cb52c3 100644
29 env["isActivityUpdateReduced"] = environment.isActivityUpdateReduced48 env["isActivityUpdateReduced"] = environment.isActivityUpdateReduced
30 env["activityFamily"] = "\(environment.activityFamily)"49 env["activityFamily"] = "\(environment.activityFamily)"
31diff --git a/ios/Widgets/WidgetLiveActivity.swift b/ios/Widgets/WidgetLiveActivity.swift50diff --git a/ios/Widgets/WidgetLiveActivity.swift b/ios/Widgets/WidgetLiveActivity.swift
32index 4d135c4..dae4744 10064451index 4d135c4e4eb1f846315654ed9d835a935d120d42..dae47445b27516fa2464a25b68bddc8f6dec3e1e 100644
33--- a/ios/Widgets/WidgetLiveActivity.swift52--- a/ios/Widgets/WidgetLiveActivity.swift
34+++ b/ios/Widgets/WidgetLiveActivity.swift53+++ b/ios/Widgets/WidgetLiveActivity.swift
35@@ -19,53 +19,41 @@ struct LiveActivityAttributes: ActivityAttributes {54@@ -19,53 +19,41 @@ struct LiveActivityAttributes: ActivityAttributes {
...@@ -132,7 +151,7 @@ index 4d135c4..dae4744 100644...@@ -132,7 +151,7 @@ index 4d135c4..dae4744 100644
132 LiveActivityBanner(context: context, nodes: nodes)151 LiveActivityBanner(context: context, nodes: nodes)
133 } else if let node = nodes["banner"] as? [String: Any] {152 } else if let node = nodes["banner"] as? [String: Any] {
134diff --git a/scripts/build-layout-registry.mjs b/scripts/build-layout-registry.mjs153diff --git a/scripts/build-layout-registry.mjs b/scripts/build-layout-registry.mjs
135index d52a60e..fa9bd77 100644154index d52a60e342c8e0a8a1d78f7174da5e60e6bd1c53..fa9bd77c5c04d459038a5b4a00e1391780b406fa 100644
136--- a/scripts/build-layout-registry.mjs155--- a/scripts/build-layout-registry.mjs
137+++ b/scripts/build-layout-registry.mjs156+++ b/scripts/build-layout-registry.mjs
138@@ -154,6 +154,8 @@ function createLayoutRegistry(expectedWidgets, capturedLayouts) {157@@ -154,6 +154,8 @@ function createLayoutRegistry(expectedWidgets, capturedLayouts) {
...@@ -146,7 +165,7 @@ index d52a60e..fa9bd77 100644...@@ -146,7 +165,7 @@ index d52a60e..fa9bd77 100644
146 await main();165 await main();
147 }166 }
148diff --git a/src/Widgets.types.ts b/src/Widgets.types.ts167diff --git a/src/Widgets.types.ts b/src/Widgets.types.ts
149index 0770613..924fa00 100644168index 07706139379384dae27befef4e3e5ae09d04a0db..924fa0029243664e369ce08c81e504b6300bfc7f 100644
150--- a/src/Widgets.types.ts169--- a/src/Widgets.types.ts
151+++ b/src/Widgets.types.ts170+++ b/src/Widgets.types.ts
152@@ -107,6 +107,10 @@ export type LiveActivityEnvironment = {171@@ -107,6 +107,10 @@ export type LiveActivityEnvironment = {
pnpm-lock.yaml+4-4
...@@ -108,7 +108,7 @@ patchedDependencies:...@@ -108,7 +108,7 @@ patchedDependencies:
108 expo-blur@58.0.3: d0311b0c0b05bd94393bd9a84653cb42503d5f3c8a19eb2627c34ace08bedf18108 expo-blur@58.0.3: d0311b0c0b05bd94393bd9a84653cb42503d5f3c8a19eb2627c34ace08bedf18
109 expo-glass-effect@58.0.3: f750041c45ab838a3530451dc7b50d6640a79141037a1b0499c5e3412a860c57109 expo-glass-effect@58.0.3: f750041c45ab838a3530451dc7b50d6640a79141037a1b0499c5e3412a860c57
110 expo-sharing@58.0.13: fe40d857765bcd6a77aac1fed275e5b8f9415c29b972decdce05fb96de5665e6110 expo-sharing@58.0.13: fe40d857765bcd6a77aac1fed275e5b8f9415c29b972decdce05fb96de5665e6
111 expo-widgets@58.0.11: 94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b111 expo-widgets@58.0.11: d00838b5b215a4c45f89b8b7d34878d158528756fbcf281bae1cbd6f0752deed
112 node-pty@1.2.0-beta.15: f2fe901c61cde17986240002d05c172d5d0272d83ffaab8d0ebeb922763be414112 node-pty@1.2.0-beta.15: f2fe901c61cde17986240002d05c172d5d0272d83ffaab8d0ebeb922763be414
113 react-native-gesture-handler@3.2.1: d518a937e3cb2df5e7d67f1ab6b265c74a8639e4572d1b032b7b747e9b1c01a9113 react-native-gesture-handler@3.2.1: d518a937e3cb2df5e7d67f1ab6b265c74a8639e4572d1b032b7b747e9b1c01a9
114 react-native-keyboard-controller@1.22.6: 6e448411781347cd0b87868ee279117514a399801c18f233ddca4fa3935be75d114 react-native-keyboard-controller@1.22.6: 6e448411781347cd0b87868ee279117514a399801c18f233ddca4fa3935be75d
...@@ -431,7 +431,7 @@ importers:...@@ -431,7 +431,7 @@ importers:
431 version: 58.0.4(expo@58.0.2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))431 version: 58.0.4(expo@58.0.2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))
432 expo-widgets:432 expo-widgets:
433 specifier: 58.0.11433 specifier: 58.0.11
434 version: 58.0.11(patch_hash=94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b)(@babel/core@7.29.7)(expo@58.0.2)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)434 version: 58.0.11(patch_hash=d00838b5b215a4c45f89b8b7d34878d158528756fbcf281bae1cbd6f0752deed)(@babel/core@7.29.7)(expo@58.0.2)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)
435 react:435 react:
436 specifier: 19.3.0436 specifier: 19.3.0
437 version: 19.3.0437 version: 19.3.0
...@@ -16305,7 +16305,7 @@ snapshots:...@@ -16305,7 +16305,7 @@ snapshots:
16305 optionalDependencies:16305 optionalDependencies:
16306 '@babel/runtime': 7.29.716306 '@babel/runtime': 7.29.7
16307 expo: 58.0.2(56fc8ddb8129740412739f0f0a6ee025)16307 expo: 58.0.2(56fc8ddb8129740412739f0f0a6ee025)
16308 expo-widgets: 58.0.11(patch_hash=94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b)(@babel/core@7.29.7)(expo@58.0.2)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)16308 expo-widgets: 58.0.11(patch_hash=d00838b5b215a4c45f89b8b7d34878d158528756fbcf281bae1cbd6f0752deed)(@babel/core@7.29.7)(expo@58.0.2)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)
16309 transitivePeerDependencies:16309 transitivePeerDependencies:
16310 - '@babel/core'16310 - '@babel/core'
16311 - supports-color16311 - supports-color
...@@ -17535,7 +17535,7 @@ snapshots:...@@ -17535,7 +17535,7 @@ snapshots:
17535 expo: 58.0.2(56fc8ddb8129740412739f0f0a6ee025)17535 expo: 58.0.2(56fc8ddb8129740412739f0f0a6ee025)
17536 react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)17536 react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)
1753717537
17538 expo-widgets@58.0.11(patch_hash=94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b)(@babel/core@7.29.7)(expo@58.0.2)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0):17538 expo-widgets@58.0.11(patch_hash=d00838b5b215a4c45f89b8b7d34878d158528756fbcf281bae1cbd6f0752deed)(@babel/core@7.29.7)(expo@58.0.2)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0):
17539 dependencies:17539 dependencies:
17540 '@expo/plist': 0.10.117540 '@expo/plist': 0.10.1
17541 '@expo/ui': 58.0.11(@babel/core@7.29.7)(expo@58.0.2)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)17541 '@expo/ui': 58.0.11(@babel/core@7.29.7)(expo@58.0.2)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)