Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .changeset/add-unhide-channel-toggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@rocket.chat/meteor": minor
"@rocket.chat/i18n": minor
---

Add dynamic Hide/Unhide toggle for channels

- Add useUnhideRoomAction hook to unhide channels
- Update Room Info panel to show Hide/Unhide based on channel state
- Update sidebar context menu with dynamic Hide/Unhide option
- Update Teams info panel with Hide/Unhide toggle
- Add translation keys for Unhide functionality
- Fix error toast when clicking Hide on already-hidden channel
13 changes: 9 additions & 4 deletions apps/meteor/client/hooks/useRoomMenuActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useLeaveRoomAction } from './menuActions/useLeaveRoom';
import { useToggleFavoriteAction } from './menuActions/useToggleFavoriteAction';
import { useToggleReadAction } from './menuActions/useToggleReadAction';
import { useHideRoomAction } from './useHideRoomAction';
import { useUnhideRoomAction } from './useUnhideRoomAction';
import { useOmnichannelPrioritiesMenu } from '../views/omnichannel/hooks/useOmnichannelPrioritiesMenu';

type RoomMenuActionsProps = {
Expand All @@ -33,6 +34,7 @@ export const useRoomMenuActions = ({
const subscription = useUserSubscription(rid);

const isFavorite = Boolean(subscription?.f);
const isRoomHidden = subscription?.open === false;
const canLeaveChannel = usePermission('leave-c');
const canLeavePrivate = usePermission('leave-p');
const canFavorite = useSetting('Favorite_Rooms') as boolean;
Expand All @@ -48,6 +50,7 @@ export const useRoomMenuActions = ({
})();

const handleHide = useHideRoomAction({ rid, type, name }, { redirect: false });
const handleUnhide = useUnhideRoomAction({ rid, type });
const handleToggleFavorite = useToggleFavoriteAction({ rid, isFavorite });
const handleToggleRead = useToggleReadAction({ rid, isUnread, subscription });
const handleLeave = useLeaveRoomAction({ rid, type, name, roomOpen });
Expand All @@ -60,10 +63,10 @@ export const useRoomMenuActions = ({
!hideDefaultOptions
? ([
!isOmnichannelRoom && {
id: 'hideRoom',
icon: 'eye-off',
content: t('Hide'),
onClick: handleHide,
id: isRoomHidden ? 'unhideRoom' : 'hideRoom',
icon: isRoomHidden ? 'eye' : 'eye-off',
content: isRoomHidden ? t('Unhide') : t('Hide'),
onClick: isRoomHidden ? handleUnhide : handleHide,
},
{
id: 'toggleRead',
Expand All @@ -89,6 +92,8 @@ export const useRoomMenuActions = ({
hideDefaultOptions,
t,
handleHide,
handleUnhide,
isRoomHidden,
isUnread,
handleToggleRead,
canFavorite,
Expand Down
46 changes: 46 additions & 0 deletions apps/meteor/client/hooks/useUnhideRoomAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { RoomType } from '@rocket.chat/core-typings';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useEndpoint, useToastMessageDispatch, useUserId } from '@rocket.chat/ui-contexts';
import { useMutation } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';

import { updateSubscription } from '../lib/mutationEffects/updateSubscription';

type UnhideRoomProps = {
rid: string;
type: RoomType;
};

export const useUnhideRoomAction = ({ rid: roomId, type }: UnhideRoomProps) => {
const { t } = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();
const userId = useUserId();

const openRoomEndpoint = useEndpoint('POST', '/v1/rooms.open');

const unhideRoom = useMutation({
mutationFn: () => openRoomEndpoint({ roomId }),
onMutate: async () => {
if (userId) {
return updateSubscription(roomId, userId, { open: true });
}
},
onSuccess: () => {
dispatchToastMessage({ type: 'success', message: t('Room_unhidden_successfully') });
},
onError: async (error, _, rollbackDocument) => {
dispatchToastMessage({ type: 'error', message: error });

if (userId && rollbackDocument) {
const { open } = rollbackDocument;
updateSubscription(roomId, userId, { open });
}
},
});

const handleUnhide = useEffectEvent(() => {
unhideRoom.mutate();
});

return handleUnhide;
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { useUserSubscription } from '@rocket.chat/ui-contexts';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import { useRoomConvertToTeam } from './actions/useRoomConvertToTeam';
import { useRoomLeave } from './actions/useRoomLeave';
import { useRoomMoveToTeam } from './actions/useRoomMoveToTeam';
import { useHideRoomAction } from '../../../../../hooks/useHideRoomAction';
import { useUnhideRoomAction } from '../../../../../hooks/useUnhideRoomAction';
import { useDeleteRoom } from '../../../../hooks/roomActions/useDeleteRoom';

type UseRoomActionsOptions = {
Expand All @@ -18,21 +20,24 @@ export const useRoomActions = (room: IRoom, options: UseRoomActionsOptions) => {
const { onClickEnterRoom, onClickEdit, resetState } = options;

const { t } = useTranslation();
const subscription = useUserSubscription(room._id);
const isRoomHidden = subscription?.open === false;

const handleLeave = useRoomLeave(room);
const { handleDelete, canDeleteRoom } = useDeleteRoom(room, { reload: resetState });
const handleMoveToTeam = useRoomMoveToTeam(room);
const handleConvertToTeam = useRoomConvertToTeam(room);
const handleHide = useHideRoomAction({ rid: room._id, type: room.t, name: room.name ?? '' });
const handleUnhide = useUnhideRoomAction({ rid: room._id, type: room.t });

return useMemo(() => {
const memoizedActions = {
items: [
{
id: 'hide',
content: t('Hide'),
icon: 'eye-off' as const,
onClick: handleHide,
id: isRoomHidden ? 'unhide' : 'hide',
content: isRoomHidden ? t('Unhide') : t('Hide'),
icon: isRoomHidden ? ('eye' as const) : ('eye-off' as const),
onClick: isRoomHidden ? handleUnhide : handleHide,
},

...(onClickEnterRoom
Expand Down Expand Up @@ -100,5 +105,17 @@ export const useRoomActions = (room: IRoom, options: UseRoomActionsOptions) => {
};

return memoizedActions;
}, [canDeleteRoom, handleConvertToTeam, handleDelete, handleHide, handleLeave, handleMoveToTeam, onClickEdit, onClickEnterRoom, t]);
}, [
canDeleteRoom,
handleConvertToTeam,
handleDelete,
handleHide,
handleUnhide,
handleLeave,
handleMoveToTeam,
isRoomHidden,
onClickEdit,
onClickEnterRoom,
t,
]);
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { useUserSubscription } from '@rocket.chat/ui-contexts';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import { useConvertToChannel } from './useConvertToChannel';
import { useLeaveTeam } from './useLeaveTeam';
import { useHideRoomAction } from '../../../../hooks/useHideRoomAction';
import { useUnhideRoomAction } from '../../../../hooks/useUnhideRoomAction';
import { useDeleteRoom } from '../../../hooks/roomActions/useDeleteRoom';

type GenProps = {
Expand All @@ -13,7 +15,10 @@ type GenProps = {

export const useTeamActions = (room: IRoom, { onClickEdit }: GenProps) => {
const { t } = useTranslation();
const subscription = useUserSubscription(room._id);
const isRoomHidden = subscription?.open === false;
const hideTeam = useHideRoomAction({ rid: room._id, type: room.t, name: room.name ?? '' });
const unhideTeam = useUnhideRoomAction({ rid: room._id, type: room.t });
const convertToChannel = useConvertToChannel(room);
const { handleDelete, canDeleteRoom } = useDeleteRoom(room);
const leaveTeam = useLeaveTeam(room);
Expand All @@ -22,10 +27,10 @@ export const useTeamActions = (room: IRoom, { onClickEdit }: GenProps) => {
() => ({
items: [
{
id: 'hide',
content: t('Hide'),
icon: 'eye-off' as const,
onClick: hideTeam,
id: isRoomHidden ? 'unhide' : 'hide',
content: isRoomHidden ? t('Unhide') : t('Hide'),
icon: isRoomHidden ? ('eye' as const) : ('eye-off' as const),
onClick: isRoomHidden ? unhideTeam : hideTeam,
},
...(onClickEdit
? [
Expand Down Expand Up @@ -70,6 +75,6 @@ export const useTeamActions = (room: IRoom, { onClickEdit }: GenProps) => {
: []),
],
}),
[t, hideTeam, leaveTeam, onClickEdit, handleDelete, canDeleteRoom, convertToChannel],
[t, hideTeam, unhideTeam, isRoomHidden, leaveTeam, onClickEdit, handleDelete, canDeleteRoom, convertToChannel],
);
};
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2498,6 +2498,8 @@
"Hide_video": "Hide video",
"High": "High",
"High_scalability": "High scalability",
"Unhide": "Unhide",
"Room_unhidden_successfully": "Room unhidden successfully",
"Highest": "Highest",
"Highlighted_chosen_word": "Highlighted chosen word",
"Highlights": "Highlights",
Expand Down