diff --git a/package.json b/package.json index 09bcbd2ff..6f5886f3b 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "react-h5-audio-player": "^3.2.0", "react-intersection-observer": "^9.7.0", "react-mentions": "^4.4.9", - "react-qrcode-logo": "^2.10.0", + "react-qrcode-logo": "^3.0.0", "react-redux": "8.0.4", "react-toastify": "^6.0.9", "react-use": "^17.4.0", @@ -269,7 +269,11 @@ "StartupWMClass": "Session" }, "asarUnpack": "node_modules/spellchecker/vendor/hunspell_dictionaries", - "target": ["deb", "rpm", "freebsd"], + "target": [ + "deb", + "rpm", + "freebsd" + ], "icon": "build/icon-linux.icns" }, "asarUnpack": [ diff --git a/ts/components/SessionQRCode.tsx b/ts/components/SessionQRCode.tsx index d6f6a3c9e..bcaaeb1b8 100644 --- a/ts/components/SessionQRCode.tsx +++ b/ts/components/SessionQRCode.tsx @@ -1,34 +1,10 @@ -import { isEmpty } from 'lodash'; -import { MouseEvent, useCallback, useEffect, useState } from 'react'; +import { MouseEvent, useRef } from 'react'; import { QRCode } from 'react-qrcode-logo'; -import useMount from 'react-use/lib/useMount'; -import styled, { CSSProperties } from 'styled-components'; +import { CSSProperties } from 'styled-components'; import { ThemeStateType } from '../themes/constants/colors'; -import { THEME_GLOBALS, getThemeValue } from '../themes/globals'; -import { saveQRCode } from '../util/saveQRCode'; -import { checkDarkTheme } from '../util/theme'; +import { THEME_GLOBALS } from '../themes/globals'; 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 = { id: string; value: string; @@ -64,90 +40,95 @@ export function SessionQRCode(props: SessionQRCodeProps) { style, } = props; - const [svgDataURL, setSvgDataURL] = useState(''); - const [currentTheme, setCurrentTheme] = useState(theme); - const [loading, setLoading] = useState(false); + 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(); + // 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' - ) - ); - } + // 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]); + // 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(); - }); + // useMount(() => { + // void loadLogoImage(); + // }); - useEffect(() => { - if (theme && theme !== currentTheme) { - setCurrentTheme(theme); - void loadLogoImage(); - } - }, [currentTheme, loadLogoImage, theme]); + // 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 ( - <StyledQRView + <AnimatedFlex container={true} justifyContent="center" alignItems="center" + width={`${size}px`} + height={`${size}px`} + id={id} aria-label={ariaLabel || 'QR code'} title={window.i18n('clickToTrustContact')} - canvasId={id} - size={size} - backgroundColor={backgroundColor} + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} + transition={{ duration: THEME_GLOBALS['--default-duration-seconds'] }} onClick={(event: MouseEvent<HTMLDivElement>) => { event.preventDefault(); - void saveQRCode(id, { - ...props, - id: `temp-${props.id}`, - backgroundColor: 'white', - foregroundColor: 'black', - ignoreTheme: true, - style: { display: 'none' }, - }); + qrRef.current?.download('jpg', id); }} - initial={{ opacity: 0 }} - animate={{ opacity: loading ? 0 : 1 }} - transition={{ duration: THEME_GLOBALS['--default-duration-seconds'] }} data-testId={dataTestId || 'session-qr-code'} style={style} > <QRCode - id={id} + ref={qrRef} + id={`${id}-canvas`} value={value} ecLevel={'Q'} size={qrCanvasSize} bgColor={backgroundColor} fgColor={foregroundColor} - quietZone={0} - logoImage={logoIsSVG ? svgDataURL : logoImage} + 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, + }} /> - </StyledQRView> + </AnimatedFlex> ); } diff --git a/ts/components/dialog/edit-profile/components.tsx b/ts/components/dialog/edit-profile/components.tsx index 5ee3df0f2..9df6de5ed 100644 --- a/ts/components/dialog/edit-profile/components.tsx +++ b/ts/components/dialog/edit-profile/components.tsx @@ -15,7 +15,7 @@ export const QRView = ({ sessionID }: { sessionID: string }) => { <SessionQRCode id={'session-account-id'} value={sessionID} - size={170} + size={190} backgroundColor={getThemeValue( isDarkTheme ? '--text-primary-color' : '--background-primary-color' )} diff --git a/ts/components/settings/section/CategoryRecoveryPassword.tsx b/ts/components/settings/section/CategoryRecoveryPassword.tsx index 3e82602dd..f1736ed0e 100644 --- a/ts/components/settings/section/CategoryRecoveryPassword.tsx +++ b/ts/components/settings/section/CategoryRecoveryPassword.tsx @@ -102,7 +102,7 @@ export const SettingsCategoryRecoveryPassword = () => { <SessionQRCode id={'session-recovery-password'} value={hexEncodedSeed} - size={240} + size={260} backgroundColor={getThemeValue( isDarkTheme ? '--text-primary-color' : '--background-primary-color' )} diff --git a/yarn.lock b/yarn.lock index 05e4051d0..de74f8da9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6116,7 +6116,7 @@ pupa@^2.1.1: dependencies: escape-goat "^2.0.0" -qrcode-generator@^1.4.1: +qrcode-generator@^1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/qrcode-generator/-/qrcode-generator-1.4.4.tgz#63f771224854759329a99048806a53ed278740e7" integrity sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw== @@ -6246,13 +6246,13 @@ react-mentions@^4.4.9: prop-types "^15.5.8" substyle "^9.1.0" -react-qrcode-logo@^2.10.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/react-qrcode-logo/-/react-qrcode-logo-2.10.0.tgz#1d29010f3c4f27860cc152b658a5c4e30c11b2f3" - integrity sha512-Q1+jLtcyDl5rLR29YdkXVLzYk62p3+541x00HxURVBQhs6SqFyEZZVhvkU/VQ082ytXa3GdCmGWMLK5z0Vhe7g== +react-qrcode-logo@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/react-qrcode-logo/-/react-qrcode-logo-3.0.0.tgz#71cb43ddef9b338cc151800968276ca210086d11" + integrity sha512-2+vZ3GNBdUpYxIKyt6SFZsDGXa0xniyUQ0wPI4O0hJTzRjttPIx1pPnH9IWQmp/4nDMoN47IBhi3Breu1KudYw== dependencies: lodash.isequal "^4.5.0" - qrcode-generator "^1.4.1" + qrcode-generator "^1.4.4" react-redux@8.0.4: version "8.0.4"