diff --git a/.changeset/wet-penguins-end.md b/.changeset/wet-penguins-end.md
new file mode 100644
index 0000000000000..b2a22d4a74130
--- /dev/null
+++ b/.changeset/wet-penguins-end.md
@@ -0,0 +1,5 @@
+---
+'@rocket.chat/meteor': minor
+---
+
+Separates voice call and video call room actions on room header.
diff --git a/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/index.ts b/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/index.ts
deleted file mode 100644
index d01e5a6a5dffd..0000000000000
--- a/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './useStartCallRoomAction';
diff --git a/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useStartCallRoomAction.tsx b/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useStartCallRoomAction.tsx
deleted file mode 100644
index a4db8c7eddd6c..0000000000000
--- a/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useStartCallRoomAction.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { GenericMenu } from '@rocket.chat/ui-client';
-import { useMemo } from 'react';
-
-import useVideoConfMenuOptions from './useVideoConfMenuOptions';
-import useVoipMenuOptions from './useVoipMenuOptions';
-import HeaderToolbarAction from '../../../components/Header/HeaderToolbarAction';
-import type { RoomToolboxActionConfig } from '../../../views/room/contexts/RoomToolboxContext';
-
-export const useStartCallRoomAction = () => {
- const videoCall = useVideoConfMenuOptions();
- const voipCall = useVoipMenuOptions();
-
- return useMemo((): RoomToolboxActionConfig | undefined => {
- if (!videoCall.allowed && !voipCall?.allowed) {
- return undefined;
- }
-
- return {
- id: 'start-call',
- title: 'Call',
- icon: 'phone',
- groups: [...videoCall.groups, ...(voipCall?.groups ?? [])],
- disabled: videoCall.disabled && (voipCall?.disabled ?? true),
- full: true,
- order: Math.max(voipCall?.order ?? Number.NEGATIVE_INFINITY, videoCall.order),
- featured: true,
- renderToolboxItem: ({ id, icon, title, disabled, className }) => (
- }
- key={id}
- title={title}
- disabled={disabled}
- items={[...(voipCall?.allowed ? voipCall.items : []), ...videoCall.items]}
- className={className}
- placement='bottom-start'
- icon={icon}
- />
- ),
- };
- }, [videoCall, voipCall]);
-};
diff --git a/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useVideoConfMenuOptions.tsx b/apps/meteor/client/hooks/roomActions/useVideoCallRoomAction.tsx
similarity index 70%
rename from apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useVideoConfMenuOptions.tsx
rename to apps/meteor/client/hooks/roomActions/useVideoCallRoomAction.tsx
index 2281e02bbac71..9146a2fc651a0 100644
--- a/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useVideoConfMenuOptions.tsx
+++ b/apps/meteor/client/hooks/roomActions/useVideoCallRoomAction.tsx
@@ -1,7 +1,5 @@
-import { isOmnichannelRoom, isRoomFederated } from '@rocket.chat/core-typings';
-import { Box } from '@rocket.chat/fuselage';
+import { isRoomFederated } from '@rocket.chat/core-typings';
import { useEffectEvent, useStableArray } from '@rocket.chat/fuselage-hooks';
-import type { GenericMenuItemProps } from '@rocket.chat/ui-client';
import { usePermission, useSetting, useUser } from '@rocket.chat/ui-contexts';
import {
useVideoConfDispatchOutgoing,
@@ -12,11 +10,11 @@ import {
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
-import { useRoom } from '../../../views/room/contexts/RoomContext';
-import type { RoomToolboxActionConfig } from '../../../views/room/contexts/RoomToolboxContext';
-import { useVideoConfWarning } from '../../../views/room/contextualBar/VideoConference/hooks/useVideoConfWarning';
+import { useRoom } from '../../views/room/contexts/RoomContext';
+import type { RoomToolboxActionConfig } from '../../views/room/contexts/RoomToolboxContext';
+import { useVideoConfWarning } from '../../views/room/contextualBar/VideoConference/hooks/useVideoConfWarning';
-const useVideoConfMenuOptions = () => {
+export const useVideoCallRoomAction = () => {
const { t } = useTranslation();
const room = useRoom();
const user = useUser();
@@ -54,7 +52,6 @@ const useVideoConfMenuOptions = () => {
const allowed = visible && permittedToCallManagement && (!user?.username || !room.muted?.includes(user.username)) && !ownUser;
const disabled = federated || (!!room.ro && !permittedToPostReadonly);
const tooltip = disabled ? t('core.Video_Call_unavailable_for_this_type_of_room') : '';
- const order = isOmnichannelRoom(room) ? -1 : 4;
const handleOpenVideoConf = useEffectEvent(async () => {
if (isCalling || isRinging) {
@@ -69,29 +66,21 @@ const useVideoConfMenuOptions = () => {
}
});
- return useMemo(() => {
- const items: GenericMenuItemProps[] = [
- {
- id: 'start-video-call',
- icon: 'video',
- disabled,
- onClick: handleOpenVideoConf,
- content: (
-
- {t('Video_call')}
-
- ),
- },
- ];
+ return useMemo((): RoomToolboxActionConfig | undefined => {
+ if (!allowed) {
+ return undefined;
+ }
return {
- items,
- disabled,
- allowed,
- order,
+ id: 'start-video-call',
+ title: 'Video_call',
+ icon: 'video',
+ featured: true,
+ action: handleOpenVideoConf,
+ order: -1,
groups,
+ disabled,
+ tooltip,
};
- }, [allowed, disabled, groups, handleOpenVideoConf, order, t, tooltip]);
+ }, [allowed, groups, disabled, handleOpenVideoConf, tooltip]);
};
-
-export default useVideoConfMenuOptions;
diff --git a/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useVoipMenuOptions.tsx b/apps/meteor/client/hooks/roomActions/useVoiceCallRoomAction.tsx
similarity index 64%
rename from apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useVoipMenuOptions.tsx
rename to apps/meteor/client/hooks/roomActions/useVoiceCallRoomAction.tsx
index b6f31ff5cedf2..c858a591387a7 100644
--- a/apps/meteor/client/hooks/roomActions/useStartCallRoomAction/useVoipMenuOptions.tsx
+++ b/apps/meteor/client/hooks/roomActions/useVoiceCallRoomAction.tsx
@@ -1,17 +1,16 @@
-import { Box } from '@rocket.chat/fuselage';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
-import type { GenericMenuItemProps } from '@rocket.chat/ui-client';
import { usePermission, useUserId } from '@rocket.chat/ui-contexts';
import { useVoipAPI, useVoipState } from '@rocket.chat/ui-voip';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
-import { useMediaPermissions } from '../../../views/room/composer/messageBox/hooks/useMediaPermissions';
-import { useRoom } from '../../../views/room/contexts/RoomContext';
-import { useUserInfoQuery } from '../../useUserInfoQuery';
-import { useVoipWarningModal } from '../../useVoipWarningModal';
+import { useMediaPermissions } from '../../views/room/composer/messageBox/hooks/useMediaPermissions';
+import { useRoom } from '../../views/room/contexts/RoomContext';
+import type { RoomToolboxActionConfig } from '../../views/room/contexts/RoomToolboxContext';
+import { useUserInfoQuery } from '../useUserInfoQuery';
+import { useVoipWarningModal } from '../useVoipWarningModal';
-const useVoipMenuOptions = () => {
+export const useVoiceCallRoomAction = () => {
const { t } = useTranslation();
const { uids = [] } = useRoom();
const ownUserId = useUserId();
@@ -32,10 +31,10 @@ const useVoipMenuOptions = () => {
const isDM = members.length === 1;
const disabled = isMicPermissionDenied || !isDM || isInCall || isPending;
- const allowed = isDM && !isInCall && !isPending;
+ const allowed = canStartVoiceCall && isDM && !isInCall && !isPending;
const canMakeVoipCall = allowed && isRemoteRegistered && isRegistered && isEnabled && !isMicPermissionDenied;
- const title = useMemo(() => {
+ const tooltip = useMemo(() => {
if (isMicPermissionDenied) {
return t('Microphone_access_not_allowed');
}
@@ -54,33 +53,20 @@ const useVoipMenuOptions = () => {
dispatchWarning();
});
- return useMemo(() => {
- if (!canStartVoiceCall) {
+ return useMemo((): RoomToolboxActionConfig | undefined => {
+ if (!allowed) {
return undefined;
}
- const items: GenericMenuItemProps[] = [
- {
- id: 'start-voip-call',
- icon: 'phone',
- disabled,
- onClick: handleOnClick,
- content: (
-
- {t('Voice_call')}
-
- ),
- },
- ];
-
return {
- items,
+ id: 'start-voice-call',
+ title: 'Voice_Call',
+ icon: 'phone',
+ featured: true,
+ action: handleOnClick,
groups: ['direct'] as const,
disabled,
- order: 4,
- allowed,
+ tooltip,
};
- }, [disabled, title, t, handleOnClick, allowed, canStartVoiceCall]);
+ }, [allowed, disabled, handleOnClick, tooltip]);
};
-
-export default useVoipMenuOptions;
diff --git a/apps/meteor/client/ui.ts b/apps/meteor/client/ui.ts
index f5e55d64833b5..2bad21ebd2fae 100644
--- a/apps/meteor/client/ui.ts
+++ b/apps/meteor/client/ui.ts
@@ -25,14 +25,15 @@ import { usePushNotificationsRoomAction } from './hooks/roomActions/usePushNotif
import { useRocketSearchRoomAction } from './hooks/roomActions/useRocketSearchRoomAction';
import { useRoomInfoRoomAction } from './hooks/roomActions/useRoomInfoRoomAction';
import { useStarredMessagesRoomAction } from './hooks/roomActions/useStarredMessagesRoomAction';
-import { useStartCallRoomAction } from './hooks/roomActions/useStartCallRoomAction';
import { useTeamChannelsRoomAction } from './hooks/roomActions/useTeamChannelsRoomAction';
import { useTeamInfoRoomAction } from './hooks/roomActions/useTeamInfoRoomAction';
import { useThreadRoomAction } from './hooks/roomActions/useThreadRoomAction';
import { useUploadedFilesListRoomAction } from './hooks/roomActions/useUploadedFilesListRoomAction';
import { useUserInfoGroupRoomAction } from './hooks/roomActions/useUserInfoGroupRoomAction';
import { useUserInfoRoomAction } from './hooks/roomActions/useUserInfoRoomAction';
+import { useVideoCallRoomAction } from './hooks/roomActions/useVideoCallRoomAction';
import { useVoIPRoomInfoRoomAction } from './hooks/roomActions/useVoIPRoomInfoRoomAction';
+import { useVoiceCallRoomAction } from './hooks/roomActions/useVoiceCallRoomAction';
import { useWebRTCVideoRoomAction } from './hooks/roomActions/useWebRTCVideoRoomAction';
import type { RoomToolboxActionConfig } from './views/room/contexts/RoomToolboxContext';
import type { QuickActionsActionConfig } from './views/room/lib/quickActions';
@@ -63,12 +64,13 @@ export const roomActionHooks = [
useRocketSearchRoomAction,
useRoomInfoRoomAction,
useStarredMessagesRoomAction,
- useStartCallRoomAction,
useTeamChannelsRoomAction,
useUploadedFilesListRoomAction,
useVoIPRoomInfoRoomAction,
useWebRTCVideoRoomAction,
useAppsRoomStarActions,
+ useVideoCallRoomAction,
+ useVoiceCallRoomAction,
] satisfies (() => RoomToolboxActionConfig | undefined)[];
export const quickActionHooks = [
diff --git a/apps/meteor/tests/e2e/federation/page-objects/fragments/home-flextab.ts b/apps/meteor/tests/e2e/federation/page-objects/fragments/home-flextab.ts
index 4c62a1199ac07..ad343b5b2a56d 100644
--- a/apps/meteor/tests/e2e/federation/page-objects/fragments/home-flextab.ts
+++ b/apps/meteor/tests/e2e/federation/page-objects/fragments/home-flextab.ts
@@ -44,6 +44,10 @@ export class FederationHomeFlextab {
return this.page.locator('[data-qa-id="ToolBoxAction-phone"]');
}
+ get btnVideoCall(): Locator {
+ return this.page.locator('[role=toolbar][aria-label="Primary Room actions"]').getByRole('button', { name: 'Video call' });
+ }
+
get btnDiscussion(): Locator {
return this.page.locator('[data-qa-id="ToolBoxAction-discussion"]');
}
diff --git a/apps/meteor/tests/e2e/federation/tests/channel/dm.spec.ts b/apps/meteor/tests/e2e/federation/tests/channel/dm.spec.ts
index c724d8a39ded3..4d01e00f76435 100644
--- a/apps/meteor/tests/e2e/federation/tests/channel/dm.spec.ts
+++ b/apps/meteor/tests/e2e/federation/tests/channel/dm.spec.ts
@@ -770,9 +770,11 @@ test.describe.parallel('Federation - Direct Messages', () => {
await poFederationChannelServer1.content.sendMessage('hello world');
await expect(poFederationChannelServer1.tabs.btnCall).toBeDisabled();
+ await expect(poFederationChannelServer1.tabs.btnVideoCall).toBeDisabled();
await poFederationChannelServer2.sidenav.openChat(usernameWithDomainFromServer1);
await expect(poFederationChannelServer2.tabs.btnCall).toBeDisabled();
+ await expect(poFederationChannelServer1.tabs.btnVideoCall).toBeDisabled();
await pageForServer2.close();
});
diff --git a/apps/meteor/tests/e2e/federation/tests/channel/private.spec.ts b/apps/meteor/tests/e2e/federation/tests/channel/private.spec.ts
index 1fcf6882bd393..29570e0372cb1 100644
--- a/apps/meteor/tests/e2e/federation/tests/channel/private.spec.ts
+++ b/apps/meteor/tests/e2e/federation/tests/channel/private.spec.ts
@@ -883,6 +883,8 @@ test.describe.parallel('Federation - Group Creation', () => {
await expect(poFederationChannelServer1.tabs.btnCall).toBeDisabled();
await expect(poFederationChannelServer2.tabs.btnCall).toBeDisabled();
+ await expect(poFederationChannelServer1.tabs.btnVideoCall).toBeDisabled();
+ await expect(poFederationChannelServer2.tabs.btnVideoCall).toBeDisabled();
await pageForServer2.close();
});
diff --git a/apps/meteor/tests/e2e/federation/tests/channel/public.spec.ts b/apps/meteor/tests/e2e/federation/tests/channel/public.spec.ts
index 0c79a309faba6..237a154c0d72c 100644
--- a/apps/meteor/tests/e2e/federation/tests/channel/public.spec.ts
+++ b/apps/meteor/tests/e2e/federation/tests/channel/public.spec.ts
@@ -889,6 +889,8 @@ test.describe.parallel('Federation - Channel Creation', () => {
await expect(poFederationChannelServer1.tabs.btnCall).toBeDisabled();
await expect(poFederationChannelServer2.tabs.btnCall).toBeDisabled();
+ await expect(poFederationChannelServer1.tabs.btnVideoCall).toBeDisabled();
+ await expect(poFederationChannelServer2.tabs.btnVideoCall).toBeDisabled();
await pageForServer2.close();
});
diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts
index cab59e8430693..905be5aa9c530 100644
--- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts
+++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts
@@ -375,12 +375,8 @@ export class HomeContent {
return this.page.locator('[data-qa-id="ToolBoxAction-pause-unfilled"]');
}
- get btnCall(): Locator {
- return this.page.locator('[data-qa-id="ToolBoxAction-phone"]');
- }
-
- get menuItemVideoCall(): Locator {
- return this.page.locator('role=menuitem[name="Video call"]');
+ get btnVideoCall(): Locator {
+ return this.page.locator('[role=toolbar][aria-label="Primary Room actions"]').getByRole('button', { name: 'Video call' });
}
get btnStartVideoCall(): Locator {
diff --git a/apps/meteor/tests/e2e/video-conference-ring.spec.ts b/apps/meteor/tests/e2e/video-conference-ring.spec.ts
index d489e1a258ac0..49b7d15a751a1 100644
--- a/apps/meteor/tests/e2e/video-conference-ring.spec.ts
+++ b/apps/meteor/tests/e2e/video-conference-ring.spec.ts
@@ -34,8 +34,7 @@ test.describe('video conference ringing', () => {
await auxContext.poHomeChannel.sidenav.openChat('user1');
await test.step('should user1 calls user2', async () => {
- await poHomeChannel.content.btnCall.click();
- await poHomeChannel.content.menuItemVideoCall.click();
+ await poHomeChannel.content.btnVideoCall.click();
await poHomeChannel.content.btnStartVideoCall.click();
await expect(poHomeChannel.content.getVideoConfPopupByName('Calling user2')).toBeVisible();
diff --git a/apps/meteor/tests/e2e/video-conference.spec.ts b/apps/meteor/tests/e2e/video-conference.spec.ts
index 63ebdd2966dc0..2c81b7b66159f 100644
--- a/apps/meteor/tests/e2e/video-conference.spec.ts
+++ b/apps/meteor/tests/e2e/video-conference.spec.ts
@@ -29,8 +29,7 @@ test.describe('video conference', () => {
test('expect create video conference in a "targetChannel"', async () => {
await poHomeChannel.sidenav.openChat(targetChannel);
- await poHomeChannel.content.btnCall.click();
- await poHomeChannel.content.menuItemVideoCall.click();
+ await poHomeChannel.content.btnVideoCall.click();
await poHomeChannel.content.btnStartVideoCall.click();
await expect(poHomeChannel.content.videoConfMessageBlock.last()).toBeVisible();
});
@@ -64,8 +63,7 @@ test.describe('video conference', () => {
test('expect create video conference in a direct', async () => {
await poHomeChannel.sidenav.openChat('user2');
- await poHomeChannel.content.btnCall.click();
- await poHomeChannel.content.menuItemVideoCall.click();
+ await poHomeChannel.content.btnVideoCall.click();
await poHomeChannel.content.btnStartVideoCall.click();
await expect(poHomeChannel.content.videoConfMessageBlock.last()).toBeVisible();
});
@@ -81,8 +79,7 @@ test.describe('video conference', () => {
test('expect create video conference in a "targetTeam"', async () => {
await poHomeChannel.sidenav.openChat(targetTeam);
- await poHomeChannel.content.btnCall.click();
- await poHomeChannel.content.menuItemVideoCall.click();
+ await poHomeChannel.content.btnVideoCall.click();
await poHomeChannel.content.btnStartVideoCall.click();
await expect(poHomeChannel.content.videoConfMessageBlock.last()).toBeVisible();
});
@@ -98,8 +95,7 @@ test.describe('video conference', () => {
test('expect create video conference in a direct multiple', async () => {
await poHomeChannel.sidenav.openChat('rocketchat.internal.admin.test, user2');
- await poHomeChannel.content.btnCall.click();
- await poHomeChannel.content.menuItemVideoCall.click();
+ await poHomeChannel.content.btnVideoCall.click();
await poHomeChannel.content.btnStartVideoCall.click();
await expect(poHomeChannel.content.videoConfMessageBlock.last()).toBeVisible();
});
@@ -115,6 +111,6 @@ test.describe('video conference', () => {
test('expect create video conference not available in a "targetReadOnlyChannel"', async () => {
await poHomeChannel.sidenav.openChat(targetReadOnlyChannel);
- await expect(poHomeChannel.content.btnCall).hasAttribute('disabled');
+ await expect(poHomeChannel.content.btnVideoCall).hasAttribute('disabled');
});
});