v0.2.6: fix kiosk-code scan resolution + add zone QR asset
All checks were successful
build-apk / build (push) Successful in 30m18s
All checks were successful
build-apk / build (push) Successful in 30m18s
ScanScreen.lookupCode tried getMetersByScannerCode first and let its thrown error-envelope abort the whole lookup, so the getMetersByZoneName fallback never ran; it also sent ZoneName in the scanned case (the API is case-sensitive — the official app lowercases). Confirmed via live mitmproxy capture of the official app: a scanned code resolves through ScannerCode, and ZoneName=dl (lowercase) returns the zone. Now tries ScannerCode -> ZoneName -> zonename(lowercased) -> TerminalSerNo, each independent and non-fatal; only reports "Lookup failed" if every attempt errored. Adds docs/zone-qr/ with the DL-Sandpoint QR (encodes ScannerCode "DL", works in both BigBrainParking and the official app) and a how-to. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
deb78bf952
commit
2bdb59b49a
4 changed files with 71 additions and 17 deletions
|
|
@ -3,14 +3,14 @@
|
|||
"name": "BigBrainParking",
|
||||
"slug": "bigbrainparking",
|
||||
"scheme": "bigbrainparking",
|
||||
"version": "0.2.5",
|
||||
"version": "0.2.6",
|
||||
"orientation": "portrait",
|
||||
"userInterfaceStyle": "automatic",
|
||||
"newArchEnabled": true,
|
||||
"icon": "./assets/icon.png",
|
||||
"android": {
|
||||
"package": "top.mowden.bigbrainparking",
|
||||
"versionCode": 15,
|
||||
"versionCode": 16,
|
||||
"edgeToEdgeEnabled": true,
|
||||
"adaptiveIcon": {
|
||||
"foregroundImage": "./assets/adaptive-icon.png",
|
||||
|
|
|
|||
|
|
@ -66,23 +66,41 @@ export function ScanScreen() {
|
|||
const lookupCode = useCallback(
|
||||
async (code: string) => {
|
||||
setBusy(true);
|
||||
try {
|
||||
let res = await ps.getMetersByScannerCode(code);
|
||||
let zone = res.Zones?.[0];
|
||||
if (!zone) {
|
||||
res = await ps.getMetersByZoneName(code);
|
||||
// A scanned/typed code can resolve by terminal serial, scanner code, or
|
||||
// zone name. Unmatched lookups return an error envelope (which the client
|
||||
// throws), and ZoneName is case-sensitive server-side — the official app
|
||||
// queries it lowercased. So try each strategy independently and don't let
|
||||
// one failing attempt abort the others.
|
||||
// ScannerCode is what kiosk QRs encode and what the official app honors;
|
||||
// zone name (case-sensitive) and terminal serial are extra fallbacks.
|
||||
const attempts = [
|
||||
() => ps.getMetersByScannerCode(code),
|
||||
() => ps.getMetersByZoneName(code),
|
||||
() => ps.getMetersByZoneName(code.toLowerCase()),
|
||||
() => ps.getMetersBySerialNumber(code),
|
||||
];
|
||||
let zone:
|
||||
| NonNullable<Awaited<ReturnType<typeof ps.getMetersByZoneName>>['Zones']>[number]
|
||||
| undefined;
|
||||
let anyResponded = false;
|
||||
for (const attempt of attempts) {
|
||||
try {
|
||||
const res = await attempt();
|
||||
anyResponded = true;
|
||||
zone = res.Zones?.[0];
|
||||
if (zone) break;
|
||||
} catch {
|
||||
// strategy didn't apply (e.g. error envelope) — try the next one
|
||||
}
|
||||
if (zone) {
|
||||
setManualOpen(false);
|
||||
navigation.navigate('MeterDetail', { zone });
|
||||
} else {
|
||||
Alert.alert('Not found', `No meter matches "${code}".`);
|
||||
}
|
||||
} catch (e: any) {
|
||||
Alert.alert('Lookup failed', e?.serverMessage ?? e?.message ?? 'error');
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
setBusy(false);
|
||||
if (zone) {
|
||||
setManualOpen(false);
|
||||
navigation.navigate('MeterDetail', { zone });
|
||||
} else if (anyResponded) {
|
||||
Alert.alert('Not found', `No meter matches "${code}".`);
|
||||
} else {
|
||||
Alert.alert('Lookup failed', 'Could not reach ParkSmarter. Check your connection.');
|
||||
}
|
||||
},
|
||||
[navigation],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue