Add live updates for the webview app

This commit is contained in:
MartinBraquet
2025-11-14 18:12:29 +01:00
parent e135293b43
commit 5bf095178d
8 changed files with 70 additions and 18 deletions

View File

@@ -257,17 +257,41 @@ npx cap sync android
## 14. Deployment Workflow
```bash
# 1. Build web app for production
yarn build-web
# Build web app for production and Sync assets to Android
yarn build-sync-android
# 2. Sync assets to Android
npx cap sync android
# 3. Build signed release APK in Android Studio
# Build signed release APK in Android Studio
```
---
## Live Updates
To avoid releasing to the app stores after every code update in the web pages, we build the new bundle and store it in Capawesome Cloud (an alternative to Ionic).
First, you need to do this one-time setup:
```
npm install -g @capawesome/cli@latest
npx @capawesome/cli login
```
Then, run this to build your local assets and push them to Capawesome. Once done, each mobile app user will receive a notice that there is a new update available, which they can approve to download.
```
yarn build-web
npx @capawesome/cli apps:bundles:create --path web/out
```
That's all. So you should run the lines above every time you want your web updates pushed to main (which essentially updates the web app) to update the mobile app as well.
Maybe we should add it to our CD. For example we set a file with `{liveUpdateVersion: 1}` and run the live update each time a push to main increments that counter.
There is a limit of 100 monthly active user per month, though. So we may need to pay or create our custom limit as we scale. Next plan is $9 / month and allows 1000 MAUs.
- ∞ Live Updates
- 100 Monthly Active Users
- 500 MB of Storage (around 10 MB per update, but we just delete the previous ones)
- 5 GB of Bandwidth
---
## 15. Resources
* [Capacitor Docs](https://capacitorjs.com/docs)

View File

@@ -8,8 +8,8 @@ android {
applicationId "com.compassconnections.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 13
versionName "1.1.2"
versionCode 14
versionName "1.1.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

View File

@@ -13,6 +13,7 @@ dependencies {
implementation project(':capacitor-keyboard')
implementation project(':capacitor-push-notifications')
implementation project(':capacitor-status-bar')
implementation project(':capawesome-capacitor-live-update')
implementation project(':capgo-capacitor-social-login')
}

View File

@@ -14,5 +14,8 @@ project(':capacitor-push-notifications').projectDir = new File('../node_modules/
include ':capacitor-status-bar'
project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacitor/status-bar/android')
include ':capawesome-capacitor-live-update'
project(':capawesome-capacitor-live-update').projectDir = new File('../node_modules/@capawesome/capacitor-live-update/android')
include ':capgo-capacitor-social-login'
project(':capgo-capacitor-social-login').projectDir = new File('../node_modules/@capgo/capacitor-social-login/android')

View File

@@ -9,7 +9,12 @@ const config: CapacitorConfig = {
appId: 'com.compassconnections.app',
appName: 'Compass',
webDir: 'web/out',
server: LOCAL_ANDROID ? { url: `http://${LOCAL_URL}:3000`, cleartext: true } : {}
server: LOCAL_ANDROID ? { url: `http://${LOCAL_URL}:3000`, cleartext: true } : {},
plugins: {
LiveUpdate: {
appId: "969bc540-8077-492f-8403-b554bee5de50"
}
}
};
export default config;

View File

@@ -36,6 +36,7 @@
"@capacitor/keyboard": "7.0.3",
"@capacitor/push-notifications": "7.0.3",
"@capacitor/status-bar": "7.0.3",
"@capawesome/capacitor-live-update": "7.2.2",
"@capgo/capacitor-social-login": "7.14.9",
"@playwright/test": "^1.54.2",
"colorette": "^2.0.20",

View File

@@ -16,17 +16,30 @@ import {isAndroidWebView} from "web/lib/util/webview"
import {Capacitor} from '@capacitor/core'
import {StatusBar} from '@capacitor/status-bar'
import {App} from '@capacitor/app'
import {useRouter} from "next/navigation";
import {Keyboard} from "@capacitor/keyboard";
import {useRouter} from "next/navigation"
import {Keyboard} from "@capacitor/keyboard"
import {LiveUpdate} from "@capawesome/capacitor-live-update"
if (Capacitor.isNativePlatform()) {
// Only runs on iOS/Android native
// Note sure it's doing anything, though, need to check
StatusBar.setOverlaysWebView({overlay: false}).catch(console.warn)
// StatusBar.setStyle({style: Style.Light}).catch(console.warn)
App.addListener('backButton', () => {
window.dispatchEvent(new CustomEvent('appBackButton'))
})
App.addListener("resume", async () => {
const {nextBundleId} = await LiveUpdate.sync()
if (nextBundleId) {
// Ask the user if they want to apply the update immediately
const shouldReload = confirm("A new update is available. Would you like to install it?")
if (shouldReload) {
await LiveUpdate.reload()
}
}
})
}
@@ -73,16 +86,16 @@ function MyApp({Component, pageProps}: AppProps<PageProps>) {
useEffect(() => {
console.log('isAndroidWebView app:', isAndroidWebView())
if (!Capacitor.isNativePlatform()) return
const onShow = () => document.body.classList.add('keyboard-open');
const onHide = () => document.body.classList.remove('keyboard-open');
const onShow = () => document.body.classList.add('keyboard-open')
const onHide = () => document.body.classList.remove('keyboard-open')
Keyboard.addListener('keyboardWillShow', onShow);
Keyboard.addListener('keyboardWillHide', onHide);
Keyboard.addListener('keyboardWillShow', onShow)
Keyboard.addListener('keyboardWillHide', onHide)
return () => {
Keyboard.removeAllListeners();
};
}, []);
Keyboard.removeAllListeners()
}
}, [])
useEffect(() => {
initTracking()

View File

@@ -1207,6 +1207,11 @@
resolved "https://registry.yarnpkg.com/@capacitor/status-bar/-/status-bar-7.0.3.tgz#4e8c1ac49cf928576cfac1c78cc3f9886088ebfe"
integrity sha512-JyRpVnKwHij9hgPWolF6PK+HT3e2HSPjN11/h2OmKxq8GAdPGARFLv+97eZl0pvuvm0Kka/LpiLb5whXISBg7Q==
"@capawesome/capacitor-live-update@7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@capawesome/capacitor-live-update/-/capacitor-live-update-7.2.2.tgz#404581ef8a22329b6f61d36cb8a166ea8c8f2f82"
integrity sha512-38fltILlpVFofY+Bz9yYXz/fl/zmKxa5F/goXmmpY+DfkfJvhFbWj92yqvRI2GhlDKbOxNyCoc9p8zYztYM4dQ==
"@capgo/capacitor-social-login@7.14.9":
version "7.14.9"
resolved "https://registry.yarnpkg.com/@capgo/capacitor-social-login/-/capacitor-social-login-7.14.9.tgz#19a79605dfbfbfe2afb9b6a082affa20460016f5"