Skip to content

docs(fliplet-barcode): use window.cordova for V3 web/native detection#269

Open
farhantariq12b wants to merge 5 commits into
v3/DEV-908-betafrom
fix/v3-barcode-html5-qrcode-chain
Open

docs(fliplet-barcode): use window.cordova for V3 web/native detection#269
farhantariq12b wants to merge 5 commits into
v3/DEV-908-betafrom
fix/v3-barcode-html5-qrcode-chain

Conversation

@farhantariq12b

Copy link
Copy Markdown
Contributor

Summary

The fliplet-barcode docs were prescribing a navigator.mediaDevices.getUserMedia-based detection signal for the V3 AI builder's "Recommended pattern (web + native)." That check is unreliable inside Cordova WebView — modern Android WebView fully supports getUserMedia, so apps running natively were being routed down the web path. The browser-shaped flow then called getUserMedia directly, which the WebView's default SystemWebChromeClient.onPermissionRequest "granted" without actually requesting Android system permission — silently failing to acquire the camera.

The library itself already solves this cleanly:

// fliplet-api/public/assets/fliplet-barcode/1.0/barcode.js:122-131
if (Fliplet.Env.is('web')) {
  return htmlScan();
}
// ...
cordova.plugins.barcodeScanner.scan(resolve, reject, options);

cordova.plugins.barcodeScanner is the existing phonegap-plugin-barcodescanner plugin shipped in fliplet-android-version-2 (cordova/plugins/phonegap-plugin-barcodescanner/ + libs/barcodescanner-release-2.1.5.aar). It handles CAMERA permission via the standard cordova.requestPermissions(CAMERA) flow — OS popup appears, ZXing native scanner UI opens. No Java patches required.

