diff --git a/native/navigation/header-right-text-button.react.js b/native/navigation/header-right-text-button.react.js index 5f4459f02..c66aac238 100644 --- a/native/navigation/header-right-text-button.react.js +++ b/native/navigation/header-right-text-button.react.js @@ -1,33 +1,40 @@ // @flow import * as React from 'react'; import { Text, TouchableOpacity } from 'react-native'; import { useStyles } from '../themes/colors.js'; type Props = { +label: string, +onPress: () => mixed, + +disabled?: boolean, }; function HeaderRightTextButton(props: Props): React.Node { - const { label, onPress } = props; + const { label, onPress, disabled } = props; const styles = useStyles(unboundStyles); + const textStyle = disabled ? styles.disabledTextStyle : styles.textStyle; return ( - - {label} + + {label} ); } const unboundStyles = { textStyle: { color: 'purpleLink', fontSize: 16, marginRight: 10, }, + disabledTextStyle: { + color: 'disabledButtonText', + fontSize: 16, + marginRight: 10, + }, }; export default HeaderRightTextButton; diff --git a/native/profile/add-keyserver.react.js b/native/profile/add-keyserver.react.js index 60bc5e791..c9e94ff7a 100644 --- a/native/profile/add-keyserver.react.js +++ b/native/profile/add-keyserver.react.js @@ -1,153 +1,170 @@ // @flow import { useNavigation } from '@react-navigation/native'; import * as React from 'react'; import { View, Text } from 'react-native'; import { addKeyserverActionType } from 'lib/actions/keyserver-actions.js'; import { useIsKeyserverURLValid } from 'lib/shared/keyserver-utils.js'; import type { KeyserverInfo } from 'lib/types/keyserver-types.js'; import { defaultKeyserverInfo } from 'lib/types/keyserver-types.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; import type { ProfileNavigationProp } from './profile.react.js'; import TextInput from '../components/text-input.react.js'; import HeaderRightTextButton from '../navigation/header-right-text-button.react.js'; import type { NavigationRoute } from '../navigation/route-names.js'; import { useSelector } from '../redux/redux-utils.js'; import { useStyles, useColors } from '../themes/colors.js'; import { useStaffCanSee } from '../utils/staff-utils.js'; +type KeyserverCheckStatus = + | { +status: 'inactive' } + | { +status: 'loading' } + | { +status: 'error' }; +const keyserverCheckStatusInactive = { status: 'inactive' }; +const keyserverCheckStatusLoading = { status: 'loading' }; +const keyserverCheckStatusError = { status: 'error' }; + type Props = { +navigation: ProfileNavigationProp<'AddKeyserver'>, +route: NavigationRoute<'AddKeyserver'>, }; // eslint-disable-next-line no-unused-vars function AddKeyserver(props: Props): React.Node { const { goBack, setOptions } = useNavigation(); const dispatch = useDispatch(); const staffCanSee = useStaffCanSee(); const currentUserID = useSelector(state => state.currentUserInfo?.id); const customServer = useSelector(state => state.customServer); const { panelForegroundTertiaryLabel } = useColors(); const styles = useStyles(unboundStyles); const [urlInput, setUrlInput] = React.useState( customServer && staffCanSee ? customServer : '', ); - const [showErrorMessage, setShowErrorMessage] = React.useState(false); + const [status, setStatus] = React.useState( + keyserverCheckStatusInactive, + ); const isKeyserverURLValidCallback = useIsKeyserverURLValid(urlInput); const onPressSave = React.useCallback(async () => { - setShowErrorMessage(false); if (!currentUserID || !urlInput) { return; } + setStatus(keyserverCheckStatusLoading); const keyserverVersionData = await isKeyserverURLValidCallback(); if (!keyserverVersionData) { - setShowErrorMessage(true); + setStatus(keyserverCheckStatusError); return; } + setStatus(keyserverCheckStatusInactive); const newKeyserverInfo: KeyserverInfo = defaultKeyserverInfo(urlInput); dispatch({ type: addKeyserverActionType, payload: { keyserverAdminUserID: keyserverVersionData.ownerID, newKeyserverInfo, }, }); goBack(); }, [currentUserID, dispatch, goBack, isKeyserverURLValidCallback, urlInput]); + const buttonDisabled = !urlInput || status.status === 'loading'; React.useEffect(() => { setOptions({ headerRight: () => ( - + ), }); - }, [onPressSave, setOptions, styles.header]); + }, [onPressSave, setOptions, buttonDisabled]); const onChangeText = React.useCallback( (text: string) => setUrlInput(text), [], ); + const showErrorMessage = status.status === 'error'; const errorMessage = React.useMemo(() => { if (!showErrorMessage) { return null; } return ( Cannot connect to keyserver. Please check the URL or your connection and try again. ); }, [showErrorMessage, styles.errorMessage]); return ( KEYSERVER URL {errorMessage} ); } const unboundStyles = { container: { paddingTop: 8, }, header: { color: 'panelBackgroundLabel', fontSize: 12, fontWeight: '400', paddingBottom: 3, paddingHorizontal: 24, }, inputContainer: { backgroundColor: 'panelForeground', flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 24, paddingVertical: 12, borderBottomWidth: 1, borderColor: 'panelForegroundBorder', borderTopWidth: 1, }, input: { color: 'panelForegroundLabel', flex: 1, fontFamily: 'Arial', fontSize: 16, paddingVertical: 0, borderBottomColor: 'transparent', }, errorMessage: { marginTop: 8, marginHorizontal: 16, color: 'redText', }, }; export default AddKeyserver;