diff --git a/native/account/registration/registration-navigator.react.js b/native/account/registration/registration-navigator.react.js index ec0517db2..b57d4881c 100644 --- a/native/account/registration/registration-navigator.react.js +++ b/native/account/registration/registration-navigator.react.js @@ -1,131 +1,131 @@ // @flow import type { StackNavigationProp, StackNavigationHelpers, } from '@react-navigation/core'; import { createStackNavigator } from '@react-navigation/stack'; import * as React from 'react'; import AccountDoesNotExist from './account-does-not-exist.react.js'; import AvatarSelection from './avatar-selection.react.js'; import ConnectEthereum from './connect-ethereum.react.js'; import ConnectFarcaster from './connect-farcaster.react.js'; import CoolOrNerdModeSelection from './cool-or-nerd-mode-selection.react.js'; import EmojiAvatarSelection from './emoji-avatar-selection.react.js'; import ExistingEthereumAccount from './existing-ethereum-account.react.js'; import KeyserverSelection from './keyserver-selection.react.js'; import PasswordSelection from './password-selection.react.js'; import RegistrationTerms from './registration-terms.react.js'; -import CreateSIWEBackupMessage from './siwe-backup-message-creation.react.js'; +import { CreateSIWEBackupMessage } from './siwe-backup-message-creation.react.js'; import UsernameSelection from './username-selection.react.js'; import RegistrationUserAvatarCameraModal from '../../media/registration-user-avatar-camera-modal.react.js'; import type { RootNavigationProp } from '../../navigation/root-navigator.react.js'; import { KeyserverSelectionRouteName, CoolOrNerdModeSelectionRouteName, ConnectEthereumRouteName, CreateSIWEBackupMessageRouteName, ExistingEthereumAccountRouteName, UsernameSelectionRouteName, ConnectFarcasterRouteName, PasswordSelectionRouteName, AvatarSelectionRouteName, EmojiAvatarSelectionRouteName, RegistrationUserAvatarCameraModalRouteName, RegistrationTermsRouteName, AccountDoesNotExistRouteName, type ScreenParamList, type RegistrationParamList, } from '../../navigation/route-names.js'; export type RegistrationNavigationProp< RouteName: $Keys = $Keys, > = StackNavigationProp; const Registration = createStackNavigator< ScreenParamList, RegistrationParamList, StackNavigationHelpers, >(); const screenOptions = { headerTransparent: true, headerBackTitleVisible: false, headerTitle: '', headerTintColor: 'white', headerLeftContainerStyle: { paddingLeft: 12, }, }; const cameraScreenOptions = { headerShown: false, }; type Props = { +navigation: RootNavigationProp<'Registration'>, ... }; // eslint-disable-next-line no-unused-vars function RegistrationNavigator(props: Props): React.Node { return ( ); } export default RegistrationNavigator; diff --git a/native/account/registration/siwe-backup-message-creation.react.js b/native/account/registration/siwe-backup-message-creation.react.js index 4ecb4b806..c4f4595bb 100644 --- a/native/account/registration/siwe-backup-message-creation.react.js +++ b/native/account/registration/siwe-backup-message-creation.react.js @@ -1,198 +1,230 @@ // @flow import Icon from '@expo/vector-icons/MaterialIcons.js'; import invariant from 'invariant'; import * as React from 'react'; import { View, Text } from 'react-native'; import { type SIWEResult, SIWEMessageTypes } from 'lib/types/siwe-types.js'; import RegistrationButtonContainer from './registration-button-container.react.js'; import RegistrationButton from './registration-button.react.js'; import RegistrationContainer from './registration-container.react.js'; import RegistrationContentContainer from './registration-content-container.react.js'; import { RegistrationContext } from './registration-context.js'; import { type RegistrationNavigationProp } from './registration-navigator.react.js'; import type { CoolOrNerdMode, AccountSelection, AvatarData, } from './registration-types.js'; import { type NavigationRoute, RegistrationTermsRouteName, } from '../../navigation/route-names.js'; import { useStyles } from '../../themes/colors.js'; import SIWEPanel from '../siwe-panel.react.js'; +type PanelState = 'closed' | 'opening' | 'open' | 'closing'; + +type CreateSIWEBackupMessageBaseProps = { + +onSuccessfulWalletSignature: (result: SIWEResult) => void, + +onExistingWalletSignature?: () => void, +}; + +const CreateSIWEBackupMessageBase: React.ComponentType = + React.memo( + function CreateSIWEBackupMessageBase( + props: CreateSIWEBackupMessageBaseProps, + ): React.Node { + const { onSuccessfulWalletSignature, onExistingWalletSignature } = props; + const styles = useStyles(unboundStyles); + + const [panelState, setPanelState] = React.useState('closed'); + + const openPanel = React.useCallback(() => { + setPanelState('opening'); + }, []); + const onPanelClosed = React.useCallback(() => { + setPanelState('closed'); + }, []); + const onPanelClosing = React.useCallback(() => { + setPanelState('closing'); + }, []); + + const siwePanelSetLoading = React.useCallback( + (loading: boolean) => { + if (panelState === 'closing' || panelState === 'closed') { + return; + } + setPanelState(loading ? 'opening' : 'open'); + }, + [panelState], + ); + + let siwePanel; + if (panelState !== 'closed') { + siwePanel = ( + + ); + } + + const newSignatureButtonText = onExistingWalletSignature + ? 'Encrypt with new signature' + : 'Encrypt with Ethereum signature'; + const newSignatureButtonVariant = onExistingWalletSignature + ? 'outline' + : 'enabled'; + + let useExistingSignatureButton; + if (onExistingWalletSignature) { + useExistingSignatureButton = ( + + ); + } + + const body = ( + + Comm encrypts user backups so that our backend is not able to see user + data. + + ); + + return ( + <> + + + Encrypting your Comm Backup + {body} + + + + + + {useExistingSignatureButton} + + + + {siwePanel} + + ); + }, + ); + export type CreateSIWEBackupMessageParams = { +userSelections: { +coolOrNerdMode: CoolOrNerdMode, +keyserverURL: string, +farcasterID: ?string, +accountSelection: AccountSelection, +avatarData: ?AvatarData, }, }; -type PanelState = 'closed' | 'opening' | 'open' | 'closing'; - type Props = { +navigation: RegistrationNavigationProp<'CreateSIWEBackupMessage'>, +route: NavigationRoute<'CreateSIWEBackupMessage'>, }; function CreateSIWEBackupMessage(props: Props): React.Node { const { navigate } = props.navigation; const { params } = props.route; const { userSelections } = params; - const styles = useStyles(unboundStyles); - - const [panelState, setPanelState] = React.useState('closed'); - - const openPanel = React.useCallback(() => { - setPanelState('opening'); - }, []); - const onPanelClosed = React.useCallback(() => { - setPanelState('closed'); - }, []); - const onPanelClosing = React.useCallback(() => { - setPanelState('closing'); - }, []); - - const siwePanelSetLoading = React.useCallback( - (loading: boolean) => { - if (panelState === 'closing' || panelState === 'closed') { - return; - } - setPanelState(loading ? 'opening' : 'open'); - }, - [panelState], - ); - const registrationContext = React.useContext(RegistrationContext); invariant(registrationContext, 'registrationContext should be set'); const { cachedSelections, setCachedSelections } = registrationContext; const onSuccessfulWalletSignature = React.useCallback( (result: SIWEResult) => { const { message, signature } = result; const newUserSelections = { ...userSelections, siweBackupSecrets: { message, signature }, }; setCachedSelections(oldUserSelections => ({ ...oldUserSelections, siweBackupSecrets: { message, signature }, })); navigate<'RegistrationTerms'>({ name: RegistrationTermsRouteName, params: { userSelections: newUserSelections }, }); }, [navigate, setCachedSelections, userSelections], ); const { siweBackupSecrets } = cachedSelections; const onExistingWalletSignature = React.useCallback(() => { const registrationTermsParams = { userSelections: { ...userSelections, siweBackupSecrets, }, }; navigate<'RegistrationTerms'>({ name: RegistrationTermsRouteName, params: registrationTermsParams, }); }, [navigate, siweBackupSecrets, userSelections]); - let siwePanel; - if (panelState !== 'closed') { - siwePanel = ( - - ); - } - - const newSignatureButtonText = siweBackupSecrets - ? 'Encrypt with new signature' - : 'Encrypt with Ethereum signature'; - const newSignatureButtonVariant = siweBackupSecrets ? 'outline' : 'enabled'; - - let useExistingSignatureButton; if (siweBackupSecrets) { - useExistingSignatureButton = ( - ); } - const body = ( - - Comm encrypts user backups so that our backend is not able to see user - data. - - ); - return ( - <> - - - Encrypting your Comm Backup - {body} - - - - - - {useExistingSignatureButton} - - - - {siwePanel} - + ); } const unboundStyles = { scrollViewContentContainer: { flexGrow: 1, }, header: { fontSize: 24, color: 'panelForegroundLabel', paddingBottom: 16, }, body: { fontFamily: 'Arial', fontSize: 15, lineHeight: 20, color: 'panelForegroundSecondaryLabel', paddingBottom: 16, }, siweBackupIcon: { color: 'panelForegroundIcon', }, siweBackupIconContainer: { flexGrow: 1, alignItems: 'center', justifyContent: 'center', }, }; -export default CreateSIWEBackupMessage; +export { CreateSIWEBackupMessageBase, CreateSIWEBackupMessage };