Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardmute - Integrate new change from web sdk #5437

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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 packages/calling-component-bindings/src/baseSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { _SupportedCaptionLanguage, _SupportedSpokenLanguage } from '@internal/r
import { ConferencePhoneInfo } from '@internal/calling-stateful-client';
/* @conditional-compile-remove(breakout-rooms) */
import { CallNotifications } from '@internal/calling-stateful-client';
/* @conditional-compile-remove(media-access) */
import { CapabilitiesChangeInfo } from '@azure/communication-calling';

/**
* Common props used to reference calling declarative client state.
Expand Down Expand Up @@ -63,6 +65,17 @@ export const getCapabilities = (
props: CallingBaseSelectorProps
): ParticipantCapabilities | undefined => state.calls[props.callId]?.capabilitiesFeature?.capabilities;

/* @conditional-compile-remove(media-access) */
/**
* @private
*/
export const getLatestCapabilitiesChangedInfo = (
state: CallClientState,
props: CallingBaseSelectorProps
): CapabilitiesChangeInfo | undefined => {
return state.calls[props.callId]?.capabilitiesFeature?.latestCapabilitiesChangeInfo;
};

/**
* @private
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,62 @@ export interface CommonCallingHandlers {
*/
onDisposeTogetherModeStreamViews: () => Promise<void>;
/* @conditional-compile-remove(media-access) */
onForbidParticipantAudio?: (userIds: string[]) => Promise<void>;
/**
* Forbid remote participants from sending audio
*
* @beta
*/
onForbidAudio?: (userIds: string[]) => Promise<void>;
/* @conditional-compile-remove(media-access) */
onPermitParticipantAudio?: (userIds: string[]) => Promise<void>;
/**
* Permit remote participants to send audio
*
* @beta
*/
onPermitAudio?: (userIds: string[]) => Promise<void>;
/* @conditional-compile-remove(media-access) */
onForbidRemoteParticipantsAudio?: () => Promise<void>;
/**
* Change meeting option forbid remote participants from sending audio
*
* @beta
*/
onForbidOthersAudio?: () => Promise<void>;
/* @conditional-compile-remove(media-access) */
onPermitRemoteParticipantsAudio?: () => Promise<void>;
/**
* Change meeting option permit remote participants to send audio
*
* @beta
*/
onPermitOthersAudio?: () => Promise<void>;

/* @conditional-compile-remove(media-access) */
onForbidParticipantVideo?: (userIds: string[]) => Promise<void>;
/**
* Forbid remote participants from sending video
*
* @beta
*/
onForbidVideo?: (userIds: string[]) => Promise<void>;
/* @conditional-compile-remove(media-access) */
onPermitParticipantVideo?: (userIds: string[]) => Promise<void>;
/**
* Permit remote participants to send video
*
* @beta
*/
onPermitVideo?: (userIds: string[]) => Promise<void>;
/* @conditional-compile-remove(media-access) */
onForbidRemoteParticipantsVideo?: () => Promise<void>;
/**
* Change meeting option forbid remote participants from sending video
*
* @beta
*/
onForbidOthersVideo?: () => Promise<void>;
/* @conditional-compile-remove(media-access) */
onPermitRemoteParticipantsVideo?: () => Promise<void>;
/**
* Change meeting option permit remote participants to send video
*
* @beta
*/
onPermitOthersVideo?: () => Promise<void>;
}

/**
Expand Down Expand Up @@ -811,41 +851,41 @@ export const createDefaultCommonCallingHandlers = memoizeOne(
}
};
/* @conditional-compile-remove(media-access) */
const onForbidParticipantAudio = async (userIds: string[]): Promise<void> => {
const onForbidAudio = async (userIds: string[]): Promise<void> => {
const participants = userIds?.map((userId) => _toCommunicationIdentifier(userId));
await call?.feature(Features.MediaAccess).forbidAudio(participants);
};
/* @conditional-compile-remove(media-access) */
const onPermitParticipantAudio = async (userIds: string[]): Promise<void> => {
const onPermitAudio = async (userIds: string[]): Promise<void> => {
const participants = userIds?.map((userId) => _toCommunicationIdentifier(userId));
await call?.feature(Features.MediaAccess).permitAudio(participants);
};
/* @conditional-compile-remove(media-access) */
const onForbidRemoteParticipantsAudio = async (): Promise<void> => {
await call?.feature(Features.MediaAccess).forbidRemoteParticipantsAudio();
const onForbidOthersAudio = async (): Promise<void> => {
await call?.feature(Features.MediaAccess).forbidOthersAudio();
};
/* @conditional-compile-remove(media-access) */
const onPermitRemoteParticipantsAudio = async (): Promise<void> => {
await call?.feature(Features.MediaAccess).permitRemoteParticipantsAudio();
const onPermitOthersAudio = async (): Promise<void> => {
await call?.feature(Features.MediaAccess).permitOthersAudio();
};

/* @conditional-compile-remove(media-access) */
const onForbidParticipantVideo = async (userIds: string[]): Promise<void> => {
const onForbidVideo = async (userIds: string[]): Promise<void> => {
const participants = userIds?.map((userId) => _toCommunicationIdentifier(userId));
await call?.feature(Features.MediaAccess).forbidVideo(participants);
};
/* @conditional-compile-remove(media-access) */
const onPermitParticipantVideo = async (userIds: string[]): Promise<void> => {
const onPermitVideo = async (userIds: string[]): Promise<void> => {
const participants = userIds?.map((userId) => _toCommunicationIdentifier(userId));
await call?.feature(Features.MediaAccess).permitVideo(participants);
};
/* @conditional-compile-remove(media-access) */
const onForbidRemoteParticipantsVideo = async (): Promise<void> => {
await call?.feature(Features.MediaAccess).forbidRemoteParticipantsVideo();
const onForbidOthersVideo = async (): Promise<void> => {
await call?.feature(Features.MediaAccess).forbidOthersVideo();
};
/* @conditional-compile-remove(media-access) */
const onPermitRemoteParticipantsVideo = async (): Promise<void> => {
await call?.feature(Features.MediaAccess).permitRemoteParticipantsVideo();
const onPermitOthersVideo = async (): Promise<void> => {
await call?.feature(Features.MediaAccess).permitOthersVideo();
};
return {
onHangUp,
Expand Down Expand Up @@ -906,21 +946,21 @@ export const createDefaultCommonCallingHandlers = memoizeOne(
/* @conditional-compile-remove(together-mode) */
onSetTogetherModeSceneSize,
/* @conditional-compile-remove(media-access) */
onForbidParticipantAudio,
onForbidAudio,
/* @conditional-compile-remove(media-access) */
onPermitParticipantAudio,
onPermitAudio,
/* @conditional-compile-remove(media-access) */
onForbidRemoteParticipantsAudio,
onForbidOthersAudio,
/* @conditional-compile-remove(media-access) */
onPermitRemoteParticipantsAudio,
onPermitOthersAudio,
/* @conditional-compile-remove(media-access) */
onForbidParticipantVideo,
onForbidVideo,
/* @conditional-compile-remove(media-access) */
onPermitParticipantVideo,
onPermitVideo,
/* @conditional-compile-remove(media-access) */
onForbidRemoteParticipantsVideo,
onForbidOthersVideo,
/* @conditional-compile-remove(media-access) */
onPermitRemoteParticipantsVideo
onPermitOthersVideo
};
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { createSelector } from 'reselect';
import { CallClientState, CallErrors, CallErrorTarget } from '@internal/calling-stateful-client';

import { DiagnosticQuality } from '@azure/communication-calling';
/* @conditional-compile-remove(media-access) */
import { CallNotifications } from '@internal/calling-stateful-client';

/**
* Selector type for {@link Notification} component.
Expand Down Expand Up @@ -180,7 +182,7 @@ export const notificationStackSelector: NotificationStackSelector = createSelect
}

appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.unmute', 'unmuteGeneric');
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.mutedByOthers', 'mutedByRemoteParticipant');
appendMuteByOthersNotificationTrampoline(latestNotifications, activeErrorMessages, latestErrors);
appendActiveErrorIfDefined(
activeErrorMessages,
latestErrors,
Expand Down Expand Up @@ -258,6 +260,39 @@ export const notificationStackSelector: NotificationStackSelector = createSelect
timestamp: latestNotifications['breakoutRoomClosingSoon'].timestamp
});
}

/* @conditional-compile-remove(media-access) */
if (latestNotifications['capabilityTurnVideoOnPresent']) {
activeNotifications.push({
type: 'capabilityTurnVideoOnPresent',
timestamp: latestNotifications['capabilityTurnVideoOnPresent'].timestamp
});
}

/* @conditional-compile-remove(media-access) */
if (latestNotifications['capabilityTurnVideoOnAbsent']) {
activeNotifications.push({
type: 'capabilityTurnVideoOnAbsent',
timestamp: latestNotifications['capabilityTurnVideoOnAbsent'].timestamp
});
}

/* @conditional-compile-remove(media-access) */
if (latestNotifications['capabilityUnmuteMicPresent']) {
activeNotifications.push({
type: 'capabilityUnmuteMicPresent',
timestamp: latestNotifications['capabilityUnmuteMicPresent'].timestamp
});
}

/* @conditional-compile-remove(media-access) */
if (latestNotifications['capabilityUnmuteMicAbsent']) {
activeNotifications.push({
type: 'capabilityUnmuteMicAbsent',
timestamp: latestNotifications['capabilityUnmuteMicAbsent'].timestamp
});
}

return { activeErrorMessages: activeErrorMessages, activeNotifications: activeNotifications };
}
);
Expand All @@ -276,3 +311,18 @@ const appendActiveErrorIfDefined = (
timestamp: latestErrors[target].timestamp
});
};

const appendMuteByOthersNotificationTrampoline = (
latestNotifications: CallNotifications,
activeErrorMessages: ActiveNotification[],
latestErrors: CallErrors
): void => {
/* @conditional-compile-remove(media-access) */
if (!latestNotifications['capabilityUnmuteMicAbsent'] && !latestNotifications['capabilityUnmuteMicPresent']) {
appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.mutedByOthers', 'mutedByRemoteParticipant');
}
/* @conditional-compile-remove(media-access) */
return;

appendActiveErrorIfDefined(activeErrorMessages, latestErrors, 'Call.mutedByOthers', 'mutedByRemoteParticipant');
};
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ export const _videoGalleryRemoteParticipantsMemo: _VideoGalleryRemoteParticipant
(participant.diagnostics?.networkSendQuality?.value ?? 0) as number
),
/* @conditional-compile-remove(media-access) */
participant.mediaAccess
participant.mediaAccess,
/* @conditional-compile-remove(media-access) */
participant.role
);
})
);
Expand All @@ -105,7 +107,8 @@ const memoizedAllConvertRemoteParticipant = memoizeFnAll(
spotlight?: Spotlight,
/* @conditional-compile-remove(remote-ufd) */
signalStrength?: number,
mediaAccess?: undefined | /* @conditional-compile-remove(media-access) */ MediaAccess
mediaAccess?: undefined | /* @conditional-compile-remove(media-access) */ MediaAccess,
role?: undefined | /* @conditional-compile-remove(media-access) */ ParticipantRole
): VideoGalleryRemoteParticipant => {
return convertRemoteParticipantToVideoGalleryRemoteParticipant(
userId,
Expand All @@ -121,7 +124,9 @@ const memoizedAllConvertRemoteParticipant = memoizeFnAll(
/* @conditional-compile-remove(remote-ufd) */
signalStrength,
/* @conditional-compile-remove(media-access) */
mediaAccess
mediaAccess,
/* @conditional-compile-remove(media-access) */
role
);
}
);
Expand All @@ -140,7 +145,8 @@ export const convertRemoteParticipantToVideoGalleryRemoteParticipant = (
spotlight?: Spotlight,
/* @conditional-compile-remove(remote-ufd) */
signalStrength?: number,
mediaAccess?: undefined | /* @conditional-compile-remove(media-access) */ MediaAccess
mediaAccess?: undefined | /* @conditional-compile-remove(media-access) */ MediaAccess,
role?: undefined | /* @conditional-compile-remove(media-access) */ ParticipantRole
): VideoGalleryRemoteParticipant => {
const rawVideoStreamsArray = Object.values(videoStreams);
let videoStream: VideoGalleryStream | undefined = undefined;
Expand Down Expand Up @@ -187,7 +193,9 @@ export const convertRemoteParticipantToVideoGalleryRemoteParticipant = (
/* @conditional-compile-remove(remote-ufd) */
signalStrength,
/* @conditional-compile-remove(media-access) */
mediaAccess
mediaAccess,
/* @conditional-compile-remove(media-access) */
role
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ export const videoGallerySelector: VideoGallerySelector = createSelector(
screenShareRemoteParticipant.raisedHand,
screenShareRemoteParticipant.contentSharingStream,
undefined,
screenShareRemoteParticipant.spotlight
screenShareRemoteParticipant.spotlight,
/* @conditional-compile-remove(media-access) */
undefined,
/* @conditional-compile-remove(media-access) */
screenShareRemoteParticipant.mediaAccess,
/* @conditional-compile-remove(media-access) */
role
)
: undefined,
localParticipant: memoizeLocalParticipant(
Expand Down
12 changes: 11 additions & 1 deletion packages/calling-stateful-client/src/CallClientState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,12 @@ export interface CallState {
* Proxy of {@link @azure/communication-calling#BreakoutRoomsFeature}.
*/
breakoutRooms?: BreakoutRoomsState;

/* @conditional-compile-remove(media-access) */
/**
* Proxy of {@link @azure/communication-calling#MediaAccessFeature}.
*/
mediaAccess?: MediaAccessState;
}

/**
Expand Down Expand Up @@ -1143,7 +1149,11 @@ export type NotificationTarget =
| 'assignedBreakoutRoomOpenedPromptJoin'
| 'assignedBreakoutRoomChanged'
| 'breakoutRoomJoined'
| 'breakoutRoomClosingSoon';
| 'breakoutRoomClosingSoon'
| /* @conditional-compile-remove(media-access) */ 'capabilityTurnVideoOnPresent'
| /* @conditional-compile-remove(media-access) */ 'capabilityTurnVideoOnAbsent'
| /* @conditional-compile-remove(media-access) */ 'capabilityUnmuteMicPresent'
| /* @conditional-compile-remove(media-access) */ 'capabilityUnmuteMicAbsent';

/**
* State only proxy for {@link @azure/communication-calling#DiagnosticsCallFeature}.
Expand Down
19 changes: 18 additions & 1 deletion packages/calling-stateful-client/src/CallContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
VideoDeviceInfo
} from '@azure/communication-calling';
/* @conditional-compile-remove(media-access) */
import { MediaAccess } from '@azure/communication-calling';
import { MediaAccess, MeetingMediaAccess } from '@azure/communication-calling';
import { RaisedHand } from '@azure/communication-calling';
/* @conditional-compile-remove(breakout-rooms) */
import { BreakoutRoom, BreakoutRoomsSettings } from '@azure/communication-calling';
Expand Down Expand Up @@ -1439,6 +1439,23 @@ export class CallContext {
});
});
}

/* @conditional-compile-remove(media-access) */
public setMeetingMediaAccess(callId: string, meetingMediaAccess: MeetingMediaAccess): void {
this.modifyState((draft: CallClientState) => {
const call = draft.calls[this._callIdHistory.latestCallId(callId)];
if (!call) {
return;
}

if (meetingMediaAccess) {
call.mediaAccess = {
isAudioPermitted: meetingMediaAccess.isAudioPermitted,
isVideoPermitted: meetingMediaAccess.isVideoPermitted
};
}
});
}
}

const toCallError = (target: CallErrorTarget, error: unknown): CallError => {
Expand Down
Loading
Loading