signal-desktop/ts/components/QrCode.tsx

63 lines
1.7 KiB
TypeScript
Raw Normal View History

2022-01-05 17:59:59 +00:00
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { ReactElement } from 'react';
2022-01-14 16:45:05 +00:00
import React, { useMemo, useRef } from 'react';
2022-01-05 17:59:59 +00:00
import qrcode from 'qrcode-generator';
import { getEnvironment, Environment } from '../environment';
2022-01-05 17:59:59 +00:00
const AUTODETECT_TYPE_NUMBER = 0;
2022-01-06 00:08:28 +00:00
const ERROR_CORRECTION_LEVEL = 'L';
2022-01-05 17:59:59 +00:00
type PropsType = Readonly<{
2022-01-14 16:45:05 +00:00
alt: string;
2022-01-05 17:59:59 +00:00
className?: string;
data: string;
}>;
export function QrCode(props: PropsType): ReactElement {
2022-01-14 16:45:05 +00:00
const { alt, className, data } = props;
2022-01-05 17:59:59 +00:00
2022-01-14 16:45:05 +00:00
const elRef = useRef<null | HTMLImageElement>(null);
2022-01-05 17:59:59 +00:00
2022-01-14 16:45:05 +00:00
const src = useMemo(() => {
const qrCode = qrcode(AUTODETECT_TYPE_NUMBER, ERROR_CORRECTION_LEVEL);
qrCode.addData(data);
qrCode.make();
2022-01-05 17:59:59 +00:00
2022-01-14 16:45:05 +00:00
const svgData = qrCode.createSvgTag({ cellSize: 1, margin: 0 });
return `data:image/svg+xml;utf8,${svgData}`;
}, [data]);
2022-01-05 17:59:59 +00:00
// Add a development-only feature to copy a QR code to the clipboard by double-clicking.
// This can be used to quickly inspect the code, or to link this Desktop with an iOS
// simulator primary, which has a debug-only option to paste the linking URL instead of
// scanning it. (By the time you read this comment Android may have a similar feature.)
const onDoubleClick = () => {
if (getEnvironment() === Environment.Production) {
return;
}
navigator.clipboard.writeText(data);
2022-01-14 16:45:05 +00:00
const el = elRef.current;
if (!el) {
return;
}
2022-01-14 16:45:05 +00:00
el.style.filter = 'brightness(50%)';
window.setTimeout(() => {
2022-01-14 16:45:05 +00:00
el.style.filter = '';
}, 150);
};
2022-01-05 17:59:59 +00:00
return (
2022-01-14 16:45:05 +00:00
<img
alt={alt}
2022-01-05 17:59:59 +00:00
className={className}
onDoubleClick={onDoubleClick}
2022-01-14 16:45:05 +00:00
ref={elRef}
src={src}
2022-01-05 17:59:59 +00:00
/>
);
}