MyCrypto/common/components/ParityQrSigner.tsx

112 lines
2.8 KiB
TypeScript

import React from 'react';
import classnames from 'classnames';
import translate from 'translations';
import { Spinner } from 'components/ui';
import QrSigner from '@parity/qr-signer';
import './ParityQrSigner.scss';
interface State {
webcamError: null | React.ReactElement<any>;
isLoading: boolean;
}
interface ScanProps {
scan: true;
onScan(data: string): void;
}
interface ShowProps {
scan: false;
account: string;
data?: string;
rlp?: string;
}
interface SharedProps {
size?: number;
}
type Props = (ScanProps | ShowProps) & SharedProps;
export default class ParityQrSigner extends React.PureComponent<Props, State> {
public state: State = {
webcamError: null,
isLoading: true
};
public componentDidMount() {
this.checkForWebcam();
if (navigator.mediaDevices) {
navigator.mediaDevices.addEventListener('devicechange', this.checkForWebcam);
}
}
public componentWillUnmount() {
if (navigator.mediaDevices && navigator.mediaDevices.ondevicechange) {
navigator.mediaDevices.removeEventListener('devicechange', this.checkForWebcam);
}
}
public checkForWebcam = async () => {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
try {
await navigator.mediaDevices.getUserMedia({ video: true });
this.setState({
webcamError: null,
isLoading: false
});
} catch (e) {
const err = e as DOMException;
let errorMessage;
switch (err.name) {
case 'NotAllowedError':
case 'SecurityError':
errorMessage = translate('ADD_PARITY_ERROR_DISABLED');
break;
case 'NotFoundError':
case 'OverconstrainedError':
errorMessage = translate('ADD_PARITY_ERROR_NO_CAM');
break;
default:
errorMessage = translate('ADD_PARITY_ERROR_UNKNOWN');
}
this.setState({
webcamError: errorMessage,
isLoading: false
});
}
}
};
public render() {
const { webcamError, isLoading } = this.state;
const size = this.props.size || 300;
return (
<div
className={classnames({
ParityQrSigner: true,
'is-disabled': !!webcamError || isLoading
})}
style={{
width: size,
height: size
}}
>
{isLoading ? (
<div className="ParityQrSigner-loader">
<Spinner size="x3" light={true} />
</div>
) : webcamError ? (
<div className="ParityQrSigner-error">
<i className="ParityQrSigner-error-icon fa fa-exclamation-circle" />
{webcamError}
</div>
) : (
<QrSigner {...this.props} size={size} />
)}
</div>
);
}
}