fix: make qr code update correctly if theme changes

even if visible, there is some flickering with the logo that I have been unable to fix.
pull/3083/head
William Grant 11 months ago
parent a629fa560c
commit bb27570a90

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 33 40" fill="none"><path fill="#000" stroke="#000" stroke-width=".3" d="m27.347 20.56-6.521-4.026h4.42c1.849 0 3.622-.818 4.929-2.275 1.307-1.457 2.041-3.432 2.041-5.492s-.734-4.036-2.041-5.492C28.867 1.818 27.095 1 25.246 1H9.813c-2.315.003-4.534 1.03-6.171 2.853-1.637 1.824-2.558 4.297-2.56 6.877 0 1.88.453 3.726 1.31 5.345.857 1.62 2.087 2.954 3.563 3.865l6.522 4.027H8.051a6.346 6.346 0 0 0-2.692.565 6.956 6.956 0 0 0-2.289 1.677 7.869 7.869 0 0 0-1.532 2.53A8.542 8.542 0 0 0 1 31.734c0 1.028.183 2.045.538 2.993a7.87 7.87 0 0 0 1.532 2.531 6.957 6.957 0 0 0 2.29 1.677c.854.385 1.77.577 2.691.566h15.433c2.315-.003 4.535-1.03 6.172-2.853 1.637-1.825 2.558-4.298 2.56-6.877 0-1.88-.452-3.725-1.308-5.345-.856-1.62-2.086-2.954-3.56-3.865Zm-20.35-2.725c-1.113-.688-2.044-1.687-2.703-2.9a8.822 8.822 0 0 1-1.05-4.014C3.156 6.79 6.27 3.406 9.979 3.406h15.128c2.587 0 4.816 2.207 4.944 5.09a5.927 5.927 0 0 1-.295 2.133 5.493 5.493 0 0 1-1.025 1.83c-.45.526-.99.945-1.59 1.232a4.395 4.395 0 0 1-1.895.435h-8.712a.918.918 0 0 0-.68.318c-.18.202-.28.475-.28.76v7.923l-8.577-5.292Zm16.321 19.258H8.191c-2.587 0-4.816-2.207-4.944-5.09a5.928 5.928 0 0 1 .295-2.131 5.491 5.491 0 0 1 1.025-1.83c.45-.527.99-.946 1.588-1.233a4.395 4.395 0 0 1 1.896-.436h8.713a.88.88 0 0 0 .37-.082.966.966 0 0 0 .313-.233c.09-.1.16-.219.209-.35.048-.13.073-.27.073-.411v-7.925l8.571 5.293c1.114.687 2.046 1.688 2.705 2.902a8.82 8.82 0 0 1 1.05 4.017c.087 4.126-3.027 7.509-6.737 7.509Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 33 40" fill="none"><path fill="black" stroke="black" stroke-width=".3" d="m27.347 20.56-6.521-4.026h4.42c1.849 0 3.622-.818 4.929-2.275 1.307-1.457 2.041-3.432 2.041-5.492s-.734-4.036-2.041-5.492C28.867 1.818 27.095 1 25.246 1H9.813c-2.315.003-4.534 1.03-6.171 2.853-1.637 1.824-2.558 4.297-2.56 6.877 0 1.88.453 3.726 1.31 5.345.857 1.62 2.087 2.954 3.563 3.865l6.522 4.027H8.051a6.346 6.346 0 0 0-2.692.565 6.956 6.956 0 0 0-2.289 1.677 7.869 7.869 0 0 0-1.532 2.53A8.542 8.542 0 0 0 1 31.734c0 1.028.183 2.045.538 2.993a7.87 7.87 0 0 0 1.532 2.531 6.957 6.957 0 0 0 2.29 1.677c.854.385 1.77.577 2.691.566h15.433c2.315-.003 4.535-1.03 6.172-2.853 1.637-1.825 2.558-4.298 2.56-6.877 0-1.88-.452-3.725-1.308-5.345-.856-1.62-2.086-2.954-3.56-3.865Zm-20.35-2.725c-1.113-.688-2.044-1.687-2.703-2.9a8.822 8.822 0 0 1-1.05-4.014C3.156 6.79 6.27 3.406 9.979 3.406h15.128c2.587 0 4.816 2.207 4.944 5.09a5.927 5.927 0 0 1-.295 2.133 5.493 5.493 0 0 1-1.025 1.83c-.45.526-.99.945-1.59 1.232a4.395 4.395 0 0 1-1.895.435h-8.712a.918.918 0 0 0-.68.318c-.18.202-.28.475-.28.76v7.923l-8.577-5.292Zm16.321 19.258H8.191c-2.587 0-4.816-2.207-4.944-5.09a5.928 5.928 0 0 1 .295-2.131 5.491 5.491 0 0 1 1.025-1.83c.45-.527.99-.946 1.588-1.233a4.395 4.395 0 0 1 1.896-.436h8.713a.88.88 0 0 0 .37-.082.966.966 0 0 0 .313-.233c.09-.1.16-.219.209-.35.048-.13.073-.27.073-.411v-7.925l8.571 5.293c1.114.687 2.046 1.688 2.705 2.902a8.82 8.82 0 0 1 1.05 4.017c.087 4.126-3.027 7.509-6.737 7.509Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" viewBox="0 0 46 56" fill="none"><path fill="#000" fill-rule="evenodd" d="M21.013.459A4.578 4.578 0 0 1 22.989 0l.01.02c.655 0 1.302.146 1.948.449.788.38 1.596.742 2.404 1.103l.93.42 4.381 2.012c1.425.65 2.85 1.303 4.276 1.955l.003.002c2.062.943 4.126 1.888 6.192 2.829 1.948.888 3.012 2.695 2.85 4.795-.011.114-.008.268-.004.443.003.095.005.196.005.3.01.243.01.497.01.79a378.737 378.737 0 0 0 0 8.048v.049l-.01.048V24.206c-.01.942-.02 1.894-.048 2.817-.047 2.452-.503 4.776-.902 6.524l-.029.117-.038.118c-.342 1.191-.731 2.46-1.235 3.77-.675 1.718-1.558 3.486-2.708 5.41l-.048.078-.057.078c-1.358 2.051-2.622 3.653-3.971 5.05a29.438 29.438 0 0 1-7.44 5.596c-.043.024-.088.05-.133.078l-.133.078-.143.078-.143.068c-1.33.606-2.917 1.28-4.655 1.758l-.038.02h-.039a5.066 5.066 0 0 1-2.527-.01 26.956 26.956 0 0 1-4.912-1.885l-.029-.03h-.029c-4.665-2.402-8.542-5.957-11.525-10.557l-.133-.156-.143-.244c-1.036-1.748-1.815-3.272-2.451-4.786-.522-1.253-.906-2.478-1.279-3.666l-.023-.074-.143-.45-.066-.224-.048-.224-.085-.435-.086-.435-.021-.107c-.193-.963-.392-1.953-.51-2.998C0 27.848.002 26.218.003 24.656V14.24l.002-.382c.002-.237.004-.459-.002-.664-.076-1.894.893-3.496 2.651-4.326l5.611-2.564 5.611-2.564 3.392-1.552.143-.069.237-.117.076-.039.44-.201c.267-.123.536-.246.805-.365.199-.091.397-.181.596-.27v-.001c.485-.22.968-.438 1.447-.667Zm4.854 25.24 4.432 2.492a6.468 6.468 0 0 1 2.42 2.393 6.592 6.592 0 0 1 .89 3.307 6.073 6.073 0 0 1-1.74 4.256 5.898 5.898 0 0 1-4.195 1.766h-10.49a4.676 4.676 0 0 1-1.829-.35 4.731 4.731 0 0 1-1.555-1.038c-.446-.447-.8-.98-1.042-1.566a4.869 4.869 0 0 1 0-3.705 4.811 4.811 0 0 1 1.042-1.566c.445-.447.974-.8 1.555-1.038a4.676 4.676 0 0 1 1.83-.35h3.008l-4.433-2.492a6.47 6.47 0 0 1-2.422-2.392 6.593 6.593 0 0 1-.89-3.308 6.074 6.074 0 0 1 1.74-4.256 5.898 5.898 0 0 1 4.194-1.766h10.49c1.256 0 2.46.507 3.349 1.408a4.843 4.843 0 0 1 1.388 3.4c0 1.274-.5 2.497-1.388 3.398a4.703 4.703 0 0 1-3.35 1.408h-3.004Zm-11.236-.989a4.99 4.99 0 0 0 1.837 1.795l5.83 3.275v-4.903a.67.67 0 0 1 .19-.47.65.65 0 0 1 .462-.197h5.921c.443 0 .882-.092 1.289-.27a3.27 3.27 0 0 0 1.08-.762 3.368 3.368 0 0 0 .897-2.452c-.087-1.785-1.602-3.15-3.36-3.15H18.494c-2.52 0-4.637 2.093-4.578 4.65.02.877.267 1.734.715 2.484Zm2.649 13.714H27.56c2.522 0 4.638-2.094 4.578-4.648a5.083 5.083 0 0 0-.713-2.486 4.988 4.988 0 0 0-1.838-1.796l-5.826-3.275v4.904a.673.673 0 0 1-.192.471.655.655 0 0 1-.463.195h-5.922c-.443 0-.881.093-1.288.27a3.273 3.273 0 0 0-1.08.763 3.364 3.364 0 0 0-.897 2.452c.087 1.784 1.602 3.15 3.36 3.15Z" clip-rule="evenodd"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" viewBox="0 0 46 56" fill="none"><path fill="black" fill-rule="evenodd" d="M21.013.459A4.578 4.578 0 0 1 22.989 0l.01.02c.655 0 1.302.146 1.948.449.788.38 1.596.742 2.404 1.103l.93.42 4.381 2.012c1.425.65 2.85 1.303 4.276 1.955l.003.002c2.062.943 4.126 1.888 6.192 2.829 1.948.888 3.012 2.695 2.85 4.795-.011.114-.008.268-.004.443.003.095.005.196.005.3.01.243.01.497.01.79a378.737 378.737 0 0 0 0 8.048v.049l-.01.048V24.206c-.01.942-.02 1.894-.048 2.817-.047 2.452-.503 4.776-.902 6.524l-.029.117-.038.118c-.342 1.191-.731 2.46-1.235 3.77-.675 1.718-1.558 3.486-2.708 5.41l-.048.078-.057.078c-1.358 2.051-2.622 3.653-3.971 5.05a29.438 29.438 0 0 1-7.44 5.596c-.043.024-.088.05-.133.078l-.133.078-.143.078-.143.068c-1.33.606-2.917 1.28-4.655 1.758l-.038.02h-.039a5.066 5.066 0 0 1-2.527-.01 26.956 26.956 0 0 1-4.912-1.885l-.029-.03h-.029c-4.665-2.402-8.542-5.957-11.525-10.557l-.133-.156-.143-.244c-1.036-1.748-1.815-3.272-2.451-4.786-.522-1.253-.906-2.478-1.279-3.666l-.023-.074-.143-.45-.066-.224-.048-.224-.085-.435-.086-.435-.021-.107c-.193-.963-.392-1.953-.51-2.998C0 27.848.002 26.218.003 24.656V14.24l.002-.382c.002-.237.004-.459-.002-.664-.076-1.894.893-3.496 2.651-4.326l5.611-2.564 5.611-2.564 3.392-1.552.143-.069.237-.117.076-.039.44-.201c.267-.123.536-.246.805-.365.199-.091.397-.181.596-.27v-.001c.485-.22.968-.438 1.447-.667Zm4.854 25.24 4.432 2.492a6.468 6.468 0 0 1 2.42 2.393 6.592 6.592 0 0 1 .89 3.307 6.073 6.073 0 0 1-1.74 4.256 5.898 5.898 0 0 1-4.195 1.766h-10.49a4.676 4.676 0 0 1-1.829-.35 4.731 4.731 0 0 1-1.555-1.038c-.446-.447-.8-.98-1.042-1.566a4.869 4.869 0 0 1 0-3.705 4.811 4.811 0 0 1 1.042-1.566c.445-.447.974-.8 1.555-1.038a4.676 4.676 0 0 1 1.83-.35h3.008l-4.433-2.492a6.47 6.47 0 0 1-2.422-2.392 6.593 6.593 0 0 1-.89-3.308 6.074 6.074 0 0 1 1.74-4.256 5.898 5.898 0 0 1 4.194-1.766h10.49c1.256 0 2.46.507 3.349 1.408a4.843 4.843 0 0 1 1.388 3.4c0 1.274-.5 2.497-1.388 3.398a4.703 4.703 0 0 1-3.35 1.408h-3.004Zm-11.236-.989a4.99 4.99 0 0 0 1.837 1.795l5.83 3.275v-4.903a.67.67 0 0 1 .19-.47.65.65 0 0 1 .462-.197h5.921c.443 0 .882-.092 1.289-.27a3.27 3.27 0 0 0 1.08-.762 3.368 3.368 0 0 0 .897-2.452c-.087-1.785-1.602-3.15-3.36-3.15H18.494c-2.52 0-4.637 2.093-4.578 4.65.02.877.267 1.734.715 2.484Zm2.649 13.714H27.56c2.522 0 4.638-2.094 4.578-4.648a5.083 5.083 0 0 0-.713-2.486 4.988 4.988 0 0 0-1.838-1.796l-5.826-3.275v4.904a.673.673 0 0 1-.192.471.655.655 0 0 1-.463.195h-5.922c-.443 0-.881.093-1.288.27a3.273 3.273 0 0 0-1.08.763 3.364 3.364 0 0 0-.897 2.452c.087 1.784 1.602 3.15 3.36 3.15Z" clip-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -1,5 +1,5 @@
import { isEmpty } from 'lodash';
import { CSSProperties, MouseEvent, useState } from 'react';
import { CSSProperties, MouseEvent, useCallback, useEffect, useState } from 'react';
import { QRCode } from 'react-qrcode-logo';
import useMount from 'react-use/lib/useMount';
import styled from 'styled-components';
@ -18,11 +18,9 @@ const StyledQRView = styled(AnimatedFlex)<{
cursor: pointer;
border-radius: 10px;
overflow: hidden;
padding: 10px;
width: fit-content;
height: auto;
${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 &&
@ -39,8 +37,9 @@ export type SessionQRCodeProps = {
logoWidth?: number;
logoHeight?: number;
logoIsSVG?: boolean;
style?: CSSProperties;
theme?: string;
ignoreTheme?: boolean;
style?: CSSProperties;
};
export function SessionQRCode(props: SessionQRCodeProps) {
@ -54,39 +53,52 @@ export function SessionQRCode(props: SessionQRCodeProps) {
logoWidth,
logoHeight,
logoIsSVG,
style,
theme,
ignoreTheme,
style,
} = props;
const [svgDataURL, setSvgDataURL] = useState('');
// Saving the QR code uses a separate react instance without the redux store so we don't use a selector here
const theme = window.Events.getThemeSetting();
const [currentTheme, setCurrentTheme] = useState(theme);
const [loading, setLoading] = useState(false);
useMount(() => {
if (logoImage && logoIsSVG && isEmpty(svgDataURL)) {
// eslint-disable-next-line more/no-then
fetch(logoImage)
.then(response => response.text())
.then(response => {
const svgString = ignoreTheme
? response
: response.replaceAll(
'black',
getThemeValue(
theme.includes('dark') ? '--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)
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(
theme.includes('dark') ? '--background-primary-color' : '--text-primary-color'
)
);
}
setSvgDataURL(`data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`);
window.log.debug(
`WIP: [SessionQRCode] SVG logo fetched: ${logoImage} 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();
});
if (logoImage && logoIsSVG && isEmpty(svgDataURL)) {
return null;
}
useEffect(() => {
if (theme && theme !== currentTheme) {
setCurrentTheme(theme);
void loadLogoImage();
}
}, [currentTheme, loadLogoImage, theme]);
const qrCanvasSize = 1000;
const canvasLogoWidth =
@ -96,6 +108,8 @@ export function SessionQRCode(props: SessionQRCodeProps) {
return (
<StyledQRView
container={true}
justifyContent="center"
alignItems="center"
aria-label={window.i18n('clickToTrustContact')}
title={window.i18n('clickToTrustContact')}
canvasId={id}
@ -113,7 +127,7 @@ export function SessionQRCode(props: SessionQRCodeProps) {
});
}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
animate={{ opacity: loading ? 0 : 1 }}
transition={{ duration: THEME_GLOBALS['--default-duration-seconds'] }}
style={style}
>

@ -38,6 +38,7 @@ const QRView = ({ sessionID }: { sessionID: string }) => {
logoWidth={40}
logoHeight={40}
logoIsSVG={true}
theme={theme}
/>
);
};

@ -68,6 +68,7 @@ const Seed = (props: SeedProps) => {
logoWidth={56}
logoHeight={56}
logoIsSVG={true}
theme={theme}
style={{ margin: '0 auto var(--margins-lg)' }}
/>

@ -88,50 +88,51 @@ export const SettingsCategoryRecoveryPassword = () => {
inline={false}
>
<SpacerMD />
<StyledRecoveryPassword
container={true}
flexDirection={'row'}
justifyContent={'space-between'}
alignItems={'center'}
width={'100%'}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
// initial load has some flickering, so we add a small delay
transition={{ duration: 0.05 }}
style={{ display: isQRVisible ? 'none' : 'flex' }}
data-testid="recovery-phrase-seed-modal"
>
{recoveryPhrase}
<SpacerSM />
<SessionIconButton
aria-label={'copy to clipboard button'}
iconType={'copy'}
iconSize={'huge'}
iconColor={'var(--text-primary-color)'}
onClick={() => {
if (isEmpty(recoveryPhrase)) {
return;
}
copyRecoveryPhrase(recoveryPhrase);
}}
{isQRVisible ? (
<SessionQRCode
id={'session-recovery-passwod'}
value={hexEncodedSeed}
size={240}
backgroundColor={getThemeValue(
theme.includes('dark') ? '--text-primary-color' : '--background-primary-color'
)}
foregroundColor={getThemeValue(
theme.includes('dark') ? '--background-primary-color' : '--text-primary-color'
)}
logoImage={'./images/session/qr/shield.svg'}
logoWidth={56}
logoHeight={56}
logoIsSVG={true}
theme={theme}
/>
</StyledRecoveryPassword>
<SessionQRCode
id={'session-recovery-passwod'}
value={hexEncodedSeed}
size={240}
backgroundColor={getThemeValue(
theme.includes('dark') ? '--text-primary-color' : '--background-primary-color'
)}
foregroundColor={getThemeValue(
theme.includes('dark') ? '--background-primary-color' : '--text-primary-color'
)}
logoImage={'./images/session/qr/shield.svg'}
logoWidth={56}
logoHeight={56}
logoIsSVG={true}
style={{ display: isQRVisible ? 'flex' : 'none' }}
/>
) : (
<StyledRecoveryPassword
container={true}
flexDirection={'row'}
justifyContent={'space-between'}
alignItems={'center'}
width={'100%'}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.05 }}
data-testid="recovery-phrase-seed-modal"
>
{recoveryPhrase}
<SpacerSM />
<SessionIconButton
aria-label={'copy to clipboard button'}
iconType={'copy'}
iconSize={'huge'}
iconColor={'var(--text-primary-color)'}
onClick={() => {
if (isEmpty(recoveryPhrase)) {
return;
}
copyRecoveryPhrase(recoveryPhrase);
}}
/>
</StyledRecoveryPassword>
)}
<SpacerMD />
<SessionIconButton
@ -139,7 +140,9 @@ export const SettingsCategoryRecoveryPassword = () => {
iconType={isQRVisible ? 'password' : 'qr'}
iconSize={isQRVisible ? 48 : 'huge'}
iconColor={'var(--text-primary-color)'}
onClick={() => setIsQRVisible(!isQRVisible)}
onClick={() => {
setIsQRVisible(!isQRVisible);
}}
padding="0"
style={{
display: 'flex',

Loading…
Cancel
Save