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

Origin/fuyan/hard mute part full draft #5452

Draft
wants to merge 50 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
322531f
Hard mute part 1 initial commit
fuyan2024 Oct 21, 2024
fbbcdbb
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part1
fuyan2024 Oct 21, 2024
563ddaf
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part1
fuyan2024 Oct 21, 2024
070e1b3
address comments
fuyan2024 Oct 21, 2024
c99dfa5
Change files
fuyan2024 Oct 22, 2024
ae2ef48
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part2
fuyan2024 Oct 30, 2024
248ee43
Integrate Teams meeting hard mute feature part 1 - components bindings
fuyan2024 Oct 31, 2024
17bb863
update
fuyan2024 Oct 31, 2024
b7d1c52
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part2
fuyan2024 Oct 31, 2024
3153d68
Change files
fuyan2024 Oct 31, 2024
9f5df4e
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 3, 2024
93bb450
Hard mute feature Part 3 - UI changes
fuyan2024 Nov 4, 2024
081d433
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 7, 2024
c105005
update
fuyan2024 Nov 7, 2024
de63a37
update
fuyan2024 Nov 7, 2024
2bb34d1
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
Nov 7, 2024
74b75bd
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
Nov 7, 2024
82e639f
update icons
Nov 7, 2024
ce09a65
update
fuyan2024 Nov 8, 2024
a2e095d
update
fuyan2024 Nov 8, 2024
96a9894
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 8, 2024
441a8ac
Stop capability notification for turnVideoOn and UnmuteMic
fuyan2024 Nov 8, 2024
a055db3
save code, to check again later
fuyan2024 Nov 9, 2024
aeae8f7
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 10, 2024
e856b8b
update
fuyan2024 Nov 10, 2024
a00e9cd
meeting media access
fuyan2024 Nov 10, 2024
a0b731f
update
fuyan2024 Nov 11, 2024
9d59347
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 13, 2024
ca140e5
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 13, 2024
03f7571
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 15, 2024
bced15c
Change condition to render audio or video hard muted icon
fuyan2024 Nov 15, 2024
8da6a96
update
fuyan2024 Nov 15, 2024
389a9a1
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 15, 2024
60516fc
update
fuyan2024 Nov 16, 2024
b74e004
update
fuyan2024 Nov 17, 2024
ad4d215
update
fuyan2024 Nov 17, 2024
d532136
update
fuyan2024 Nov 18, 2024
d57c0a6
update
fuyan2024 Nov 18, 2024
d8a1793
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 19, 2024
bd5559e
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 21, 2024
9f04f68
update
fuyan2024 Nov 21, 2024
fc27278
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 22, 2024
509f8ea
api rename
fuyan2024 Nov 22, 2024
f272857
add media access event listener
fuyan2024 Nov 24, 2024
d79c342
Merge remote-tracking branch 'origin/main' into fuyan/hard_mute_part3
fuyan2024 Nov 29, 2024
17600b2
update meeting media access setting
fuyan2024 Nov 29, 2024
aa494e9
update
fuyan2024 Nov 29, 2024
d347add
Initial commit hard mute draft full PR
fuyan2024 Nov 29, 2024
b77288b
update api names
fuyan2024 Nov 29, 2024
4a5cc9a
update
fuyan2024 Nov 29, 2024
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 @@ -3,6 +3,8 @@
import { CallState, DominantSpeakersInfo, EnvironmentInfo } from '@azure/communication-calling';
/* @conditional-compile-remove(breakout-rooms) */
import { BreakoutRoom } from '@azure/communication-calling';
/* @conditional-compile-remove(media-access) */
import { CapabilitiesChangeInfo } from '@azure/communication-calling';
import { ParticipantCapabilities } from '@azure/communication-calling';
import { ParticipantRole } from '@azure/communication-calling';
import { toFlatCommunicationIdentifier } from '@internal/acs-ui-common';
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,22 @@ export interface CommonCallingHandlers {
*/
onDisposeTogetherModeStreamViews: () => Promise<void>;
/* @conditional-compile-remove(media-access) */
onForbidParticipantAudio?: (userIds: string[]) => Promise<void>;
onForbidAudio?: (userIds: string[]) => Promise<void>;
/* @conditional-compile-remove(media-access) */
onPermitParticipantAudio?: (userIds: string[]) => Promise<void>;
onPermitAudio?: (userIds: string[]) => Promise<void>;
/* @conditional-compile-remove(media-access) */
onForbidRemoteParticipantsAudio?: () => Promise<void>;
onForbidOthersAudio?: () => Promise<void>;
/* @conditional-compile-remove(media-access) */
onPermitRemoteParticipantsAudio?: () => Promise<void>;
onPermitOthersAudio?: () => Promise<void>;

/* @conditional-compile-remove(media-access) */
onForbidParticipantVideo?: (userIds: string[]) => Promise<void>;
onForbidVideo?: (userIds: string[]) => Promise<void>;
/* @conditional-compile-remove(media-access) */
onPermitParticipantVideo?: (userIds: string[]) => Promise<void>;
onPermitVideo?: (userIds: string[]) => Promise<void>;
/* @conditional-compile-remove(media-access) */
onForbidRemoteParticipantsVideo?: () => Promise<void>;
onForbidOthersVideo?: () => Promise<void>;
/* @conditional-compile-remove(media-access) */
onPermitRemoteParticipantsVideo?: () => Promise<void>;
onPermitOthersVideo?: () => Promise<void>;
}

/**
Expand Down Expand Up @@ -811,41 +811,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 +906,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 @@ -18,6 +18,8 @@ import { ActiveNotification, NotificationType } from '@internal/react-components
import { createSelector } from 'reselect';

import { CallClientState, CallErrors, CallErrorTarget } from '@internal/calling-stateful-client';
/* @conditional-compile-remove(media-access) */
import { CallNotifications } from '@internal/calling-stateful-client';

import { DiagnosticQuality } from '@azure/communication-calling';

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}.
*/
meetingMediaAccess?: 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.meetingMediaAccess = {
isAudioPermitted: meetingMediaAccess.isAudioPermitted,
isVideoPermitted: meetingMediaAccess.isVideoPermitted
};
}
});
}
}

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