diff --git a/native/account/registration/keyserver-selection.react.js b/native/account/registration/keyserver-selection.react.js index a874e76eb..2bb9c28e9 100644 --- a/native/account/registration/keyserver-selection.react.js +++ b/native/account/registration/keyserver-selection.react.js @@ -1,196 +1,165 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; -import { Text, TextInput } from 'react-native'; +import { Text } from 'react-native'; 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 type { RegistrationNavigationProp } from './registration-navigator.react.js'; +import RegistrationTextInput from './registration-text-input.react.js'; import { RegistrationTile, RegistrationTileHeader, } from './registration-tile.react.js'; import type { CoolOrNerdMode } from './registration-types.js'; import CommIcon from '../../components/comm-icon.react.js'; import { type NavigationRoute, ConnectEthereumRouteName, } from '../../navigation/route-names.js'; import { useStyles, useColors } from '../../themes/colors.js'; type Selection = 'ashoat' | 'custom'; export type KeyserverSelectionParams = { +userSelections: { +coolOrNerdMode: CoolOrNerdMode, }, }; type Props = { +navigation: RegistrationNavigationProp<'KeyserverSelection'>, +route: NavigationRoute<'KeyserverSelection'>, }; // eslint-disable-next-line no-unused-vars function KeyserverSelection(props: Props): React.Node { const [customKeyserver, setCustomKeyserver] = React.useState(''); const customKeyserverTextInputRef = React.useRef(); const [currentSelection, setCurrentSelection] = React.useState(); const selectAshoat = React.useCallback(() => { setCurrentSelection('ashoat'); customKeyserverTextInputRef.current?.blur(); }, []); const customKeyserverEmpty = !customKeyserver; const selectCustom = React.useCallback(() => { setCurrentSelection('custom'); if (customKeyserverEmpty) { customKeyserverTextInputRef.current?.focus(); } }, [customKeyserverEmpty]); - - const [customKeyserverInputFocused, setCustomKeyserverInputFocused] = - React.useState(false); const onCustomKeyserverFocus = React.useCallback(() => { setCurrentSelection('custom'); - setCustomKeyserverInputFocused(true); - }, []); - const onCustomKeyserverBlur = React.useCallback(() => { - setCustomKeyserverInputFocused(false); }, []); let keyserverUsername; if (currentSelection === 'ashoat') { keyserverUsername = 'ashoat'; } else if (currentSelection === 'custom' && customKeyserver) { keyserverUsername = customKeyserver; } const buttonState = keyserverUsername ? 'enabled' : 'disabled'; const { navigate } = props.navigation; const { coolOrNerdMode } = props.route.params.userSelections; const onSubmit = React.useCallback(() => { invariant( keyserverUsername, 'Button should be disabled if keyserverUsername is not set', ); navigate<'ConnectEthereum'>({ name: ConnectEthereumRouteName, params: { userSelections: { coolOrNerdMode, keyserverUsername } }, }); }, [navigate, coolOrNerdMode, keyserverUsername]); const styles = useStyles(unboundStyles); - const keyserverInputStyle = React.useMemo( - () => - customKeyserverInputFocused - ? [styles.keyserverInput, styles.focusedKeyserverInput] - : styles.keyserverInput, - [ - customKeyserverInputFocused, - styles.keyserverInput, - styles.focusedKeyserverInput, - ], - ); - const colors = useColors(); return ( Select a keyserver to join Chat communities on Comm are hosted on keyservers, which are user-operated backends. Keyservers allow Comm to offer strong privacy guarantees without sacrificing functionality. ashoat Ashoat is Comm’s founder, and his keyserver currently hosts most of the communities on Comm. Enter a keyserver - ); } const unboundStyles = { header: { fontSize: 24, color: 'panelForegroundLabel', paddingBottom: 16, }, body: { fontSize: 15, lineHeight: 20, color: 'panelForegroundSecondaryLabel', paddingBottom: 16, }, tileTitleText: { flex: 1, fontSize: 18, color: 'panelForegroundLabel', }, tileBody: { fontSize: 13, color: 'panelForegroundSecondaryLabel', }, cloud: { marginRight: 8, }, - keyserverInput: { - color: 'panelForegroundLabel', - borderColor: 'panelSecondaryForegroundBorder', - borderWidth: 1, - borderRadius: 4, - padding: 12, - }, - focusedKeyserverInput: { - borderColor: 'panelForegroundLabel', - }, }; export default KeyserverSelection; diff --git a/native/account/registration/registration-text-input.react.js b/native/account/registration/registration-text-input.react.js new file mode 100644 index 000000000..517833ee0 --- /dev/null +++ b/native/account/registration/registration-text-input.react.js @@ -0,0 +1,80 @@ +// @flow + +import * as React from 'react'; +import { TextInput } from 'react-native'; + +import { useStyles, useColors } from '../../themes/colors.js'; + +type Props = React.ElementConfig; + +function ForwardedRegistrationTextInput(props: Props, ref): React.Node { + const { onFocus, onBlur, style, placeholderTextColor, ...rest } = props; + + const [focused, setFocused] = React.useState(false); + const ourOnFocus = React.useCallback( + event => { + setFocused(true); + onFocus?.(event); + }, + [onFocus], + ); + const ourOnBlur = React.useCallback( + event => { + setFocused(false); + onBlur?.(event); + }, + [onBlur], + ); + + const styles = useStyles(unboundStyles); + const ourStyle = React.useMemo( + () => + focused + ? [styles.textInput, styles.focusedTextInput, style] + : [styles.textInput, style], + [focused, styles.textInput, styles.focusedTextInput, style], + ); + + const colors = useColors(); + const ourPlaceholderTextColor = + placeholderTextColor ?? colors.panelSecondaryForegroundBorder; + + return ( + + ); +} + +const unboundStyles = { + textInput: { + color: 'panelForegroundLabel', + borderColor: 'panelSecondaryForegroundBorder', + borderWidth: 1, + borderRadius: 4, + padding: 12, + }, + focusedTextInput: { + borderColor: 'panelForegroundLabel', + }, +}; + +const RegistrationTextInput: React.AbstractComponent< + Props, + React.ElementRef, +> = React.forwardRef>( + ForwardedRegistrationTextInput, +); +RegistrationTextInput.displayName = 'RegistrationTextInput'; + +const MemoizedRegistrationTextInput: typeof RegistrationTextInput = React.memo< + Props, + React.ElementRef, +>(RegistrationTextInput); + +export default MemoizedRegistrationTextInput;