Skip to content
Merged
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
14 changes: 1 addition & 13 deletions apps/meteor/client/views/room/body/MediaCallRoom.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { isDirectMessageRoom } from '@rocket.chat/core-typings';
import type { PeerInfo } from '@rocket.chat/ui-voip';
import {
MediaCallRoomActivity,
usePeekMediaSessionState,
usePeekMediaSessionPeerInfo,
usePeekMediaSessionFeatures,
} from '@rocket.chat/ui-voip';
import { MediaCallRoomActivity, usePeekMediaSessionState, usePeekMediaSessionPeerInfo } from '@rocket.chat/ui-voip';
import type { ReactNode } from 'react';
import { memo } from 'react';

Expand All @@ -33,15 +28,8 @@ export type MediaCallRoomProps = {
const MediaCallRoom = ({ children }: MediaCallRoomProps) => {
const state = usePeekMediaSessionState();
const peerInfo = usePeekMediaSessionPeerInfo();
const features = usePeekMediaSessionFeatures();
const room = useRoom();

const screenShareEnabled = features.includes('screen-share');

if (!screenShareEnabled) {
return children;
}

if (state !== 'ongoing' || !isMediaCallRoom(room, peerInfo)) {
return children;
}
Expand Down
1 change: 0 additions & 1 deletion apps/meteor/ee/server/settings/voip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export function addSettings(): Promise<void> {
type: 'boolean',
public: true,
invalidValue: false,
alert: 'VoIP_TeamCollab_Screen_Sharing_Enabled_Alert',
i18nDescription: 'VoIP_TeamCollab_Screen_Sharing_Enabled_Description',
});

Expand Down
8 changes: 6 additions & 2 deletions apps/meteor/tests/e2e/page-objects/fragments/voice-calls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class Widget {

private readonly transferModal: TransferModal;

constructor(page: Page) {
constructor(private readonly page: Page) {
this.transferModal = new TransferModal(page, page.getByRole('dialog', { name: 'Transfer call' }));
this.root = page.getByRole('dialog', { name: 'Voice call', exact: false });
this.callControls = new VoiceCallControls(this.root.getByRole('group'));
Expand Down Expand Up @@ -140,7 +140,11 @@ export class Widget {
return timerToSeconds(text);
}

async initiateCall(): Promise<void> {
async initiateCall(username?: string): Promise<void> {
if (username) {
await this.root.getByRole('textbox', { name: 'Enter username or number' }).fill(username);
await this.page.getByRole('listbox').getByRole('option', { name: username }).click();
Comment thread
gabriellsh marked this conversation as resolved.
}
await this.callControls.call.click();
await expect(this.callControls.cancel).toBeVisible();
}
Expand Down
40 changes: 14 additions & 26 deletions apps/meteor/tests/e2e/voice-calls-ee.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,10 @@ test.describe('Internal Voice Calls - Enterprise Edition', () => {
test('should initiate voice call from direct message', async () => {
const [user1, user2] = sessions;

await test.step('should open direct message with user2', async () => {
await user1.poHomeChannel.navbar.openChat('user2');
await expect(user1.poHomeChannel.composer.inputMessage).toBeVisible();
});

await test.step('initiate a voice call from room toolbar', async () => {
await user1.poHomeChannel.content.btnVoiceCall.click();
await test.step('establish call connection', async () => {
await user1.poHomeChannel.navbar.btnNewVoiceCall.click();
Comment thread
gabriellsh marked this conversation as resolved.
await expect(user1.poHomeChannel.voiceCalls.widget.content).toBeVisible();
await user1.poHomeChannel.voiceCalls.widget.initiateCall();
await user1.poHomeChannel.voiceCalls.widget.initiateCall(Users.user2.data.username);
});

await test.step('user2 accepts the call', async () => {
Expand All @@ -59,37 +54,34 @@ test.describe('Internal Voice Calls - Enterprise Edition', () => {
test('should handle call controls during active call', async () => {
const [user1, user2] = sessions;
await test.step('establish call connection', async () => {
await user1.poHomeChannel.navbar.openChat('user2');
await expect(user1.poHomeChannel.composer.inputMessage).toBeVisible();
await user1.poHomeChannel.content.btnVoiceCall.click();
await user1.poHomeChannel.voiceCalls.widget.initiateCall();
await user1.poHomeChannel.navbar.btnNewVoiceCall.click();
await user1.poHomeChannel.voiceCalls.widget.initiateCall(Users.user2.data.username);
await user2.poHomeChannel.voiceCalls.widget.acceptCall();
});

await test.step('should mute/unmute microphone from user1', async () => {
// User1 mutes microphone
await user1.poHomeChannel.voiceCalls.widget.muteSelf();

// User1 unmutes microphone
await user1.poHomeChannel.voiceCalls.widget.unmuteSelf();
});

await test.step('should put call on hold from user1', async () => {
// User1 puts call on hold
await user1.poHomeChannel.voiceCalls.widget.holdSelf();

// User1 resumes call
await user1.poHomeChannel.voiceCalls.widget.resumeSelf();
});

await test.step('should access dialpad during call', async () => {
// User1 opens dial pad
await user1.poHomeChannel.voiceCalls.widget.openDialpad();

// User1 closes dial pad
await user1.poHomeChannel.voiceCalls.widget.closeDialpad();
});

await test.step('should not display screen share button', async () => {
await expect(user1.poHomeChannel.voiceCalls.widget.controls.shareScreen).not.toBeVisible();
await expect(user2.poHomeChannel.voiceCalls.widget.controls.shareScreen).not.toBeVisible();
});

await test.step('should end the call from user1', async () => {
await user1.poHomeChannel.voiceCalls.widget.endCall();
await expect(user2.poHomeChannel.voiceCalls.widget.content).not.toBeVisible();
Expand All @@ -106,10 +98,8 @@ test.describe('Internal Voice Calls - Enterprise Edition', () => {
const user3 = { page: user3Context.page, poHomeChannel: new HomeChannel(user3Context.page) };

await test.step('establish call between user1 and user2', async () => {
await user1.poHomeChannel.navbar.openChat('user2');
await expect(user1.poHomeChannel.composer.inputMessage).toBeVisible();
await user1.poHomeChannel.content.btnVoiceCall.click();
await user1.poHomeChannel.voiceCalls.widget.initiateCall();
await user1.poHomeChannel.navbar.btnNewVoiceCall.click();
await user1.poHomeChannel.voiceCalls.widget.initiateCall(Users.user2.data.username);
await user2.poHomeChannel.voiceCalls.widget.acceptCall();
});

Expand Down Expand Up @@ -139,10 +129,8 @@ test.describe('Internal Voice Calls - Enterprise Edition', () => {
const [user1, user2] = sessions;

await test.step('user1 initiates call to user2', async () => {
await user1.poHomeChannel.navbar.openChat('user2');
await expect(user1.poHomeChannel.composer.inputMessage).toBeVisible();
await user1.poHomeChannel.content.btnVoiceCall.click();
await user1.poHomeChannel.voiceCalls.widget.initiateCall();
await user1.poHomeChannel.navbar.btnNewVoiceCall.click();
await user1.poHomeChannel.voiceCalls.widget.initiateCall(Users.user2.data.username);
});

await test.step('user2 declines the call', async () => {
Expand Down
2 changes: 0 additions & 2 deletions packages/i18n/src/locales/de.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,6 @@
"Call_ended_bold": "*Sprachanruf beendet*",
"Call_not_answered_bold": "*Sprachanruf nicht angenommen*",
"Call_failed_bold": "*Sprachanruf fehlgeschlagen*",
"Call_feature_unsupported": "Die Gegenseite unterstützt dies nicht",
"Call_transferred_bold": "*Sprachanruf weitergeleitet*",
"Call_history": "Anrufverlauf",
"Call_history_provides_a_record_of_when_calls_took_place_and_who_joined": "In der Anrufliste wird festgehalten, wann Anrufe getätigt wurden und wer daran teilgenommen hat.",
Expand Down Expand Up @@ -5930,7 +5929,6 @@
"VoIP_TeamCollab_Mobile_Ringing_Enabled_Description": "Ermöglicht Benutzern, Anrufe in der mobilen App zu tätigen und zu empfangen.",
"VoIP_TeamCollab_Screen_Sharing_Enabled": "Bildschirmfreigabe",
"VoIP_TeamCollab_Screen_Sharing_Enabled_Description": "Ermöglicht Benutzern, ihren Bildschirm während Sprachanrufen freizugeben.",
"VoIP_TeamCollab_Screen_Sharing_Enabled_Alert": "Die Bildschirmfreigabe befindet sich derzeit in der Beta-Phase.",
"VoIP_TeamCollab_Internal_SIP_Beta_Alert": "Das Weiterleiten interner Anrufe über SIP befindet sich in der Beta-Phase und wird nicht für den Produktiveinsatz empfohlen.",
"VoIP_TeamCollab_Drachtio_Host": "Drachtio-Host",
"VoIP_TeamCollab_Drachtio_Port": "Drachtio-Port",
Expand Down
2 changes: 0 additions & 2 deletions packages/i18n/src/locales/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,6 @@
"Call_ended_bold": "*Voice call ended*",
"Call_not_answered_bold": "*Voice call not answered*",
"Call_failed_bold": "*Voice call failed*",
"Call_feature_unsupported": "Other party doesn't support this",
"Call_transferred_bold": "*Voice call transferred*",
"Call_history": "Call history",
"Call_history_provides_a_record_of_when_calls_took_place_and_who_joined": "Call history provides a record of when calls took place and who joined.",
Expand Down Expand Up @@ -6060,7 +6059,6 @@
"VoIP_TeamCollab_Mobile_Ringing_Enabled_Description": "Allow users to make and receive calls on the mobile app.",
"VoIP_TeamCollab_Screen_Sharing_Enabled": "Screen sharing",
"VoIP_TeamCollab_Screen_Sharing_Enabled_Description": "Allow users to share their screen during voice calls.",
"VoIP_TeamCollab_Screen_Sharing_Enabled_Alert": "Screen sharing is currently in beta.",
"VoIP_TeamCollab_Internal_SIP_Beta_Alert": "Routing of internal calls through SIP is in beta and is not recommended for production use.",
"VoIP_TeamCollab_Drachtio_Host": "Drachtio Host",
"VoIP_TeamCollab_Drachtio_Port": "Drachtio Port",
Expand Down
2 changes: 0 additions & 2 deletions packages/i18n/src/locales/pt-BR.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,6 @@
"Call_ended_bold": "*Chamada de voz encerrada*",
"Call_not_answered_bold": "*Chamada de voz não atendida*",
"Call_failed_bold": "*Falha na chamada de voz*",
"Call_feature_unsupported": "A outra parte não suporta isso",
"Call_transferred_bold": "*Chamada de voz transferida*",
"Call_history": "Histórico de chamadas",
"Call_history_provides_a_record_of_when_calls_took_place_and_who_joined": "O histórico de chamadas fornece um registro de quando as chamadas foram realizadas e quem participou.",
Expand Down Expand Up @@ -5875,7 +5874,6 @@
"VoIP_TeamCollab_Mobile_Ringing_Enabled_Description": "Permitir que os usuários façam e recebam chamadas no aplicativo móvel.",
"VoIP_TeamCollab_Screen_Sharing_Enabled": "Compartilhamento de tela",
"VoIP_TeamCollab_Screen_Sharing_Enabled_Description": "Permitir que os usuários compartilhem a tela durante as chamadas de voz.",
"VoIP_TeamCollab_Screen_Sharing_Enabled_Alert": "O compartilhamento de tela está atualmente na versão beta.",
"VoIP_TeamCollab_Internal_SIP_Beta_Alert": "O roteamento de chamadas internas por SIP está em fase beta e não é recomendado para uso em produção.",
"VoIP_TeamCollab_Drachtio_Host": "Host do Drachtio",
"VoIP_TeamCollab_Drachtio_Port": "Porta do Drachtio",
Expand Down
2 changes: 0 additions & 2 deletions packages/i18n/src/locales/sv.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,6 @@
"Call_ended_bold": "*Röstsamtal avslutad*",
"Call_not_answered_bold": "*Röstsamtal besvarades inte*",
"Call_failed_bold": "*Röstsamtal misslyckades*",
"Call_feature_unsupported": "Andra parten stöder inte detta",
"Call_transferred_bold": "*Röstsamtal överfördes*",
"Call_history": "Samtalhistorik",
"Call_history_provides_a_record_of_when_calls_took_place_and_who_joined": "I samtalshistoriken samlas information om när samtal ägt rum och vilka som deltog.",
Expand Down Expand Up @@ -5858,7 +5857,6 @@
"VoIP_TeamCollab_Mobile_Ringing_Enabled_Description": "Tillåt användare att göra och ta emot samtal i mobilappen.",
"VoIP_TeamCollab_Screen_Sharing_Enabled": "Skärmdelning",
"VoIP_TeamCollab_Screen_Sharing_Enabled_Description": "Tillåt användare att dela sin skärm under röstsamtal.",
"VoIP_TeamCollab_Screen_Sharing_Enabled_Alert": "Skärmdelning är för närvarande i beta.",
"VoIP_TeamCollab_Internal_SIP_Beta_Alert": "Routning av interna samtal genom SIP är i beta och rekommenderas inte för produktionsanvändning.",
"VoIP_TeamCollab_Drachtio_Host": "Drachtio Host",
"VoIP_TeamCollab_Drachtio_Port": "Drachtio Port",
Expand Down
6 changes: 5 additions & 1 deletion packages/ui-voip/src/providers/MockedMediaCallProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { UserStatus } from '@rocket.chat/core-typings';
import type { CallFeature } from '@rocket.chat/media-signaling';
import { callFeatureList } from '@rocket.chat/media-signaling';
import type { ReactNode } from 'react';
import { useState } from 'react';

Expand All @@ -18,6 +20,7 @@ export type MockedMediaCallProviderProps = {
held?: boolean;
onClickDirectMessage?: () => void;
instanceProps?: Partial<MockedInstanceProviderProps>;
supportedFeatures?: readonly CallFeature[];
};

const MockedMediaCallProvider = ({
Expand All @@ -31,6 +34,7 @@ const MockedMediaCallProvider = ({
muted = false,
held = false,
instanceProps,
supportedFeatures = callFeatureList,
}: MockedMediaCallProviderProps) => {
const [peerInfo, setPeerInfo] = useState<PeerInfo | undefined>({
displayName: 'John Doe',
Expand Down Expand Up @@ -122,7 +126,7 @@ const MockedMediaCallProvider = ({
remoteMuted,
remoteHeld,
callId: undefined,
supportedFeatures: ['audio', 'screen-share', 'transfer', 'hold'],
supportedFeatures,
} as SessionState;

const contextValue = {
Expand Down
38 changes: 22 additions & 16 deletions packages/ui-voip/src/views/MediaCallPopoutView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const MediaCallPopoutView = ({ user, onClickClosePopout }: MediaCallPopoutViewPr
streams: { localScreen },
} = useMediaCallView();

const { muted, held, peerInfo, connectionState, startedAt } = sessionState;
const { muted, held, peerInfo, connectionState, startedAt, supportedFeatures } = sessionState;

const { ref, borderBoxSize } = useResizeObserver<HTMLDivElement>();

Expand Down Expand Up @@ -82,21 +82,27 @@ const MediaCallPopoutView = ({ user, onClickClosePopout }: MediaCallPopoutViewPr
}
>
<ToggleButton label={t('Mute')} icons={['mic', 'mic-off']} titles={[t('Mute'), t('Unmute')]} pressed={muted} onToggle={onMute} />
<ToggleButton
label={t('Hold')}
icons={['pause-shape-unfilled', 'pause-shape-unfilled']}
titles={[t('Hold'), t('Resume')]}
pressed={held}
onToggle={onHold}
/>
<ToggleButton
label={t('Share_screen')}
icons={['desktop-arrow-up', 'desktop-cross']}
titles={[t('Share_screen'), t('Stop_sharing_screen')]}
pressed={localScreen?.active ?? false}
onToggle={onToggleScreenSharing}
/>
<ActionButton disabled={connecting || reconnecting} label={t('Forward')} icon='arrow-forward' onClick={onForward} />
{supportedFeatures.includes('hold') && (
<ToggleButton
label={t('Hold')}
icons={['pause-shape-unfilled', 'pause-shape-unfilled']}
titles={[t('Hold'), t('Resume')]}
pressed={held}
onToggle={onHold}
/>
)}
{supportedFeatures.includes('screen-share') && (
<ToggleButton
label={t('Share_screen')}
icons={['desktop-arrow-up', 'desktop-cross']}
titles={[t('Share_screen'), t('Stop_sharing_screen')]}
pressed={localScreen?.active ?? false}
onToggle={onToggleScreenSharing}
/>
)}
{supportedFeatures.includes('transfer') && (
<ActionButton disabled={connecting || reconnecting} label={t('Forward')} icon='arrow-forward' onClick={onForward} />
)}
<ActionButton label={t('Voice_call__user__hangup', { user: peerInfo.displayName })} icon='phone-off' danger onClick={onEndCall} />
</ActionStrip>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const MediaCallRoomSection = ({ showChat, onToggleChat, user, containerHeight }:

const isPopout = currentViews.has('popout');

const { muted, held, peerInfo, connectionState, startedAt } = sessionState;
const { muted, held, peerInfo, connectionState, startedAt, supportedFeatures } = sessionState;

const shouldWrapCards = useShouldWrapCards(showChat, containerHeight);

Expand All @@ -69,6 +69,10 @@ const MediaCallRoomSection = ({ showChat, onToggleChat, user, containerHeight }:

useRegisterView('room');

const screenShareAvailable = supportedFeatures.includes('screen-share');
const holdAvailable = supportedFeatures.includes('hold');
const transferAvailable = supportedFeatures.includes('transfer');

if (!peerInfo || 'number' in peerInfo) {
return null;
}
Expand Down Expand Up @@ -108,21 +112,27 @@ const MediaCallRoomSection = ({ showChat, onToggleChat, user, containerHeight }:
}
>
<ToggleButton label={t('Mute')} icons={['mic', 'mic-off']} titles={[t('Mute'), t('Unmute')]} pressed={muted} onToggle={onMute} />
<ToggleButton
label={t('Hold')}
icons={['pause-shape-unfilled', 'pause-shape-unfilled']}
titles={[t('Hold'), t('Resume')]}
pressed={held}
onToggle={onHold}
/>
<ToggleButton
label={t('Share_screen')}
icons={['desktop-arrow-up', 'desktop-cross']}
titles={[t('Share_screen'), t('Stop_sharing_screen')]}
pressed={localScreen?.active ?? false}
onToggle={onToggleScreenSharing}
/>
<ActionButton disabled={connecting || reconnecting} label={t('Forward')} icon='arrow-forward' onClick={onForward} />
{holdAvailable && (
<ToggleButton
label={t('Hold')}
icons={['pause-shape-unfilled', 'pause-shape-unfilled']}
titles={[t('Hold'), t('Resume')]}
pressed={held}
onToggle={onHold}
/>
)}
{screenShareAvailable && (
<ToggleButton
label={t('Share_screen')}
icons={['desktop-arrow-up', 'desktop-cross']}
titles={[t('Share_screen'), t('Stop_sharing_screen')]}
pressed={localScreen?.active ?? false}
onToggle={onToggleScreenSharing}
/>
)}
{transferAvailable && (
<ActionButton disabled={connecting || reconnecting} label={t('Forward')} icon='arrow-forward' onClick={onForward} />
)}
<ActionButton label={t('Voice_call__user__hangup', { user: peerInfo.displayName })} icon='phone-off' danger onClick={onEndCall} />
</ActionStrip>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,17 @@ export const OngoingCallConnecting: Story = {
connectionState: 'CONNECTING',
},
};

export const OngoingCallDisabledAllFeatures: Story = {
args: {
state: 'ongoing',
supportedFeatures: [],
},
};

export const OngoingCallDisabledAllButScreenshare: Story = {
args: {
state: 'ongoing',
supportedFeatures: ['screen-share'],
},
};
Loading
Loading