Skip to content

Commit 5bf0951

Browse files
committed
Add live updates for the webview app
1 parent e135293 commit 5bf0951

File tree

8 files changed

+69
-17
lines changed

8 files changed

+69
-17
lines changed

android/README.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,38 @@ npx cap sync android
257257
## 14. Deployment Workflow
258258

259259
```bash
260-
# 1. Build web app for production
261-
yarn build-web
260+
# Build web app for production and Sync assets to Android
261+
yarn build-sync-android
262262

263-
# 2. Sync assets to Android
264-
npx cap sync android
263+
# Build signed release APK in Android Studio
264+
```
265+
266+
---
267+
268+
## Live Updates
269+
270+
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).
265271

266-
# 3. Build signed release APK in Android Studio
272+
First, you need to do this one-time setup:
267273
```
274+
npm install -g @capawesome/cli@latest
275+
npx @capawesome/cli login
276+
```
277+
278+
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.
279+
```
280+
yarn build-web
281+
npx @capawesome/cli apps:bundles:create --path web/out
282+
```
283+
284+
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.
285+
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.
286+
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.
287+
288+
- ∞ Live Updates
289+
- 100 Monthly Active Users
290+
- 500 MB of Storage (around 10 MB per update, but we just delete the previous ones)
291+
- 5 GB of Bandwidth
268292

269293
---
270294

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ android {
88
applicationId "com.compassconnections.app"
99
minSdkVersion rootProject.ext.minSdkVersion
1010
targetSdkVersion rootProject.ext.targetSdkVersion
11-
versionCode 13
12-
versionName "1.1.2"
11+
versionCode 14
12+
versionName "1.1.3"
1313
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1414
aaptOptions {
1515
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

android/app/capacitor.build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dependencies {
1313
implementation project(':capacitor-keyboard')
1414
implementation project(':capacitor-push-notifications')
1515
implementation project(':capacitor-status-bar')
16+
implementation project(':capawesome-capacitor-live-update')
1617
implementation project(':capgo-capacitor-social-login')
1718

1819
}

android/capacitor.settings.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ project(':capacitor-push-notifications').projectDir = new File('../node_modules/
1414
include ':capacitor-status-bar'
1515
project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacitor/status-bar/android')
1616

17+
include ':capawesome-capacitor-live-update'
18+
project(':capawesome-capacitor-live-update').projectDir = new File('../node_modules/@capawesome/capacitor-live-update/android')
19+
1720
include ':capgo-capacitor-social-login'
1821
project(':capgo-capacitor-social-login').projectDir = new File('../node_modules/@capgo/capacitor-social-login/android')

capacitor.config.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ const config: CapacitorConfig = {
99
appId: 'com.compassconnections.app',
1010
appName: 'Compass',
1111
webDir: 'web/out',
12-
server: LOCAL_ANDROID ? { url: `http://${LOCAL_URL}:3000`, cleartext: true } : {}
12+
server: LOCAL_ANDROID ? { url: `http://${LOCAL_URL}:3000`, cleartext: true } : {},
13+
plugins: {
14+
LiveUpdate: {
15+
appId: "969bc540-8077-492f-8403-b554bee5de50"
16+
}
17+
}
1318
};
1419

1520
export default config;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"@capacitor/keyboard": "7.0.3",
3737
"@capacitor/push-notifications": "7.0.3",
3838
"@capacitor/status-bar": "7.0.3",
39+
"@capawesome/capacitor-live-update": "7.2.2",
3940
"@capgo/capacitor-social-login": "7.14.9",
4041
"@playwright/test": "^1.54.2",
4142
"colorette": "^2.0.20",

web/pages/_app.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,30 @@ import {isAndroidWebView} from "web/lib/util/webview"
1616
import {Capacitor} from '@capacitor/core'
1717
import {StatusBar} from '@capacitor/status-bar'
1818
import {App} from '@capacitor/app'
19-
import {useRouter} from "next/navigation";
20-
import {Keyboard} from "@capacitor/keyboard";
19+
import {useRouter} from "next/navigation"
20+
import {Keyboard} from "@capacitor/keyboard"
21+
import {LiveUpdate} from "@capawesome/capacitor-live-update"
2122

2223
if (Capacitor.isNativePlatform()) {
2324
// Only runs on iOS/Android native
2425
// Note sure it's doing anything, though, need to check
2526
StatusBar.setOverlaysWebView({overlay: false}).catch(console.warn)
2627
// StatusBar.setStyle({style: Style.Light}).catch(console.warn)
28+
2729
App.addListener('backButton', () => {
2830
window.dispatchEvent(new CustomEvent('appBackButton'))
2931
})
32+
33+
App.addListener("resume", async () => {
34+
const {nextBundleId} = await LiveUpdate.sync()
35+
if (nextBundleId) {
36+
// Ask the user if they want to apply the update immediately
37+
const shouldReload = confirm("A new update is available. Would you like to install it?")
38+
if (shouldReload) {
39+
await LiveUpdate.reload()
40+
}
41+
}
42+
})
3043
}
3144

3245

@@ -73,16 +86,16 @@ function MyApp({Component, pageProps}: AppProps<PageProps>) {
7386
useEffect(() => {
7487
console.log('isAndroidWebView app:', isAndroidWebView())
7588
if (!Capacitor.isNativePlatform()) return
76-
const onShow = () => document.body.classList.add('keyboard-open');
77-
const onHide = () => document.body.classList.remove('keyboard-open');
89+
const onShow = () => document.body.classList.add('keyboard-open')
90+
const onHide = () => document.body.classList.remove('keyboard-open')
7891

79-
Keyboard.addListener('keyboardWillShow', onShow);
80-
Keyboard.addListener('keyboardWillHide', onHide);
92+
Keyboard.addListener('keyboardWillShow', onShow)
93+
Keyboard.addListener('keyboardWillHide', onHide)
8194

8295
return () => {
83-
Keyboard.removeAllListeners();
84-
};
85-
}, []);
96+
Keyboard.removeAllListeners()
97+
}
98+
}, [])
8699

87100
useEffect(() => {
88101
initTracking()

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,11 @@
12071207
resolved "https://registry.yarnpkg.com/@capacitor/status-bar/-/status-bar-7.0.3.tgz#4e8c1ac49cf928576cfac1c78cc3f9886088ebfe"
12081208
integrity sha512-JyRpVnKwHij9hgPWolF6PK+HT3e2HSPjN11/h2OmKxq8GAdPGARFLv+97eZl0pvuvm0Kka/LpiLb5whXISBg7Q==
12091209

1210+
"@capawesome/[email protected]":
1211+
version "7.2.2"
1212+
resolved "https://registry.yarnpkg.com/@capawesome/capacitor-live-update/-/capacitor-live-update-7.2.2.tgz#404581ef8a22329b6f61d36cb8a166ea8c8f2f82"
1213+
integrity sha512-38fltILlpVFofY+Bz9yYXz/fl/zmKxa5F/goXmmpY+DfkfJvhFbWj92yqvRI2GhlDKbOxNyCoc9p8zYztYM4dQ==
1214+
12101215
12111216
version "7.14.9"
12121217
resolved "https://registry.yarnpkg.com/@capgo/capacitor-social-login/-/capacitor-social-login-7.14.9.tgz#19a79605dfbfbfe2afb9b6a082affa20460016f5"

0 commit comments

Comments
 (0)