From 384987262bd8511552065f092e046abae43b9bc8 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 Jul 2026 22:50:25 +0300 Subject: [PATCH] check for a deployment before prompting to apply it Reloading into an update re-delivers the deep link that triggered it, and the same link can also just be tapped again. Checking first means both cases are silent when there is nothing new to apply - the version mismatch warning no longer fires ahead of the check either. Co-Authored-By: Claude Fable 5 --- src/lib/hooks/useIntentHandler.ts | 4 +-- src/lib/hooks/useOTAUpdates.ts | 50 +++++++++++++++++++------------ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts index 61bc201467..71a3437ad2 100644 --- a/src/lib/hooks/useIntentHandler.ts +++ b/src/lib/hooks/useIntentHandler.ts @@ -94,9 +94,9 @@ export function useIntentHandler() { : null if (!channel) { Alert.alert('Error', 'No channel provided to look for.') - } else { - tryApplyUpdate(channel, appVersion) + return } + tryApplyUpdate(channel, appVersion) return } default: { diff --git a/src/lib/hooks/useOTAUpdates.ts b/src/lib/hooks/useOTAUpdates.ts index 048f98ed53..7b7224bcb0 100644 --- a/src/lib/hooks/useOTAUpdates.ts +++ b/src/lib/hooks/useOTAUpdates.ts @@ -168,6 +168,12 @@ export function useApplyPullRequestOTAUpdate() { updateId: fetchedUpdate.manifest.id, }) try { + /* + * TODO: once expo-linking is upgraded to >= 57, enable this so the + * re-delivered initial URL doesn't trigger a redundant silent check + * after the reload. + */ + // Linking.clearInitialURL() await reloadAsync() } catch (e) { device.remove(['pendingOTAUpdate']) @@ -186,29 +192,35 @@ export function useApplyPullRequestOTAUpdate() { })() } - if (declaredAppVersion && declaredAppVersion !== APP_VERSION) { - Alert.alert( - 'App Version Mismatch', - `This OTA update was built for a different version of the app.\n\nCurrent app version: ${APP_VERSION}\nOTA app version: ${declaredAppVersion}\n\nApplying it anyway may cause the app to stop working and require a reinstall.`, - [ - { - text: 'Cancel', - style: 'cancel', - }, - { - text: 'Apply Anyway', - style: 'destructive', - onPress: applyUpdate, - }, - ], - ) - return - } - + /* + * Check before prompting about anything, so that re-running this while + * already on the newest update of `channel` stays silent. Reloading into an + * update re-delivers the deep link that triggered it, and the same link may + * also just be tapped again. + */ setPending(true) try { if (!(await checkForDeployment())) return + if (declaredAppVersion && declaredAppVersion !== APP_VERSION) { + Alert.alert( + 'App Version Mismatch', + `This OTA update was built for a different version of the app.\n\nCurrent app version: ${APP_VERSION}\nOTA app version: ${declaredAppVersion}\n\nApplying it anyway may cause the app to stop working and require a reinstall.`, + [ + { + text: 'Cancel', + style: 'cancel', + }, + { + text: 'Apply Anyway', + style: 'destructive', + onPress: applyUpdate, + }, + ], + ) + return + } + Alert.alert( `Apply update from ${deploymentName}?`, 'The app will relaunch after the update is applied.',