diff --git a/lib/hooks/relationship-prompt.js b/lib/hooks/relationship-prompt.js
index 30cf569ae..7b87f345b 100644
--- a/lib/hooks/relationship-prompt.js
+++ b/lib/hooks/relationship-prompt.js
@@ -1,127 +1,171 @@
// @flow
import invariant from 'invariant';
import * as React from 'react';
import {
updateRelationships as serverUpdateRelationships,
updateRelationshipsActionTypes,
} from '../actions/relationship-actions.js';
import { useLegacyAshoatKeyserverCall } from '../keyserver-conn/legacy-keyserver-call.js';
import { getSingleOtherUser } from '../shared/thread-utils.js';
import type { ThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
import {
relationshipActions,
type TraditionalRelationshipAction,
} from '../types/relationship-types.js';
import type { UserInfo } from '../types/user-types.js';
import { useDispatchActionPromise } from '../utils/redux-promise-utils.js';
import { useSelector } from '../utils/redux-utils.js';
type RelationshipCallbacks = {
+blockUser: () => void,
+unblockUser: () => void,
+friendUser: () => void,
+unfriendUser: () => void,
};
+type RelationshipLoadingState = {
+ +isLoadingBlockUser: boolean,
+ +isLoadingUnblockUser: boolean,
+ +isLoadingFriendUser: boolean,
+ +isLoadingUnfriendUser: boolean,
+};
+
type RelationshipPromptData = {
+otherUserInfo: ?UserInfo,
+callbacks: RelationshipCallbacks,
+ +loadingState: RelationshipLoadingState,
};
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(
+ const { callbacks, loadingState } = useRelationshipCallbacks(
otherUserInfo?.id,
onErrorCallback,
);
return React.useMemo(
() => ({
otherUserInfo,
callbacks,
+ loadingState,
}),
- [callbacks, otherUserInfo],
+ [callbacks, loadingState, otherUserInfo],
);
}
function useRelationshipCallbacks(
otherUserID?: string,
onErrorCallback?: () => void,
-): RelationshipCallbacks {
+): {
+ +callbacks: RelationshipCallbacks,
+ +loadingState: RelationshipLoadingState,
+} {
+ const [isLoadingBlockUser, setIsLoadingBlockUser] = React.useState(false);
+ const [isLoadingUnblockUser, setIsLoadingUnblockUser] = React.useState(false);
+ const [isLoadingFriendUser, setIsLoadingFriendUser] = React.useState(false);
+ const [isLoadingUnfriendUser, setIsLoadingUnfriendUser] =
+ React.useState(false);
+
const callUpdateRelationships = useLegacyAshoatKeyserverCall(
serverUpdateRelationships,
);
const updateRelationship = React.useCallback(
- async (action: TraditionalRelationshipAction) => {
+ async (
+ action: TraditionalRelationshipAction,
+ setInProgress: boolean => mixed,
+ ) => {
try {
+ setInProgress(true);
invariant(otherUserID, 'Other user info id should be present');
return await callUpdateRelationships({
action,
userIDs: [otherUserID],
});
} catch (e) {
onErrorCallback?.();
throw e;
+ } finally {
+ setInProgress(false);
}
},
[callUpdateRelationships, onErrorCallback, otherUserID],
);
const dispatchActionPromise = useDispatchActionPromise();
const onButtonPress = React.useCallback(
- (action: TraditionalRelationshipAction) => {
+ (
+ action: TraditionalRelationshipAction,
+ setInProgress: boolean => mixed,
+ ) => {
void dispatchActionPromise(
updateRelationshipsActionTypes,
- updateRelationship(action),
+ updateRelationship(action, setInProgress),
);
},
[dispatchActionPromise, updateRelationship],
);
const blockUser = React.useCallback(
- () => onButtonPress(relationshipActions.BLOCK),
+ () => onButtonPress(relationshipActions.BLOCK, setIsLoadingBlockUser),
[onButtonPress],
);
const unblockUser = React.useCallback(
- () => onButtonPress(relationshipActions.UNBLOCK),
+ () => onButtonPress(relationshipActions.UNBLOCK, setIsLoadingUnblockUser),
[onButtonPress],
);
const friendUser = React.useCallback(
- () => onButtonPress(relationshipActions.FRIEND),
+ () => onButtonPress(relationshipActions.FRIEND, setIsLoadingFriendUser),
[onButtonPress],
);
const unfriendUser = React.useCallback(
- () => onButtonPress(relationshipActions.UNFRIEND),
+ () => onButtonPress(relationshipActions.UNFRIEND, setIsLoadingUnfriendUser),
[onButtonPress],
);
return React.useMemo(
() => ({
+ callbacks: {
+ blockUser,
+ unblockUser,
+ friendUser,
+ unfriendUser,
+ },
+ loadingState: {
+ isLoadingBlockUser,
+ isLoadingUnblockUser,
+ isLoadingFriendUser,
+ isLoadingUnfriendUser,
+ },
+ }),
+ [
blockUser,
- unblockUser,
friendUser,
+ isLoadingBlockUser,
+ isLoadingFriendUser,
+ isLoadingUnblockUser,
+ isLoadingUnfriendUser,
+ unblockUser,
unfriendUser,
- }),
- [blockUser, friendUser, unblockUser, unfriendUser],
+ ],
);
}
export { useRelationshipPrompt, useRelationshipCallbacks };
diff --git a/web/settings/relationship/block-list-row.react.js b/web/settings/relationship/block-list-row.react.js
index c88314a40..94c90a1f4 100644
--- a/web/settings/relationship/block-list-row.react.js
+++ b/web/settings/relationship/block-list-row.react.js
@@ -1,43 +1,45 @@
// @flow
import * as React from 'react';
import SWMansionIcon from 'lib/components/swmansion-icon.react.js';
import { useRelationshipCallbacks } from 'lib/hooks/relationship-prompt.js';
import css from './user-list-row.css';
import type { UserRowProps } from './user-list.react.js';
import UserAvatar from '../../avatars/user-avatar.react.js';
import MenuItem from '../../components/menu-item.react.js';
import Menu from '../../components/menu.react.js';
import { usePushUserProfileModal } from '../../modals/user-profile/user-profile-utils.js';
function BlockListRow(props: UserRowProps): React.Node {
const { userInfo, onMenuVisibilityChange } = props;
- const { unblockUser } = useRelationshipCallbacks(userInfo.id);
+ const {
+ callbacks: { unblockUser },
+ } = useRelationshipCallbacks(userInfo.id);
const editIcon =