Skip to content

Commit 2bda441

Browse files
regression: Federated room entering an invalid state after accepting invitation (#38093)
1 parent 35a6fdf commit 2bda441

File tree

3 files changed

+18
-44
lines changed

3 files changed

+18
-44
lines changed

apps/meteor/client/views/room/RoomInvite.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { isRoomFederated } from '@rocket.chat/core-typings';
22
import type { IUser, IInviteSubscription } from '@rocket.chat/core-typings';
3-
import type { ComponentProps } from 'react';
3+
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
4+
import { useQueryClient } from '@tanstack/react-query';
5+
import { useEffect, type ComponentProps } from 'react';
46
import { useTranslation } from 'react-i18next';
57

68
import Header from './Header';
@@ -10,6 +12,7 @@ import type { IRoomWithFederationOriginalName } from './contexts/RoomContext';
1012
import { useRoomInvitation } from './hooks/useRoomInvitation';
1113
import RoomLayout from './layout/RoomLayout';
1214
import { links } from '../../lib/links';
15+
import { roomsQueryKeys, subscriptionsQueryKeys } from '../../lib/queryKeys';
1316

1417
type RoomInviteProps = Omit<ComponentProps<typeof RoomLayout>, 'header' | 'body' | 'aside'> & {
1518
userId?: IUser['_id'];
@@ -19,12 +22,25 @@ type RoomInviteProps = Omit<ComponentProps<typeof RoomLayout>, 'header' | 'body'
1922

2023
const RoomInvite = ({ room, subscription, userId, ...props }: RoomInviteProps) => {
2124
const { t } = useTranslation();
25+
const queryClient = useQueryClient();
2226
const { acceptInvite, rejectInvite, isPending } = useRoomInvitation(room);
2327

2428
const infoLink = isRoomFederated(room) ? { label: t('Learn_more_about_Federation'), href: links.go.matrixFederation } : undefined;
2529

2630
useGoToHomeOnRemoved(room, userId);
2731

32+
const invalidateQueries = useEffectEvent(() => {
33+
const reference = room.federationOriginalName ?? room.name ?? room._id;
34+
void queryClient.invalidateQueries({ queryKey: roomsQueryKeys.room(room._id) });
35+
void queryClient.invalidateQueries({ queryKey: subscriptionsQueryKeys.subscription(room._id) });
36+
void queryClient.invalidateQueries({ queryKey: roomsQueryKeys.roomReference(reference, room.t, userId) });
37+
});
38+
39+
useEffect(() => {
40+
// Invalidate room and subscription queries when unmounting (invite accepted or rejected)
41+
return () => invalidateQueries();
42+
}, [invalidateQueries]);
43+
2844
return (
2945
<RoomLayout
3046
{...props}

apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,4 @@ describe('useRoomInvitation', () => {
8181

8282
await waitFor(() => expect(mockInviteEndpoint).not.toHaveBeenCalled());
8383
});
84-
85-
it('should redirect to /home after rejecting an invite', async () => {
86-
const { result } = renderHook(() => useRoomInvitation(mockedRoom), { wrapper: appRoot });
87-
88-
act(() => void result.current.rejectInvite());
89-
90-
await waitFor(() => expect(mockedNavigate).toHaveBeenCalledWith('/home'));
91-
});
92-
93-
it('should not redirect to /home after accepting an invite', async () => {
94-
const { result } = renderHook(() => useRoomInvitation(mockedRoom), { wrapper: appRoot });
95-
96-
act(() => void result.current.acceptInvite());
97-
98-
await waitFor(() => expect(mockedNavigate).not.toHaveBeenCalled());
99-
});
10084
});

apps/meteor/client/views/room/hooks/useRoomInvitation.tsx

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,10 @@
1-
import { useRouter, useUser } from '@rocket.chat/ui-contexts';
2-
import { useQueryClient } from '@tanstack/react-query';
3-
41
import { useRoomRejectInvitationModal } from './useRoomRejectInvitationModal';
52
import { useEndpointMutation } from '../../../hooks/useEndpointMutation';
6-
import { roomsQueryKeys, subscriptionsQueryKeys } from '../../../lib/queryKeys';
73
import type { IRoomWithFederationOriginalName } from '../contexts/RoomContext';
84

95
export const useRoomInvitation = (room: IRoomWithFederationOriginalName) => {
10-
const queryClient = useQueryClient();
11-
const user = useUser();
12-
const router = useRouter();
13-
146
const { open: openConfirmationModal } = useRoomRejectInvitationModal(room);
15-
16-
const replyInvite = useEndpointMutation('POST', '/v1/rooms.invite', {
17-
onSuccess: async (_, { action }) => {
18-
const reference = room.federationOriginalName ?? room.name;
19-
20-
if (reference) {
21-
await queryClient.refetchQueries({
22-
queryKey: roomsQueryKeys.roomReference(reference, room.t, user?._id, user?.username),
23-
});
24-
}
25-
26-
await queryClient.invalidateQueries({ queryKey: roomsQueryKeys.room(room._id) });
27-
await queryClient.invalidateQueries({ queryKey: subscriptionsQueryKeys.subscription(room._id) });
28-
29-
if (action === 'reject') {
30-
router.navigate('/home');
31-
}
32-
},
33-
});
7+
const replyInvite = useEndpointMutation('POST', '/v1/rooms.invite');
348

359
return {
3610
...replyInvite,

0 commit comments

Comments
 (0)