Page MenuHomePhabricator

D12019.diff
No OneTemporary

D12019.diff

diff --git a/native/account/registration/registration-navigator.react.js b/native/account/registration/registration-navigator.react.js
--- a/native/account/registration/registration-navigator.react.js
+++ b/native/account/registration/registration-navigator.react.js
@@ -3,8 +3,19 @@
import type {
StackNavigationProp,
StackNavigationHelpers,
+ ParamListBase,
+ StackNavigatorProps,
+ StackNavigationState,
+ StackOptions,
+ StackRouterOptions,
+ StackNavigationEventMap,
+ ExtraStackNavigatorProps,
} from '@react-navigation/core';
-import { createStackNavigator } from '@react-navigation/stack';
+import {
+ createNavigatorFactory,
+ useNavigationBuilder,
+} from '@react-navigation/native';
+import { StackView } from '@react-navigation/stack';
import * as React from 'react';
import AccountDoesNotExist from './account-does-not-exist.react.js';
@@ -16,6 +27,10 @@
import ExistingEthereumAccount from './existing-ethereum-account.react.js';
import KeyserverSelection from './keyserver-selection.react.js';
import PasswordSelection from './password-selection.react.js';
+import RegistrationRouter, {
+ type RegistrationRouterExtraNavigationHelpers,
+ type RegistrationRouterNavigationAction,
+} from './registration-router.js';
import RegistrationTerms from './registration-terms.react.js';
import { CreateSIWEBackupMessage } from './siwe-backup-message-creation.react.js';
import UsernameSelection from './username-selection.react.js';
@@ -39,17 +54,73 @@
type RegistrationParamList,
} from '../../navigation/route-names.js';
+export type RegistrationNavigationHelpers<
+ ParamList: ParamListBase = ParamListBase,
+> = {
+ ...$Exact<StackNavigationHelpers<ParamList>>,
+ ...RegistrationRouterExtraNavigationHelpers,
+};
+
+type RegistrationNavigatorProps = StackNavigatorProps<
+ RegistrationNavigationHelpers<>,
+>;
+function RegistrationNavigator({
+ initialRouteName,
+ children,
+ screenOptions,
+ defaultScreenOptions,
+ screenListeners,
+ id,
+ ...rest
+}: RegistrationNavigatorProps) {
+ const { state, descriptors, navigation } = useNavigationBuilder<
+ StackNavigationState,
+ RegistrationRouterNavigationAction,
+ StackOptions,
+ StackRouterOptions,
+ RegistrationNavigationHelpers<>,
+ StackNavigationEventMap,
+ ExtraStackNavigatorProps,
+ >(RegistrationRouter, {
+ id,
+ initialRouteName,
+ children,
+ screenOptions,
+ defaultScreenOptions,
+ screenListeners,
+ });
+ return (
+ <StackView
+ {...rest}
+ state={state}
+ descriptors={descriptors}
+ navigation={navigation}
+ />
+ );
+}
+const createRegistrationNavigator = createNavigatorFactory<
+ StackNavigationState,
+ StackOptions,
+ StackNavigationEventMap,
+ RegistrationNavigationHelpers<>,
+ ExtraStackNavigatorProps,
+>(RegistrationNavigator);
+
export type RegistrationNavigationProp<
RouteName: $Keys<RegistrationParamList> = $Keys<RegistrationParamList>,
-> = StackNavigationProp<ScreenParamList, RouteName>;
+> = {
+ ...StackNavigationProp<ScreenParamList, RouteName>,
+ ...RegistrationRouterExtraNavigationHelpers,
+};
-const Registration = createStackNavigator<
+const Registration = createRegistrationNavigator<
ScreenParamList,
RegistrationParamList,
StackNavigationHelpers<ScreenParamList>,
>();
const screenOptions = {
+ headerShown: true,
headerTransparent: true,
headerBackTitleVisible: false,
headerTitle: '',
@@ -68,7 +139,7 @@
...
};
// eslint-disable-next-line no-unused-vars
-function RegistrationNavigator(props: Props): React.Node {
+function RegistrationComponent(props: Props): React.Node {
return (
<Registration.Navigator
screenOptions={screenOptions}
@@ -131,4 +202,4 @@
);
}
-export default RegistrationNavigator;
+export default RegistrationComponent;
diff --git a/native/account/registration/registration-router.js b/native/account/registration/registration-router.js
new file mode 100644
--- /dev/null
+++ b/native/account/registration/registration-router.js
@@ -0,0 +1,104 @@
+// @flow
+
+import type {
+ StackAction,
+ Route,
+ Router,
+ StackRouterOptions,
+ StackNavigationState,
+ RouterConfigOptions,
+} from '@react-navigation/core';
+import { StackRouter } from '@react-navigation/native';
+
+import type { ConnectEthereumParams } from './connect-ethereum.react.js';
+import { reconnectEthereumActionType } from '../../navigation/action-types.js';
+import { removeScreensFromStack } from '../../navigation/navigation-utils.js';
+import {
+ ConnectEthereumRouteName,
+ ConnectFarcasterRouteName,
+} from '../../navigation/route-names.js';
+
+type ReconnectEthereumAction = {
+ +type: 'RECONNECT_ETHEREUM',
+ +payload: {
+ +params: ConnectEthereumParams,
+ },
+};
+export type RegistrationRouterNavigationAction =
+ | StackAction
+ | ReconnectEthereumAction;
+
+export type RegistrationRouterExtraNavigationHelpers = {
+ +reconnectEthereum: ConnectEthereumParams => void,
+};
+
+function RegistrationRouter(
+ routerOptions: StackRouterOptions,
+): Router<StackNavigationState, RegistrationRouterNavigationAction> {
+ const {
+ getStateForAction: baseGetStateForAction,
+ actionCreators: baseActionCreators,
+ ...rest
+ } = StackRouter(routerOptions);
+ return {
+ ...rest,
+ getStateForAction: (
+ lastState: StackNavigationState,
+ action: RegistrationRouterNavigationAction,
+ options: RouterConfigOptions,
+ ) => {
+ if (action.type === reconnectEthereumActionType) {
+ // First, we look to see if ConnectEthereum is already in the stack.
+ // If it is, we'll pop all later screens and navigate to it.
+ const routeNames = lastState.routes.map(({ name }) => name);
+ if (routeNames.includes(ConnectEthereumRouteName)) {
+ const newState = removeScreensFromStack(
+ lastState,
+ (route: Route<>) =>
+ route.name === ConnectEthereumRouteName ? 'break' : 'remove',
+ );
+ const connectEthereumRoute = newState.routes[newState.index];
+ const restRoutes = newState.routes.slice(0, -1);
+ return {
+ ...newState,
+ routes: [
+ ...restRoutes,
+ {
+ ...connectEthereumRoute,
+ params: action.payload.params,
+ },
+ ],
+ };
+ }
+ // If it's not in the stack, we'll pop up to ConnectFarcaster
+ // and then push a new route
+ const newState = removeScreensFromStack(lastState, (route: Route<>) =>
+ route.name === ConnectFarcasterRouteName ? 'break' : 'remove',
+ );
+ return {
+ ...newState,
+ routes: [
+ ...newState.routes,
+ {
+ name: ConnectEthereumRouteName,
+ key: 'ReconnectEthereum',
+ params: action.payload.params,
+ },
+ ],
+ index: newState.index + 1,
+ };
+ } else {
+ return baseGetStateForAction(lastState, action, options);
+ }
+ },
+ actionCreators: {
+ ...baseActionCreators,
+ reconnectEthereum: (params: ConnectEthereumParams) => ({
+ type: reconnectEthereumActionType,
+ payload: { params },
+ }),
+ },
+ };
+}
+
+export default RegistrationRouter;
diff --git a/native/account/registration/registration-terms.react.js b/native/account/registration/registration-terms.react.js
--- a/native/account/registration/registration-terms.react.js
+++ b/native/account/registration/registration-terms.react.js
@@ -1,10 +1,5 @@
// @flow
-import type {
- StackNavigationEventMap,
- StackNavigationState,
- StackOptions,
-} from '@react-navigation/core';
import invariant from 'invariant';
import * as React from 'react';
import { Text, View, Image, Linking, Alert } from 'react-native';
@@ -24,11 +19,7 @@
} from './registration-types.js';
import commSwooshSource from '../../img/comm-swoosh.png';
import { logInActionType } from '../../navigation/action-types.js';
-import type { RootNavigationProp } from '../../navigation/root-navigator.react.js';
-import type {
- NavigationRoute,
- ScreenParamList,
-} from '../../navigation/route-names.js';
+import type { NavigationRoute } from '../../navigation/route-names.js';
import { useStyles } from '../../themes/colors.js';
export type RegistrationTermsParams = {
@@ -69,14 +60,17 @@
}, [setCachedSelections]);
const { navigation } = props;
- const goBackToHome = navigation.getParent<
- ScreenParamList,
- 'Registration',
- StackNavigationState,
- StackOptions,
- StackNavigationEventMap,
- RootNavigationProp<'Registration'>,
- >()?.goBack;
+ const { reconnectEthereum } = navigation;
+ const { coolOrNerdMode, keyserverURL, farcasterID } = userSelections;
+ const navigateToConnectEthereum = React.useCallback(() => {
+ reconnectEthereum({
+ userSelections: {
+ coolOrNerdMode,
+ keyserverURL,
+ farcasterID,
+ },
+ });
+ }, [reconnectEthereum, coolOrNerdMode, keyserverURL, farcasterID]);
const onNonceExpired = React.useCallback(() => {
setCachedSelections(oldUserSelections => ({
...oldUserSelections,
@@ -85,12 +79,12 @@
Alert.alert(
'Registration attempt timed out',
'Please try to connect your Ethereum wallet again',
- [{ text: 'OK', onPress: goBackToHome }],
+ [{ text: 'OK', onPress: navigateToConnectEthereum }],
{
cancelable: false,
},
);
- }, [goBackToHome, setCachedSelections]);
+ }, [setCachedSelections, navigateToConnectEthereum]);
const onProceed = React.useCallback(async () => {
setRegistrationInProgress(true);
diff --git a/native/navigation/action-types.js b/native/navigation/action-types.js
--- a/native/navigation/action-types.js
+++ b/native/navigation/action-types.js
@@ -15,3 +15,6 @@
export const replaceWithThreadActionType = 'REPLACE_WITH_THREAD';
export const clearThreadsActionType = 'CLEAR_THREADS';
export const pushNewThreadActionType = 'PUSH_NEW_THREAD';
+
+// RegistrationRouter
+export const reconnectEthereumActionType = 'RECONNECT_ETHEREUM';

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 2, 11:04 PM (21 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2609189
Default Alt Text
D12019.diff (9 KB)

Event Timeline