Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3398454
D12019.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D12019.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D12019: [native] Refocus ConnectEthereum if registration fails due to expired nonce
Attached
Detach File
Event Timeline
Log In to Comment