feat: upgraded react-qrcode-logo to v3

pull/3083/head
William Grant 10 months ago
parent db7355ef8e
commit 11b3a0ece1

@ -117,7 +117,7 @@
"react-h5-audio-player": "^3.2.0", "react-h5-audio-player": "^3.2.0",
"react-intersection-observer": "^9.7.0", "react-intersection-observer": "^9.7.0",
"react-mentions": "^4.4.9", "react-mentions": "^4.4.9",
"react-qrcode-logo": "^2.10.0", "react-qrcode-logo": "^3.0.0",
"react-redux": "8.0.4", "react-redux": "8.0.4",
"react-toastify": "^6.0.9", "react-toastify": "^6.0.9",
"react-use": "^17.4.0", "react-use": "^17.4.0",
@ -269,7 +269,11 @@
"StartupWMClass": "Session" "StartupWMClass": "Session"
}, },
"asarUnpack": "node_modules/spellchecker/vendor/hunspell_dictionaries", "asarUnpack": "node_modules/spellchecker/vendor/hunspell_dictionaries",
"target": ["deb", "rpm", "freebsd"], "target": [
"deb",
"rpm",
"freebsd"
],
"icon": "build/icon-linux.icns" "icon": "build/icon-linux.icns"
}, },
"asarUnpack": [ "asarUnpack": [

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

@ -15,7 +15,7 @@ export const QRView = ({ sessionID }: { sessionID: string }) => {
<SessionQRCode <SessionQRCode
id={'session-account-id'} id={'session-account-id'}
value={sessionID} value={sessionID}
size={170} size={190}
backgroundColor={getThemeValue( backgroundColor={getThemeValue(
isDarkTheme ? '--text-primary-color' : '--background-primary-color' isDarkTheme ? '--text-primary-color' : '--background-primary-color'
)} )}

@ -102,7 +102,7 @@ export const SettingsCategoryRecoveryPassword = () => {
<SessionQRCode <SessionQRCode
id={'session-recovery-password'} id={'session-recovery-password'}
value={hexEncodedSeed} value={hexEncodedSeed}
size={240} size={260}
backgroundColor={getThemeValue( backgroundColor={getThemeValue(
isDarkTheme ? '--text-primary-color' : '--background-primary-color' isDarkTheme ? '--text-primary-color' : '--background-primary-color'
)} )}

@ -6116,7 +6116,7 @@ pupa@^2.1.1:
dependencies: dependencies:
escape-goat "^2.0.0" escape-goat "^2.0.0"
qrcode-generator@^1.4.1: qrcode-generator@^1.4.4:
version "1.4.4" version "1.4.4"
resolved "https://registry.yarnpkg.com/qrcode-generator/-/qrcode-generator-1.4.4.tgz#63f771224854759329a99048806a53ed278740e7" resolved "https://registry.yarnpkg.com/qrcode-generator/-/qrcode-generator-1.4.4.tgz#63f771224854759329a99048806a53ed278740e7"
integrity sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw== integrity sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==
@ -6246,13 +6246,13 @@ react-mentions@^4.4.9:
prop-types "^15.5.8" prop-types "^15.5.8"
substyle "^9.1.0" substyle "^9.1.0"
react-qrcode-logo@^2.10.0: react-qrcode-logo@^3.0.0:
version "2.10.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/react-qrcode-logo/-/react-qrcode-logo-2.10.0.tgz#1d29010f3c4f27860cc152b658a5c4e30c11b2f3" resolved "https://registry.yarnpkg.com/react-qrcode-logo/-/react-qrcode-logo-3.0.0.tgz#71cb43ddef9b338cc151800968276ca210086d11"
integrity sha512-Q1+jLtcyDl5rLR29YdkXVLzYk62p3+541x00HxURVBQhs6SqFyEZZVhvkU/VQ082ytXa3GdCmGWMLK5z0Vhe7g== integrity sha512-2+vZ3GNBdUpYxIKyt6SFZsDGXa0xniyUQ0wPI4O0hJTzRjttPIx1pPnH9IWQmp/4nDMoN47IBhi3Breu1KudYw==
dependencies: dependencies:
lodash.isequal "^4.5.0" lodash.isequal "^4.5.0"
qrcode-generator "^1.4.1" qrcode-generator "^1.4.4"
react-redux@8.0.4: react-redux@8.0.4:
version "8.0.4" version "8.0.4"

Loading…
Cancel
Save