diff --git a/native/components/relationship-button.react.js b/native/components/relationship-button.react.js index c61527a90..4ebd2d463 100644 --- a/native/components/relationship-button.react.js +++ b/native/components/relationship-button.react.js @@ -1,94 +1,95 @@ // @flow import Icon from '@expo/vector-icons/FontAwesome5.js'; import * as React from 'react'; import { Text } from 'react-native'; -import Button from './button.react.js'; +import LoadableButton from './loadable-button.react.js'; import { useStyles, useColors } from '../themes/colors.js'; type RelationshipButtonType = | 'add' | 'withdraw' | 'accept' | 'reject' | 'block' | 'unblock'; type Props = { +type: RelationshipButtonType, +onPress: () => mixed, + +isLoading: boolean, }; function RelationshipButton(props: Props): React.Node { - const { type, onPress } = props; + const { type, onPress, isLoading } = props; const styles = useStyles(unboundStyles); const colors = useColors(); const buttonStyle = React.useMemo(() => { const result = [styles.buttonContainer]; if (type === 'add' || type === 'accept' || type === 'unblock') { result.push(styles.greenButton); } else { result.push(styles.redButton); } return result; }, [styles.buttonContainer, styles.greenButton, styles.redButton, type]); - let buttonText = 'Add Friend'; + let buttonText = 'Add friend'; let icon = 'user-plus'; if (type === 'withdraw') { - buttonText = 'Withdraw Friend Request'; + buttonText = 'Withdraw friend request'; icon = 'user-minus'; } else if (type === 'accept') { buttonText = 'Accept'; } else if (type === 'reject') { buttonText = 'Reject'; icon = 'user-minus'; } else if (type === 'block') { - buttonText = 'Block User'; + buttonText = 'Block user'; icon = 'user-shield'; } else if (type === 'unblock') { - buttonText = 'Unblock User'; + buttonText = 'Unblock user'; icon = 'user-shield'; } return ( - + ); } const unboundStyles = { buttonContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingVertical: 8, borderRadius: 8, }, buttonIcon: { paddingRight: 8, }, buttonText: { color: 'floatingButtonLabel', }, greenButton: { backgroundColor: 'vibrantGreenButton', }, redButton: { backgroundColor: 'vibrantRedButton', }, }; export default RelationshipButton; diff --git a/native/user-profile/user-profile-relationship-button.react.js b/native/user-profile/user-profile-relationship-button.react.js index f27371cb2..9685bb0c7 100644 --- a/native/user-profile/user-profile-relationship-button.react.js +++ b/native/user-profile/user-profile-relationship-button.react.js @@ -1,158 +1,177 @@ // @flow import * as React from 'react'; import { Text, View } from 'react-native'; import { useRelationshipPrompt } from 'lib/hooks/relationship-prompt.js'; import type { SetState } from 'lib/types/hook-types.js'; import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { userRelationshipStatus } from 'lib/types/relationship-types.js'; import type { UserInfo } from 'lib/types/user-types'; import { userProfileActionButtonHeight } from './user-profile-constants.js'; import RelationshipButton from '../components/relationship-button.react.js'; import { useStyles } from '../themes/colors.js'; import { unknownErrorAlertDetails } from '../utils/alert-messages.js'; import Alert from '../utils/alert.js'; const onErrorCallback = () => { Alert.alert( unknownErrorAlertDetails.title, unknownErrorAlertDetails.message, [{ text: 'OK' }], ); }; type Props = { +threadInfo: ThreadInfo, +pendingPersonalThreadUserInfo?: UserInfo, +setUserProfileRelationshipButtonHeight: SetState, }; function UserProfileRelationshipButton(props: Props): React.Node { const { threadInfo, pendingPersonalThreadUserInfo, setUserProfileRelationshipButtonHeight, } = props; const { otherUserInfo, callbacks: { friendUser, unfriendUser }, + loadingState: { isLoadingFriendUser, isLoadingUnfriendUser }, } = useRelationshipPrompt( threadInfo, onErrorCallback, pendingPersonalThreadUserInfo, ); React.useLayoutEffect(() => { if ( !otherUserInfo || otherUserInfo.relationshipStatus === userRelationshipStatus.FRIEND ) { setUserProfileRelationshipButtonHeight(0); } else if ( otherUserInfo?.relationshipStatus === userRelationshipStatus.REQUEST_RECEIVED ) { const incomingFriendRequestButtonsContainerHeight = 88; setUserProfileRelationshipButtonHeight( incomingFriendRequestButtonsContainerHeight, ); } else { setUserProfileRelationshipButtonHeight(userProfileActionButtonHeight); } }, [ otherUserInfo, otherUserInfo?.relationshipStatus, setUserProfileRelationshipButtonHeight, ]); const styles = useStyles(unboundStyles); const userProfileRelationshipButton = React.useMemo(() => { if ( !otherUserInfo || !otherUserInfo.username || otherUserInfo.relationshipStatus === userRelationshipStatus.FRIEND ) { return null; } if ( otherUserInfo.relationshipStatus === userRelationshipStatus.REQUEST_RECEIVED ) { return ( Incoming friend request - + - + ); } if ( otherUserInfo.relationshipStatus === userRelationshipStatus.REQUEST_SENT ) { return ( - + ); } return ( - + ); }, [ friendUser, + isLoadingFriendUser, + isLoadingUnfriendUser, otherUserInfo, styles.acceptFriendRequestButtonContainer, styles.incomingFriendRequestButtonsContainer, styles.incomingFriendRequestContainer, styles.incomingFriendRequestLabel, styles.rejectFriendRequestButtonContainer, styles.singleButtonContainer, unfriendUser, ]); return userProfileRelationshipButton; } const unboundStyles = { singleButtonContainer: { marginTop: 16, }, incomingFriendRequestContainer: { marginTop: 24, }, incomingFriendRequestLabel: { color: 'modalForegroundLabel', }, incomingFriendRequestButtonsContainer: { flexDirection: 'row', marginTop: 8, }, acceptFriendRequestButtonContainer: { flex: 1, marginRight: 4, }, rejectFriendRequestButtonContainer: { flex: 1, marginLeft: 4, }, }; export default UserProfileRelationshipButton;