Skip to content

Commit c309073

Browse files
chore: disable Transfer Call button when the opposite client doesn't support being transferred (#39486)
1 parent 4aba0b0 commit c309073

18 files changed

Lines changed: 62 additions & 26 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import type { CallFeature } from '@rocket.chat/media-signaling';
2+
3+
export const DEFAULT_CALL_FEATURES: CallFeature[] = ['audio'];
4+
export const SIP_CALL_FEATURES: CallFeature[] = ['audio', 'transfer', 'hold'];

ee/packages/media-calls/src/definition/common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type InternalCallParams = {
1515
requestedService?: CallService;
1616
parentCallId?: string;
1717
requestedBy?: MediaCallSignedContact;
18-
features?: CallFeature[];
18+
features: CallFeature[];
1919
};
2020

2121
export type MediaCallHeader = AtLeast<IMediaCall, '_id' | 'caller' | 'callee'>;

ee/packages/media-calls/src/internal/SignalProcessor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {
1010
} from '@rocket.chat/media-signaling';
1111
import { MediaCalls } from '@rocket.chat/models';
1212

13+
import { DEFAULT_CALL_FEATURES } from '../constants';
1314
import type { InternalCallParams } from '../definition/common';
1415
import { logger } from '../logger';
1516
import { mediaCallDirector } from '../server/CallDirector';
@@ -180,7 +181,7 @@ export class GlobalSignalProcessor {
180181

181182
const services = signal.supportedServices ?? [];
182183
const requestedService = services.includes('webrtc') ? 'webrtc' : services[0];
183-
const features = signal.supportedFeatures ?? ['audio'];
184+
const features = signal.supportedFeatures ?? DEFAULT_CALL_FEATURES;
184185

185186
const params: InternalCallParams = {
186187
caller: {

ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type {
2020
} from '@rocket.chat/media-signaling';
2121
import { MediaCallChannels, MediaCallNegotiations, MediaCalls } from '@rocket.chat/models';
2222

23+
import { DEFAULT_CALL_FEATURES } from '../../constants';
2324
import type { IMediaCallAgent } from '../../definition/IMediaCallAgent';
2425
import { logger } from '../../logger';
2526
import { mediaCallDirector } from '../../server/CallDirector';
@@ -137,7 +138,7 @@ export class UserActorSignalProcessor {
137138
case 'ack':
138139
return this.clientIsReachable();
139140
case 'accept':
140-
return this.clientHasAccepted(signal.supportedFeatures || ['audio']);
141+
return this.clientHasAccepted(signal.supportedFeatures || DEFAULT_CALL_FEATURES);
141142
case 'unavailable':
142143
return this.clientIsUnavailable();
143144
case 'reject':

ee/packages/media-calls/src/internal/agents/UserActorAgent.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ export class UserActorAgent extends BaseMediaCallAgent {
151151
requestedService: call.service,
152152
requestedBy: call.transferredBy,
153153
parentCallId: call._id,
154+
features: call.features as CallFeature[],
154155
});
155156
}
156157

ee/packages/media-calls/src/server/CallDirector.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { InsertionModel } from '@rocket.chat/model-typings';
1111
import { MediaCallNegotiations, MediaCalls } from '@rocket.chat/models';
1212

1313
import { getCastDirector, getMediaCallServer } from './injection';
14+
import { DEFAULT_CALL_FEATURES } from '../constants';
1415
import type { IMediaCallAgent } from '../definition/IMediaCallAgent';
1516
import type { IMediaCallCastDirector } from '../definition/IMediaCallCastDirector';
1617
import type { InternalCallParams, MediaCallHeader } from '../definition/common';
@@ -79,7 +80,7 @@ class MediaCallDirector {
7980
this.scheduleExpirationCheckByCallId(call._id);
8081

8182
const updatedCall = await MediaCalls.findOneById(call._id, { projection: { features: 1 } });
82-
const features = (updatedCall?.features || ['audio']) as CallFeature[];
83+
const features = (updatedCall?.features || DEFAULT_CALL_FEATURES) as CallFeature[];
8384

8485
await calleeAgent.onCallAccepted(call._id, { signedContractId: data.calleeContractId, features });
8586
await calleeAgent.oppositeAgent?.onCallAccepted(call._id, { signedContractId: call.caller.contractId, features });
@@ -177,17 +178,7 @@ class MediaCallDirector {
177178
}
178179

179180
public async createCall(params: CreateCallParams): Promise<IMediaCall> {
180-
const {
181-
caller,
182-
callee,
183-
requestedCallId,
184-
requestedService,
185-
callerAgent,
186-
calleeAgent,
187-
parentCallId,
188-
requestedBy,
189-
features = ['audio'],
190-
} = params;
181+
const { caller, callee, requestedCallId, requestedService, callerAgent, calleeAgent, parentCallId, requestedBy, features } = params;
191182

192183
// The caller must always have a contract to create the call
193184
if (!caller.contractId) {

ee/packages/media-calls/src/sip/providers/IncomingSipCall.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { SipMessage, SrfRequest, SrfResponse } from 'drachtio-srf';
1111
import type Srf from 'drachtio-srf';
1212

1313
import { BaseSipCall } from './BaseSipCall';
14+
import { SIP_CALL_FEATURES } from '../../constants';
1415
import { logger } from '../../logger';
1516
import { BroadcastActorAgent } from '../../server/BroadcastAgent';
1617
import { mediaCallDirector } from '../../server/CallDirector';
@@ -103,6 +104,7 @@ export class IncomingSipCall extends BaseSipCall {
103104
callee,
104105
callerAgent,
105106
calleeAgent,
107+
features: SIP_CALL_FEATURES,
106108
});
107109

108110
const negotiationId = await mediaCallDirector.startNewNegotiation(call, 'caller', webrtcOffer);

ee/packages/media-calls/src/sip/providers/OutgoingSipCall.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type Srf from 'drachtio-srf';
55
import type { SrfRequest, SrfResponse } from 'drachtio-srf';
66

77
import { BaseSipCall } from './BaseSipCall';
8+
import { SIP_CALL_FEATURES } from '../../constants';
89
import type { InternalCallParams } from '../../definition/common';
910
import { logger } from '../../logger';
1011
import { BroadcastActorAgent } from '../../server/BroadcastAgent';
@@ -72,7 +73,7 @@ export class OutgoingSipCall extends BaseSipCall {
7273
callee: signedCallee,
7374
calleeAgent,
7475
callerAgent,
75-
features: ['audio'],
76+
features: SIP_CALL_FEATURES,
7677
});
7778

7879
const channel = await calleeAgent.getOrCreateChannel(call, session.sessionId);
@@ -267,7 +268,7 @@ export class OutgoingSipCall extends BaseSipCall {
267268
await mediaCallDirector.acceptCall(call, this.agent, {
268269
calleeContractId: this.session.sessionId,
269270
webrtcAnswer: { type: 'answer', sdp: this.sipDialog.remote.sdp },
270-
supportedFeatures: ['audio'],
271+
supportedFeatures: SIP_CALL_FEATURES,
271272
});
272273
}
273274

packages/i18n/src/locales/en.i18n.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@
990990
"Call_ended_bold": "*Voice call ended*",
991991
"Call_not_answered_bold": "*Voice call not answered*",
992992
"Call_failed_bold": "*Voice call failed*",
993+
"Call_feature_unsupported": "Other party doesn't support this",
993994
"Call_transferred_bold": "*Voice call transferred*",
994995
"Call_history": "Call history",
995996
"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.",

packages/media-signaling/src/definition/call/IClientMediaCall.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export type CallRole = 'caller' | 'callee';
1919

2020
export type CallService = 'webrtc';
2121

22-
export const callFeatureList = ['audio'] as const;
22+
export const callFeatureList = ['audio', 'transfer', 'hold'] as const;
2323

2424
export type CallFeature = (typeof callFeatureList)[number];
2525

@@ -80,6 +80,7 @@ export interface IClientMediaCall {
8080
role: CallRole;
8181
service: CallService | null;
8282
flags: readonly CallFlag[];
83+
features: readonly CallFeature[];
8384

8485
state: CallState;
8586
ignored: boolean;

0 commit comments

Comments
 (0)