Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix scanning of small QR codes with JS #22651

Merged
merged 4 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions build-scripts/gulp/gather-static.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ function copyMapPanel(staticDir) {
);
}

function copyZXingWasm(staticDir) {
const staticPath = genStaticPath(staticDir);
copyFileDir(
npmPath("zxing-wasm/dist/reader/zxing_reader.wasm"),
staticPath("js")
);
}

gulp.task("copy-locale-data", async () => {
const staticDir = paths.app_output_static;
copyLocaleData(staticDir);
Expand Down Expand Up @@ -143,6 +151,7 @@ gulp.task("copy-static-app", async () => {
copyMapPanel(staticDir);

// Qr Scanner assets
copyZXingWasm(staticDir);
copyQrScannerWorker(staticDir);
});

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"@webcomponents/scoped-custom-element-registry": "0.0.9",
"@webcomponents/webcomponentsjs": "2.8.0",
"app-datepicker": "5.1.1",
"barcode-detector": "2.2.11",
"chart.js": "4.4.6",
"color-name": "2.0.0",
"comlink": "4.4.1",
Expand Down
16 changes: 15 additions & 1 deletion src/components/ha-qr-scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
// The BarcodeDetector Web API is not yet supported in all browsers,
// and "qr-scanner" defaults to a suboptimal implementation if it is not available.
// The following import makes a better implementation available that is based on a
// WebAssembly port of ZXing:
import { setZXingModuleOverrides } from "barcode-detector";
import type QrScanner from "qr-scanner";
import { fireEvent } from "../common/dom/fire_event";
import { stopPropagation } from "../common/dom/stop_propagation";
Expand All @@ -16,6 +21,15 @@ import "./ha-list-item";
import "./ha-textfield";
import type { HaTextField } from "./ha-textfield";

setZXingModuleOverrides({
locateFile: (path: string, prefix: string) => {
if (path.endsWith(".wasm")) {
return "/static/js/zxing_reader.wasm";
}
return prefix + path;
},
});

@customElement("ha-qr-scanner")
class HaQrScanner extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
Expand Down Expand Up @@ -174,7 +188,7 @@ class HaQrScanner extends LitElement {
}

private _qrCodeError = (err: any) => {
if (err === "No QR code found") {
if (err.endsWith("No QR code found")) {
this._qrNotFoundCount++;
if (this._qrNotFoundCount === 250) {
this._reportError(err);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -690,9 +690,6 @@ class DialogZWaveJSAddNode extends LitElement {
provisioningInfo
);
this._status = "provisioned";
if (this._params?.addedCallback) {
this._params.addedCallback();
}
} catch (err: any) {
this._error = err.message;
this._status = "failed";
Expand Down Expand Up @@ -831,9 +828,6 @@ class DialogZWaveJSAddNode extends LitElement {
if (message.event === "interview completed") {
this._unsubscribe();
this._status = "finished";
if (this._params?.addedCallback) {
this._params.addedCallback();
}
}

if (message.event === "interview stage completed") {
Expand Down Expand Up @@ -874,6 +868,9 @@ class DialogZWaveJSAddNode extends LitElement {
}
if (this._entryId) {
stopZwaveInclusion(this.hass, this._entryId);
if (this._params?.onStop) {
this._params.onStop();
}
}
this._requestedGrant = undefined;
this._dsk = undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { fireEvent } from "../../../../../common/dom/fire_event";

export interface ZWaveJSAddNodeDialogParams {
entry_id: string;
addedCallback?: () => void;
onStop?: () => void;
}

export const loadAddNodeDialog = () => import("./dialog-zwave_js-add-node");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,8 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
private async _addNodeClicked() {
showZWaveJSAddNodeDialog(this, {
entry_id: this.configEntryId!,
addedCallback: () => this._fetchData(),
// refresh the data after the dialog is closed. add a small delay for the inclusion state to update
onStop: () => setTimeout(() => this._fetchData(), 100),
});
}

Expand Down
34 changes: 34 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3944,6 +3944,20 @@ __metadata:
languageName: node
linkType: hard

"@types/dom-webcodecs@npm:^0.1.13":
version: 0.1.13
resolution: "@types/dom-webcodecs@npm:0.1.13"
checksum: 10/99cb227416725efd4b22175ef18988ae3fc728480fe6ed2192777d7dba52d18af540b4df49fcfa3cf73753d1dcf9d5399b089702bde215d78679284848b078f7
languageName: node
linkType: hard

"@types/emscripten@npm:^1.39.13":
version: 1.39.13
resolution: "@types/emscripten@npm:1.39.13"
checksum: 10/02c0446150f9cc2c74dc3a551f86ce13df266c33d8b98d11d9f17263e2d98a6a6b4d36bdd15066c4e1547ae1ed2d52eed9420116b4935d119009e0f53ddbb041
languageName: node
linkType: hard

"@types/eslint-scope@npm:^3.7.7":
version: 3.7.7
resolution: "@types/eslint-scope@npm:3.7.7"
Expand Down Expand Up @@ -5742,6 +5756,16 @@ __metadata:
languageName: node
linkType: hard

"barcode-detector@npm:2.2.11":
version: 2.2.11
resolution: "barcode-detector@npm:2.2.11"
dependencies:
"@types/dom-webcodecs": "npm:^0.1.13"
zxing-wasm: "npm:1.2.14"
checksum: 10/91f04ac8a73a5fccf15d08c2b148e3f9584448956de9b2506f5c5c3213ba133c504cd6890926f4fde2b1294e42b9943f979820440bc8373388d5a86cb6c764c5
languageName: node
linkType: hard

"bare-events@npm:^2.2.0":
version: 2.5.0
resolution: "bare-events@npm:2.5.0"
Expand Down Expand Up @@ -8833,6 +8857,7 @@ __metadata:
app-datepicker: "npm:5.1.1"
babel-loader: "npm:9.2.1"
babel-plugin-template-html-minifier: "npm:4.1.0"
barcode-detector: "npm:2.2.11"
browserslist-useragent-regexp: "npm:4.1.3"
chai: "npm:5.1.2"
chart.js: "npm:4.4.6"
Expand Down Expand Up @@ -15465,3 +15490,12 @@ __metadata:
checksum: 10/f2e05b767ed3141e6372a80af9caa4715d60969227f38b1a4370d60bffe153c9c5b33a862905609afc9b375ec57cd40999810d20e5e10229a204e8bde7ef255c
languageName: node
linkType: hard

"zxing-wasm@npm:1.2.14":
version: 1.2.14
resolution: "zxing-wasm@npm:1.2.14"
dependencies:
"@types/emscripten": "npm:^1.39.13"
checksum: 10/02ea0408553f1aebb412a97c5e11887c58da1b2adff636302232535e752b91bdb3f358411259b6cddd34b341df565336bc03f48895e362f61316018d9bbff8c3
languageName: node
linkType: hard
Loading