Skip to content

Commit

Permalink
[native] Avoid updating relationships before the previous call finished
Browse files Browse the repository at this point in the history
Summary:
Make sure we don't update the relationship before the previous call ended. Currently, it is possible to click a button multiple times in a row which results in multiple thick threads being created.

https://linear.app/comm/issue/ENG-9508/adding-new-friends-can-result-in-creating-multiple-thick-threads

Test Plan: Click the `save` button multiple times and check if only one thread was created.

Reviewers: kamil, inka

Reviewed By: inka

Subscribers: ashoat

Differential Revision: https://phab.comm.dev/D13632
  • Loading branch information
palys-swm committed Oct 14, 2024
1 parent 56bb0af commit 621eb40
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions native/profile/relationship-list.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { updateRelationshipsActionTypes } from 'lib/actions/relationship-actions
import { useENSNames } from 'lib/hooks/ens-cache.js';
import { useUpdateRelationships } from 'lib/hooks/relationship-hooks.js';
import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { useUserSearchIndex } from 'lib/selectors/nav-selectors.js';
import { userRelationshipsSelector } from 'lib/selectors/relationship-selectors.js';
import { useSearchUsers } from 'lib/shared/search-utils.js';
Expand Down Expand Up @@ -82,6 +83,10 @@ function keyExtractor(item: ListItem) {
const tagDataLabelExtractor = (userInfo: GlobalAccountUserInfo) =>
userInfo.username;

const loadingStatusSelector = createLoadingStatusSelector(
updateRelationshipsActionTypes,
);

type Props = {
+navigation: ProfileNavigationProp<'FriendList' | 'BlockList'>,
+route: NavigationRoute<'FriendList' | 'BlockList'>,
Expand Down Expand Up @@ -197,8 +202,11 @@ function RelationshipList(props: Props): React.Node {
tagInputRef.current?.focus();
}, []);

const updateInProgress = React.useRef(false);

const updateRelationships = useUpdateRelationships();
const updateRelationshipsOnServer = React.useCallback(async () => {
updateInProgress.current = true;
const action = {
[FriendListRouteName]: relationshipActions.FRIEND,
[BlockListRouteName]: relationshipActions.BLOCK,
Expand All @@ -217,6 +225,8 @@ function RelationshipList(props: Props): React.Node {
{ cancelable: true, onDismiss: onUnknownErrorAlertAcknowledged },
);
throw e;
} finally {
updateInProgress.current = false;
}
}, [
routeName,
Expand All @@ -228,7 +238,7 @@ function RelationshipList(props: Props): React.Node {
const dispatchActionPromise = useDispatchActionPromise();
const noCurrentTags = currentTags.length === 0;
const onPressAdd = React.useCallback(() => {
if (noCurrentTags) {
if (noCurrentTags || updateInProgress.current) {
return;
}
void dispatchActionPromise(
Expand Down Expand Up @@ -285,6 +295,7 @@ function RelationshipList(props: Props): React.Node {

const { setOptions } = navigation;
const prevNoCurrentTags = React.useRef(noCurrentTags);
const loadingStatus = useSelector(loadingStatusSelector);
React.useEffect(() => {
let setSaveButtonDisabled;
if (!prevNoCurrentTags.current && noCurrentTags) {
Expand All @@ -301,11 +312,15 @@ function RelationshipList(props: Props): React.Node {
<LinkButton
text="Save"
onPress={onPressAdd}
disabled={setSaveButtonDisabled}
disabled={
setSaveButtonDisabled ||
loadingStatus === 'loading' ||
updateInProgress.current
}
/>
),
});
}, [setOptions, noCurrentTags, onPressAdd]);
}, [setOptions, noCurrentTags, onPressAdd, loadingStatus]);

const relationships = useSelector(userRelationshipsSelector);
const viewerID = useSelector(
Expand Down

0 comments on commit 621eb40

Please sign in to comment.