diff --git a/native/account/registration/username-selection.react.js b/native/account/registration/username-selection.react.js
index cdbefeef4..7840937c9 100644
--- a/native/account/registration/username-selection.react.js
+++ b/native/account/registration/username-selection.react.js
@@ -1,240 +1,240 @@
// @flow
import invariant from 'invariant';
import * as React from 'react';
import { View, Text } from 'react-native';
import {
exactSearchUser,
exactSearchUserActionTypes,
} from 'lib/actions/user-actions.js';
import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { validUsernameRegex } from 'lib/shared/account-utils.js';
import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js';
import { isValidEthereumAddress } from 'lib/utils/siwe-utils.js';
import RegistrationButtonContainer from './registration-button-container.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 RegistrationTextInput from './registration-text-input.react.js';
import type { CoolOrNerdMode } from './registration-types.js';
import PrimaryButton from '../../components/primary-button.react.js';
import { commRustModule } from '../../native-modules.js';
import {
type NavigationRoute,
PasswordSelectionRouteName,
} from '../../navigation/route-names.js';
-import { useSelector } from '../../redux/redux-utils.js';
import { useStyles } from '../../themes/colors.js';
-const exactSearchUserLoadingStatusSelector = createLoadingStatusSelector(
- exactSearchUserActionTypes,
-);
-
export type UsernameSelectionParams = {
+userSelections: {
+coolOrNerdMode?: ?CoolOrNerdMode,
+keyserverURL?: ?string,
+farcasterID: ?string,
},
};
type UsernameError = 'username_invalid' | 'username_taken';
type Props = {
+navigation: RegistrationNavigationProp<'UsernameSelection'>,
+route: NavigationRoute<'UsernameSelection'>,
};
function UsernameSelection(props: Props): React.Node {
const registrationContext = React.useContext(RegistrationContext);
invariant(registrationContext, 'registrationContext should be set');
const { cachedSelections, setCachedSelections } = registrationContext;
const [username, setUsername] = React.useState(
cachedSelections.username ?? '',
);
const validUsername =
username.search(validUsernameRegex) > -1 &&
!isValidEthereumAddress(username.toLowerCase());
const [usernameError, setUsernameError] = React.useState();
const checkUsernameValidity = React.useCallback(() => {
if (!validUsername) {
setUsernameError('username_invalid');
return false;
}
setUsernameError(null);
return true;
}, [validUsername]);
const { userSelections } = props.route.params;
const { keyserverURL } = userSelections;
const serverCallParamOverride = React.useMemo(() => {
if (keyserverURL) {
return { urlPrefix: keyserverURL };
}
return undefined;
}, [keyserverURL]);
+ const [usernameSearchLoading, setUsernameSearchLoading] =
+ React.useState(false);
+
const exactSearchUserCall = useLegacyAshoatKeyserverCall(
exactSearchUser,
serverCallParamOverride,
);
const dispatchActionPromise = useDispatchActionPromise();
const { navigate } = props.navigation;
const onProceed = React.useCallback(async () => {
if (!checkUsernameValidity()) {
return;
}
+ setUsernameSearchLoading(true);
+
let userAlreadyExists;
- if (usingCommServicesAccessToken) {
- const findUserIDResponseString =
- await commRustModule.findUserIDForUsername(username);
- const findUserIDResponse = JSON.parse(findUserIDResponseString);
- userAlreadyExists =
- !!findUserIDResponse.userID || findUserIDResponse.isReserved;
- } else {
- const searchPromise = exactSearchUserCall(username);
- void dispatchActionPromise(exactSearchUserActionTypes, searchPromise);
- const { userInfo } = await searchPromise;
- userAlreadyExists = !!userInfo;
+ try {
+ if (usingCommServicesAccessToken) {
+ const findUserIDResponseString =
+ await commRustModule.findUserIDForUsername(username);
+ const findUserIDResponse = JSON.parse(findUserIDResponseString);
+ userAlreadyExists =
+ !!findUserIDResponse.userID || findUserIDResponse.isReserved;
+ } else {
+ const searchPromise = exactSearchUserCall(username);
+ void dispatchActionPromise(exactSearchUserActionTypes, searchPromise);
+ const { userInfo } = await searchPromise;
+ userAlreadyExists = !!userInfo;
+ }
+ } finally {
+ setUsernameSearchLoading(false);
}
if (userAlreadyExists) {
setUsernameError('username_taken');
return;
}
setUsernameError(undefined);
setCachedSelections(oldUserSelections => ({
...oldUserSelections,
username,
}));
navigate<'PasswordSelection'>({
name: PasswordSelectionRouteName,
params: {
userSelections: {
...userSelections,
username,
},
},
});
}, [
checkUsernameValidity,
username,
exactSearchUserCall,
dispatchActionPromise,
setCachedSelections,
navigate,
userSelections,
]);
- const exactSearchUserCallLoading = useSelector(
- state => exactSearchUserLoadingStatusSelector(state) === 'loading',
- );
let buttonVariant = 'disabled';
- if (exactSearchUserCallLoading) {
+ if (usernameSearchLoading) {
buttonVariant = 'loading';
} else if (validUsername) {
buttonVariant = 'enabled';
}
const styles = useStyles(unboundStyles);
let errorText;
if (usernameError === 'username_invalid') {
errorText = (
<>
Usernames must:
{'1. '}
Be at least one character long.
{'2. '}
Start with either a letter or a number.
{'3. '}
Contain only letters, numbers, or the characters “-” and “_”.
>
);
} else if (usernameError === 'username_taken') {
errorText = (
Username taken. Please try another one
);
}
const shouldAutoFocus = React.useRef(!cachedSelections.username);
return (
Pick a username
{errorText}
);
}
const unboundStyles = {
header: {
fontSize: 24,
color: 'panelForegroundLabel',
paddingBottom: 16,
},
error: {
marginTop: 16,
},
errorText: {
fontFamily: 'Arial',
fontSize: 15,
lineHeight: 20,
color: 'redText',
},
listItem: {
flexDirection: 'row',
},
listItemNumber: {
fontWeight: 'bold',
},
listItemContent: {
flexShrink: 1,
},
};
export default UsernameSelection;