Skip to content

Commit

Permalink
chore: Remove toggleFavorite client meteor method (#33734)
Browse files Browse the repository at this point in the history
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
  • Loading branch information
yash-rajpal and tassoevan authored Nov 25, 2024
1 parent dbdb521 commit a27a9c4
Show file tree
Hide file tree
Showing 16 changed files with 154 additions and 69 deletions.
9 changes: 5 additions & 4 deletions apps/meteor/client/hooks/useReactiveQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export const useReactiveQuery = <TQueryFnData, TData = TQueryFnData, TQueryKey e
): UseQueryResult<TData, Error> => {
const queryClient = useQueryClient();

return useQuery(
return useQuery({
queryKey,
(): Promise<TQueryFnData> =>
queryFn: (): Promise<TQueryFnData> =>
new Promise((resolve, reject) => {
queueMicrotask(() => {
Tracker.autorun((c) => {
Expand All @@ -33,6 +33,7 @@ export const useReactiveQuery = <TQueryFnData, TData = TQueryFnData, TQueryKey e
});
});
}),
{ staleTime: Infinity, ...options },
);
staleTime: Infinity,
...options,
});
};
19 changes: 19 additions & 0 deletions apps/meteor/client/lib/mutationEffects/room.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Meteor } from 'meteor/meteor';

import { Subscriptions } from '../../../app/models/client';

export const toggleFavoriteRoom = (roomId: string, favorite: boolean) => {
const userId = Meteor.userId()!;

Subscriptions.update(
{
'rid': roomId,
'u._id': userId,
},
{
$set: {
f: favorite,
},
},
);
};
5 changes: 5 additions & 0 deletions apps/meteor/client/lib/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ export const roomsQueryKeys = {
messageActionsWithParameters: (rid: IRoom['_id'], message: IMessage | Serialized<IMessage>) =>
[...roomsQueryKeys.messageActions(rid, message._id), message] as const,
};

export const subscriptionsQueryKeys = {
all: ['subscriptions'] as const,
subscription: (rid: IRoom['_id']) => [...subscriptionsQueryKeys.all, { rid }] as const,
};
1 change: 0 additions & 1 deletion apps/meteor/client/methods/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import './hideRoom';
import './openRoom';
import './pinMessage';
import './toggleFavorite';
import './unpinMessage';
import './updateMessage';
24 changes: 0 additions & 24 deletions apps/meteor/client/methods/toggleFavorite.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useEndpoint } from '@rocket.chat/ui-contexts';
import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { subscriptionsQueryKeys } from '../../../../../../lib/queryKeys';

export const usePutChatOnHoldMutation = (
options?: Omit<UseMutationOptions<void, Error, IRoom['_id']>, 'mutationFn'>,
): UseMutationResult<void, Error, IRoom['_id']> => {
Expand All @@ -19,7 +21,7 @@ export const usePutChatOnHoldMutation = (
onSuccess: async (data, rid, context) => {
await queryClient.invalidateQueries(['current-chats']);
await queryClient.invalidateQueries(['rooms', rid]);
await queryClient.invalidateQueries(['subscriptions', { rid }]);
await queryClient.invalidateQueries(subscriptionsQueryKeys.subscription(rid));
return options?.onSuccess?.(data, rid, context);
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useMethod } from '@rocket.chat/ui-contexts';
import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { subscriptionsQueryKeys } from '../../../../../../lib/queryKeys';

export const useReturnChatToQueueMutation = (
options?: Omit<UseMutationOptions<void, Error, IRoom['_id']>, 'mutationFn'>,
): UseMutationResult<void, Error, IRoom['_id']> => {
Expand All @@ -18,9 +20,9 @@ export const useReturnChatToQueueMutation = (
...options,
onSuccess: async (data, rid, context) => {
await queryClient.invalidateQueries(['current-chats']);
await queryClient.removeQueries(['rooms', rid]);
await queryClient.removeQueries(['/v1/rooms.info', rid]);
await queryClient.removeQueries(['subscriptions', { rid }]);
queryClient.removeQueries(['rooms', rid]);
queryClient.removeQueries(['/v1/rooms.info', rid]);
queryClient.removeQueries(subscriptionsQueryKeys.subscription(rid));
return options?.onSuccess?.(data, rid, context);
},
},
Expand Down
20 changes: 5 additions & 15 deletions apps/meteor/client/views/room/Header/icons/Favorite.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
import type { IRoom, ISubscription } from '@rocket.chat/core-typings';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useSetting, useMethod, useTranslation, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useSetting, useTranslation } from '@rocket.chat/ui-contexts';
import React, { memo } from 'react';

import { HeaderState } from '../../../../components/Header';
import { useUserIsSubscribed } from '../../contexts/RoomContext';
import { useToggleFavoriteMutation } from '../../hooks/useToggleFavoriteMutation';

const Favorite = ({ room: { _id, f: favorite = false, t: type, name } }: { room: IRoom & { f?: ISubscription['f'] } }) => {
const t = useTranslation();
const subscribed = useUserIsSubscribed();
const dispatchToastMessage = useToastMessageDispatch();

const isFavoritesEnabled = useSetting('Favorite_Rooms') && ['c', 'p', 'd', 't'].includes(type);
const toggleFavorite = useMethod('toggleFavorite');
const isFavoritesEnabled = useSetting('Favorite_Rooms', true) && ['c', 'p', 'd', 't'].includes(type);
const { mutate: toggleFavorite } = useToggleFavoriteMutation();

const handleFavoriteClick = useEffectEvent(() => {
if (!isFavoritesEnabled) {
return;
}

try {
toggleFavorite(_id, !favorite);
dispatchToastMessage({
type: 'success',
message: !favorite
? t('__roomName__was_added_to_favorites', { roomName: name })
: t('__roomName__was_removed_from_favorites', { roomName: name }),
});
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
}
toggleFavorite({ roomId: _id, favorite: !favorite, roomName: name || '' });
});

const favoriteLabel = favorite ? `${t('Unfavorite')} ${name}` : `${t('Favorite')} ${name}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useEndpoint } from '@rocket.chat/ui-contexts';
import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { subscriptionsQueryKeys } from '../../../../../../lib/queryKeys';

export const usePutChatOnHoldMutation = (
options?: Omit<UseMutationOptions<void, Error, IRoom['_id']>, 'mutationFn'>,
): UseMutationResult<void, Error, IRoom['_id']> => {
Expand All @@ -19,7 +21,7 @@ export const usePutChatOnHoldMutation = (
onSuccess: async (data, rid, context) => {
await queryClient.invalidateQueries(['current-chats']);
await queryClient.invalidateQueries(['rooms', rid]);
await queryClient.invalidateQueries(['subscriptions', { rid }]);
await queryClient.invalidateQueries(subscriptionsQueryKeys.subscription(rid));
return options?.onSuccess?.(data, rid, context);
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useMethod } from '@rocket.chat/ui-contexts';
import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { subscriptionsQueryKeys } from '../../../../../../lib/queryKeys';

export const useReturnChatToQueueMutation = (
options?: Omit<UseMutationOptions<void, Error, IRoom['_id']>, 'mutationFn'>,
): UseMutationResult<void, Error, IRoom['_id']> => {
Expand All @@ -18,9 +20,9 @@ export const useReturnChatToQueueMutation = (
...options,
onSuccess: async (data, rid, context) => {
await queryClient.invalidateQueries(['current-chats']);
await queryClient.removeQueries(['rooms', rid]);
await queryClient.removeQueries(['/v1/rooms.info', rid]);
await queryClient.removeQueries(['subscriptions', { rid }]);
queryClient.removeQueries(['rooms', rid]);
queryClient.removeQueries(['/v1/rooms.info', rid]);
queryClient.removeQueries(subscriptionsQueryKeys.subscription(rid));
return options?.onSuccess?.(data, rid, context);
},
},
Expand Down
20 changes: 5 additions & 15 deletions apps/meteor/client/views/room/HeaderV2/icons/Favorite.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
import type { IRoom, ISubscription } from '@rocket.chat/core-typings';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useSetting, useMethod, useTranslation, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useSetting, useTranslation } from '@rocket.chat/ui-contexts';
import React, { memo } from 'react';

import { HeaderState } from '../../../../components/Header';
import { useUserIsSubscribed } from '../../contexts/RoomContext';
import { useToggleFavoriteMutation } from '../../hooks/useToggleFavoriteMutation';

const Favorite = ({ room: { _id, f: favorite = false, t: type, name } }: { room: IRoom & { f?: ISubscription['f'] } }) => {
const t = useTranslation();
const subscribed = useUserIsSubscribed();
const dispatchToastMessage = useToastMessageDispatch();

const isFavoritesEnabled = useSetting('Favorite_Rooms') && ['c', 'p', 'd', 't'].includes(type);
const toggleFavorite = useMethod('toggleFavorite');
const isFavoritesEnabled = useSetting('Favorite_Rooms', true) && ['c', 'p', 'd', 't'].includes(type);
const { mutate: toggleFavorite } = useToggleFavoriteMutation();

const handleFavoriteClick = useEffectEvent(() => {
if (!isFavoritesEnabled) {
return;
}

try {
toggleFavorite(_id, !favorite);
dispatchToastMessage({
type: 'success',
message: !favorite
? t('__roomName__was_added_to_favorites', { roomName: name })
: t('__roomName__was_removed_from_favorites', { roomName: name }),
});
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
}
toggleFavorite({ roomId: _id, favorite: !favorite, roomName: name || '' });
});

const favoriteLabel = favorite ? `${t('Unfavorite')} ${name}` : `${t('Favorite')} ${name}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useEndpoint, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { subscriptionsQueryKeys } from '../../../../../lib/queryKeys';

export const useResumeChatOnHoldMutation = (
options?: Omit<UseMutationOptions<void, Error, IRoom['_id']>, 'mutationFn'>,
): UseMutationResult<void, Error, IRoom['_id']> => {
Expand All @@ -21,7 +23,7 @@ export const useResumeChatOnHoldMutation = (
onSuccess: async (data, rid, context) => {
await queryClient.invalidateQueries(['current-chats']);
await queryClient.invalidateQueries(['rooms', rid]);
await queryClient.invalidateQueries(['subscriptions', { rid }]);
await queryClient.invalidateQueries(subscriptionsQueryKeys.subscription(rid));
return options?.onSuccess?.(data, rid, context);
},
onError: (error) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { mockAppRoot } from '@rocket.chat/mock-providers';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook, waitFor } from '@testing-library/react';
import React from 'react';

import { useToggleFavoriteMutation } from './useToggleFavoriteMutation';
import { subscriptionsQueryKeys } from '../../../lib/queryKeys';

it('should work', async () => {
const endpointHandler = jest.fn(() => null);

const { result } = renderHook(() => useToggleFavoriteMutation(), {
legacyRoot: true,
wrapper: mockAppRoot().withEndpoint('POST', '/v1/rooms.favorite', endpointHandler).build(),
});

result.current.mutate({ roomId: 'general', favorite: true, roomName: 'general' });

await waitFor(() => expect(result.current.status).toBe('success'));
expect(endpointHandler).toHaveBeenCalledWith({
roomId: 'general',
favorite: true,
});
});

it('should invalidate any subscription queries', async () => {
const queryClient = new QueryClient();
jest.spyOn(queryClient, 'invalidateQueries');

const { result } = renderHook(() => useToggleFavoriteMutation(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('POST', '/v1/rooms.favorite', async () => null)
.wrap((children) => <QueryClientProvider client={queryClient} children={children} />)
.build(),
});

result.current.mutate({ roomId: 'general', favorite: true, roomName: 'general' });

await waitFor(() => expect(result.current.status).toBe('success'));

expect(queryClient.invalidateQueries).toHaveBeenCalledWith(subscriptionsQueryKeys.subscription('general'));
});
48 changes: 48 additions & 0 deletions apps/meteor/client/views/room/hooks/useToggleFavoriteMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';
import { useEndpoint, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';

import { toggleFavoriteRoom } from '../../../lib/mutationEffects/room';
import { subscriptionsQueryKeys } from '../../../lib/queryKeys';

export const useToggleFavoriteMutation = () => {
const { t } = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();

const toggleFavorite = useEndpoint('POST', '/v1/rooms.favorite');
const queryClient = useQueryClient();

return useMutation(
async ({ roomId, favorite }: { roomId: string; favorite: boolean; roomName: string }) => {
await toggleFavorite({ roomId, favorite });
},
{
onMutate: ({ roomId, favorite }) => {
queryClient.setQueryData<SubscriptionWithRoom | null>(subscriptionsQueryKeys.subscription(roomId), (subscription) =>
subscription
? {
...subscription,
f: favorite,
}
: undefined,
);
},
onSuccess: (_data, { roomId, favorite, roomName }) => {
toggleFavoriteRoom(roomId, favorite);
dispatchToastMessage({
type: 'success',
message: favorite
? t('__roomName__was_added_to_favorites', { roomName })
: t('__roomName__was_removed_from_favorites', { roomName }),
});
},
onError: (error) => {
dispatchToastMessage({ type: 'error', message: error });
},
onSettled: (_data, _error, { roomId }) => {
queryClient.invalidateQueries(subscriptionsQueryKeys.subscription(roomId));
},
},
);
};
3 changes: 2 additions & 1 deletion apps/meteor/client/views/room/providers/RoomProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useReactiveValue } from '../../../hooks/useReactiveValue';
import { useRoomInfoEndpoint } from '../../../hooks/useRoomInfoEndpoint';
import { useSidePanelNavigation } from '../../../hooks/useSidePanelNavigation';
import { RoomManager } from '../../../lib/RoomManager';
import { subscriptionsQueryKeys } from '../../../lib/queryKeys';
import { roomCoordinator } from '../../../lib/rooms/roomCoordinator';
import ImageGalleryProvider from '../../../providers/ImageGalleryProvider';
import RoomNotFound from '../RoomNotFound';
Expand Down Expand Up @@ -45,7 +46,7 @@ const RoomProvider = ({ rid, children }: RoomProviderProps): ReactElement => {
}
}, [resultFromLocal.data, resultFromLocal.isSuccess, resultFromServer, router]);

const subscriptionQuery = useReactiveQuery(['subscriptions', { rid }], () => Subscriptions.findOne({ rid }) ?? null);
const subscriptionQuery = useReactiveQuery(subscriptionsQueryKeys.subscription(rid), () => Subscriptions.findOne({ rid }) ?? null);

useRedirectOnSettingsChanged(subscriptionQuery.data);

Expand Down
3 changes: 3 additions & 0 deletions apps/meteor/tests/mocks/client/meteor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ export const Meteor = {
setItem: jest.fn(),
},
users: {},
userId: () => 'uid',
};

export const Mongo = {
Collection: class Collection {
findOne = jest.fn();

update = jest.fn();
},
};

Expand Down

0 comments on commit a27a9c4

Please sign in to comment.