The web client already has a full mobile UI (MobileShell and 17 sibling screens) and ships as a PWA, so what was missing to get an APK was a native container, not an interface. The WebView loads the instance over the network instead of bundling a copy of the web build. Bundling would mean republishing an APK on every site deploy — there is no electron-updater equivalent here — and it would move the page to https://localhost, turning every same-origin /api and /ws call into a cross-origin one. The cost is no offline mode, which for a realtime chat app costs nothing: public/index.html covers the unreachable-server case. packages/mobile sits outside the pnpm workspace on purpose. Capacitor's CLI and Gradle both assume a flat node_modules, and keeping it out leaves pnpm-lock.yaml and the existing web/desktop CI untouched by it. Icons are generated from the existing brand art. The launch screen is a layer-list over the brand background rather than Capacitor's per-density splash.png set, which is light and flashed white before the WebView painted. CI builds an *unsigned* APK. The signing key stays on the VPS and is applied there — an APK signature is what proves an update came from us, so the key has no reason to exist on a second machine. Background voice (foreground service) is not in this commit: a plain WebView is throttled when the screen goes off and the call drops. That is the next phase. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import type { CapacitorConfig } from '@capacitor/cli';
|
|
|
|
/**
|
|
* O APK e uma casca fina: a WebView carrega a instancia pela rede em vez de
|
|
* servir uma copia do app web embutida no pacote.
|
|
*
|
|
* Duas razoes, nesta ordem:
|
|
*
|
|
* 1. Atualizacao. O site muda a cada deploy. Com os arquivos embutidos, cada
|
|
* mudanca no app web exigiria republicar e reinstalar o APK a mao — nao ha
|
|
* updater automatico no Android como o electron-updater faz no desktop.
|
|
* Pela rede, o telefone recebe a mesma versao que o navegador, na hora.
|
|
*
|
|
* 2. Origem. O cliente fala com /api e /ws na mesma origem. Embutido, a pagina
|
|
* rodaria em https://localhost e toda chamada viraria cross-origin, o que
|
|
* obrigaria a abrir CORS no servidor para uma origem que qualquer app pode
|
|
* reivindicar.
|
|
*
|
|
* O preco e nao funcionar offline, o que para um app de chat em tempo real nao
|
|
* e perda: sem servidor nao ha o que mostrar. A pagina em public/ so aparece se
|
|
* a WebView nao alcancar o servidor.
|
|
*/
|
|
const config: CapacitorConfig = {
|
|
appId: 'com.resenhacord.app',
|
|
appName: 'Resenhacord',
|
|
webDir: 'public',
|
|
android: {
|
|
// A captura de audio e video da WebView e concedida pelo bridge do
|
|
// Capacitor, que traduz o pedido do getUserMedia para a permissao nativa.
|
|
allowMixedContent: false,
|
|
},
|
|
server: {
|
|
url: 'https://chat.resenha.website',
|
|
// Sem cleartext: a instancia e servida por HTTPS (Caddy), e o WebRTC do
|
|
// LiveKit exige contexto seguro de qualquer forma.
|
|
cleartext: false,
|
|
androidScheme: 'https',
|
|
},
|
|
};
|
|
|
|
export default config;
|