feat(FF): Add android in app update - #10976
Conversation
a18fc14 to
2b81a87
Compare
2b81a87 to
3a9bdad
Compare
3a9bdad to
57d181e
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR implements Android In-App Updates functionality that allows users to update the app without going to the Play Store. The implementation uses Google Play's App Update API to check for available updates and handle the update process with user notifications.
Key changes:
- Adds Android In-App Update functionality using Google Play's App Update API
- Implements update checking and notification system with React Native bridge
- Adds toast notifications to prompt users when updates are downloaded
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| src/setupJest.tsx | Adds Jest mocks for new update-related native module methods |
| src/app/utils/usePromptForUpdate.tsx | New hook that manages update checking and user notifications |
| src/app/Scenes/HomeView/HomeView.tsx | Integrates the update prompt hook into the home screen |
| src/app/NativeModules/ArtsyNativeModule.tsx | Adds React Native bridge methods for update functionality |
| android/app/src/main/java/net/artsy/app/MainActivity.kt | Implements Android In-App Update logic using Google Play API |
| android/app/src/main/java/net/artsy/app/ArtsyNativeModule.java | Adds native module methods to bridge update functionality to React Native |
| android/app/build.gradle | Adds Google Play App Update dependencies |
Comments suppressed due to low confidence (1)
src/app/NativeModules/ArtsyNativeModule.tsx:27
- The hardcoded timeout value 12000 is a magic number. Consider extracting this to a named constant with a descriptive name that explains why this delay is necessary.
}
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| checkForAppUpdate: | ||
| Platform.OS === "ios" | ||
| ? () => { | ||
| console.error("checkForAppUpdate is not supported on iOS") |
There was a problem hiding this comment.
outside scope of this pr, but I wonder if there is a way to get errors at type check time or with eslint when we use a native module without a platform check.
brainbicycle
left a comment
There was a problem hiding this comment.
the code and experience looks really great and good to have the capability!
I am wondering what our policy should be about using this? maybe a discussion for mobile practice or a separate meeting?
|
@cursor review |
There was a problem hiding this comment.
Bugbot free trial expires on September 8, 2025
Learn more in the Cursor dashboard.
MounirDhahri
left a comment
There was a problem hiding this comment.
Nice one! LGTM as well. Let's discuss how aggressive we want to be with this
| setTimeout(() => { | ||
| // delay prompt until homescreen loads | ||
| ArtsyNativeModule.checkForAppUpdate() | ||
| }, 12000) |
There was a problem hiding this comment.
The home screen takes no more than 3 seconds to load - so we can maybe decrease this
There was a problem hiding this comment.
I tried 5,7, and 10, and the update prompt shows up so quickly that before the homescreen loads 😅 so I went with 15 and was too long, so I ended up with 12 and it was perfect
6073203
6073203 to
a0650d9
Compare
|
Adds Android In-App Updates via the Play Core |
| completeAppUpdate: | ||
| Platform.OS === "ios" | ||
| ? console.error("completeAppUpdate is unsupported on iOS") | ||
| : NativeModules.ArtsyNativeModule.completeAppUpdate, |
There was a problem hiding this comment.
This calls console.error at import time and assigns its return value (undefined) to completeAppUpdate. ArtsyNativeModule is imported at app startup, so every iOS launch logs "completeAppUpdate is unsupported on iOS" even when the method is never called, and ArtsyNativeModule.completeAppUpdate is undefined rather than a callable no-op. Wrap it in a function like checkForAppUpdate above.
| : NativeModules.ArtsyNativeModule.completeAppUpdate, | |
| completeAppUpdate: | |
| Platform.OS === "ios" | |
| ? () => { | |
| console.error("completeAppUpdate is unsupported on iOS") | |
| } | |
| : NativeModules.ArtsyNativeModule.completeAppUpdate, |
| setTimeout(() => { | ||
| // delay prompt until homescreen loads | ||
| ArtsyNativeModule.checkForAppUpdate() | ||
| }, 12000) |
There was a problem hiding this comment.
🟢 The 12s timer isn't cleared on unmount. If the user leaves Home before it fires, checkForAppUpdate still runs (and the whole flow re-arms every time Home remounts). Keep the id and clear it in the cleanup alongside eventListener.remove():
| setTimeout(() => { | |
| // delay prompt until homescreen loads | |
| ArtsyNativeModule.checkForAppUpdate() | |
| }, 12000) | |
| const timeoutId = setTimeout(() => { | |
| // delay prompt until homescreen loads | |
| ArtsyNativeModule.checkForAppUpdate() | |
| }, 12000) |
Then add clearTimeout(timeoutId) to the returned cleanup.
| * This is used to check for app updates on every app launch. | ||
| * Also monitors for downloaded updates and shows restart toast. | ||
| */ | ||
| export const usePromptForUpdate = () => { |
There was a problem hiding this comment.
🟡 No test covers this hook. Worth one that mocks ArtsyNativeModule and asserts: on Android the toast shows when updateDownloaded is true and when the onAppUpdateDownloaded event fires, the toast CTA calls completeAppUpdate, and nothing runs on iOS. That would also have caught the completeAppUpdate shim bug flagged in ArtsyNativeModule.tsx.
This PR resolves []
Description
This PR adds the native Android In-App Updates
android-in-app-updates-demo-low.mp4