diff --git a/lib/hooks/relationship-prompt.js b/lib/hooks/relationship-prompt.js index ac19d16a2..46ddda387 100644 --- a/lib/hooks/relationship-prompt.js +++ b/lib/hooks/relationship-prompt.js @@ -1,103 +1,121 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; import { useSelector } from 'react-redux'; import { updateRelationships as serverUpdateRelationships, updateRelationshipsActionTypes, } from '../actions/relationship-actions'; import { getSingleOtherUser } from '../shared/thread-utils'; import { type RelationshipAction, relationshipActions, } from '../types/relationship-types'; import type { ThreadInfo } from '../types/thread-types'; import type { UserInfo } from '../types/user-types'; import { useDispatchActionPromise, useServerCall } from '../utils/action-utils'; +type RelationshipCallbacks = { + +blockUser: () => void, + +unblockUser: () => void, + +friendUser: () => void, + +unfriendUser: () => void, +}; + type RelationshipPromptData = { +otherUserInfo: ?UserInfo, - +callbacks: { - +blockUser: () => void, - +unblockUser: () => void, - +friendUser: () => void, - +unfriendUser: () => void, - }, + +callbacks: RelationshipCallbacks, }; function useRelationshipPrompt( threadInfo: ThreadInfo, onErrorCallback?: () => void, pendingPersonalThreadUserInfo?: ?UserInfo, ): RelationshipPromptData { // We're fetching the info from state because we need the most recent // relationship status. Additionally, member info does not contain info // about relationship. const otherUserInfo = useSelector(state => { const otherUserID = getSingleOtherUser(threadInfo, state.currentUserInfo?.id) ?? pendingPersonalThreadUserInfo?.id; const { userInfos } = state.userStore; return otherUserID && userInfos[otherUserID] ? userInfos[otherUserID] : pendingPersonalThreadUserInfo; }); + const callbacks = useRelationshipCallbacks( + otherUserInfo?.id, + onErrorCallback, + ); + + return { + otherUserInfo, + callbacks, + }; +} + +function useRelationshipCallbacks( + otherUserID?: string, + onErrorCallback?: () => void, +): RelationshipCallbacks { const callUpdateRelationships = useServerCall(serverUpdateRelationships); const updateRelationship = React.useCallback( async (action: RelationshipAction) => { try { - invariant(otherUserInfo?.id, 'Other user info id should be present'); + invariant(otherUserID, 'Other user info id should be present'); return await callUpdateRelationships({ action, - userIDs: [otherUserInfo.id], + userIDs: [otherUserID], }); } catch (e) { onErrorCallback?.(); throw e; } }, - [callUpdateRelationships, onErrorCallback, otherUserInfo?.id], + [callUpdateRelationships, onErrorCallback, otherUserID], ); const dispatchActionPromise = useDispatchActionPromise(); const onButtonPress = React.useCallback( (action: RelationshipAction) => { dispatchActionPromise( updateRelationshipsActionTypes, updateRelationship(action), ); }, [dispatchActionPromise, updateRelationship], ); const blockUser = React.useCallback( () => onButtonPress(relationshipActions.BLOCK), [onButtonPress], ); const unblockUser = React.useCallback( () => onButtonPress(relationshipActions.UNBLOCK), [onButtonPress], ); const friendUser = React.useCallback( () => onButtonPress(relationshipActions.FRIEND), [onButtonPress], ); const unfriendUser = React.useCallback( () => onButtonPress(relationshipActions.UNFRIEND), [onButtonPress], ); - return { - otherUserInfo, - callbacks: { + + return React.useMemo( + () => ({ blockUser, unblockUser, friendUser, unfriendUser, - }, - }; + }), + [blockUser, friendUser, unblockUser, unfriendUser], + ); } -export { useRelationshipPrompt }; +export { useRelationshipPrompt, useRelationshipCallbacks };