Calling missing media keys indicator
This commit is contained in:
parent
436ee1a18f
commit
d97aa68716
13 changed files with 280 additions and 84 deletions
|
@ -326,6 +326,7 @@ export function GroupCall1(): JSX.Element {
|
|||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
isHandRaised: false,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 1.3,
|
||||
|
@ -353,6 +354,7 @@ export function GroupCallYourHandRaised(): JSX.Element {
|
|||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
isHandRaised: false,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 1.3,
|
||||
|
@ -372,26 +374,32 @@ export function GroupCallYourHandRaised(): JSX.Element {
|
|||
const PARTICIPANT_EMOJIS = ['❤️', '🤔', '✨', '😂', '🦄'] as const;
|
||||
|
||||
// We generate these upfront so that the list is stable when you move the slider.
|
||||
const allRemoteParticipants = times(MAX_PARTICIPANTS).map(index => ({
|
||||
aci: generateAci(),
|
||||
demuxId: index,
|
||||
hasRemoteAudio: index % 3 !== 0,
|
||||
hasRemoteVideo: index % 4 !== 0,
|
||||
isHandRaised: (index - 3) % 10 === 0,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: Math.random() < 0.7 ? 1.3 : Math.random() * 0.4 + 0.6,
|
||||
...getDefaultConversationWithServiceId({
|
||||
isBlocked: index === 10 || index === MAX_PARTICIPANTS - 1,
|
||||
title: `Participant ${
|
||||
(index - 2) % 4 === 0
|
||||
? PARTICIPANT_EMOJIS[
|
||||
Math.floor((index - 2) / 4) % PARTICIPANT_EMOJIS.length
|
||||
]
|
||||
: ''
|
||||
} ${index + 1}`,
|
||||
}),
|
||||
}));
|
||||
const allRemoteParticipants = times(MAX_PARTICIPANTS).map(index => {
|
||||
const mediaKeysReceived = (index + 1) % 20 !== 0;
|
||||
|
||||
return {
|
||||
aci: generateAci(),
|
||||
addedTime: Date.now() - 60000,
|
||||
demuxId: index,
|
||||
hasRemoteAudio: mediaKeysReceived ? index % 3 !== 0 : false,
|
||||
hasRemoteVideo: mediaKeysReceived ? index % 4 !== 0 : false,
|
||||
isHandRaised: (index - 3) % 10 === 0,
|
||||
mediaKeysReceived,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: Math.random() < 0.7 ? 1.3 : Math.random() * 0.4 + 0.6,
|
||||
...getDefaultConversationWithServiceId({
|
||||
isBlocked: index === 10 || index === MAX_PARTICIPANTS - 1,
|
||||
title: `Participant ${
|
||||
(index - 2) % 4 === 0
|
||||
? PARTICIPANT_EMOJIS[
|
||||
Math.floor((index - 2) / 4) % PARTICIPANT_EMOJIS.length
|
||||
]
|
||||
: ''
|
||||
} ${index + 1}`,
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
export function GroupCallManyPaginated(): JSX.Element {
|
||||
const props = createProps({
|
||||
|
@ -471,6 +479,7 @@ export function GroupCallReconnecting(): JSX.Element {
|
|||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
isHandRaised: false,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 1.3,
|
||||
|
@ -793,3 +802,38 @@ function useHandRaiser(
|
|||
}, [frequency, call, max, min]);
|
||||
return call;
|
||||
}
|
||||
|
||||
export function GroupCallSomeoneMissingMediaKeys(): JSX.Element {
|
||||
return (
|
||||
<CallScreen
|
||||
{...createProps({
|
||||
callMode: CallMode.Group,
|
||||
remoteParticipants: allRemoteParticipants
|
||||
.slice(0, 5)
|
||||
.map((participant, index) => ({
|
||||
...participant,
|
||||
addedTime: index === 1 ? Date.now() - 60000 : undefined,
|
||||
hasRemoteAudio: false,
|
||||
hasRemoteVideo: false,
|
||||
mediaKeysReceived: index !== 1,
|
||||
})),
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function GroupCallSomeoneBlocked(): JSX.Element {
|
||||
return (
|
||||
<CallScreen
|
||||
{...createProps({
|
||||
callMode: CallMode.Group,
|
||||
remoteParticipants: allRemoteParticipants
|
||||
.slice(0, 5)
|
||||
.map((participant, index) => ({
|
||||
...participant,
|
||||
isBlocked: index === 1,
|
||||
})),
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ function createParticipant(
|
|||
hasRemoteAudio: Boolean(participantProps.hasRemoteAudio),
|
||||
hasRemoteVideo: Boolean(participantProps.hasRemoteVideo),
|
||||
isHandRaised: Boolean(participantProps.isHandRaised),
|
||||
mediaKeysReceived: Boolean(participantProps.mediaKeysReceived),
|
||||
presenting: Boolean(participantProps.presenting),
|
||||
sharingScreen: Boolean(participantProps.sharingScreen),
|
||||
videoAspectRatio: 1.3,
|
||||
|
|
|
@ -24,6 +24,7 @@ const allRemoteParticipants = times(MAX_PARTICIPANTS).map(index => ({
|
|||
hasRemoteAudio: index % 3 !== 0,
|
||||
hasRemoteVideo: index % 4 !== 0,
|
||||
isHandRaised: (index - 2) % 8 === 0,
|
||||
mediaKeysReceived: (index + 1) % 20 !== 0,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 1.3,
|
||||
|
|
|
@ -35,13 +35,17 @@ const getFrameBuffer = memoize(() => Buffer.alloc(FRAME_BUFFER_SIZE));
|
|||
const createProps = (
|
||||
overrideProps: OverridePropsType,
|
||||
{
|
||||
addedTime,
|
||||
isBlocked = false,
|
||||
hasRemoteAudio = false,
|
||||
presenting = false,
|
||||
isHandRaised = false,
|
||||
hasRemoteAudio = false,
|
||||
mediaKeysReceived = true,
|
||||
presenting = false,
|
||||
}: {
|
||||
addedTime?: number;
|
||||
isBlocked?: boolean;
|
||||
hasRemoteAudio?: boolean;
|
||||
mediaKeysReceived?: boolean;
|
||||
presenting?: boolean;
|
||||
isHandRaised?: boolean;
|
||||
} = {}
|
||||
|
@ -54,10 +58,12 @@ const createProps = (
|
|||
audioLevel: 0,
|
||||
remoteParticipant: {
|
||||
aci: generateAci(),
|
||||
addedTime,
|
||||
demuxId: 123,
|
||||
hasRemoteAudio,
|
||||
hasRemoteVideo: true,
|
||||
isHandRaised,
|
||||
mediaKeysReceived,
|
||||
presenting,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 1.3,
|
||||
|
@ -165,3 +171,24 @@ export function Blocked(): JSX.Element {
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NoMediaKeys(): JSX.Element {
|
||||
return (
|
||||
<GroupCallRemoteParticipant
|
||||
{...createProps(
|
||||
{
|
||||
isInPip: false,
|
||||
height: 120,
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
addedTime: Date.now() - 60 * 1000,
|
||||
hasRemoteAudio: true,
|
||||
mediaKeysReceived: false,
|
||||
}
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,9 +27,12 @@ import { ContactName } from './conversation/ContactName';
|
|||
import { useIntersectionObserver } from '../hooks/useIntersectionObserver';
|
||||
import { MAX_FRAME_HEIGHT, MAX_FRAME_WIDTH } from '../calling/constants';
|
||||
import { useValueAtFixedRate } from '../hooks/useValueAtFixedRate';
|
||||
import { Theme } from '../util/theme';
|
||||
import { isOlderThan } from '../util/timestamp';
|
||||
|
||||
const MAX_TIME_TO_SHOW_STALE_VIDEO_FRAMES = 10000;
|
||||
const MAX_TIME_TO_SHOW_STALE_SCREENSHARE_FRAMES = 60000;
|
||||
const DELAY_TO_SHOW_MISSING_MEDIA_KEYS = 5000;
|
||||
|
||||
type BasePropsType = {
|
||||
getFrameBuffer: () => Buffer;
|
||||
|
@ -77,6 +80,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
|
|||
|
||||
const {
|
||||
acceptedMessageRequest,
|
||||
addedTime,
|
||||
avatarPath,
|
||||
color,
|
||||
demuxId,
|
||||
|
@ -85,6 +89,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
|
|||
isHandRaised,
|
||||
isBlocked,
|
||||
isMe,
|
||||
mediaKeysReceived,
|
||||
profileName,
|
||||
sharedGroupNames,
|
||||
sharingScreen,
|
||||
|
@ -102,7 +107,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
|
|||
const [isWide, setIsWide] = useState<boolean>(
|
||||
videoAspectRatio ? videoAspectRatio >= 1 : true
|
||||
);
|
||||
const [showBlockInfo, setShowBlockInfo] = useState(false);
|
||||
const [showErrorDialog, setShowErrorDialog] = useState(false);
|
||||
|
||||
// We have some state (`hasReceivedVideoRecently`) and this ref. We can't have a
|
||||
// single state value like `lastReceivedVideoAt` because (1) it won't automatically
|
||||
|
@ -129,6 +134,11 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
|
|||
|
||||
const wantsToShowVideo = hasRemoteVideo && !isBlocked && isVisible;
|
||||
const hasVideoToShow = wantsToShowVideo && hasReceivedVideoRecently;
|
||||
const showMissingMediaKeys = Boolean(
|
||||
!mediaKeysReceived &&
|
||||
addedTime &&
|
||||
isOlderThan(addedTime, DELAY_TO_SHOW_MISSING_MEDIA_KEYS)
|
||||
);
|
||||
|
||||
const videoFrameSource = useMemo(
|
||||
() => getGroupCallVideoFrameSource(demuxId),
|
||||
|
@ -293,29 +303,94 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
|
|||
}
|
||||
}
|
||||
|
||||
let noVideoNode: ReactNode;
|
||||
let errorDialogTitle: ReactNode;
|
||||
let errorDialogBody = '';
|
||||
if (!hasVideoToShow) {
|
||||
const showDialogButton = (
|
||||
<button
|
||||
type="button"
|
||||
className="module-ongoing-call__group-call-remote-participant__more-info"
|
||||
onClick={() => {
|
||||
setShowErrorDialog(true);
|
||||
}}
|
||||
>
|
||||
{i18n('icu:moreInfo')}
|
||||
</button>
|
||||
);
|
||||
if (isBlocked) {
|
||||
noVideoNode = (
|
||||
<>
|
||||
<i className="module-ongoing-call__group-call-remote-participant__error-icon module-ongoing-call__group-call-remote-participant__error-icon--blocked" />
|
||||
{showDialogButton}
|
||||
</>
|
||||
);
|
||||
errorDialogTitle = (
|
||||
<div className="module-ongoing-call__group-call-remote-participant__more-info-modal-title">
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id="icu:calling__you-have-blocked"
|
||||
components={{
|
||||
name: <ContactName key="name" title={title} />,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
errorDialogBody = i18n('icu:calling__block-info');
|
||||
} else if (showMissingMediaKeys) {
|
||||
noVideoNode = (
|
||||
<>
|
||||
<i className="module-ongoing-call__group-call-remote-participant__error-icon module-ongoing-call__group-call-remote-participant__error-icon--missing-media-keys" />
|
||||
<div className="module-ongoing-call__group-call-remote-participant__error">
|
||||
{i18n('icu:calling__missing-media-keys', { name: title })}
|
||||
</div>
|
||||
{showDialogButton}
|
||||
</>
|
||||
);
|
||||
errorDialogTitle = (
|
||||
<div className="module-ongoing-call__group-call-remote-participant__more-info-modal-title">
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id="icu:calling__missing-media-keys"
|
||||
components={{
|
||||
name: <ContactName key="name" title={title} />,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
errorDialogBody = i18n('icu:calling__missing-media-keys-info');
|
||||
} else {
|
||||
noVideoNode = (
|
||||
<Avatar
|
||||
acceptedMessageRequest={acceptedMessageRequest}
|
||||
avatarPath={avatarPath}
|
||||
badge={undefined}
|
||||
color={color || AvatarColors[0]}
|
||||
noteToSelf={false}
|
||||
conversationType="direct"
|
||||
i18n={i18n}
|
||||
isMe={isMe}
|
||||
profileName={profileName}
|
||||
title={title}
|
||||
sharedGroupNames={sharedGroupNames}
|
||||
size={avatarSize}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{showBlockInfo && (
|
||||
{showErrorDialog && (
|
||||
<ConfirmationDialog
|
||||
dialogName="GroupCallRemoteParticipant.blockInfo"
|
||||
cancelText={i18n('icu:ok')}
|
||||
i18n={i18n}
|
||||
onClose={() => {
|
||||
setShowBlockInfo(false);
|
||||
}}
|
||||
title={
|
||||
<div className="module-ongoing-call__group-call-remote-participant__blocked--modal-title">
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id="icu:calling__you-have-blocked"
|
||||
components={{
|
||||
name: <ContactName key="name" title={title} />,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
onClose={() => setShowErrorDialog(false)}
|
||||
theme={Theme.Dark}
|
||||
title={errorDialogTitle}
|
||||
>
|
||||
{i18n('icu:calling__block-info')}
|
||||
{errorDialogBody}
|
||||
</ConfirmationDialog>
|
||||
)}
|
||||
|
||||
|
@ -372,40 +447,12 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
|
|||
}}
|
||||
/>
|
||||
)}
|
||||
{!hasVideoToShow && (
|
||||
{noVideoNode && (
|
||||
<CallBackgroundBlur
|
||||
avatarPath={avatarPath}
|
||||
className="module-ongoing-call__group-call-remote-participant-background"
|
||||
>
|
||||
{isBlocked ? (
|
||||
<>
|
||||
<i className="module-ongoing-call__group-call-remote-participant__blocked" />
|
||||
<button
|
||||
type="button"
|
||||
className="module-ongoing-call__group-call-remote-participant__blocked--info"
|
||||
onClick={() => {
|
||||
setShowBlockInfo(true);
|
||||
}}
|
||||
>
|
||||
{i18n('icu:moreInfo')}
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<Avatar
|
||||
acceptedMessageRequest={acceptedMessageRequest}
|
||||
avatarPath={avatarPath}
|
||||
badge={undefined}
|
||||
color={color || AvatarColors[0]}
|
||||
noteToSelf={false}
|
||||
conversationType="direct"
|
||||
i18n={i18n}
|
||||
isMe={isMe}
|
||||
profileName={profileName}
|
||||
title={title}
|
||||
sharedGroupNames={sharedGroupNames}
|
||||
size={avatarSize}
|
||||
/>
|
||||
)}
|
||||
{noVideoNode}
|
||||
</CallBackgroundBlur>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -1086,11 +1086,14 @@ export class CallingClass {
|
|||
aci = '00000000-0000-4000-8000-000000000000';
|
||||
}
|
||||
assertDev(isAciString(aci), 'remote participant aci must be a aci');
|
||||
|
||||
return {
|
||||
aci,
|
||||
addedTime: normalizeGroupCallTimestamp(remoteDeviceState.addedTime),
|
||||
demuxId: remoteDeviceState.demuxId,
|
||||
hasRemoteAudio: !remoteDeviceState.audioMuted,
|
||||
hasRemoteVideo: !remoteDeviceState.videoMuted,
|
||||
mediaKeysReceived: remoteDeviceState.mediaKeysReceived,
|
||||
presenting: Boolean(remoteDeviceState.presenting),
|
||||
sharingScreen: Boolean(remoteDeviceState.sharingScreen),
|
||||
speakerTime: normalizeGroupCallTimestamp(
|
||||
|
|
|
@ -76,9 +76,11 @@ export type GroupCallPeekInfoType = ReadonlyDeep<{
|
|||
// eslint-disable-next-line local-rules/type-alias-readonlydeep
|
||||
export type GroupCallParticipantInfoType = {
|
||||
aci: AciString;
|
||||
addedTime?: number;
|
||||
demuxId: number;
|
||||
hasRemoteAudio: boolean;
|
||||
hasRemoteVideo: boolean;
|
||||
mediaKeysReceived: boolean;
|
||||
presenting: boolean;
|
||||
sharingScreen: boolean;
|
||||
speakerTime?: number;
|
||||
|
|
|
@ -246,10 +246,12 @@ const mapStateToActiveCallProp = (
|
|||
remoteParticipants.push({
|
||||
...remoteConversation,
|
||||
aci: remoteParticipant.aci,
|
||||
addedTime: remoteParticipant.addedTime,
|
||||
demuxId: remoteParticipant.demuxId,
|
||||
hasRemoteAudio: remoteParticipant.hasRemoteAudio,
|
||||
hasRemoteVideo: remoteParticipant.hasRemoteVideo,
|
||||
isHandRaised: raisedHands.has(remoteParticipant.demuxId),
|
||||
mediaKeysReceived: remoteParticipant.mediaKeysReceived,
|
||||
presenting: remoteParticipant.presenting,
|
||||
sharingScreen: remoteParticipant.sharingScreen,
|
||||
speakerTime: remoteParticipant.speakerTime,
|
||||
|
|
|
@ -118,6 +118,7 @@ describe('calling duck', () => {
|
|||
demuxId: 123,
|
||||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 4 / 3,
|
||||
|
@ -906,6 +907,7 @@ describe('calling duck', () => {
|
|||
demuxId: 123,
|
||||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 4 / 3,
|
||||
|
@ -935,6 +937,7 @@ describe('calling duck', () => {
|
|||
demuxId: 123,
|
||||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 4 / 3,
|
||||
|
@ -966,6 +969,7 @@ describe('calling duck', () => {
|
|||
demuxId: 456,
|
||||
hasRemoteAudio: false,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 16 / 9,
|
||||
|
@ -993,6 +997,7 @@ describe('calling duck', () => {
|
|||
demuxId: 456,
|
||||
hasRemoteAudio: false,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 16 / 9,
|
||||
|
@ -1037,6 +1042,7 @@ describe('calling duck', () => {
|
|||
demuxId: 456,
|
||||
hasRemoteAudio: false,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 16 / 9,
|
||||
|
@ -1089,6 +1095,7 @@ describe('calling duck', () => {
|
|||
demuxId: 456,
|
||||
hasRemoteAudio: false,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 16 / 9,
|
||||
|
@ -1128,6 +1135,7 @@ describe('calling duck', () => {
|
|||
demuxId: 456,
|
||||
hasRemoteAudio: false,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 16 / 9,
|
||||
|
@ -1160,6 +1168,7 @@ describe('calling duck', () => {
|
|||
demuxId: 456,
|
||||
hasRemoteAudio: false,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 16 / 9,
|
||||
|
@ -1204,6 +1213,7 @@ describe('calling duck', () => {
|
|||
demuxId: 456,
|
||||
hasRemoteAudio: false,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 16 / 9,
|
||||
|
@ -1882,6 +1892,7 @@ describe('calling duck', () => {
|
|||
demuxId: 123,
|
||||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 4 / 3,
|
||||
|
@ -1908,6 +1919,7 @@ describe('calling duck', () => {
|
|||
demuxId: 123,
|
||||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 4 / 3,
|
||||
|
@ -1954,6 +1966,7 @@ describe('calling duck', () => {
|
|||
demuxId: 123,
|
||||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 4 / 3,
|
||||
|
@ -2004,6 +2017,7 @@ describe('calling duck', () => {
|
|||
demuxId: 123,
|
||||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 4 / 3,
|
||||
|
@ -2048,6 +2062,7 @@ describe('calling duck', () => {
|
|||
demuxId: 123,
|
||||
hasRemoteAudio: true,
|
||||
hasRemoteVideo: true,
|
||||
mediaKeysReceived: true,
|
||||
presenting: false,
|
||||
sharingScreen: false,
|
||||
videoAspectRatio: 4 / 3,
|
||||
|
|
|
@ -156,10 +156,12 @@ export enum GroupCallJoinState {
|
|||
|
||||
export type GroupCallRemoteParticipantType = ConversationType & {
|
||||
aci: AciString;
|
||||
addedTime?: number;
|
||||
demuxId: number;
|
||||
hasRemoteAudio: boolean;
|
||||
hasRemoteVideo: boolean;
|
||||
isHandRaised: boolean;
|
||||
mediaKeysReceived: boolean;
|
||||
presenting: boolean;
|
||||
sharingScreen: boolean;
|
||||
speakerTime?: number;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue