Reuse html element for local preview visuals
This commit is contained in:
parent
bb69f81b9f
commit
17c908bbf4
14 changed files with 86 additions and 109 deletions
|
@ -4231,6 +4231,10 @@ button.module-image__border-overlay:focus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__local-preview-video-container {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
&__local-preview-fullsize {
|
&__local-preview-fullsize {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -4283,18 +4287,23 @@ button.module-image__border-overlay:focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
&__video {
|
&__video {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
video {
|
||||||
// The background-color is seen while the video loads.
|
// The background-color is seen while the video loads.
|
||||||
background-color: $color-gray-75;
|
background-color: $color-gray-75;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transform: rotateY(180deg);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
transform: rotateY(180deg);
|
||||||
&--presenting {
|
&--presenting {
|
||||||
transform: inherit;
|
transform: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__controls {
|
&__controls {
|
||||||
z-index: $z-index-above-above-base;
|
z-index: $z-index-above-above-base;
|
||||||
|
@ -4373,8 +4382,13 @@ button.module-image__border-overlay:focus {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset-inline-end: 4px;
|
inset-inline-end: 4px;
|
||||||
transform: rotateY(180deg);
|
|
||||||
width: 32px;
|
width: 32px;
|
||||||
|
|
||||||
|
video {
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,14 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-height: calc(100% - 140px);
|
max-height: calc(100% - 140px);
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
|
|
||||||
|
// Border radius should clip children
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--camera-is-on video {
|
||||||
|
width: auto;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--camera-is-off {
|
&--camera-is-off {
|
||||||
|
|
|
@ -130,7 +130,7 @@ const createProps = (storyProps: Partial<PropsType> = {}): PropsType => ({
|
||||||
setGroupCallVideoRequest: action('set-group-call-video-request'),
|
setGroupCallVideoRequest: action('set-group-call-video-request'),
|
||||||
setIsCallActive: action('set-is-call-active'),
|
setIsCallActive: action('set-is-call-active'),
|
||||||
setLocalAudio: action('set-local-audio'),
|
setLocalAudio: action('set-local-audio'),
|
||||||
setLocalPreview: action('set-local-preview'),
|
setLocalPreviewContainer: action('set-local-preview-container'),
|
||||||
setLocalVideo: action('set-local-video'),
|
setLocalVideo: action('set-local-video'),
|
||||||
setRendererCanvas: action('set-renderer-canvas'),
|
setRendererCanvas: action('set-renderer-canvas'),
|
||||||
setOutgoingRing: action('set-outgoing-ring'),
|
setOutgoingRing: action('set-outgoing-ring'),
|
||||||
|
|
|
@ -37,7 +37,6 @@ import type {
|
||||||
SendGroupCallReactionType,
|
SendGroupCallReactionType,
|
||||||
SetGroupCallVideoRequestType,
|
SetGroupCallVideoRequestType,
|
||||||
SetLocalAudioType,
|
SetLocalAudioType,
|
||||||
SetLocalPreviewType,
|
|
||||||
SetLocalVideoType,
|
SetLocalVideoType,
|
||||||
SetRendererCanvasType,
|
SetRendererCanvasType,
|
||||||
StartCallType,
|
StartCallType,
|
||||||
|
@ -127,7 +126,7 @@ export type PropsType = {
|
||||||
setIsCallActive: (_: boolean) => void;
|
setIsCallActive: (_: boolean) => void;
|
||||||
setLocalAudio: (_: SetLocalAudioType) => void;
|
setLocalAudio: (_: SetLocalAudioType) => void;
|
||||||
setLocalVideo: (_: SetLocalVideoType) => void;
|
setLocalVideo: (_: SetLocalVideoType) => void;
|
||||||
setLocalPreview: (_: SetLocalPreviewType) => void;
|
setLocalPreviewContainer: (container: HTMLDivElement | null) => void;
|
||||||
setOutgoingRing: (_: boolean) => void;
|
setOutgoingRing: (_: boolean) => void;
|
||||||
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
||||||
showShareCallLinkViaSignal: (
|
showShareCallLinkViaSignal: (
|
||||||
|
@ -192,7 +191,7 @@ function ActiveCallManager({
|
||||||
sendGroupCallReaction,
|
sendGroupCallReaction,
|
||||||
setGroupCallVideoRequest,
|
setGroupCallVideoRequest,
|
||||||
setLocalAudio,
|
setLocalAudio,
|
||||||
setLocalPreview,
|
setLocalPreviewContainer,
|
||||||
setLocalVideo,
|
setLocalVideo,
|
||||||
setRendererCanvas,
|
setRendererCanvas,
|
||||||
setOutgoingRing,
|
setOutgoingRing,
|
||||||
|
@ -351,7 +350,7 @@ function ActiveCallManager({
|
||||||
hasLocalVideo={hasLocalVideo}
|
hasLocalVideo={hasLocalVideo}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
setGroupCallVideoRequest={setGroupCallVideoRequestForConversation}
|
setGroupCallVideoRequest={setGroupCallVideoRequestForConversation}
|
||||||
setLocalPreview={setLocalPreview}
|
setLocalPreviewContainer={setLocalPreviewContainer}
|
||||||
setRendererCanvas={setRendererCanvas}
|
setRendererCanvas={setRendererCanvas}
|
||||||
switchToPresentationView={switchToPresentationView}
|
switchToPresentationView={switchToPresentationView}
|
||||||
switchFromPresentationView={switchFromPresentationView}
|
switchFromPresentationView={switchFromPresentationView}
|
||||||
|
@ -383,7 +382,7 @@ function ActiveCallManager({
|
||||||
onJoinCall={joinActiveCall}
|
onJoinCall={joinActiveCall}
|
||||||
outgoingRing={outgoingRing}
|
outgoingRing={outgoingRing}
|
||||||
peekedParticipants={peekedParticipants}
|
peekedParticipants={peekedParticipants}
|
||||||
setLocalPreview={setLocalPreview}
|
setLocalPreviewContainer={setLocalPreviewContainer}
|
||||||
setLocalAudio={setLocalAudio}
|
setLocalAudio={setLocalAudio}
|
||||||
setLocalVideo={setLocalVideo}
|
setLocalVideo={setLocalVideo}
|
||||||
setOutgoingRing={setOutgoingRing}
|
setOutgoingRing={setOutgoingRing}
|
||||||
|
@ -471,7 +470,7 @@ function ActiveCallManager({
|
||||||
sendGroupCallRaiseHand={sendGroupCallRaiseHand}
|
sendGroupCallRaiseHand={sendGroupCallRaiseHand}
|
||||||
sendGroupCallReaction={sendGroupCallReaction}
|
sendGroupCallReaction={sendGroupCallReaction}
|
||||||
setGroupCallVideoRequest={setGroupCallVideoRequestForConversation}
|
setGroupCallVideoRequest={setGroupCallVideoRequestForConversation}
|
||||||
setLocalPreview={setLocalPreview}
|
setLocalPreviewContainer={setLocalPreviewContainer}
|
||||||
setRendererCanvas={setRendererCanvas}
|
setRendererCanvas={setRendererCanvas}
|
||||||
setLocalAudio={setLocalAudio}
|
setLocalAudio={setLocalAudio}
|
||||||
setLocalVideo={setLocalVideo}
|
setLocalVideo={setLocalVideo}
|
||||||
|
@ -567,7 +566,7 @@ export function CallManager({
|
||||||
setGroupCallVideoRequest,
|
setGroupCallVideoRequest,
|
||||||
setIsCallActive,
|
setIsCallActive,
|
||||||
setLocalAudio,
|
setLocalAudio,
|
||||||
setLocalPreview,
|
setLocalPreviewContainer,
|
||||||
setLocalVideo,
|
setLocalVideo,
|
||||||
setOutgoingRing,
|
setOutgoingRing,
|
||||||
setRendererCanvas,
|
setRendererCanvas,
|
||||||
|
@ -662,7 +661,7 @@ export function CallManager({
|
||||||
sendGroupCallReaction={sendGroupCallReaction}
|
sendGroupCallReaction={sendGroupCallReaction}
|
||||||
setGroupCallVideoRequest={setGroupCallVideoRequest}
|
setGroupCallVideoRequest={setGroupCallVideoRequest}
|
||||||
setLocalAudio={setLocalAudio}
|
setLocalAudio={setLocalAudio}
|
||||||
setLocalPreview={setLocalPreview}
|
setLocalPreviewContainer={setLocalPreviewContainer}
|
||||||
setLocalVideo={setLocalVideo}
|
setLocalVideo={setLocalVideo}
|
||||||
setOutgoingRing={setOutgoingRing}
|
setOutgoingRing={setOutgoingRing}
|
||||||
setRendererCanvas={setRendererCanvas}
|
setRendererCanvas={setRendererCanvas}
|
||||||
|
|
|
@ -219,7 +219,7 @@ const createProps = (
|
||||||
sendGroupCallReaction: action('send-group-call-reaction'),
|
sendGroupCallReaction: action('send-group-call-reaction'),
|
||||||
setGroupCallVideoRequest: action('set-group-call-video-request'),
|
setGroupCallVideoRequest: action('set-group-call-video-request'),
|
||||||
setLocalAudio: action('set-local-audio'),
|
setLocalAudio: action('set-local-audio'),
|
||||||
setLocalPreview: action('set-local-preview'),
|
setLocalPreviewContainer: action('set-local-preview-container'),
|
||||||
setLocalVideo: action('set-local-video'),
|
setLocalVideo: action('set-local-video'),
|
||||||
setRendererCanvas: action('set-renderer-canvas'),
|
setRendererCanvas: action('set-renderer-canvas'),
|
||||||
stickyControls: false,
|
stickyControls: false,
|
||||||
|
|
|
@ -13,7 +13,6 @@ import type {
|
||||||
SendGroupCallRaiseHandType,
|
SendGroupCallRaiseHandType,
|
||||||
SendGroupCallReactionType,
|
SendGroupCallReactionType,
|
||||||
SetLocalAudioType,
|
SetLocalAudioType,
|
||||||
SetLocalPreviewType,
|
|
||||||
SetLocalVideoType,
|
SetLocalVideoType,
|
||||||
SetRendererCanvasType,
|
SetRendererCanvasType,
|
||||||
} from '../state/ducks/calling';
|
} from '../state/ducks/calling';
|
||||||
|
@ -119,7 +118,7 @@ export type PropsType = {
|
||||||
) => void;
|
) => void;
|
||||||
setLocalAudio: (_: SetLocalAudioType) => void;
|
setLocalAudio: (_: SetLocalAudioType) => void;
|
||||||
setLocalVideo: (_: SetLocalVideoType) => void;
|
setLocalVideo: (_: SetLocalVideoType) => void;
|
||||||
setLocalPreview: (_: SetLocalPreviewType) => void;
|
setLocalPreviewContainer: (container: HTMLDivElement | null) => void;
|
||||||
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
||||||
stickyControls: boolean;
|
stickyControls: boolean;
|
||||||
switchToPresentationView: () => void;
|
switchToPresentationView: () => void;
|
||||||
|
@ -209,7 +208,7 @@ export function CallScreen({
|
||||||
sendGroupCallReaction,
|
sendGroupCallReaction,
|
||||||
setLocalAudio,
|
setLocalAudio,
|
||||||
setLocalVideo,
|
setLocalVideo,
|
||||||
setLocalPreview,
|
setLocalPreviewContainer,
|
||||||
setRendererCanvas,
|
setRendererCanvas,
|
||||||
stickyControls,
|
stickyControls,
|
||||||
switchToPresentationView,
|
switchToPresentationView,
|
||||||
|
@ -294,15 +293,6 @@ export function CallScreen({
|
||||||
|
|
||||||
const [showControls, setShowControls] = useState(true);
|
const [showControls, setShowControls] = useState(true);
|
||||||
|
|
||||||
const localVideoRef = useRef<HTMLVideoElement | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setLocalPreview({ element: localVideoRef });
|
|
||||||
return () => {
|
|
||||||
setLocalPreview({ element: undefined });
|
|
||||||
};
|
|
||||||
}, [setLocalPreview, setRendererCanvas]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
!showControls ||
|
!showControls ||
|
||||||
|
@ -431,7 +421,10 @@ export function CallScreen({
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{isSendingVideo ? (
|
{isSendingVideo ? (
|
||||||
<video ref={localVideoRef} autoPlay />
|
<div
|
||||||
|
className="module-ongoing-call__local-preview-container"
|
||||||
|
ref={setLocalPreviewContainer}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CallBackgroundBlur avatarUrl={me.avatarUrl}>
|
<CallBackgroundBlur avatarUrl={me.avatarUrl}>
|
||||||
<div className="module-calling__spacer module-calling__camera-is-off-spacer" />
|
<div className="module-calling__spacer module-calling__camera-is-off-spacer" />
|
||||||
|
@ -444,14 +437,13 @@ export function CallScreen({
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
localPreviewNode = isSendingVideo ? (
|
localPreviewNode = isSendingVideo ? (
|
||||||
<video
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'module-ongoing-call__footer__local-preview__video',
|
'module-ongoing-call__footer__local-preview__video',
|
||||||
presentingSource &&
|
presentingSource &&
|
||||||
'module-ongoing-call__footer__local-preview__video--presenting'
|
'module-ongoing-call__footer__local-preview__video--presenting'
|
||||||
)}
|
)}
|
||||||
ref={localVideoRef}
|
ref={setLocalPreviewContainer}
|
||||||
autoPlay
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CallBackgroundBlur avatarUrl={me.avatarUrl}>
|
<CallBackgroundBlur avatarUrl={me.avatarUrl}>
|
||||||
|
|
|
@ -84,7 +84,7 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => {
|
||||||
outgoingRing: overrideProps.outgoingRing ?? false,
|
outgoingRing: overrideProps.outgoingRing ?? false,
|
||||||
peekedParticipants: overrideProps.peekedParticipants || [],
|
peekedParticipants: overrideProps.peekedParticipants || [],
|
||||||
setLocalAudio: action('set-local-audio'),
|
setLocalAudio: action('set-local-audio'),
|
||||||
setLocalPreview: action('set-local-preview'),
|
setLocalPreviewContainer: action('set-local-preview-container'),
|
||||||
setLocalVideo: action('set-local-video'),
|
setLocalVideo: action('set-local-video'),
|
||||||
setOutgoingRing: action('set-outgoing-ring'),
|
setOutgoingRing: action('set-outgoing-ring'),
|
||||||
showParticipantsList: overrideProps.showParticipantsList ?? false,
|
showParticipantsList: overrideProps.showParticipantsList ?? false,
|
||||||
|
|
|
@ -6,7 +6,6 @@ import FocusTrap from 'focus-trap-react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type {
|
import type {
|
||||||
SetLocalAudioType,
|
SetLocalAudioType,
|
||||||
SetLocalPreviewType,
|
|
||||||
SetLocalVideoType,
|
SetLocalVideoType,
|
||||||
} from '../state/ducks/calling';
|
} from '../state/ducks/calling';
|
||||||
import { CallingButton, CallingButtonType } from './CallingButton';
|
import { CallingButton, CallingButtonType } from './CallingButton';
|
||||||
|
@ -74,7 +73,7 @@ export type PropsType = {
|
||||||
peekedParticipants: Array<ConversationType>;
|
peekedParticipants: Array<ConversationType>;
|
||||||
setLocalAudio: (_: SetLocalAudioType) => void;
|
setLocalAudio: (_: SetLocalAudioType) => void;
|
||||||
setLocalVideo: (_: SetLocalVideoType) => void;
|
setLocalVideo: (_: SetLocalVideoType) => void;
|
||||||
setLocalPreview: (_: SetLocalPreviewType) => void;
|
setLocalPreviewContainer: (container: HTMLDivElement | null) => void;
|
||||||
setOutgoingRing: (_: boolean) => void;
|
setOutgoingRing: (_: boolean) => void;
|
||||||
showParticipantsList: boolean;
|
showParticipantsList: boolean;
|
||||||
toggleParticipants: () => void;
|
toggleParticipants: () => void;
|
||||||
|
@ -100,7 +99,7 @@ export function CallingLobby({
|
||||||
onJoinCall,
|
onJoinCall,
|
||||||
peekedParticipants,
|
peekedParticipants,
|
||||||
setLocalAudio,
|
setLocalAudio,
|
||||||
setLocalPreview,
|
setLocalPreviewContainer,
|
||||||
setLocalVideo,
|
setLocalVideo,
|
||||||
setOutgoingRing,
|
setOutgoingRing,
|
||||||
toggleParticipants,
|
toggleParticipants,
|
||||||
|
@ -108,8 +107,6 @@ export function CallingLobby({
|
||||||
toggleSettings,
|
toggleSettings,
|
||||||
outgoingRing,
|
outgoingRing,
|
||||||
}: PropsType): JSX.Element {
|
}: PropsType): JSX.Element {
|
||||||
const localVideoRef = React.useRef<null | HTMLVideoElement>(null);
|
|
||||||
|
|
||||||
const shouldShowLocalVideo = hasLocalVideo && availableCameras.length > 0;
|
const shouldShowLocalVideo = hasLocalVideo && availableCameras.length > 0;
|
||||||
|
|
||||||
const isGroupOrAdhocCall = isGroupOrAdhocCallMode(callMode);
|
const isGroupOrAdhocCall = isGroupOrAdhocCallMode(callMode);
|
||||||
|
@ -130,14 +127,6 @@ export function CallingLobby({
|
||||||
? togglePip
|
? togglePip
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
setLocalPreview({ element: localVideoRef });
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
setLocalPreview({ element: undefined });
|
|
||||||
};
|
|
||||||
}, [setLocalPreview]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
function handleKeyDown(event: KeyboardEvent): void {
|
function handleKeyDown(event: KeyboardEvent): void {
|
||||||
let eventHandled = false;
|
let eventHandled = false;
|
||||||
|
@ -275,10 +264,9 @@ export function CallingLobby({
|
||||||
>
|
>
|
||||||
<div className="module-calling__container dark-theme">
|
<div className="module-calling__container dark-theme">
|
||||||
{shouldShowLocalVideo ? (
|
{shouldShowLocalVideo ? (
|
||||||
<video
|
<div
|
||||||
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-on"
|
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-on"
|
||||||
ref={localVideoRef}
|
ref={setLocalPreviewContainer}
|
||||||
autoPlay
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CallBackgroundBlur
|
<CallBackgroundBlur
|
||||||
|
|
|
@ -78,7 +78,7 @@ export default {
|
||||||
hasLocalVideo: false,
|
hasLocalVideo: false,
|
||||||
i18n,
|
i18n,
|
||||||
setGroupCallVideoRequest: action('set-group-call-video-request'),
|
setGroupCallVideoRequest: action('set-group-call-video-request'),
|
||||||
setLocalPreview: action('set-local-preview'),
|
setLocalPreviewContainer: action('set-local-preview-container'),
|
||||||
setRendererCanvas: action('set-renderer-canvas'),
|
setRendererCanvas: action('set-renderer-canvas'),
|
||||||
switchFromPresentationView: action('switch-to-presentation-view'),
|
switchFromPresentationView: action('switch-to-presentation-view'),
|
||||||
switchToPresentationView: action('switch-to-presentation-view'),
|
switchToPresentationView: action('switch-to-presentation-view'),
|
||||||
|
|
|
@ -7,10 +7,7 @@ import type { VideoFrameSource } from '@signalapp/ringrtc';
|
||||||
import { CallingPipRemoteVideo } from './CallingPipRemoteVideo';
|
import { CallingPipRemoteVideo } from './CallingPipRemoteVideo';
|
||||||
import type { LocalizerType } from '../types/Util';
|
import type { LocalizerType } from '../types/Util';
|
||||||
import type { ActiveCallType, GroupCallVideoRequest } from '../types/Calling';
|
import type { ActiveCallType, GroupCallVideoRequest } from '../types/Calling';
|
||||||
import type {
|
import type { SetRendererCanvasType } from '../state/ducks/calling';
|
||||||
SetLocalPreviewType,
|
|
||||||
SetRendererCanvasType,
|
|
||||||
} from '../state/ducks/calling';
|
|
||||||
import { missingCaseError } from '../util/missingCaseError';
|
import { missingCaseError } from '../util/missingCaseError';
|
||||||
import { useActivateSpeakerViewOnPresenting } from '../hooks/useActivateSpeakerViewOnPresenting';
|
import { useActivateSpeakerViewOnPresenting } from '../hooks/useActivateSpeakerViewOnPresenting';
|
||||||
import type { CallingImageDataCache } from './CallManager';
|
import type { CallingImageDataCache } from './CallManager';
|
||||||
|
@ -60,7 +57,7 @@ export type PropsType = {
|
||||||
_: Array<GroupCallVideoRequest>,
|
_: Array<GroupCallVideoRequest>,
|
||||||
speakerHeight: number
|
speakerHeight: number
|
||||||
) => void;
|
) => void;
|
||||||
setLocalPreview: (_: SetLocalPreviewType) => void;
|
setLocalPreviewContainer: (container: HTMLDivElement | null) => void;
|
||||||
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
||||||
switchToPresentationView: () => void;
|
switchToPresentationView: () => void;
|
||||||
switchFromPresentationView: () => void;
|
switchFromPresentationView: () => void;
|
||||||
|
@ -80,7 +77,7 @@ export function CallingPip({
|
||||||
imageDataCache,
|
imageDataCache,
|
||||||
i18n,
|
i18n,
|
||||||
setGroupCallVideoRequest,
|
setGroupCallVideoRequest,
|
||||||
setLocalPreview,
|
setLocalPreviewContainer,
|
||||||
setRendererCanvas,
|
setRendererCanvas,
|
||||||
switchToPresentationView,
|
switchToPresentationView,
|
||||||
switchFromPresentationView,
|
switchFromPresentationView,
|
||||||
|
@ -89,7 +86,6 @@ export function CallingPip({
|
||||||
const isRTL = i18n.getLocaleDirection() === 'rtl';
|
const isRTL = i18n.getLocaleDirection() === 'rtl';
|
||||||
|
|
||||||
const videoContainerRef = React.useRef<null | HTMLDivElement>(null);
|
const videoContainerRef = React.useRef<null | HTMLDivElement>(null);
|
||||||
const localVideoRef = React.useRef(null);
|
|
||||||
|
|
||||||
const [windowWidth, setWindowWidth] = React.useState(window.innerWidth);
|
const [windowWidth, setWindowWidth] = React.useState(window.innerWidth);
|
||||||
const [windowHeight, setWindowHeight] = React.useState(window.innerHeight);
|
const [windowHeight, setWindowHeight] = React.useState(window.innerHeight);
|
||||||
|
@ -104,10 +100,6 @@ export function CallingPip({
|
||||||
switchFromPresentationView,
|
switchFromPresentationView,
|
||||||
});
|
});
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
setLocalPreview({ element: localVideoRef });
|
|
||||||
}, [setLocalPreview]);
|
|
||||||
|
|
||||||
const hangUp = React.useCallback(() => {
|
const hangUp = React.useCallback(() => {
|
||||||
hangUpActiveCall('pip button click');
|
hangUpActiveCall('pip button click');
|
||||||
}, [hangUpActiveCall]);
|
}, [hangUpActiveCall]);
|
||||||
|
@ -313,10 +305,9 @@ export function CallingPip({
|
||||||
setGroupCallVideoRequest={setGroupCallVideoRequest}
|
setGroupCallVideoRequest={setGroupCallVideoRequest}
|
||||||
/>
|
/>
|
||||||
{hasLocalVideo ? (
|
{hasLocalVideo ? (
|
||||||
<video
|
<div
|
||||||
className="module-calling-pip__video--local"
|
className="module-calling-pip__video--local"
|
||||||
ref={localVideoRef}
|
ref={setLocalPreviewContainer}
|
||||||
autoPlay
|
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="module-calling-pip__actions">
|
<div className="module-calling-pip__actions">
|
||||||
|
|
|
@ -326,10 +326,14 @@ export type NotifyScreenShareStatusOptionsType = Readonly<
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export class CallingClass {
|
export class CallingClass {
|
||||||
readonly videoCapturer: GumVideoCapturer;
|
private readonly videoCapturer: GumVideoCapturer;
|
||||||
|
|
||||||
readonly videoRenderer: CanvasVideoRenderer;
|
readonly videoRenderer: CanvasVideoRenderer;
|
||||||
|
|
||||||
|
private localPreviewContainer: HTMLDivElement | null = null;
|
||||||
|
|
||||||
|
private localPreview: HTMLVideoElement | undefined;
|
||||||
|
|
||||||
private reduxInterface?: CallingReduxInterface;
|
private reduxInterface?: CallingReduxInterface;
|
||||||
|
|
||||||
public _sfuUrl?: string;
|
public _sfuUrl?: string;
|
||||||
|
@ -953,6 +957,21 @@ export class CallingClass {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setLocalPreviewContainer(container: HTMLDivElement | null): void {
|
||||||
|
// Reuse HTMLVideoElement between different containers so that the preview
|
||||||
|
// of the last frame stays valid even if there are no new frames on the
|
||||||
|
// underlying MediaStream.
|
||||||
|
if (this.localPreview == null) {
|
||||||
|
this.localPreview = document.createElement('video');
|
||||||
|
this.localPreview.autoplay = true;
|
||||||
|
this.videoCapturer.setLocalPreview({ current: this.localPreview });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.localPreviewContainer?.removeChild(this.localPreview);
|
||||||
|
this.localPreviewContainer = container;
|
||||||
|
this.localPreviewContainer?.appendChild(this.localPreview);
|
||||||
|
}
|
||||||
|
|
||||||
public async cleanupStaleRingingCalls(): Promise<void> {
|
public async cleanupStaleRingingCalls(): Promise<void> {
|
||||||
const calls = await DataWriter.getRecentStaleRingsAndMarkOlderMissed();
|
const calls = await DataWriter.getRecentStaleRingsAndMarkOlderMissed();
|
||||||
|
|
||||||
|
|
|
@ -420,11 +420,6 @@ type StartCallLinkLobbyPayloadType = {
|
||||||
callLinkRootKey: string;
|
callLinkRootKey: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line local-rules/type-alias-readonlydeep
|
|
||||||
export type SetLocalPreviewType = {
|
|
||||||
element: React.RefObject<HTMLVideoElement> | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
// eslint-disable-next-line local-rules/type-alias-readonlydeep
|
// eslint-disable-next-line local-rules/type-alias-readonlydeep
|
||||||
export type SetRendererCanvasType = {
|
export type SetRendererCanvasType = {
|
||||||
element: React.RefObject<HTMLCanvasElement> | undefined;
|
element: React.RefObject<HTMLCanvasElement> | undefined;
|
||||||
|
@ -1835,14 +1830,6 @@ function setIsCallActive(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLocalPreview(
|
|
||||||
payload: SetLocalPreviewType
|
|
||||||
): ThunkAction<void, RootStateType, unknown, never> {
|
|
||||||
return () => {
|
|
||||||
calling.videoCapturer.setLocalPreview(payload.element);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function setRendererCanvas(
|
function setRendererCanvas(
|
||||||
payload: SetRendererCanvasType
|
payload: SetRendererCanvasType
|
||||||
): ThunkAction<void, RootStateType, unknown, never> {
|
): ThunkAction<void, RootStateType, unknown, never> {
|
||||||
|
@ -2661,7 +2648,6 @@ export const actions = {
|
||||||
setGroupCallVideoRequest,
|
setGroupCallVideoRequest,
|
||||||
setIsCallActive,
|
setIsCallActive,
|
||||||
setLocalAudio,
|
setLocalAudio,
|
||||||
setLocalPreview,
|
|
||||||
setLocalVideo,
|
setLocalVideo,
|
||||||
setOutgoingRing,
|
setOutgoingRing,
|
||||||
setRendererCanvas,
|
setRendererCanvas,
|
||||||
|
@ -3802,8 +3788,7 @@ export function reducer(
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...(action.payload == null ? abortCapturer(state) : state),
|
||||||
capturerBaton: undefined,
|
|
||||||
activeCallState: {
|
activeCallState: {
|
||||||
...activeCallState,
|
...activeCallState,
|
||||||
presentingSource: action.payload,
|
presentingSource: action.payload,
|
||||||
|
|
|
@ -116,6 +116,10 @@ async function notifyForCall(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setLocalPreviewContainer(container: HTMLDivElement | null): void {
|
||||||
|
callingService.setLocalPreviewContainer(container);
|
||||||
|
}
|
||||||
|
|
||||||
const playRingtone = callingTones.playRingtone.bind(callingTones);
|
const playRingtone = callingTones.playRingtone.bind(callingTones);
|
||||||
const stopRingtone = callingTones.stopRingtone.bind(callingTones);
|
const stopRingtone = callingTones.stopRingtone.bind(callingTones);
|
||||||
|
|
||||||
|
@ -449,7 +453,6 @@ export const SmartCallManager = memo(function SmartCallManager() {
|
||||||
setIsCallActive,
|
setIsCallActive,
|
||||||
setLocalAudio,
|
setLocalAudio,
|
||||||
setLocalVideo,
|
setLocalVideo,
|
||||||
setLocalPreview,
|
|
||||||
setOutgoingRing,
|
setOutgoingRing,
|
||||||
setRendererCanvas,
|
setRendererCanvas,
|
||||||
switchToPresentationView,
|
switchToPresentationView,
|
||||||
|
@ -509,7 +512,7 @@ export const SmartCallManager = memo(function SmartCallManager() {
|
||||||
setGroupCallVideoRequest={setGroupCallVideoRequest}
|
setGroupCallVideoRequest={setGroupCallVideoRequest}
|
||||||
setIsCallActive={setIsCallActive}
|
setIsCallActive={setIsCallActive}
|
||||||
setLocalAudio={setLocalAudio}
|
setLocalAudio={setLocalAudio}
|
||||||
setLocalPreview={setLocalPreview}
|
setLocalPreviewContainer={setLocalPreviewContainer}
|
||||||
setLocalVideo={setLocalVideo}
|
setLocalVideo={setLocalVideo}
|
||||||
setOutgoingRing={setOutgoingRing}
|
setOutgoingRing={setOutgoingRing}
|
||||||
setRendererCanvas={setRendererCanvas}
|
setRendererCanvas={setRendererCanvas}
|
||||||
|
|
|
@ -2032,13 +2032,6 @@
|
||||||
"updated": "2024-01-06T00:59:20.678Z",
|
"updated": "2024-01-06T00:59:20.678Z",
|
||||||
"reasonDetail": "Recent bursts shown for burst behavior like throttling."
|
"reasonDetail": "Recent bursts shown for burst behavior like throttling."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "React-useRef",
|
|
||||||
"path": "ts/components/CallScreen.tsx",
|
|
||||||
"line": " const localVideoRef = useRef<HTMLVideoElement | null>(null);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-12-01T01:31:12.757Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "React-useRef",
|
"rule": "React-useRef",
|
||||||
"path": "ts/components/CallScreen.tsx",
|
"path": "ts/components/CallScreen.tsx",
|
||||||
|
@ -2085,13 +2078,6 @@
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2024-01-16T22:59:06.336Z"
|
"updated": "2024-01-16T22:59:06.336Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "React-useRef",
|
|
||||||
"path": "ts/components/CallingLobby.tsx",
|
|
||||||
"line": " const localVideoRef = React.useRef<null | HTMLVideoElement>(null);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-07-30T16:57:33.618Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "React-useRef",
|
"rule": "React-useRef",
|
||||||
"path": "ts/components/CallingPendingParticipants.tsx",
|
"path": "ts/components/CallingPendingParticipants.tsx",
|
||||||
|
@ -2102,11 +2088,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "React-useRef",
|
"rule": "React-useRef",
|
||||||
"path": "ts/components/CallingPip.tsx",
|
"path": "ts/components/CallingPendingParticipants.tsx",
|
||||||
"line": " const localVideoRef = React.useRef(null);",
|
"line": " const lastParticipantRef = React.useRef<ConversationType | undefined>();",
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-10-26T19:12:24.410Z",
|
"updated": "2024-09-20T02:11:27.851Z",
|
||||||
"reasonDetail": "Used to get the local video element for rendering."
|
"reasonDetail": "For fading out, to keep showing the last known participant"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "React-useRef",
|
"rule": "React-useRef",
|
||||||
|
@ -3126,13 +3112,5 @@
|
||||||
"line": " message.innerHTML = window.i18n('icu:optimizingApplication');",
|
"line": " message.innerHTML = window.i18n('icu:optimizingApplication');",
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-09-17T21:02:59.414Z"
|
"updated": "2021-09-17T21:02:59.414Z"
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "React-useRef",
|
|
||||||
"path": "ts/components/CallingPendingParticipants.tsx",
|
|
||||||
"line": " const lastParticipantRef = React.useRef<ConversationType | undefined>();",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2024-09-20T02:11:27.851Z",
|
|
||||||
"reasonDetail": "For fading out, to keep showing the last known participant"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue