fix(mobile): open Quick Links in the external browser so JotForm data survives the camera #16

Merged
mohlec merged 3 commits from fix/links-external-browser into ncw/main 2026-08-07 16:07:29 +00:00
Owner

Quick Links opened in an in-app Chrome Custom Tab. A Custom Tab belongs to this app's process, so when Android kills the backgrounded app - routine on Samsung One UI the moment something memory-hungry like the camera starts - the tab is destroyed and any half-filled JotForm goes with it.

That is the same failure the dispatch board's Work Order flow had. It was fixed there by handing the URL to the OS default browser, which gets its own Android task and survives the app being killed.

The mechanism was already in place - openPluginMobile(..., external) - and the JSDoc already described this exact camera scenario. But external defaulted to false, and both Quick Links call sites simply omitted the argument:

header.tsx:253   openPluginMobile(serverUrl, NCW_DISPATCH_PLUGIN_ID, ..., true);   <- dispatch, fixed
header.tsx:257   openPluginMobile(serverUrl, NCW_LINKS_PLUGIN_ID, ...);            <- links, missed
quick_actions:100 openPluginMobile(serverUrl, NCW_LINKS_PLUGIN_ID, ...);           <- links, missed

So this was not an oversight in the links plugin at all - nothing in slash-links-plugin needs to change. It was a default that made the unsafe path the quiet one.

Changes

  • external now defaults to true. Every current caller opens a page that leads to a JotForm, so the safe behaviour is the default and a new call site cannot reintroduce this bug by omission. Passing false is now a deliberate act, documented as being for pages with no form state worth protecting.
  • Both Quick Links call sites pass true explicitly, for readability at the call site.

Checked before changing

Linking.openURL could in principle bounce straight back into the app if it registered an intent filter for the server host. It does not - AndroidManifest.xml declares only the slash:// and slashauth:// custom schemes, no https host. So the URL goes to the default browser as intended.

Trade-off

The technician now leaves the Slash app when they open Quick Links, and returns via the app switcher rather than a back button. That is the same trade already accepted for the dispatch board, and it is the price of the form surviving a trip to the camera.

Note on delivery

Unlike the plugin-side work, this needs a new APK on each phone - it will not reach anyone through a server deploy.

Quick Links opened in an in-app Chrome Custom Tab. A Custom Tab belongs to **this app's process**, so when Android kills the backgrounded app - routine on Samsung One UI the moment something memory-hungry like the camera starts - the tab is destroyed and any half-filled JotForm goes with it. That is the same failure the dispatch board's Work Order flow had. It was fixed there by handing the URL to the OS default browser, which gets its own Android task and survives the app being killed. ## Why Quick Links was missed The mechanism was already in place - `openPluginMobile(..., external)` - and the JSDoc already described this exact camera scenario. But `external` defaulted to **false**, and both Quick Links call sites simply omitted the argument: ``` header.tsx:253 openPluginMobile(serverUrl, NCW_DISPATCH_PLUGIN_ID, ..., true); <- dispatch, fixed header.tsx:257 openPluginMobile(serverUrl, NCW_LINKS_PLUGIN_ID, ...); <- links, missed quick_actions:100 openPluginMobile(serverUrl, NCW_LINKS_PLUGIN_ID, ...); <- links, missed ``` So this was not an oversight in the links plugin at all - nothing in `slash-links-plugin` needs to change. It was a default that made the unsafe path the quiet one. ## Changes - **`external` now defaults to `true`.** Every current caller opens a page that leads to a JotForm, so the safe behaviour is the default and a new call site cannot reintroduce this bug by omission. Passing `false` is now a deliberate act, documented as being for pages with no form state worth protecting. - Both Quick Links call sites pass `true` explicitly, for readability at the call site. ## Checked before changing `Linking.openURL` could in principle bounce straight back into the app if it registered an intent filter for the server host. It does not - `AndroidManifest.xml` declares only the `slash://` and `slashauth://` custom schemes, no `https` host. So the URL goes to the default browser as intended. ## Trade-off The technician now leaves the Slash app when they open Quick Links, and returns via the app switcher rather than a back button. That is the same trade already accepted for the dispatch board, and it is the price of the form surviving a trip to the camera. ## Note on delivery Unlike the plugin-side work, this needs a **new APK on each phone** - it will not reach anyone through a server deploy.
Custom Tabs live in this app's process, so when Android kills the
backgrounded app - routine on Samsung One UI when the camera starts -
the tab dies and any half-filled JotForm goes with it. The dispatch
board was moved to the OS browser for this reason; Quick Links was not,
because the flag defaults to false and its call sites omitted it.

Defaulting to true means omitting the argument is now the safe choice.
mohlec merged commit 4fd8519cf7 into ncw/main 2026-08-07 16:07:29 +00:00
mohlec deleted branch fix/links-external-browser 2026-08-07 16:07:29 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
slash/slash-mobile!16
No description provided.