diff --git a/lib/components/secondary-device-qr-auth-context-provider.react.js b/lib/components/secondary-device-qr-auth-context-provider.react.js --- a/lib/components/secondary-device-qr-auth-context-provider.react.js +++ b/lib/components/secondary-device-qr-auth-context-provider.react.js @@ -88,19 +88,15 @@ const identityClient = identityContext?.identityClient; const openSecondaryQRAuth = React.useCallback(async () => { - try { - const [ed25519, rawAESKey] = await Promise.all([ - getContentSigningKey(), - generateAESKey(), - ]); - const aesKeyAsHexString: string = uintArrayToHexString(rawAESKey); - - setUnauthorizedDeviceID(ed25519); - setQRData({ deviceID: ed25519, aesKey: aesKeyAsHexString }); - setQRAuthFinished(false); - } catch (err) { - console.error('Failed to generate QR Code:', err); - } + const [ed25519, rawAESKey] = await Promise.all([ + getContentSigningKey(), + generateAESKey(), + ]); + const aesKeyAsHexString: string = uintArrayToHexString(rawAESKey); + + setUnauthorizedDeviceID(ed25519); + setQRData({ deviceID: ed25519, aesKey: aesKeyAsHexString }); + setQRAuthFinished(false); }, [generateAESKey, setUnauthorizedDeviceID]); const closeSecondaryQRAuth = React.useCallback(() => { @@ -139,6 +135,7 @@ payload: JSON.stringify(message), }); setQRAuthFinished(true); + setQRData(null); })(); }, [ sendMessageToDevice, @@ -270,13 +267,32 @@ const { qrData, openSecondaryQRAuth, closeSecondaryQRAuth, canGenerateQRs } = useSecondaryDeviceQRAuthContext(); + const [attemptNumber, setAttemptNumber] = React.useState(0); + React.useEffect(() => { - if (canGenerateQRs) { - void openSecondaryQRAuth(); - return closeSecondaryQRAuth; + if (!canGenerateQRs || qrData) { + return; } - return undefined; - }, [closeSecondaryQRAuth, canGenerateQRs, openSecondaryQRAuth]); + void (async () => { + try { + console.log('Generating new QR code'); + await openSecondaryQRAuth(); + } catch (e) { + console.log('Failed to generate QR Code:', e); + setTimeout(() => setAttemptNumber(attemptNumber + 1), 500); + } + })(); + }, [ + closeSecondaryQRAuth, + canGenerateQRs, + openSecondaryQRAuth, + attemptNumber, + qrData, + ]); + + React.useEffect(() => { + return closeSecondaryQRAuth; + }, [closeSecondaryQRAuth]); const { platform } = getConfig().platformDetails; const qrCodeURL = React.useMemo(() => { diff --git a/native/account/qr-code-screen.react.js b/native/account/qr-code-screen.react.js --- a/native/account/qr-code-screen.react.js +++ b/native/account/qr-code-screen.react.js @@ -2,7 +2,12 @@ import { useFocusEffect } from '@react-navigation/core'; import * as React from 'react'; -import { View, Text, useWindowDimensions } from 'react-native'; +import { + View, + Text, + useWindowDimensions, + ActivityIndicator, +} from 'react-native'; import QRCode from 'react-native-qrcode-svg'; import { useSecondaryDeviceQRAuthContext } from 'lib/components/secondary-device-qr-auth-context-provider.react.js'; @@ -18,7 +23,7 @@ import LinkButton from '../components/link-button.react.js'; import type { NavigationRoute } from '../navigation/route-names.js'; import { RestorePromptScreenRouteName } from '../navigation/route-names.js'; -import { useStyles } from '../themes/colors.js'; +import { useColors, useStyles } from '../themes/colors.js'; type QRCodeScreenProps = { +navigation: AuthNavigationProp<'QRCodeScreen'>, @@ -29,14 +34,29 @@ const { qrData, openSecondaryQRAuth, closeSecondaryQRAuth, canGenerateQRs } = useSecondaryDeviceQRAuthContext(); + const [attemptNumber, setAttemptNumber] = React.useState(0); + useFocusEffect( React.useCallback(() => { - if (canGenerateQRs) { - void openSecondaryQRAuth(); - return closeSecondaryQRAuth; + if (!canGenerateQRs || qrData) { + return; } - return undefined; - }, [canGenerateQRs, closeSecondaryQRAuth, openSecondaryQRAuth]), + void (async () => { + try { + console.log('Generating new QR code'); + await openSecondaryQRAuth(); + } catch (e) { + console.log('Failed to generate QR Code:', e); + setTimeout(() => setAttemptNumber(attemptNumber + 1), 500); + } + })(); + }, [attemptNumber, canGenerateQRs, openSecondaryQRAuth, qrData]), + ); + + useFocusEffect( + React.useCallback(() => { + return closeSecondaryQRAuth; + }, [closeSecondaryQRAuth]), ); const { platform } = getConfig().platformDetails; @@ -49,6 +69,12 @@ return qrCodeLinkURL(qrData.aesKey, qrData.deviceID, deviceType); }, [canGenerateQRs, platform, qrData]); + React.useEffect(() => { + if (qrCodeURL) { + console.log(`QR Code URL: ${qrCodeURL}`); + } + }, [qrCodeURL]); + const styles = useStyles(unboundStyles); const usingRestoreFlow = useIsRestoreFlowEnabled(); @@ -72,6 +98,20 @@ const { width } = useWindowDimensions(); const qrCodeSize = width * 0.7; + const colors = useColors(); + + const qrCode = React.useMemo(() => { + if (qrCodeURL) { + return ; + } + return ( + + ); + }, [colors.modalForegroundTertiaryLabel, qrCodeSize, qrCodeURL]); return ( @@ -82,9 +122,7 @@ Open the Comm app on your logged-in phone and scan the QR code below: - - - + {qrCode} How to find the scanner: