|
1 | | -import { useRouter, useUser } from '@rocket.chat/ui-contexts'; |
| 1 | +import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; |
| 2 | +import { useStream, useUser } from '@rocket.chat/ui-contexts'; |
2 | 3 | import { useQueryClient } from '@tanstack/react-query'; |
| 4 | +import { useEffect } from 'react'; |
3 | 5 |
|
4 | 6 | import { useRoomRejectInvitationModal } from './useRoomRejectInvitationModal'; |
5 | 7 | import { useEndpointMutation } from '../../../hooks/useEndpointMutation'; |
6 | 8 | import { roomsQueryKeys, subscriptionsQueryKeys } from '../../../lib/queryKeys'; |
7 | 9 | import type { IRoomWithFederationOriginalName } from '../contexts/RoomContext'; |
8 | 10 |
|
9 | 11 | export const useRoomInvitation = (room: IRoomWithFederationOriginalName) => { |
10 | | - const queryClient = useQueryClient(); |
11 | 12 | const user = useUser(); |
12 | | - const router = useRouter(); |
13 | 13 |
|
| 14 | + if (!user) { |
| 15 | + throw new Error('error-user-not-found'); |
| 16 | + } |
| 17 | + |
| 18 | + const queryClient = useQueryClient(); |
| 19 | + const subscribeToNotifyUser = useStream('notify-user'); |
14 | 20 | const { open: openConfirmationModal } = useRoomRejectInvitationModal(room); |
| 21 | + const replyInvite = useEndpointMutation('POST', '/v1/rooms.invite'); |
15 | 22 |
|
16 | | - const replyInvite = useEndpointMutation('POST', '/v1/rooms.invite', { |
17 | | - onSuccess: async (_, { action }) => { |
18 | | - const reference = room.federationOriginalName ?? room.name; |
| 23 | + const invalidateQueries = useEffectEvent(() => { |
| 24 | + const reference = room.federationOriginalName ?? room.name ?? room._id; |
| 25 | + return Promise.all([ |
| 26 | + queryClient.invalidateQueries({ queryKey: roomsQueryKeys.room(room._id) }), |
| 27 | + queryClient.invalidateQueries({ queryKey: subscriptionsQueryKeys.subscription(room._id) }), |
| 28 | + queryClient.refetchQueries({ |
| 29 | + queryKey: roomsQueryKeys.roomReference(reference, room.t, user._id, user.username), |
| 30 | + }), |
| 31 | + ]); |
| 32 | + }); |
19 | 33 |
|
20 | | - if (reference) { |
21 | | - await queryClient.refetchQueries({ |
22 | | - queryKey: roomsQueryKeys.roomReference(reference, room.t, user?._id, user?.username), |
23 | | - }); |
24 | | - } |
| 34 | + useEffect(() => { |
| 35 | + // Only listen for subscription changes if the mutation has been initiated |
| 36 | + if (!replyInvite.isPending) { |
| 37 | + return; |
| 38 | + } |
25 | 39 |
|
26 | | - await queryClient.invalidateQueries({ queryKey: roomsQueryKeys.room(room._id) }); |
27 | | - await queryClient.invalidateQueries({ queryKey: subscriptionsQueryKeys.subscription(room._id) }); |
| 40 | + /* |
| 41 | + * NOTE: We need to listen for subscription changes here because when accepting an invitation |
| 42 | + * to a federated room, the server processes the acceptance asynchronously. Therefore, |
| 43 | + * we cannot rely solely on the mutation's completion to know when the subscription status |
| 44 | + * has changed. By subscribing to the 'notify-user' stream, we can react to changes in the |
| 45 | + * subscription status and ensure that our UI reflects the most up-to-date information. |
| 46 | + */ |
| 47 | + return subscribeToNotifyUser(`${user._id}/subscriptions-changed`, async (event, data) => { |
| 48 | + if (data.rid !== room._id) { |
| 49 | + return; |
| 50 | + } |
28 | 51 |
|
29 | | - if (action === 'reject') { |
30 | | - router.navigate('/home'); |
| 52 | + if (event !== 'removed' && data.status !== undefined) { |
| 53 | + return; |
31 | 54 | } |
32 | | - }, |
33 | | - }); |
| 55 | + |
| 56 | + await invalidateQueries(); |
| 57 | + }); |
| 58 | + }, [room._id, user._id, invalidateQueries, replyInvite.isPending, subscribeToNotifyUser]); |
34 | 59 |
|
35 | 60 | return { |
36 | 61 | ...replyInvite, |
|
0 commit comments