- capacitor.config.json: appId gr.bonamin.xenia, webDir dist-native, androidScheme http (origin http://localhost - no mixed-content block when calling venue servers over plain HTTP on the LAN) - vite: `--mode native` builds to dist-native with the PWA plugin disabled (no service worker inside the app) - Android: minSdk 24 / target 36; CAMERA permission for QR pairing; cleartext allowed via network_security_config (LAN IPs can't be listed per-domain); allowBackup=false so backups never carry login tokens - Release signing reads ~/.xenia/keystore.properties (override with XENIA_KEYSTORE_PROPS) - the key never enters the repo; versionName 1.0.0 / versionCode 1 with a bump-both rule for sideloaded updates - npm scripts build:native, apk:debug, apk:release (scripts/build-apk.mjs); APKs land in releases/ (gitignored); release APK is also copied to public/downloads/ so venue servers serve it at /downloads/xenia-waiter.apk - waiter nginx: /downloads/ served as application/vnd.android.package-archive, real 404 when missing (never falls through to index.html) - launcher icons + splash generated from the app icon (assets/ is the source) - .gitattributes: gradlew LF, *.bat CRLF Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
1.8 KiB
JavaScript
61 lines
1.8 KiB
JavaScript
import { defineConfig } from 'vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import { VitePWA } from 'vite-plugin-pwa'
|
|
|
|
// `vite build --mode native` builds the UI bundled inside the Capacitor app:
|
|
// no service worker (the app ships its own files) and a separate output dir so
|
|
// it never mixes with the web build served by the venue's nginx.
|
|
export default defineConfig(({ mode }) => {
|
|
const native = mode === 'native'
|
|
|
|
return {
|
|
build: {
|
|
outDir: native ? 'dist-native' : 'dist',
|
|
},
|
|
server: {
|
|
host: '0.0.0.0',
|
|
port: 5173,
|
|
allowedHosts: ['all'],
|
|
proxy: {
|
|
'/api/ws': {
|
|
target: 'ws://localhost:8000',
|
|
ws: true,
|
|
changeOrigin: true,
|
|
},
|
|
'/api': {
|
|
target: 'http://localhost:8000',
|
|
changeOrigin: true,
|
|
},
|
|
},
|
|
},
|
|
plugins: [
|
|
react(),
|
|
VitePWA({
|
|
disable: native,
|
|
registerType: 'prompt',
|
|
manifest: {
|
|
name: 'Xenia',
|
|
short_name: 'Xenia',
|
|
start_url: '/',
|
|
display: 'standalone',
|
|
background_color: '#0f172a',
|
|
theme_color: '#0f172a',
|
|
icons: [
|
|
{ src: '/icons/icon-192.png', sizes: '192x192', type: 'image/png', purpose: 'any' },
|
|
{ src: '/icons/icon-192.png', sizes: '192x192', type: 'image/png', purpose: 'maskable' },
|
|
{ src: '/icons/icon-512.png', sizes: '512x512', type: 'image/png', purpose: 'any' },
|
|
{ src: '/icons/icon-512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' },
|
|
],
|
|
},
|
|
workbox: {
|
|
globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
|
|
runtimeCaching: [],
|
|
},
|
|
devOptions: {
|
|
enabled: false,
|
|
},
|
|
}),
|
|
],
|
|
}
|
|
})
|