Files
fusion/packages/mobile/capacitor.config.ts
gsxdsm aa6d21eeca FN-7583: route Android back gesture through fusion:native-back so task detail returns to board
Fixes the Android predictive back-gesture (edge swipe) not returning from a task detail view to the board, even though the hardware/legacy Back button worked correctly.

- Patch the generated Android manifest post-sync to set android:enableOnBackInvokedCallback="true" on the <application> tag, opting into AndroidX's OnBackPressedDispatcher for predictive-back gesture completion (mitigating ionic-team/capacitor-plugins#2418 via the disableBackButtonHandler toggle shipped in @capacitor/app@7.1.0).
- Wire the patch script into Capacitor's capacitor:sync:after npm-script hook so it runs automatically after every cap sync (and therefore after cap run android / build:mobile).
- Ensure both the back gesture and the hardware Back button funnel through the same AndroidBackButtonManager backButton listener, dispatching the shared fusion:native-back event consumed by the dashboard's nav-history stack.
- Add regression coverage: a unit test for the manifest patch script's idempotent opt-in behavior, and a dashboard test asserting the task detail view returns to the board on fusion:native-back.
- Document the Android manifest patch rationale and the unchanged dashboard-side invariant in packages/mobile/README.md.

Files changed:
 .../__tests__/TaskDetail.swipe-back.test.tsx       |  13 +++
 packages/mobile/README.md                          |  31 +++++++
 packages/mobile/capacitor.config.ts                |  13 +++
 packages/mobile/package.json                       |   2 +
 packages/mobile/scripts/patch-android-manifest.ts  |  90 ++++++++++++++++++
 packages/mobile/src/__tests__/native-shell.test.ts | 102 +++++++++++++++++++++
 6 files changed, 251 insertions(+)

Fusion-Task-Id: FN-7583

Fusion-Task-Lineage: ad0cb02c-6e49-448a-8c93-607cd5ae657b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:57:36 -07:00

48 lines
2.3 KiB
TypeScript

/// <reference types="@capacitor-community/safe-area" />
import type { CapacitorConfig } from "@capacitor/cli";
const liveReloadEnabled = process.env.FUSION_LIVE_RELOAD === "true";
const config: CapacitorConfig = {
appId: "com.fusion.mobile",
appName: "Fusion",
webDir: "../dashboard/dist/client",
// FNXC:MobileShell 2026-06-16-19:20: status-bar overlap fix.
// The mobile app is a thin Capacitor webview wrapping the Fusion dashboard,
// often loaded REMOTELY (server.url). Relying on env(safe-area-inset-*) in the
// served CSS is fragile: it depends on the device Chromium version reporting
// insets AND on the (cacheable, service-worker-backed) dashboard CSS being
// current. Instead we force @capacitor-community/safe-area to pad the WHOLE
// webview natively on every Android device. Per the plugin docs, setting both
// flags false makes it "only add padding around the webview on all Android
// devices" and stop passing insets through, so the app can never render under
// the status/navigation bars regardless of CSS or webview version.
plugins: {
SafeArea: {
detectViewportFitCoverChanges: false,
initialViewportFitCover: false,
},
// FNXC:TaskDetailAndroidBack 2026-07-05-11:40:
// FN-7583: keep the @capacitor/app native backButton handler ENABLED (the default,
// pinned explicitly below). `AndroidBackButtonManager` in `src/plugins/native-shell.ts`
// relies on the plugin's "backButton" event to dispatch the shared `fusion:native-back`
// event that the dashboard's nav-history stack consumes for both the hardware Back
// button and the Android 13+ predictive-back GESTURE (once the gesture is actually
// delivered — see `scripts/patch-android-manifest.ts` for the manifest opt-in that
// makes that so). Setting `disableBackButtonHandler: true` would stop the plugin from
// emitting "backButton" entirely, breaking BOTH the button and the gesture routing —
// never flip this without replacing `AndroidBackButtonManager`'s dispatch seam too.
App: {
disableBackButtonHandler: false,
},
},
server: {
url: liveReloadEnabled
? process.env.FUSION_SERVER_URL || "http://localhost:5173"
: undefined,
cleartext: liveReloadEnabled,
},
};
export default config;