mirror of
https://github.com/pezkuwichain/pezkuwi-ui.git
synced 2026-06-17 19:31:04 +00:00
@@ -24,14 +24,12 @@
|
||||
"@polkadot/ui-settings": "3.8.2",
|
||||
"@polkadot/util": "^13.0.2",
|
||||
"@polkadot/util-crypto": "^13.0.2",
|
||||
"@zxing/browser": "^0.1.5",
|
||||
"@zxing/library": "^0.21.2",
|
||||
"qrcode-generator": "^1.4.4",
|
||||
"react-qr-reader": "^2.2.1",
|
||||
"styled-components": "^6.1.1",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-qr-reader": "^2.1.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@polkadot/util": "*",
|
||||
"@polkadot/util-crypto": "*",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2017-2024 @polkadot/react-qr authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import Reader from 'react-qr-reader';
|
||||
import { BrowserQRCodeReader, type IScannerControls } from '@zxing/browser';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
|
||||
import { styled } from './styled.js';
|
||||
import { createImgSize } from './util.js';
|
||||
@@ -23,6 +23,9 @@ const DEFAULT_ERROR = (error: Error): void => {
|
||||
};
|
||||
|
||||
function Scan ({ className = '', delay = DEFAULT_DELAY, onError = DEFAULT_ERROR, onScan, size, style = {} }: Props): React.ReactElement<Props> {
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
const controlsRef = useRef<IScannerControls | null>(null);
|
||||
|
||||
const containerStyle = useMemo(
|
||||
() => createImgSize(size),
|
||||
[size]
|
||||
@@ -33,21 +36,52 @@ function Scan ({ className = '', delay = DEFAULT_DELAY, onError = DEFAULT_ERROR,
|
||||
[onError]
|
||||
);
|
||||
|
||||
const _onScan = useCallback(
|
||||
(data: string | null) => data && onScan(data),
|
||||
[onScan]
|
||||
);
|
||||
useEffect(() => {
|
||||
const codeReader = new BrowserQRCodeReader();
|
||||
|
||||
const startScanning = async () => {
|
||||
try {
|
||||
const videoInputDevices = await BrowserQRCodeReader.listVideoInputDevices();
|
||||
const selectedDeviceId = videoInputDevices[0].deviceId;
|
||||
|
||||
controlsRef.current = await codeReader.decodeFromVideoDevice(
|
||||
selectedDeviceId,
|
||||
videoRef.current ?? undefined,
|
||||
(result, error) => {
|
||||
if (result) {
|
||||
onScan(result.getText());
|
||||
}
|
||||
|
||||
if (error && !(error instanceof Error)) {
|
||||
_onError(new Error(error));
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
_onError(error instanceof Error ? error : new Error('Unknown error occurred'));
|
||||
}
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
const timeoutId = setTimeout(startScanning, delay);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (controlsRef.current) {
|
||||
controlsRef.current.stop();
|
||||
}
|
||||
};
|
||||
}, [onScan, _onError, delay]);
|
||||
|
||||
return (
|
||||
<StyledDiv
|
||||
className={className}
|
||||
style={containerStyle}
|
||||
>
|
||||
<Reader
|
||||
<video
|
||||
className='ui--qr-Scan'
|
||||
delay={delay}
|
||||
onError={_onError}
|
||||
onScan={_onScan}
|
||||
ref={videoRef}
|
||||
style={style}
|
||||
/>
|
||||
</StyledDiv>
|
||||
@@ -60,10 +94,6 @@ const StyledDiv = styled.div`
|
||||
height: 100%;
|
||||
transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
width: 100%;
|
||||
|
||||
video {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user