You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/components/SessionQRCode.tsx

135 lines
3.8 KiB
TypeScript

import { MouseEvent, useRef } from 'react';
import { QRCode } from 'react-qrcode-logo';
import { CSSProperties } from 'styled-components';
import { ThemeStateType } from '../themes/constants/colors';
import { THEME_GLOBALS } from '../themes/globals';
import { AnimatedFlex } from './basic/Flex';
export type SessionQRCodeProps = {
id: string;
value: string;
size: number;
backgroundColor?: string;
foregroundColor?: string;
logoImage?: string;
logoWidth?: number;
logoHeight?: number;
logoIsSVG?: boolean;
theme?: ThemeStateType;
ignoreTheme?: boolean;
ariaLabel?: string;
dataTestId?: string;
style?: CSSProperties;
};
export function SessionQRCode(props: SessionQRCodeProps) {
const {
id,
value,
size,
backgroundColor = 'white',
foregroundColor = 'black',
logoImage,
logoWidth,
logoHeight,
logoIsSVG,
theme,
ignoreTheme,
ariaLabel,
dataTestId,
style,
} = props;
const qrRef = useRef<QRCode>(null);
// const [svgDataURL, setSvgDataURL] = useState('');
// const [currentTheme, setCurrentTheme] = useState(theme);
// const [loading, setLoading] = useState(false);
// const loadLogoImage = useCallback(async () => {
// if (logoImage && logoIsSVG) {
// setLoading(true);
// try {
// const response = await fetch(logoImage);
// let svgString = await response.text();
// if (!ignoreTheme && theme && !isEmpty(theme)) {
// svgString = svgString.replaceAll(
// 'black',
// getThemeValue(
// checkDarkTheme(theme) ? '--background-primary-color' : '--text-primary-color'
// )
// );
// }
// setSvgDataURL(`data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`);
// } catch (error) {
// window.log.error('Error fetching the QR Code logo which is an svg:', error);
// }
// setLoading(false);
// }
// }, [ignoreTheme, logoImage, logoIsSVG, theme]);
// useMount(() => {
// void loadLogoImage();
// });
// useEffect(() => {
// if (theme && theme !== currentTheme) {
// setCurrentTheme(theme);
// void loadLogoImage();
// }
// }, [currentTheme, loadLogoImage, theme]);
const qrCanvasSize = 1000;
const canvasLogoWidth =
logoWidth && logoHeight ? (qrCanvasSize * 0.25 * logoWidth) / logoHeight : undefined;
const canvasLogoHeight = logoHeight ? (qrCanvasSize * 0.25 * logoHeight) / logoHeight : undefined;
// We use an AnimatedFlex because we fade in the QR code to hide the logo flickering on first render
return (
<AnimatedFlex
container={true}
justifyContent="center"
alignItems="center"
width={`${size}px`}
height={`${size}px`}
id={id}
aria-label={ariaLabel || 'QR code'}
title={window.i18n('clickToTrustContact')}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: THEME_GLOBALS['--default-duration-seconds'] }}
onClick={(event: MouseEvent<HTMLDivElement>) => {
event.preventDefault();
qrRef.current?.download('jpg', id);
}}
data-testId={dataTestId || 'session-qr-code'}
style={style}
>
<QRCode
ref={qrRef}
id={`${id}-canvas`}
value={value}
ecLevel={'Q'}
size={qrCanvasSize}
bgColor={backgroundColor}
fgColor={foregroundColor}
quietZone={40}
logoImage={logoImage}
logoWidth={canvasLogoWidth}
logoHeight={canvasLogoHeight}
removeQrCodeBehindLogo={true}
logoOnLoad={e => window.log.debug(`WIP: [SessionQRCode] logo loaded`, e)}
style={{
borderRadius: '10px',
cursor: 'pointer',
overflow: 'hidden',
width: size,
height: size,
}}
/>
</AnimatedFlex>
);
}