@robotical/webapp-types 3.21.12 → 3.21.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-types/package.json +14 -5
- package/dist-types/src/components/disposables/SwitchableCameraScanner/configure-barcode-detector.d.ts +2 -0
- package/dist-types/src/components/disposables/SwitchableCameraScanner/configure-barcode-detector.js +11 -0
- package/dist-types/src/components/disposables/SwitchableCameraScanner/index.d.ts +1 -0
- package/dist-types/src/components/disposables/SwitchableCameraScanner/index.js +1 -0
- package/dist-types/src/components/modals/LEDLightsOrQRVerificationModal/index.d.ts +3 -1
- package/dist-types/src/components/modals/LEDLightsOrQRVerificationModal/index.js +65 -15
- package/package.json +1 -1
package/dist-types/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "marty-web-app",
|
|
3
|
-
"version": "3.21.
|
|
3
|
+
"version": "3.21.14",
|
|
4
4
|
"private": true,
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=20"
|
|
7
|
+
},
|
|
5
8
|
"dependencies": {
|
|
6
9
|
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
|
7
10
|
"@radix-ui/react-icons": "^1.3.2",
|
|
@@ -13,7 +16,7 @@
|
|
|
13
16
|
"@robotical/cog-shooter-game": "^0.1.27",
|
|
14
17
|
"@robotical/jumping-game": "^0.1.29",
|
|
15
18
|
"@robotical/martyblocks": "^4.0.67",
|
|
16
|
-
"@robotical/martyblocksjr": "^4.
|
|
19
|
+
"@robotical/martyblocksjr": "^4.3.0",
|
|
17
20
|
"@robotical/maze": "^0.1.21",
|
|
18
21
|
"@robotical/rc-sequencer": "^1.1.15",
|
|
19
22
|
"@robotical/ricjs-robotical-addons": "^1.2.8",
|
|
@@ -23,7 +26,7 @@
|
|
|
23
26
|
"@robotical/skiing-game": "^0.1.24",
|
|
24
27
|
"@robotical/space-shooter-game": "^0.1.15",
|
|
25
28
|
"@sentry/react": "^8.55.2",
|
|
26
|
-
"@yudiel/react-qr-scanner": "2.
|
|
29
|
+
"@yudiel/react-qr-scanner": "2.6.0",
|
|
27
30
|
"aws-sdk": "^2.1394.0",
|
|
28
31
|
"bowser": "^2.11.0",
|
|
29
32
|
"core-js": "^3.6.5",
|
|
@@ -44,20 +47,26 @@
|
|
|
44
47
|
"semver": "^7.3.7",
|
|
45
48
|
"styled-components": "^5.3.3",
|
|
46
49
|
"typescript": "^4.6.2",
|
|
47
|
-
"web-vitals": "^2.1.4"
|
|
50
|
+
"web-vitals": "^2.1.4",
|
|
51
|
+
"zxing-wasm": "3.1.1"
|
|
48
52
|
},
|
|
49
53
|
"scripts": {
|
|
50
54
|
"copy-space-shooter-assets": "node copy-space-shooter-assets.js",
|
|
55
|
+
"copy-qr-wasm": "shx rm -rf ./public/qr-scanner && shx mkdir -p ./public/qr-scanner && shx cp ./node_modules/zxing-wasm/dist/reader/zxing_reader.wasm ./public/qr-scanner/zxing_reader.wasm",
|
|
51
56
|
"copy-mb": "shx rm -rf ./public/MartyBlocks && shx mkdir -p ./public/MartyBlocks && shx cp -r ./node_modules/@robotical/martyblocks/dist/. ./public/MartyBlocks/",
|
|
52
57
|
"copy-mbjr": "shx rm -rf ./public/MartyBlocksJR && shx mkdir -p ./public/MartyBlocksJR && shx cp -r ./node_modules/@robotical/martyblocksjr/editions/free/src/. ./public/MartyBlocksJR/",
|
|
53
58
|
"clean-mb": "shx rm -r ./node_modules/@robotical/martyblocks",
|
|
54
59
|
"clean-mbjr": "shx rm -r ./node_modules/@robotical/martyblocksjr",
|
|
55
60
|
"transpile-public-legacy": "node scripts/transpile-public-legacy.js",
|
|
56
|
-
"prepare": "npm run copy-mb && npm run copy-mbjr && npm run copy-space-shooter-assets && NODE_OPTIONS=\"--max-old-space-size=8192\" npm run transpile-public-legacy",
|
|
61
|
+
"prepare": "npm run copy-mb && npm run copy-mbjr && npm run copy-space-shooter-assets && npm run copy-qr-wasm && NODE_OPTIONS=\"--max-old-space-size=8192\" npm run transpile-public-legacy",
|
|
62
|
+
"prestart": "npm run copy-qr-wasm",
|
|
57
63
|
"start": "react-scripts start",
|
|
58
64
|
"start-pwa": "http-server build -c-1 -p 3001 --directory build",
|
|
65
|
+
"prebuild": "npm run copy-qr-wasm",
|
|
59
66
|
"build": "react-scripts build",
|
|
67
|
+
"prebuild:prod": "npm run copy-qr-wasm",
|
|
60
68
|
"build:prod": "GENERATE_SOURCEMAP=false react-scripts build && tsc --project tsconfig.prod.json",
|
|
69
|
+
"prebuild:sentry": "npm run copy-qr-wasm",
|
|
61
70
|
"build:sentry": "GENERATE_SOURCEMAP=true react-scripts build && tsc --project tsconfig.prod.json",
|
|
62
71
|
"sentry:upload-sourcemaps": "sentry-cli sourcemaps inject build/static/js && sentry-cli sourcemaps upload --release \"marty-web-app@$npm_package_version\" --validate --strict --wait build/static/js",
|
|
63
72
|
"sentry:remove-sourcemaps": "find build/static/js -type f -name '*.map' -delete",
|
package/dist-types/src/components/disposables/SwitchableCameraScanner/configure-barcode-detector.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { setZXingModuleOverrides } from "@yudiel/react-qr-scanner";
|
|
2
|
+
var qrScannerAssetUrl = "".concat((process.env.PUBLIC_URL || "").replace(/\/$/, ""), "/qr-scanner/zxing_reader.wasm");
|
|
3
|
+
export var locateBarcodeDetectorFile = function (path, prefix) {
|
|
4
|
+
return path === "zxing_reader.wasm" ? qrScannerAssetUrl : "".concat(prefix).concat(path);
|
|
5
|
+
};
|
|
6
|
+
// A fresh overrides object also drops zxing-wasm's cached module promise,
|
|
7
|
+
// allowing a retry after a transient initialization failure.
|
|
8
|
+
export var resetBarcodeDetectorModule = function () {
|
|
9
|
+
return setZXingModuleOverrides({ locateFile: locateBarcodeDetectorFile });
|
|
10
|
+
};
|
|
11
|
+
resetBarcodeDetectorModule();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type IScannerProps } from "@yudiel/react-qr-scanner";
|
|
2
|
+
import "./configure-barcode-detector";
|
|
2
3
|
type Props = IScannerProps;
|
|
3
4
|
export default function SwitchableCameraScanner({ constraints, ...scannerProps }: Props): import("react/jsx-runtime").JSX.Element;
|
|
4
5
|
export {};
|
|
@@ -26,6 +26,7 @@ import { useTranslation } from "react-i18next";
|
|
|
26
26
|
import { MdCameraswitch } from "react-icons/md";
|
|
27
27
|
import { Scanner } from "@yudiel/react-qr-scanner";
|
|
28
28
|
import isPhoneApp from "../../../utils/phone-app-communication/is-phone-app";
|
|
29
|
+
import "./configure-barcode-detector";
|
|
29
30
|
import { acquireCameraStreamLifecycleGuard, addCameraStreamLifecycleOwner, } from "./camera-stream-lifecycle-guard";
|
|
30
31
|
import styles from "./styles.module.css";
|
|
31
32
|
function LifecycleGuardedScanner(props) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { RaftTypeE } from "../../../types/raft";
|
|
2
|
-
export
|
|
2
|
+
export type QRScannerErrorDisposition = "permission-denied" | "detector-unavailable" | "unexpected";
|
|
3
|
+
export declare const classifyQRScannerError: (error: unknown) => QRScannerErrorDisposition;
|
|
4
|
+
export declare const reportQRScannerError: (error: unknown) => QRScannerErrorDisposition;
|
|
3
5
|
type Props = {
|
|
4
6
|
targetRaftType: RaftTypeE.COG;
|
|
5
7
|
allowSwitchToMarty?: boolean;
|
|
@@ -46,33 +46,65 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
49
|
-
import { useEffect, useState } from "react";
|
|
49
|
+
import { useEffect, useRef, useState } from "react";
|
|
50
50
|
import modalState from "../../../state-observables/modal/ModalState";
|
|
51
51
|
import styles from "./styles.module.css";
|
|
52
52
|
import { HiOutlineLightBulb } from "react-icons/hi";
|
|
53
53
|
import { MdQrCode } from "react-icons/md";
|
|
54
54
|
import { ReactComponent as BluetoothSVG } from "../../../assets/configuration/bluetooth.svg";
|
|
55
55
|
import { MAIN_BLUE } from "../../../styles/colors";
|
|
56
|
-
|
|
57
|
-
import { centerText } from '@yudiel/react-qr-scanner';
|
|
56
|
+
import { centerText, } from "@yudiel/react-qr-scanner";
|
|
58
57
|
import { ConnManager } from "@robotical/roboticaljs";
|
|
59
58
|
import { useTranslation } from "react-i18next";
|
|
60
59
|
import SwitchableCameraScanner from "../../disposables/SwitchableCameraScanner";
|
|
60
|
+
import { resetBarcodeDetectorModule } from "../../disposables/SwitchableCameraScanner/configure-barcode-detector";
|
|
61
61
|
import Logger from "../../../services/logger/Logger";
|
|
62
62
|
var SHOW_LOGS = true;
|
|
63
63
|
var TAG = "LEDLightsOrQRVerificationModal";
|
|
64
|
+
var getErrorProperty = function (error, property) {
|
|
65
|
+
if (error === null || typeof error !== "object") {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
var errorRecord = error;
|
|
69
|
+
return property in errorRecord ? errorRecord[property] : undefined;
|
|
70
|
+
};
|
|
71
|
+
export var classifyQRScannerError = function (error) {
|
|
72
|
+
var cause = getErrorProperty(error, "cause");
|
|
73
|
+
var errorKind = getErrorProperty(error, "kind");
|
|
74
|
+
var errorName = getErrorProperty(error, "name");
|
|
75
|
+
var causeName = getErrorProperty(cause, "name");
|
|
76
|
+
var errorMessage = getErrorProperty(error, "message");
|
|
77
|
+
var causeMessage = getErrorProperty(cause, "message");
|
|
78
|
+
if (errorKind === "permission-denied" ||
|
|
79
|
+
errorName === "NotAllowedError" ||
|
|
80
|
+
errorName === "PermissionDeniedError" ||
|
|
81
|
+
causeName === "NotAllowedError" ||
|
|
82
|
+
causeName === "PermissionDeniedError") {
|
|
83
|
+
return "permission-denied";
|
|
84
|
+
}
|
|
85
|
+
if ((errorName === "NotSupportedError" || causeName === "NotSupportedError") &&
|
|
86
|
+
[errorMessage, causeMessage].some(function (message) {
|
|
87
|
+
return typeof message === "string" &&
|
|
88
|
+
message.includes("Barcode detection service unavailable");
|
|
89
|
+
})) {
|
|
90
|
+
return "detector-unavailable";
|
|
91
|
+
}
|
|
92
|
+
return "unexpected";
|
|
93
|
+
};
|
|
64
94
|
export var reportQRScannerError = function (error) {
|
|
65
|
-
var
|
|
66
|
-
|
|
67
|
-
"name" in error &&
|
|
68
|
-
typeof error.name === "string"
|
|
69
|
-
? error.name
|
|
70
|
-
: "";
|
|
71
|
-
if (errorName === "NotAllowedError" || errorName === "PermissionDeniedError") {
|
|
95
|
+
var disposition = classifyQRScannerError(error);
|
|
96
|
+
if (disposition === "permission-denied") {
|
|
72
97
|
Logger.warn(SHOW_LOGS, TAG, "QR camera permission was not granted", error);
|
|
73
|
-
return;
|
|
98
|
+
return disposition;
|
|
99
|
+
}
|
|
100
|
+
var cause = getErrorProperty(error, "cause");
|
|
101
|
+
if (cause !== undefined) {
|
|
102
|
+
Logger.error(SHOW_LOGS, TAG, "QR scanner failed", cause, error);
|
|
74
103
|
}
|
|
75
|
-
|
|
104
|
+
else {
|
|
105
|
+
Logger.error(SHOW_LOGS, TAG, error);
|
|
106
|
+
}
|
|
107
|
+
return disposition;
|
|
76
108
|
};
|
|
77
109
|
export default function LEDLightsOrQRVerificationModal(_a) {
|
|
78
110
|
var _this = this;
|
|
@@ -134,12 +166,19 @@ export default function LEDLightsOrQRVerificationModal(_a) {
|
|
|
134
166
|
var id = _a.id, title = _a.title, subtitle = _a.subtitle, icon = _a.icon;
|
|
135
167
|
return (_jsxs("button", __assign({ type: "button", className: qrSelected && id === 'qr' ? [styles.card, styles.qrselected].join(" ") : styles.card, onClick: function () { return handleSelect(id); }, "aria-label": title, "aria-pressed": id === "qr" ? qrSelected : false }, { children: [_jsx("div", __assign({ className: styles.icon }, { children: icon })), _jsx("h3", __assign({ className: styles.title }, { children: title })), _jsx("p", __assign({ className: styles.subtitle }, { children: subtitle }))] }), id));
|
|
136
168
|
}) })) :
|
|
137
|
-
_jsx("div", __assign({ className: styles.cogNote }, { children: _jsxs("strong", { children: ["Don't forget to ", _jsx("span", __assign({ className: styles.cogNoteHighlight }, { children: "turn on" })), " your Cog!"] }) }))] }), qrSelected && _jsx(QRContent, { setSerialNo: setSerialNoFromQR }), _jsxs("div", __assign({ className: styles.buttonsContainer }, { children: [isButtonToConnectVisible && _jsx("button", __assign({ type: "button", className: styles.connectButton, onClick: handleConnect }, { children: t('connection.qr_connect_button') })), _jsx("button", __assign({ type: "button", className: styles.cancelButton, onClick: function () { return modalState.closeModal(cancelResult); } }, { children: t('connection.cancel') }))] }))] })));
|
|
169
|
+
_jsx("div", __assign({ className: styles.cogNote }, { children: _jsxs("strong", { children: ["Don't forget to ", _jsx("span", __assign({ className: styles.cogNoteHighlight }, { children: "turn on" })), " your Cog!"] }) }))] }), qrSelected && (_jsx(QRContent, { setSerialNo: setSerialNoFromQR, onScannerUnavailable: function () { return setQRSelected(false); } })), _jsxs("div", __assign({ className: styles.buttonsContainer }, { children: [isButtonToConnectVisible && _jsx("button", __assign({ type: "button", className: styles.connectButton, onClick: handleConnect }, { children: t('connection.qr_connect_button') })), _jsx("button", __assign({ type: "button", className: styles.cancelButton, onClick: function () { return modalState.closeModal(cancelResult); } }, { children: t('connection.cancel') }))] }))] })));
|
|
138
170
|
}
|
|
139
171
|
function QRContent(_a) {
|
|
140
172
|
var _this = this;
|
|
141
173
|
var _b;
|
|
142
|
-
var setSerialNo = _a.setSerialNo;
|
|
174
|
+
var setSerialNo = _a.setSerialNo, onScannerUnavailable = _a.onScannerUnavailable;
|
|
175
|
+
var isActiveRef = useRef(true);
|
|
176
|
+
useEffect(function () {
|
|
177
|
+
isActiveRef.current = true;
|
|
178
|
+
return function () {
|
|
179
|
+
isActiveRef.current = false;
|
|
180
|
+
};
|
|
181
|
+
}, []);
|
|
143
182
|
var onQrCodeFound = function (result) { return __awaiter(_this, void 0, void 0, function () {
|
|
144
183
|
var rawValue, serialNo;
|
|
145
184
|
var _a;
|
|
@@ -154,8 +193,19 @@ function QRContent(_a) {
|
|
|
154
193
|
return [2 /*return*/];
|
|
155
194
|
});
|
|
156
195
|
}); };
|
|
196
|
+
var onScannerError = function (error) {
|
|
197
|
+
if (!isActiveRef.current) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (reportQRScannerError(error) !== "detector-unavailable") {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
resetBarcodeDetectorModule();
|
|
204
|
+
onScannerUnavailable();
|
|
205
|
+
window.applicationManager.toaster.error("QR scanning is unavailable. Please use LED verification or select QR Code Verification to try again.", { autoClose: false });
|
|
206
|
+
};
|
|
157
207
|
var isWebapp = ((_b = window.applicationManager.deviceInfo) === null || _b === void 0 ? void 0 : _b.manufacturer) === "Webapp";
|
|
158
|
-
return (_jsx("div", __assign({ className: styles.QRcontainer }, { children: _jsx("div", __assign({ className: styles.QRscannerContainer }, { children: _jsx(SwitchableCameraScanner, { styles: { container: { transform: isWebapp ? 'scaleX(-1)' : 'none' } }, onError:
|
|
208
|
+
return (_jsx("div", __assign({ className: styles.QRcontainer }, { children: _jsx("div", __assign({ className: styles.QRscannerContainer }, { children: _jsx(SwitchableCameraScanner, { styles: { container: { transform: isWebapp ? 'scaleX(-1)' : 'none' } }, onError: onScannerError, formats: [
|
|
159
209
|
"qr_code",
|
|
160
210
|
"micro_qr_code",
|
|
161
211
|
"rm_qr_code",
|