Files
HiveGrid-Wireframes/hivegrid-cloud/apps/mobile/capacitor.config.ts
T

98 lines
3.4 KiB
TypeScript

/**
* Capacitor 7 configuration for the toolctrl mobile wrapper.
*
* The mobile app re-uses the React Router v7 build artifact produced by
* `pnpm --filter @toolctrl/web build` (written to `apps/web/build/client`)
* as its `webDir`. In development the Capacitor runtime can point at a
* live web origin via `MOBILE_LIVE_RELOAD_URL` (for example
* `http://localhost:3000`, `http://10.0.2.2:3000`, or a staging URL) so
* iterating on the UI does not require a full native rebuild.
*
* AppId is fixed to `de.toolctrl.app` — must match the iOS Bundle-ID and
* the Android applicationId in `apps/mobile/android/app/build.gradle`.
*
* @see docs/improvement-plan/08-mobile-cli-storybook-sdk/capacitor.md
* @see docs/operations/capacitor.md
*/
import type { CapacitorConfig } from "@capacitor/cli";
export function readLiveReloadUrl(rawValue = process.env.MOBILE_LIVE_RELOAD_URL): string | undefined {
const trimmed = rawValue?.trim();
if (!trimmed) return undefined;
if (!/^[a-z][a-z\d+.-]*:\/\//i.test(trimmed)) {
throw new Error("MOBILE_LIVE_RELOAD_URL must be an absolute http(s) URL, e.g. http://10.0.2.2:3000.");
}
let parsed: URL;
try {
parsed = new URL(trimmed);
} catch {
throw new Error("MOBILE_LIVE_RELOAD_URL must be an absolute http(s) URL, e.g. http://10.0.2.2:3000.");
}
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
throw new Error("MOBILE_LIVE_RELOAD_URL must use http:// for local dev or https:// for staging.");
}
return trimmed;
}
const liveReloadUrl = readLiveReloadUrl();
const config: CapacitorConfig = {
appId: "de.toolctrl.app",
appName: "ToolCtrl",
// Web assets are produced by the @toolctrl/web React Router v7 build.
// Path is relative to this config file (apps/mobile/) — the build
// artifact lives under apps/web/build/client.
webDir: "../web/build/client",
// Server config is only emitted when MOBILE_LIVE_RELOAD_URL is set.
// Production builds (CI / store submissions) must run with this env var
// unset so the bundle uses the embedded webDir assets.
server: liveReloadUrl
? {
url: liveReloadUrl,
// Allow http only when the URL is explicitly http:// (dev mode);
// production live-reload against staging should be https://.
cleartext: liveReloadUrl.startsWith("http://"),
}
: undefined,
ios: {
// Keep native WebView scrolling enabled while letting iOS manage safe
// area insets. Status-bar styling is managed by @capacitor/status-bar.
scrollEnabled: true,
contentInset: "automatic",
},
android: {
// Keep mixed content disabled. Cleartext live-reload exceptions are
// constrained in network_security_config.xml; see docs/operations/capacitor.md.
allowMixedContent: false,
},
plugins: {
SplashScreen: {
launchShowDuration: 1500,
launchAutoHide: true,
backgroundColor: "#ffffff",
androidScaleType: "CENTER_CROP",
splashFullScreen: true,
splashImmersive: true,
},
StatusBar: {
style: "default",
overlaysWebView: false,
},
PushNotifications: {
presentationOptions: ["badge", "sound", "alert"],
},
Preferences: {
// Group name maps to the iOS UserDefaults suite and the Android
// SharedPreferences file. Keep stable across releases to avoid
// orphaning stored session state.
group: "de.toolctrl.app.secure",
},
},
};
export default config;