diff --git a/lib/shared/relationship-utils.js b/lib/shared/relationship-utils.js index bb5ed5fde..83a6aab2f 100644 --- a/lib/shared/relationship-utils.js +++ b/lib/shared/relationship-utils.js @@ -1,85 +1,110 @@ // @flow import invariant from 'invariant'; import { type RelationshipButton, type UserRelationshipStatus, userRelationshipStatus, relationshipButtons, relationshipActions, type RelationshipAction, } from '../types/relationship-types'; import type { UserInfo } from '../types/user-types'; function sortIDs(firstId: string, secondId: string): string[] { return [Number(firstId), Number(secondId)] .sort((a, b) => a - b) .map(num => num.toString()); } function getAvailableRelationshipButtons( userInfo: UserInfo, ): RelationshipButton[] { const relationship = userInfo.relationshipStatus; if (relationship === userRelationshipStatus.FRIEND) { return [relationshipButtons.UNFRIEND, relationshipButtons.BLOCK]; } else if (relationship === userRelationshipStatus.BLOCKED_VIEWER) { return [relationshipButtons.BLOCK]; } else if ( relationship === userRelationshipStatus.BOTH_BLOCKED || relationship === userRelationshipStatus.BLOCKED_BY_VIEWER ) { return [relationshipButtons.UNBLOCK]; } else if (relationship === userRelationshipStatus.REQUEST_RECEIVED) { return [ relationshipButtons.ACCEPT, relationshipButtons.REJECT, relationshipButtons.BLOCK, ]; } else if (relationship === userRelationshipStatus.REQUEST_SENT) { return [relationshipButtons.WITHDRAW, relationshipButtons.BLOCK]; } else { return [relationshipButtons.FRIEND, relationshipButtons.BLOCK]; } } function relationshipBlockedInEitherDirection( relationshipStatus: UserRelationshipStatus, ): boolean { return ( relationshipStatus === userRelationshipStatus.BLOCKED_VIEWER || relationshipStatus === userRelationshipStatus.BLOCKED_BY_VIEWER || relationshipStatus === userRelationshipStatus.BOTH_BLOCKED ); } function getRelationshipDispatchAction( relationshipButton: RelationshipButton, ): RelationshipAction { if (relationshipButton === relationshipButtons.BLOCK) { return relationshipActions.BLOCK; } else if ( relationshipButton === relationshipButtons.FRIEND || relationshipButton === relationshipButtons.ACCEPT ) { return relationshipActions.FRIEND; } else if ( relationshipButton === relationshipButtons.UNFRIEND || relationshipButton === relationshipButtons.REJECT || relationshipButton === relationshipButtons.WITHDRAW ) { return relationshipActions.UNFRIEND; } else if (relationshipButton === relationshipButtons.UNBLOCK) { return relationshipActions.UNBLOCK; } invariant(false, 'relationshipButton conditions should be exhaustive'); } +function getRelationshipActionText( + relationshipButton: RelationshipButton, + username: string, +): string { + switch (relationshipButton) { + case relationshipButtons.BLOCK: + return `Block ${username}`; + case relationshipButtons.FRIEND: + return `Add ${username} to friends`; + case relationshipButtons.UNFRIEND: + return `Unfriend ${username}`; + case relationshipButtons.UNBLOCK: + return `Unblock ${username}`; + case relationshipButtons.ACCEPT: + return `Accept friend request from ${username}`; + case relationshipButtons.REJECT: + return `Reject friend request from ${username}`; + case relationshipButtons.WITHDRAW: + return `Withdraw request to friend ${username}`; + default: + invariant(false, 'invalid relationshipButton value'); + } +} + export { sortIDs, getAvailableRelationshipButtons, relationshipBlockedInEitherDirection, getRelationshipDispatchAction, + getRelationshipActionText, }; diff --git a/native/chat/settings/thread-settings-edit-relationship.react.js b/native/chat/settings/thread-settings-edit-relationship.react.js index d28a481de..a8096bfdf 100644 --- a/native/chat/settings/thread-settings-edit-relationship.react.js +++ b/native/chat/settings/thread-settings-edit-relationship.react.js @@ -1,135 +1,126 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; import { Alert, Text, View } from 'react-native'; import { updateRelationships as serverUpdateRelationships, updateRelationshipsActionTypes, } from 'lib/actions/relationship-actions'; -import { getRelationshipDispatchAction } from 'lib/shared/relationship-utils'; +import { + getRelationshipActionText, + getRelationshipDispatchAction, +} from 'lib/shared/relationship-utils'; import { getSingleOtherUser } from 'lib/shared/thread-utils'; import { type RelationshipAction, type RelationshipButton, - relationshipButtons, } from 'lib/types/relationship-types'; import type { ThreadInfo } from 'lib/types/thread-types'; import { useDispatchActionPromise, useServerCall, } from 'lib/utils/action-utils'; import Button from '../../components/button.react'; import { useSelector } from '../../redux/redux-utils'; import { useStyles, useColors } from '../../themes/colors'; import type { ViewStyle } from '../../types/styles'; type Props = { +threadInfo: ThreadInfo, +buttonStyle: ViewStyle, +relationshipButton: RelationshipButton, }; const ThreadSettingsEditRelationship: React.ComponentType = React.memo( function ThreadSettingsEditRelationship(props: Props) { const otherUserInfo = useSelector(state => { const currentUserID = state.currentUserInfo?.id; const otherUserID = getSingleOtherUser(props.threadInfo, currentUserID); invariant(otherUserID, 'Other user should be specified'); const { userInfos } = state.userStore; return userInfos[otherUserID]; }); invariant(otherUserInfo, 'Other user info should be specified'); const callUpdateRelationships = useServerCall(serverUpdateRelationships); const updateRelationship = React.useCallback( async (action: RelationshipAction) => { try { return await callUpdateRelationships({ action, userIDs: [otherUserInfo.id], }); } catch (e) { Alert.alert('Unknown error', 'Uhh... try again?', [{ text: 'OK' }], { cancelable: true, }); throw e; } }, [callUpdateRelationships, otherUserInfo], ); const { relationshipButton } = props; const relationshipAction = React.useMemo( () => getRelationshipDispatchAction(relationshipButton), [relationshipButton], ); const dispatchActionPromise = useDispatchActionPromise(); const onButtonPress = React.useCallback(() => { dispatchActionPromise( updateRelationshipsActionTypes, updateRelationship(relationshipAction), ); }, [dispatchActionPromise, relationshipAction, updateRelationship]); const colors = useColors(); const { panelIosHighlightUnderlay } = colors; const styles = useStyles(unboundStyles); const otherUserInfoUsername = otherUserInfo.username; invariant(otherUserInfoUsername, 'Other user username should be specified'); - let relationshipButtonText; - if (relationshipButton === relationshipButtons.BLOCK) { - relationshipButtonText = `Block ${otherUserInfoUsername}`; - } else if (relationshipButton === relationshipButtons.FRIEND) { - relationshipButtonText = `Add ${otherUserInfoUsername} to friends`; - } else if (relationshipButton === relationshipButtons.UNFRIEND) { - relationshipButtonText = `Unfriend ${otherUserInfoUsername}`; - } else if (relationshipButton === relationshipButtons.UNBLOCK) { - relationshipButtonText = `Unblock ${otherUserInfoUsername}`; - } else if (relationshipButton === relationshipButtons.ACCEPT) { - relationshipButtonText = `Accept friend request from ${otherUserInfoUsername}`; - } else if (relationshipButton === relationshipButtons.REJECT) { - relationshipButtonText = `Reject friend request from ${otherUserInfoUsername}`; - } else if (relationshipButton === relationshipButtons.WITHDRAW) { - relationshipButtonText = `Withdraw request to friend ${otherUserInfoUsername}`; - } + const relationshipButtonText = React.useMemo( + () => + getRelationshipActionText(relationshipButton, otherUserInfoUsername), + [otherUserInfoUsername, relationshipButton], + ); return ( ); }, ); const unboundStyles = { button: { flexDirection: 'row', paddingHorizontal: 12, paddingVertical: 10, }, container: { backgroundColor: 'panelForeground', paddingHorizontal: 12, }, text: { color: 'redText', flex: 1, fontSize: 16, }, }; export default ThreadSettingsEditRelationship;