diff --git a/lib/shared/relationship-utils.js b/lib/shared/relationship-utils.js index 1aa32c56d..bb5ed5fde 100644 --- a/lib/shared/relationship-utils.js +++ b/lib/shared/relationship-utils.js @@ -1,58 +1,85 @@ // @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'); +} + export { sortIDs, getAvailableRelationshipButtons, relationshipBlockedInEitherDirection, + getRelationshipDispatchAction, }; diff --git a/native/chat/settings/thread-settings-edit-relationship.react.js b/native/chat/settings/thread-settings-edit-relationship.react.js index 5f4b48cf5..d28a481de 100644 --- a/native/chat/settings/thread-settings-edit-relationship.react.js +++ b/native/chat/settings/thread-settings-edit-relationship.react.js @@ -1,150 +1,135 @@ // @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 { getSingleOtherUser } from 'lib/shared/thread-utils'; import { type RelationshipAction, type RelationshipButton, relationshipButtons, - relationshipActions, } 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(() => { - 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'); - }, [relationshipButton]); + 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}`; } 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;