Repository navigation
feat(formulus): support settings deep links - #1009
allennakalema06-web wants to merge 3 commits into
Conversation
Mishael-2584
left a comment
There was a problem hiding this comment.
Thanks @allennakalema06-web, the approach is good: it reuses the existing confirmation flow and keeps bare FRMLS: scanning working.
Two things to resolve before merge: iOS delivery of the link, and how older app versions handle the new QR format. I've also left a few smaller suggestions inline.
| <key>CFBundleURLTypes</key> | ||
| <array> | ||
| <dict> | ||
| <key>CFBundleURLName</key> | ||
| <string>org.opendataensemble.formulus</string> | ||
| <key>CFBundleURLSchemes</key> | ||
| <array> | ||
| <string>formulus</string> | ||
| </array> | ||
| </dict> | ||
| </array> |
There was a problem hiding this comment.
The scheme is registered here, but I don't think iOS will hand the link to React Native yet. This app uses the scene lifecycle (UIApplicationSceneManifest + SceneDelegate), and SceneDelegate.swift only implements willConnectTo. With scenes, incoming URLs arrive through scene(_:openURLContexts:) (app already running) and connectionOptions.urlContexts (cold start), not application(_:open:options:). Neither is forwarded to RCTLinkingManager today.
Could we add that and test on an iOS device, or limit this PR to Android and say so in the description? Right now it reads as if iOS is supported, but it's untested.
| u: username, | ||
| p: password, | ||
| }); | ||
| return `formulus://settings?payload=${encodeURIComponent(frmls)}`; |
There was a problem hiding this comment.
This makes the portal emit only the new formulus:// link. Any Formulus build without this PR will reject these QR codes ("Not FRMLS format"), and field devices often update slowly.
Could we keep a way to generate the old format for a release or two (a toggle in the portal and a --legacy flag in synk qr), or at least note a minimum app version in the release notes? The same applies to qr.go and generateQR.ts.
| const settings = await QRSettingsService.processQRCode( | ||
| `formulus://settings?payload=${encodeURIComponent(payload)}`, | ||
| ); |
There was a problem hiding this comment.
React Navigation has already decoded payload here. We re-encode it, wrap it back into formulus://settings?payload=..., and then unwrapQRCode strips and decodes it again. It works, but it's a roundabout path.
Suggestion: add a method like QRSettingsService.parsePayload(payload) that takes the FRMLS string directly, and call that here. parseQRCode then only handles full scanned strings.
| if (!mountedRef.current) return; | ||
|
|
||
| setDropdownOpen(false); | ||
| setEditor({ label: '', initialSettings: settings }); |
There was a problem hiding this comment.
If the user already has the new-profile form open, a link replaces it and discards what they typed. Maybe skip the link, or ask first, when editor is already set.
| function unwrapQRCode(qrString: string): string { | ||
| if (qrString.startsWith('FRMLS:')) return qrString; | ||
|
|
||
| const prefix = `${FORMULUS_SETTINGS_URL}?payload=`; | ||
| if (!qrString.startsWith(prefix)) { | ||
| throw new Error('Not a Formulus settings link'); | ||
| } |
There was a problem hiding this comment.
The strict startsWith(prefix) check fails on formulus://settings/?payload=..., and on links with extra params after the payload (...&foo=bar). In that second case the extra text becomes part of the payload and decoding returns wrong output.
Could we extract the value more flexibly (e.g. /[?&]payload=([^&#]*)/, or new URL() since react-native-url-polyfill is already a dependency)? Also, decodeURIComponent throws on a malformed % sequence, so a small test for that and for a trailing param would be good.
Summary
Implements #915 by wrapping Formulus settings QR payloads in a formulus://settings?payload=... deep link while preserving support for existing bare FRMLS: payloads.
Changes
Validation
iOS
The custom formulus URL scheme is registered through CFBundleURLTypes. Physical iOS Camera/Code Scanner handling of the custom scheme has not been verified and may require follow-up testing on an iOS device.