The catch: Fliplet.Env.is('web') is unreliable inside V3 Studio preview iframes (they set window.ENV.platform === 'native' even though Cordova isn't loaded), which is why the library can't be called bare from V3 apps the way it's called from V1's form-builder codeScanner field (fliplet-widget-form-builder/js/components/codeScanner.js:50).

This PR makes the recipe route to Fliplet.Barcode.scan() only when the native Cordova runtime is actually loaded, and uses inline html5-qrcode on web/preview for component-style UX.

What changed

  • Detection signal: typeof window.cordova !== 'undefined' — defined only when the native runtime has loaded; absent in Studio preview iframes and on published web. Replaces navigator.mediaDevices.getUserMedia (returned true on Cordova WebView, broke native flow).
  • Native path: Fliplet.Barcode.scan({ prompt }) only. Internally routes through the cordova plugin → OS popup → ZXing UI. No getUserMedia / Html5Qrcode / permission warm-up on native.
  • Web/preview path: inline new window.Html5Qrcode('web-scanner', { verbose: false }).start(...) into a <div id="web-scanner"> with min-height: 320px. Browser handles its own permission prompt.
  • Single chain load: Fliplet.require.lazy.chain('fliplet-barcode') serves both paths — chain bundles html5-qrcode.min.js AND barcode.js. Reaffirms: do NOT declare html5-qrcode separately, do NOT use jsqr.
  • What NOT to do list updated with the new prescriptions (no Fliplet.Env.is, no window.ENV.platform, no getUserMedia for detection, no Html5Qrcode on the native path).
  • Drops the requestCameraPermission warm-up that earlier recipe versions used — was a workaround for routing Cordova WebView to the web path; no longer applicable now that Cordova goes through Fliplet.Barcode.scan().

Companion catalog notes (so search_libraries returns the new guidance for the V3 builder) are in fliplet-studio branch fix/v3-barcode-html5-qrcode-chain — PR not opened yet.

Why this matters

The V3 AI builder kept emitting scanner apps that needed either (a) a per-fork Java patch to SystemWebChromeClient.onPermissionRequest, or (b) a defensive fallback that pulled html5-qrcode from cdn.jsdelivr.net at runtime — both unnecessary once the recipe stops bypassing the cordova plugin. Customer apps shipping with the previous recipe would have needed shell-fork maintenance to acquire camera on Android; this PR makes the recipe work first-attempt against an unmodified Fliplet Android shell, matching how V1 form-builder apps have always invoked the scanner.

End-to-end verified with FLIPLET_CLI_BRANCH=fix/v3-barcode-html5-qrcode-chain against a freshly-generated V3 app: agent produced conforming Scanner.vue (window.cordova check, Fliplet.Barcode.scan() on native, inline Html5Qrcode on web). Web scan worked in Studio preview without modification.

Test plan

  • V1 parity check: fliplet-widget-form-builder/js/components/codeScanner.js:50 calls Fliplet.Barcode.scan() — same library + cordova plugin + permission mechanism the new recipe uses.
  • Plugin presence verified in shell: assets/www/cordova_plugins.js registers cordova.plugins.barcodeScanner; libs/barcodescanner-release-2.1.5.aar bundled; src/com/phonegap/plugins/barcodescanner/ compiled.
  • Chain bundles html5-qrcode: inspected pages.html chain JSON layer 1 → cdn.fliplet.test/assets/html5-qrcode/2.3.8/html5-qrcode.min.js. Chain load exposes window.Html5Qrcode globally.
  • V3 builder fresh-app gen produces conforming Scanner.vue (verified via FLIPLET_CLI_BRANCH override on local dev stack).
  • Web preview test: tap "Scan" → browser permission popup → inline scanner → scans QR → ticket verified.
  • Reviewer: confirm renders cleanly via bundle exec jekyll build after merge.
  • Native device test (any device, no Java patch): tap "Scan" → OS popup via cordova plugin → ZXing scanner → scans QR.

🤖 Generated with Claude Code

farhantariq12b and others added 4 commits May 22, 2026 22:11
…code

The previous doc said scanning was "only supported in native apps".
On the V3 AI builder the agent followed that hint and produced apps
that gated the scan flow behind `Fliplet.Env.is('native')` or showed
"preview only" fallback copy — blocking working web scanners.

Field-tested fix from a customer's working SFC: branch on
`navigator.mediaDevices.getUserMedia` availability instead of any
Fliplet.Env/window.cordova check. If the web camera API is available
(modern browsers AND modern Cordova WebViews), open an inline
`<video>` + hidden `<canvas>` and decode QR codes with `jsQR`. Only
fall back to `Fliplet.Barcode.scan()` when the web API is genuinely
unavailable.

Adds a Recommended pattern (web + native) section with the four core
methods — scanTicket / startWebScanner / scanLoop / stopWebScanner —
extracted from the working SFC. Brief template note (the two refs
needed) and an explicit cleanup hook for beforeUnmount. Anti-pattern
callout: do NOT branch on Fliplet.Env.is('web') or window.ENV.platform.

Keeps the original Simple native-only usage as a fallback for native-
only apps that prefer the Cordova plugin's full-screen scanner UI.

Co-Authored-By: Claude <noreply@anthropic.com>
html5-qrcode is already bundled inside the fliplet-barcode chain — loading
the chain via Fliplet.require.lazy.chain('fliplet-barcode') exposes
window.Html5Qrcode globally. This removes the need for a separate jsqr lazy
dep and the manual <video>/<canvas>/jsQR render loop.

Other key changes:
- Adds a requestCameraPermission() warm-up step before Html5Qrcode.start()
  so Cordova WebView's incomplete permissions pre-flight doesn't reject.
- Keeps navigator.mediaDevices.getUserMedia as the web/native detection
  signal (Fliplet.Env.is and window.ENV.platform are wrong inside Studio
  preview iframes).
- Inline <div id="web-scanner"> with min-height: 320px replaces the jsQR
  <video>+<canvas> rendering pair.
- Cleanup uses scanner.stop() then scanner.clear() each in try/catch.

Co-Authored-By: Claude <noreply@anthropic.com>
…let.Barcode.scan

The previous recipe detected web via navigator.mediaDevices.getUserMedia,
which returns true on modern Cordova WebView. That routed native apps to
the html5-qrcode + raw getUserMedia path, bypassing the Cordova permission
system — the OS camera popup never appeared and the camera silently failed
unless the shell's SystemWebChromeClient.onPermissionRequest was patched to
bridge WebView resource requests to Android system permissions.

The correct detection signal is `typeof window.cordova !== 'undefined'` —
defined only when the Cordova native runtime is actually loaded (Studio
preview iframes and published web never have it). With that:

- Native (window.cordova defined): call Fliplet.Barcode.scan() directly.
  Internally it routes through cordova.plugins.barcodeScanner which handles
  CAMERA permission via the standard cordova.requestPermissions mechanism
  — OS popup appears automatically, native scanner UI opens. No Java
  patches, no permission warm-up, no Html5Qrcode on native.

- Web / Studio preview (window.cordova undefined): inline html5-qrcode in
  a <div id="web-scanner">. Browser shows its own getUserMedia prompt.

Recipe is back to the v1-style pattern that worked first-attempt on native
without any platform-side fork maintenance.

Co-Authored-By: Claude <noreply@anthropic.com>
… review

Same canonical recipe (window.cordova detection, Fliplet.Barcode.scan on
native, inline Html5Qrcode on web). Tone change only — public dev docs
shouldn't characterize Fliplet APIs as "unreliable" or surface internal
platform-detection edge cases. Four targeted edits:

- Note paragraph (line 13): drop the "Fliplet.Env.is is unreliable in
  Studio preview iframes" warning and the redundant "for apps that target
  both web and native" qualifier. Present the Recommended pattern as the
  canonical implementation that handles all three surfaces.
- "Three rules" list: reframe as "Why this pattern works" with positive
  prescriptions. No more "DO NOT use X — those return wrong values" callouts.
- Inline JS comment in scanTicket: trim the "Do NOT branch on Fliplet.Env.is"
  warning. Keep the brief positive description of window.cordova.
- "What NOT to do" section: reframe as "Things to avoid" with three concise
  bullets focused on the actual mistakes (separate html5-qrcode declaration,
  getUserMedia/Html5Qrcode on native path, <video>+<canvas> rendering).

Recipe code blocks are byte-identical. Net -7 lines.

Co-Authored-By: Claude <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented May 26, 2026

Copy link
Copy Markdown

Deploying fliplet-cli with  Cloudflare Pages  Cloudflare Pages

Latest commit: fca7d4a
Status:🚫  Build failed.

View logs

…iptions

Per review follow-up — jsqr was a legacy alternative the recipe previously
considered. The canonical recipe uses html5-qrcode via the fliplet-barcode
chain only; mentioning jsqr in "do not use" callouts is noise. Removed
from three places:

- Install paragraph
- "Why this pattern works" point 2
- "Things to avoid" bullet

Same effect — the agent has no path that would surface jsqr now that the
recipe is described positively. Catalog notes in fliplet-studio#8548 get
the same simplification in a follow-up commit there.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant