diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index 28495dc..c52e5bb 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -11,6 +11,13 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up Node 20 + uses: actions/setup-node@v4 + with: + node-version: '20' - name: Set up JDK 17 uses: actions/setup-java@v4 @@ -21,12 +28,19 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 - - name: Lint + unit tests + assemble debug - run: ./gradlew lint test :app:assembleDebug + - name: Install wrapper deps + run: npm ci + + - name: Build loto + sync into Android + run: npm run build + + - name: Assemble debug APK + working-directory: android + run: ./gradlew :app:assembleDebug - name: Upload debug APK uses: actions/upload-artifact@v4 with: name: debug-apk - path: app/build/outputs/apk/debug/*.apk + path: android/app/build/outputs/apk/debug/*.apk retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b367664..a074f02 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,6 +10,13 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up Node 20 + uses: actions/setup-node@v4 + with: + node-version: '20' - name: Set up JDK 17 uses: actions/setup-java@v4 @@ -20,20 +27,27 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 + - name: Install wrapper deps + run: npm ci + + - name: Build loto + sync into Android + run: npm run build + - name: Decode keystore run: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > keystore.jks - - name: Build release bundle and APK - run: ./gradlew :app:bundleRelease :app:assembleRelease + - name: Build signed AAB + APK + working-directory: android env: LOTO_KEYSTORE_PATH: ${{ github.workspace }}/keystore.jks LOTO_KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} LOTO_KEY_ALIAS: ${{ secrets.KEY_ALIAS }} LOTO_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + run: ./gradlew :app:bundleRelease :app:assembleRelease - name: Upload to GitHub Release uses: softprops/action-gh-release@v2 with: files: | - app/build/outputs/apk/release/*.apk - app/build/outputs/bundle/release/*.aab + android/app/build/outputs/apk/release/*.apk + android/app/build/outputs/bundle/release/*.aab diff --git a/.gitignore b/.gitignore index 43413b9..8cea5ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,35 @@ -*.iml -.gradle -.idea -local.properties -.DS_Store -build -captures -.externalNativeBuild -.cxx +# Node +node_modules/ +npm-debug.log* + +# Loto build (regenerated by `npm run build:loto`) +loto/build/ +loto/.svelte-kit/ + +# Android build outputs +android/.gradle/ +android/build/ +android/app/build/ +android/capacitor-cordova-android-plugins/ +android/local.properties +android/.idea/ +android/captures/ +android/.externalNativeBuild/ +android/.cxx/ + +# Capacitor sync artifacts (regenerated by `npx cap sync`) +android/app/src/main/assets/public/ +android/app/src/main/assets/capacitor.config.json +android/app/src/main/assets/capacitor.plugins.json + +# Signing *.apk *.aab *.keystore *.jks google-services.json -proguard/ + +# Editor / OS +*.iml +.idea/ +.DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0ca4bf6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "loto"] + path = loto + url = https://github.com/tiennm99/loto.git diff --git a/README.md b/README.md index f687401..72a997a 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,127 @@ -# Lô tô — Android +# Lô tô — Android (Capacitor wrapper) ![build-debug](https://github.com/tiennm99/loto-android/actions/workflows/build-debug.yml/badge.svg) -Native Android port of [tiennm99/loto](https://github.com/tiennm99/loto) (SvelteKit web app). +Fully-offline Android wrapper around [tiennm99/loto](https://github.com/tiennm99/loto) +(SvelteKit PWA). All assets — HTML, JS, CSS, and 184 voice MP3s — are bundled +into the APK at build time. No network is required at runtime. -Lô tô hội chợ TN1 — Vietnamese fairground bingo with host (quản trò) + player modes, -called-number speech in Vietnamese (Hoài My / Nam Minh voices). +> **Note:** the previous native Kotlin/Compose port lives in git history at +> commit `9a35686` and earlier. This repo is now a thin wrapper; loto evolves +> upstream and we just rebuild + ship. + +## How it works + +``` +loto/ (git submodule, pinned SHA) + └── npm run build → loto/build/ (SvelteKit static output) + ↓ + npx cap sync + ↓ +android/app/src/main/assets/public/ (bundled into APK) + ↓ + WebView serves https://localhost/* off-disk +``` + +Capacitor's bridge serves the bundled site from `https://localhost`, which is +loopback only (no INTERNET permission requested). Workbox precache, IndexedDB, +and the `