Skip to content

Commit 02d4b59

Browse files
committed
Fix scanner stale error state
1 parent dccb123 commit 02d4b59

1 file changed

Lines changed: 24 additions & 6 deletions

File tree

client/src/components/qrCodeScanner.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,26 @@ import { useNavigate } from "react-router";
88
const QRCodeScannerModal = () => {
99
const [visible, setVisible] = useState(false);
1010
const [lastError, setLastError] = useState<string | null>(null);
11+
const [scannerSession, setScannerSession] = useState(0);
1112
const t = useTranslate();
1213
const navigate = useNavigate();
1314

15+
// Force a fresh scanner instance after each open/close cycle so stale camera errors do not persist.
16+
const resetScanner = () => {
17+
setLastError(null);
18+
setScannerSession((current) => current + 1);
19+
};
20+
21+
const openScanner = () => {
22+
resetScanner();
23+
setVisible(true);
24+
};
25+
26+
const closeScanner = () => {
27+
setVisible(false);
28+
resetScanner();
29+
};
30+
1431
const onScan = (detectedCodes: IDetectedBarcode[]) => {
1532
if (detectedCodes.length === 0) {
1633
return;
@@ -20,25 +37,25 @@ const QRCodeScannerModal = () => {
2037
// Check for the spoolman ID format
2138
const spoolMatch = result.match(/^web\+spoolman:s-(?<id>[0-9]+)$/i);
2239
if (spoolMatch && spoolMatch.groups) {
23-
setVisible(false);
40+
closeScanner();
2441
navigate(`/spool/show/${spoolMatch.groups.id}`);
2542
return;
2643
}
2744
const filamentMatch = result.match(/^web\+spoolman:f-(?<id>[0-9]+)$/i);
2845
if (filamentMatch && filamentMatch.groups) {
29-
setVisible(false);
46+
closeScanner();
3047
navigate(`/filament/show/${filamentMatch.groups.id}`);
3148
return;
3249
}
3350
const spoolURLmatch = result.match(/^https?:\/\/[^/]+(?:\/[^/]+)*\/spool\/show\/(?<id>[0-9]+)$/i);
3451
if (spoolURLmatch && spoolURLmatch.groups) {
35-
setVisible(false);
52+
closeScanner();
3653
navigate(`/spool/show/${spoolURLmatch.groups.id}`);
3754
return;
3855
}
3956
const filamentURLmatch = result.match(/^https?:\/\/[^/]+(?:\/[^/]+)*\/filament\/show\/(?<id>[0-9]+)$/i);
4057
if (filamentURLmatch && filamentURLmatch.groups) {
41-
setVisible(false);
58+
closeScanner();
4259
navigate(`/filament/show/${filamentURLmatch.groups.id}`);
4360
}
4461
};
@@ -47,15 +64,16 @@ const QRCodeScannerModal = () => {
4764
<>
4865
<FloatButton
4966
type="primary"
50-
onClick={() => setVisible(true)}
67+
onClick={openScanner}
5168
icon={<CameraOutlined />}
5269
shape="circle"
5370
style={{ right: "var(--camera-button-right)", bottom: "var(--camera-button-bottom)" }}
5471
/>
55-
<Modal open={visible} destroyOnHidden onCancel={() => setVisible(false)} footer={null} title={t("scanner.title")}>
72+
<Modal open={visible} destroyOnHidden onCancel={closeScanner} footer={null} title={t("scanner.title")}>
5673
<Space direction="vertical" style={{ width: "100%" }}>
5774
<p>{t("scanner.description")}</p>
5875
<Scanner
76+
key={scannerSession}
5977
constraints={{
6078
facingMode: "environment",
6179
}}

0 commit comments

Comments
 (0)