Repository navigation
Conversation
Brings back the update banner from 072ffe5, which was dropped when main was synced to the SnapBiodata app in 1574658. - Point store lookup at SnapBiodata (App Store 6791839989, com.snapbiodata.app) - Mount the banner under the Home screen header - Restyle with the app's theme colours - Add sp-react-native-in-app-updates and Jest mocks Requires a new native build; not deliverable via OTA alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- No empty gap on Home when the banner is hidden (spacing moves into the banner and only renders when visible) - iOS: open the App Store directly instead of a second confirm alert - Android: drop the version badge (Play Core reports versionCode, not a display version) - Compare against the installed binary's version, not package.json, which an OTA bundle can change - Keep the check throttle across Home remounts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Podfile post_install: raise pod deployment targets below 15.1 (newer Xcode rejects them) and compile the fmt pod as C++17 (fmt 11.0.2 bundled with RN 0.81 fails under newer Apple clang with "call to consteval function ... is not a constant expression"). - run-ios.sh: "$SIM_NAME…" made bash read the ellipsis as part of the variable name and abort with "unbound variable"; brace it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fb12756 moved app.config.js to EAS project ca1367f7 (@agastyaai/snapbiodata) but Expo.plist and AndroidManifest.xml still pointed at the old project 46cb38f5. `eas update` publishes to the app.config project, so builds never saw those updates. Native builds made from now on check the right project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the Home-only banner with a bottom sheet mounted at the app root, so it shows on every screen (Home, Editor, Preview). - New store build → "New version available" → App Store page (iOS) or Play in-app update (Android) - OTA downloaded → "Update ready" → restart into the new bundle - With both pending, the store prompt shows first; "Later" on it slides it down and brings up the OTA prompt - Foreground checks now download a found OTA, so "Update ready" appears without waiting for a cold start - sp-react-native-in-app-updates is required lazily: it pulls in react-native-device-info, which throws at import on binaries without the native module (the current 1.0.0 production build, same runtime). An OTA of this code to that build skips the store check instead of crashing on launch - Dev menu items preview each prompt in debug builds - Pin react-native-device-info 14.1.1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Port Agastya's scripts/sync-version.js: `yarn version:bump <x.y.z>` sets package.json and syncs Android versionName, iOS MARKETING_VERSION and the OTA runtime version (strings.xml, Expo.plist); fails loudly if a pattern is missing - app.config.js runtimeVersion now follows package.json, so an OTA only reaches binaries of the release it was published from (1.0.1 adds native modules the 1.0.0 binary lacks) - 1.0.1: 1.0.0 is live on the App Store, which won't accept new builds for a released version, and the in-app "New version available" prompt needs a higher store version to fire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Gear button in the Home header opens Settings; a gold dot on it shows
when a store update or a downloaded OTA is waiting
- "App updates" card with four states: up to date (+ "Check for
updates", last-checked time), new store version (installed → store
version, App Store "What's new" on iOS, "Update now"), OTA ready
("Restart now"), and OTA downloading
- About: installed version + build, and when the running OTA was
published (an OTA doesn't change the version number)
- Update state moved into one shared store (useSyncExternalStore) so the
prompt, the gear dot and Settings always agree
- The bottom-sheet prompt is hidden, not unmounted, on Settings, so a
"Later" is still remembered back on Home
- Dev menu: "Preview update prompt: Off" to leave a preview
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Play production submit: changesNotSentForReview + explicit applicationId, as in Agastya. Without changesNotSentForReview the Play API tries to send the release for review itself and rejects the upload whenever the console needs changes sent manually, so nothing lands on the production track - Staging Android submit: internal track, releaseStatus completed - Explicit EAS `environment` per profile; staging-apk / production-apk profiles for direct installs - WHATS_NEW.txt flow: production deploy/submit show the notes, ask to confirm, then sync them to iOS/Android fastlane metadata - eas:update:* now prompt for the message and confirm before publishing - WHATS_NEW.txt for 1.0.2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…here is one - Settings shows no update UI at all when the app is up to date (only the version); the "App updates" card and "Check for updates" are gone - When a store update or a downloaded OTA exists: one "Update Available · New ›" row at the top - iOS store update: tapping asks "There is an updated version (x) available on the App Store. Would you like to upgrade?" (Upgrade / Cancel); Android goes straight to Google's in-app update screen, which is its own confirm - OTA: "Update Ready" alert with Restart / Later - About row renamed "Last updated" (when the running OTA was published) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.0.2 shipped from tag v1.0.2 (Android 29, iOS 52). From here, OTAs published from this branch target 1.0.3 builds; OTA fixes for 1.0.2 users must be published from v1.0.2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The store check compares versions inside sp-react-native-in-app-updates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
In-app update prompts for both kinds of update, Zepto/Blinkit style, shown only when an update exists:
Plus a Settings screen, release tooling aligned with the Agastya app, and a few build/OTA fixes found along the way.
Shipped as 1.0.2 (tag
v1.0.2; Android versionCode 29, iOS build 52). Branch is now at 1.0.3.Visual walkthrough of every scenario: https://claude.ai/artifact/9CukaMG2xRRBrK6sqHQpi5
What the user sees
Version 1.0.2 (52).How it works
react-native-device-info→getVersion()(nativeMARKETING_VERSION/versionName), notpackage.jsonsp-react-native-in-app-updates→https://itunes.apple.com/lookup?bundleId=<production bundle id>, semver comparesp-react-native-in-app-updates→ Play CoreAppUpdateManager(installed vs available versionCode; only works for Play installs)expo-updates:checkForUpdateAsync()thenfetchUpdateAsync();useUpdates().isUpdatePendingdrives "ready"Checks run on mount and when the app returns to the foreground, throttled to once a minute. All state lives in one shared store (
useSyncExternalStore), so the sheet, the gear dot and Settings always agree.Runtime version = app version (
app.config.js, synced toExpo.plist/strings.xmlbyyarn version:bump). An OTA only reaches builds of the version it was published from. Never bump the version for an OTA; bump only for store builds.Files
Core: port these
src/hooks/useAppUpdates.tsstoreUpdateAvailable,otaReady,otaDownloading,hasUpdate,latestStoreVersion,applyOta(),goToStore(). Dev-menu previews (Cmd+D → "Preview update prompt: Store / OTA / Store + OTA / Off").src/hooks/updateState.tsresolvePrompt(): store first, then OTA, respecting "Later".src/services/storeUpdate.tsrequireofsp-react-native-in-app-updates:react-native-device-infothrows at import when its native module is missing, so a top-level import crashes any older binary that receives this JS via OTA.src/constants/appUpdate.tssrc/components/AppUpdatePrompt.tsxModal). Mounted once at the app root,hiddenprop instead of unmounting (keeps "Later"). Slides out before swapping store → OTA.src/screens/SettingsScreen.tsxsrc/screens/HomeScreen.tsxhasUpdate).App.tsx<AppUpdatePrompt hidden={screen === 'settings'} />at the root; Settings route; Android back.__mocks__/expo-updates.js,__mocks__/sp-react-native-in-app-updates.js,jest.config.jssrc/hooks/__tests__/updateState.test.ts,src/components/__tests__/AppUpdatePrompt.test.tsx,src/screens/__tests__/SettingsScreen.test.tsxRelease tooling (already in Agastya; ported from there)
scripts/sync-version.js(yarn version:bump x.y.z),scripts/confirm-release-notes.js,scripts/sync-release-notes.js,scripts/eas-update.js,WHATS_NEW.txt,eas.json(changesNotSentForReview, APK profiles,environment).Repo-specific fixes (probably not needed elsewhere)
fb033e6:Expo.plist/AndroidManifest.xmlOTA URL pointed at an old EAS project, soeas updatenever reached builds.d1b891b: Xcode 27: Podfile raises pod deployment targets to 15.1 and buildsfmtas C++17.Porting to another app (e.g. Agastya)
yarn add sp-react-native-in-app-updates(+react-native-device-infoandexpo-updatesif missing; pin device-info withresolutionsif versions conflict), thenpod install. This is native code: it only works after a new store build. OTA alone cannot deliver it; the lazyrequirekeeps older binaries from crashing.src/constants/appUpdate.ts): App Store numeric ID, Android package, iOS production bundle ID.NavigationContainer, next to the navigator. Passhiddenwhile the Settings/Profile screen is focused.storeUpdateAvailable || otaReady.C,serif,MAX_CONTENT_WIDTHfromsrc/theme.moduleNameMapperentries.runtimeVersion=versionviasync-version.js).countryis passed, so Apple searches the US store. Fine if the app is available in the US; otherwise passcountryincheckNeedsUpdate. (Verified: SnapBiodata and Agastya both resolve.)Test plan
yarn eas:update:staging→ "Update ready" → restart → "Last updated" row🤖 Generated with Claude Code