testing(utils): add test for auth and scanner
This commit is contained in:
parent
118ca1ed82
commit
fac5e7b66c
9 changed files with 238 additions and 88 deletions
42
frontend/package-lock.json
generated
42
frontend/package-lock.json
generated
|
@ -9,7 +9,7 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ericblade/quagga2": "^1.8.4",
|
"@ericblade/quagga2": "^1.8.4",
|
||||||
"@tanstack/react-query": "^5.52.1",
|
"@tanstack/react-query": "^5.59.15",
|
||||||
"@tanstack/react-table": "^8.20.5",
|
"@tanstack/react-table": "^8.20.5",
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
"@testing-library/jest-dom": "^5.17.0",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"fast-xml-parser": "^4.5.0",
|
"fast-xml-parser": "^4.5.0",
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
|
"jest-canvas-mock": "^2.5.2",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-bootstrap": "^2.10.4",
|
"react-bootstrap": "^2.10.4",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
@ -3727,9 +3728,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tanstack/query-core": {
|
"node_modules/@tanstack/query-core": {
|
||||||
"version": "5.56.2",
|
"version": "5.59.13",
|
||||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.56.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.13.tgz",
|
||||||
"integrity": "sha512-gor0RI3/R5rVV3gXfddh1MM+hgl0Z4G7tj6Xxpq6p2I03NGPaJ8dITY9Gz05zYYb/EJq9vPas/T4wn9EaDPd4Q==",
|
"integrity": "sha512-Oou0bBu/P8+oYjXsJQ11j+gcpLAMpqW42UlokQYEz4dE7+hOtVO9rVuolJKgEccqzvyFzqX4/zZWY+R/v1wVsQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
|
@ -3737,12 +3738,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tanstack/react-query": {
|
"node_modules/@tanstack/react-query": {
|
||||||
"version": "5.56.2",
|
"version": "5.59.15",
|
||||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.56.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.15.tgz",
|
||||||
"integrity": "sha512-SR0GzHVo6yzhN72pnRhkEFRAHMsUo5ZPzAxfTMvUxFIDVS6W9LYUp6nXW3fcHVdg0ZJl8opSH85jqahvm6DSVg==",
|
"integrity": "sha512-QbVlAkTI78wB4Mqgf2RDmgC0AOiJqer2c5k9STOOSXGv1S6ZkY37r/6UpE8DbQ2Du0ohsdoXgFNEyv+4eDoPEw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/query-core": "5.56.2"
|
"@tanstack/query-core": "5.59.13"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
|
@ -6655,6 +6656,12 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cssfontparser": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/cssnano": {
|
"node_modules/cssnano": {
|
||||||
"version": "5.1.15",
|
"version": "5.1.15",
|
||||||
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz",
|
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz",
|
||||||
|
@ -10610,6 +10617,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jest-canvas-mock": {
|
||||||
|
"version": "2.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.5.2.tgz",
|
||||||
|
"integrity": "sha512-vgnpPupjOL6+L5oJXzxTxFrlGEIbHdZqFU+LFNdtLxZ3lRDCl17FlTMM7IatoRQkrcyOTMlDinjUguqmQ6bR2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cssfontparser": "^1.2.1",
|
||||||
|
"moo-color": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/jest-changed-files": {
|
"node_modules/jest-changed-files": {
|
||||||
"version": "27.5.1",
|
"version": "27.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz",
|
||||||
|
@ -12147,6 +12164,15 @@
|
||||||
"mkdirp": "bin/cmd.js"
|
"mkdirp": "bin/cmd.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/moo-color": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "^1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"proxy": "http://localhost:3001",
|
"proxy": "http://localhost:3001",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ericblade/quagga2": "^1.8.4",
|
"@ericblade/quagga2": "^1.8.4",
|
||||||
"@tanstack/react-query": "^5.52.1",
|
"@tanstack/react-query": "^5.59.15",
|
||||||
"@tanstack/react-table": "^8.20.5",
|
"@tanstack/react-table": "^8.20.5",
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
"@testing-library/jest-dom": "^5.17.0",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"fast-xml-parser": "^4.5.0",
|
"fast-xml-parser": "^4.5.0",
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
|
"jest-canvas-mock": "^2.5.2",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-bootstrap": "^2.10.4",
|
"react-bootstrap": "^2.10.4",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { render, screen } from '@testing-library/react';
|
|
||||||
import App from './App';
|
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
|
||||||
render(<App />);
|
|
||||||
const linkElement = screen.getByText(/learn react/i);
|
|
||||||
expect(linkElement).toBeInTheDocument();
|
|
||||||
});
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { QuaggaJSResultObject } from "@ericblade/quagga2";
|
||||||
|
import { getMedianOfCodeErrors } from "../getMedianOfCodeErrors";
|
||||||
|
|
||||||
|
export const createMockQuaggaResult = (
|
||||||
|
decodedCodes: Array<{
|
||||||
|
error?: number;
|
||||||
|
code: number;
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
}> = []
|
||||||
|
): QuaggaJSResultObject => ({
|
||||||
|
codeResult: {
|
||||||
|
code: "123456",
|
||||||
|
start: 0,
|
||||||
|
end: 10,
|
||||||
|
codeset: 1,
|
||||||
|
startInfo: {
|
||||||
|
error: 0,
|
||||||
|
code: 1,
|
||||||
|
start: 0,
|
||||||
|
end: 5,
|
||||||
|
},
|
||||||
|
decodedCodes,
|
||||||
|
endInfo: {
|
||||||
|
error: 0,
|
||||||
|
code: 1,
|
||||||
|
start: 5,
|
||||||
|
end: 10,
|
||||||
|
},
|
||||||
|
direction: 1,
|
||||||
|
format: "QR",
|
||||||
|
},
|
||||||
|
barcodes: [],
|
||||||
|
line: [{ x: 0, y: 0 }],
|
||||||
|
angle: 0,
|
||||||
|
pattern: [],
|
||||||
|
box: [],
|
||||||
|
boxes: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getMedianOfCodeErrors", () => {
|
||||||
|
it("should return the median of code errors when there are valid errors", () => {
|
||||||
|
const result = createMockQuaggaResult([
|
||||||
|
{ error: 1, code: 1, start: 0, end: 5 },
|
||||||
|
{ error: 3, code: 1, start: 5, end: 10 },
|
||||||
|
{ error: 2, code: 1, start: 0, end: 10 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const median = getMedianOfCodeErrors(result);
|
||||||
|
expect(median).toBe(2); // The median of [1, 3, 2] is 2
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return undefined when there are no code errors", () => {
|
||||||
|
const result = createMockQuaggaResult([
|
||||||
|
{ code: 1, start: 0, end: 5 }, // No error property
|
||||||
|
{ code: 1, start: 5, end: 10 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const median = getMedianOfCodeErrors(result);
|
||||||
|
expect(median).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle an empty decodedCodes array", () => {
|
||||||
|
const result = createMockQuaggaResult([]);
|
||||||
|
|
||||||
|
const median = getMedianOfCodeErrors(result);
|
||||||
|
expect(median).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,66 @@
|
||||||
|
import React from "react";
|
||||||
|
import { render, waitFor, cleanup } from "@testing-library/react";
|
||||||
|
import { AuthContext } from "../../../App";
|
||||||
|
import { useAuth } from "../useAuthentication";
|
||||||
|
|
||||||
|
const MockedComponent: React.FC = () => {
|
||||||
|
const { authenticated } = useAuth();
|
||||||
|
return <div>{authenticated}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
let authenticated = false;
|
||||||
|
const setAuthenticated = (args: boolean) => (authenticated = args);
|
||||||
|
|
||||||
|
describe("useAuth", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should set authenticated to true when fetch returns ok", async () => {
|
||||||
|
global.fetch = jest.fn(() => Promise.resolve({ ok: true })) as jest.Mock;
|
||||||
|
|
||||||
|
render(
|
||||||
|
<AuthContext.Provider value={{ authenticated, setAuthenticated }}>
|
||||||
|
<MockedComponent />
|
||||||
|
</AuthContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
|
||||||
|
|
||||||
|
expect(authenticated).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should set authenticated to false when fetch returns not ok", async () => {
|
||||||
|
global.fetch = jest.fn(() => Promise.resolve({ ok: false })) as jest.Mock;
|
||||||
|
|
||||||
|
render(
|
||||||
|
<AuthContext.Provider value={{ authenticated, setAuthenticated }}>
|
||||||
|
<MockedComponent />
|
||||||
|
</AuthContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
|
||||||
|
|
||||||
|
expect(authenticated).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call fetch once", async () => {
|
||||||
|
global.fetch = jest.fn(() => Promise.resolve({ ok: false })) as jest.Mock;
|
||||||
|
|
||||||
|
render(
|
||||||
|
<AuthContext.Provider value={{ authenticated, setAuthenticated }}>
|
||||||
|
<MockedComponent />
|
||||||
|
</AuthContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(fetch).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
34
frontend/src/shared/utils/drawQuaggaProcessing.ts
Normal file
34
frontend/src/shared/utils/drawQuaggaProcessing.ts
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import Quagga, { QuaggaJSResultObject } from "@ericblade/quagga2";
|
||||||
|
|
||||||
|
export const drawQuaggaProcessing = (result: QuaggaJSResultObject) => {
|
||||||
|
const drawingCtx = Quagga.canvas.ctx.overlay;
|
||||||
|
const drawingCanvas = Quagga.canvas.dom.overlay;
|
||||||
|
drawingCtx.font = "24px Arial";
|
||||||
|
drawingCtx.fillStyle = "green";
|
||||||
|
const width = drawingCanvas.getAttribute("width");
|
||||||
|
const height = drawingCanvas.getAttribute("height");
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
if (result.boxes && width && height) {
|
||||||
|
drawingCtx.clearRect(0, 0, parseInt(width), parseInt(height));
|
||||||
|
result.boxes
|
||||||
|
.filter((box) => box !== result.box)
|
||||||
|
.forEach((box) => {
|
||||||
|
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, {
|
||||||
|
color: "purple",
|
||||||
|
lineWidth: 2,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (result.box) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, {
|
||||||
|
color: "blue",
|
||||||
|
lineWidth: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (result.codeResult && result.codeResult.code) {
|
||||||
|
drawingCtx.font = "24px Arial";
|
||||||
|
drawingCtx.fillText(result.codeResult.code, 10, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
20
frontend/src/shared/utils/getMedianOfCodeErrors.ts
Normal file
20
frontend/src/shared/utils/getMedianOfCodeErrors.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { QuaggaJSResultObject } from "@ericblade/quagga2";
|
||||||
|
|
||||||
|
export const getMedianOfCodeErrors = (result: QuaggaJSResultObject) => {
|
||||||
|
const errors = result.codeResult.decodedCodes.flatMap((x) => x.error);
|
||||||
|
const medianOfErrors = getMedian(errors);
|
||||||
|
return medianOfErrors;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMedian = (arr: (number | undefined)[]) => {
|
||||||
|
const newArr = [...arr].filter((x) => typeof x !== "undefined");
|
||||||
|
if (!newArr.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newArr.sort((a, b) => a! - b!);
|
||||||
|
const half = Math.floor(newArr.length / 2);
|
||||||
|
if (newArr.length % 2 === 1) {
|
||||||
|
return newArr[half];
|
||||||
|
}
|
||||||
|
return (newArr[half - 1]! + newArr[half]!) / 2;
|
||||||
|
};
|
|
@ -1,11 +1,10 @@
|
||||||
import { useCallback, useContext } from "react";
|
import { useCallback, useContext, useEffect } from "react";
|
||||||
import { AuthContext } from "../../App";
|
import { AuthContext } from "../../App";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
|
||||||
|
|
||||||
type UseAuthHook = { authenticated: boolean };
|
type UseAuthHook = { authenticated: boolean };
|
||||||
|
|
||||||
export const useAuth = (): UseAuthHook => {
|
export const useAuth = (): UseAuthHook => {
|
||||||
const auth = useContext(AuthContext);
|
const { authenticated, setAuthenticated } = useContext(AuthContext);
|
||||||
|
|
||||||
const authenticationCheck = useCallback(
|
const authenticationCheck = useCallback(
|
||||||
async () =>
|
async () =>
|
||||||
|
@ -16,17 +15,14 @@ export const useAuth = (): UseAuthHook => {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
auth.setAuthenticated?.(res.ok);
|
setAuthenticated?.(res.ok);
|
||||||
//react-query can't handle undefined without throwing a warning ...
|
|
||||||
return null;
|
|
||||||
}),
|
}),
|
||||||
[auth]
|
[setAuthenticated]
|
||||||
);
|
);
|
||||||
|
|
||||||
useQuery({
|
useEffect(() => {
|
||||||
queryFn: authenticationCheck,
|
authenticationCheck();
|
||||||
queryKey: ["auth"],
|
}, [authenticationCheck]);
|
||||||
});
|
|
||||||
|
|
||||||
return auth;
|
return { authenticated };
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,8 @@ import Quagga, {
|
||||||
QuaggaJSResultObject,
|
QuaggaJSResultObject,
|
||||||
} from "@ericblade/quagga2";
|
} from "@ericblade/quagga2";
|
||||||
import { useState, useCallback, useEffect } from "react";
|
import { useState, useCallback, useEffect } from "react";
|
||||||
|
import { getMedianOfCodeErrors } from "./getMedianOfCodeErrors";
|
||||||
|
import { drawQuaggaProcessing } from "./drawQuaggaProcessing";
|
||||||
|
|
||||||
const constraints = {
|
const constraints = {
|
||||||
width: 640,
|
width: 640,
|
||||||
|
@ -29,28 +31,6 @@ export const useScanner = ({
|
||||||
|
|
||||||
const [scannerRef, setScannerRef] = useState<HTMLDivElement | null>(null);
|
const [scannerRef, setScannerRef] = useState<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
const getMedian = useCallback((arr: (number | undefined)[]) => {
|
|
||||||
const newArr = [...arr].filter((x) => typeof x !== "undefined");
|
|
||||||
if (!newArr.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
newArr.sort((a, b) => a! - b!);
|
|
||||||
const half = Math.floor(newArr.length / 2);
|
|
||||||
if (newArr.length % 2 === 1) {
|
|
||||||
return newArr[half];
|
|
||||||
}
|
|
||||||
return (newArr[half - 1]! + newArr[half]!) / 2;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const getMedianOfCodeErrors = useCallback(
|
|
||||||
(result: QuaggaJSResultObject) => {
|
|
||||||
const errors = result.codeResult.decodedCodes.flatMap((x) => x.error);
|
|
||||||
const medianOfErrors = getMedian(errors);
|
|
||||||
return medianOfErrors;
|
|
||||||
},
|
|
||||||
[getMedian]
|
|
||||||
);
|
|
||||||
|
|
||||||
const errorCheck = useCallback(
|
const errorCheck = useCallback(
|
||||||
(result: QuaggaJSResultObject) => {
|
(result: QuaggaJSResultObject) => {
|
||||||
if (!onDetected) {
|
if (!onDetected) {
|
||||||
|
@ -66,42 +46,9 @@ export const useScanner = ({
|
||||||
onDetected(result.codeResult.code);
|
onDetected(result.codeResult.code);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[getMedianOfCodeErrors, onDetected]
|
[onDetected]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleProcessed = (result: QuaggaJSResultObject) => {
|
|
||||||
const drawingCtx = Quagga.canvas.ctx.overlay;
|
|
||||||
const drawingCanvas = Quagga.canvas.dom.overlay;
|
|
||||||
drawingCtx.font = "24px Arial";
|
|
||||||
drawingCtx.fillStyle = "green";
|
|
||||||
const width = drawingCanvas.getAttribute("width");
|
|
||||||
const height = drawingCanvas.getAttribute("height");
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
if (result.boxes && width && height) {
|
|
||||||
drawingCtx.clearRect(0, 0, parseInt(width), parseInt(height));
|
|
||||||
result.boxes
|
|
||||||
.filter((box) => box !== result.box)
|
|
||||||
.forEach((box) => {
|
|
||||||
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, {
|
|
||||||
color: "purple",
|
|
||||||
lineWidth: 2,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (result.box) {
|
|
||||||
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, {
|
|
||||||
color: "blue",
|
|
||||||
lineWidth: 2,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (result.codeResult && result.codeResult.code) {
|
|
||||||
drawingCtx.font = "24px Arial";
|
|
||||||
drawingCtx.fillText(result.codeResult.code, 10, 20);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getCameraId = useCallback(async () => {
|
const getCameraId = useCallback(async () => {
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
video: { facingMode: "environment" },
|
video: { facingMode: "environment" },
|
||||||
|
@ -150,7 +97,7 @@ export const useScanner = ({
|
||||||
locate: true,
|
locate: true,
|
||||||
},
|
},
|
||||||
async (err) => {
|
async (err) => {
|
||||||
Quagga.onProcessed(handleProcessed);
|
Quagga.onProcessed(drawQuaggaProcessing);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return console.error("Error starting Quagga:", err);
|
return console.error("Error starting Quagga:", err);
|
||||||
|
@ -170,7 +117,7 @@ export const useScanner = ({
|
||||||
await Quagga.CameraAccess.release();
|
await Quagga.CameraAccess.release();
|
||||||
await Quagga.stop();
|
await Quagga.stop();
|
||||||
Quagga.offDetected(errorCheck);
|
Quagga.offDetected(errorCheck);
|
||||||
Quagga.offProcessed(handleProcessed);
|
Quagga.offProcessed(drawQuaggaProcessing);
|
||||||
}, [errorCheck]);
|
}, [errorCheck]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
Loading…
Reference in a new issue