fix(video): properly render reconnecting view
The stream state change handler in video-list-item is using a component state reference inside a DOM event callback - which means it is always presuming `isStreamHealthy` is false (initial value). That prevents the health state from actually transitioning when necessary (and consequently rendering the reconnecting view in video-list item). This commit removes the state-based transition check in the state change handler and unifies the reconnecting view to use the username placeholde (replacing the loading spinners).
This commit is contained in:
parent
f2a3031b04
commit
e9f0a7347c
@ -26,7 +26,7 @@ const VideoListItem = (props) => {
|
|||||||
makeDragOperations, dragging, draggingOver, isRTL
|
makeDragOperations, dragging, draggingOver, isRTL
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [videoIsReady, setVideoIsReady] = useState(false);
|
const [videoDataLoaded, setVideoDataLoaded] = useState(false);
|
||||||
const [isStreamHealthy, setIsStreamHealthy] = useState(false);
|
const [isStreamHealthy, setIsStreamHealthy] = useState(false);
|
||||||
const [isMirrored, setIsMirrored] = useState(VideoService.mirrorOwnWebcam(user?.userId));
|
const [isMirrored, setIsMirrored] = useState(VideoService.mirrorOwnWebcam(user?.userId));
|
||||||
const [isVideoSqueezed, setIsVideoSqueezed] = useState(false);
|
const [isVideoSqueezed, setIsVideoSqueezed] = useState(false);
|
||||||
@ -41,7 +41,7 @@ const VideoListItem = (props) => {
|
|||||||
const videoTag = useRef();
|
const videoTag = useRef();
|
||||||
const videoContainer = useRef();
|
const videoContainer = useRef();
|
||||||
|
|
||||||
const shouldRenderReconnect = !isStreamHealthy && videoIsReady;
|
const videoIsReady = isStreamHealthy && videoDataLoaded;
|
||||||
const { animations } = Settings.application;
|
const { animations } = Settings.application;
|
||||||
const talking = voiceUser?.talking;
|
const talking = voiceUser?.talking;
|
||||||
|
|
||||||
@ -49,14 +49,11 @@ const VideoListItem = (props) => {
|
|||||||
const { streamState } = e.detail;
|
const { streamState } = e.detail;
|
||||||
const newHealthState = !isStreamStateUnhealthy(streamState);
|
const newHealthState = !isStreamStateUnhealthy(streamState);
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
setIsStreamHealthy(newHealthState);
|
||||||
if (newHealthState !== isStreamHealthy) {
|
|
||||||
setIsStreamHealthy(newHealthState);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSetVideoIsReady = () => {
|
const onLoadedData = () => {
|
||||||
setVideoIsReady(true);
|
setVideoDataLoaded(true);
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
|
|
||||||
/* used when re-sharing cameras after leaving a breakout room.
|
/* used when re-sharing cameras after leaving a breakout room.
|
||||||
@ -71,10 +68,10 @@ const VideoListItem = (props) => {
|
|||||||
onVideoItemMount(videoTag.current);
|
onVideoItemMount(videoTag.current);
|
||||||
subscribeToStreamStateChange(cameraId, onStreamStateChange);
|
subscribeToStreamStateChange(cameraId, onStreamStateChange);
|
||||||
resizeObserver.observe(videoContainer.current);
|
resizeObserver.observe(videoContainer.current);
|
||||||
videoTag?.current?.addEventListener('loadeddata', handleSetVideoIsReady);
|
videoTag?.current?.addEventListener('loadeddata', onLoadedData);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
videoTag?.current?.removeEventListener('loadeddata', handleSetVideoIsReady);
|
videoTag?.current?.removeEventListener('loadeddata', onLoadedData);
|
||||||
resizeObserver.disconnect();
|
resizeObserver.disconnect();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
@ -96,10 +93,10 @@ const VideoListItem = (props) => {
|
|||||||
// This is here to prevent the videos from freezing when they're
|
// This is here to prevent the videos from freezing when they're
|
||||||
// moved around the dom by react, e.g., when changing the user status
|
// moved around the dom by react, e.g., when changing the user status
|
||||||
// see https://bugs.chromium.org/p/chromium/issues/detail?id=382879
|
// see https://bugs.chromium.org/p/chromium/issues/detail?id=382879
|
||||||
if (videoIsReady) {
|
if (videoDataLoaded) {
|
||||||
playElement(videoTag.current);
|
playElement(videoTag.current);
|
||||||
}
|
}
|
||||||
}, [videoIsReady]);
|
}, [videoDataLoaded]);
|
||||||
|
|
||||||
// component will unmount
|
// component will unmount
|
||||||
useEffect(() => () => {
|
useEffect(() => () => {
|
||||||
@ -130,7 +127,7 @@ const VideoListItem = (props) => {
|
|||||||
<UserAvatarVideo
|
<UserAvatarVideo
|
||||||
user={user}
|
user={user}
|
||||||
voiceUser={voiceUser}
|
voiceUser={voiceUser}
|
||||||
unhealthyStream={shouldRenderReconnect}
|
unhealthyStream={videoDataLoaded && !isStreamHealthy}
|
||||||
squeezed={false}
|
squeezed={false}
|
||||||
/>
|
/>
|
||||||
<Styled.BottomBar>
|
<Styled.BottomBar>
|
||||||
@ -158,7 +155,7 @@ const VideoListItem = (props) => {
|
|||||||
>
|
>
|
||||||
<UserAvatarVideo
|
<UserAvatarVideo
|
||||||
user={user}
|
user={user}
|
||||||
unhealthyStream={shouldRenderReconnect}
|
unhealthyStream={videoDataLoaded && !isStreamHealthy}
|
||||||
squeezed
|
squeezed
|
||||||
/>
|
/>
|
||||||
{renderSqueezedButton()}
|
{renderSqueezedButton()}
|
||||||
@ -213,7 +210,7 @@ const VideoListItem = (props) => {
|
|||||||
<Styled.VideoContainer>
|
<Styled.VideoContainer>
|
||||||
<Styled.Video
|
<Styled.Video
|
||||||
mirrored={isMirrored}
|
mirrored={isMirrored}
|
||||||
unhealthyStream={shouldRenderReconnect}
|
unhealthyStream={videoDataLoaded && !isStreamHealthy}
|
||||||
data-test={isMirrored ? 'mirroredVideoContainer' : 'videoContainer'}
|
data-test={isMirrored ? 'mirroredVideoContainer' : 'videoContainer'}
|
||||||
ref={videoTag}
|
ref={videoTag}
|
||||||
autoPlay
|
autoPlay
|
||||||
@ -229,8 +226,6 @@ const VideoListItem = (props) => {
|
|||||||
: (isVideoSqueezed)
|
: (isVideoSqueezed)
|
||||||
? renderWebcamConnectingSqueezed()
|
? renderWebcamConnectingSqueezed()
|
||||||
: renderWebcamConnecting()}
|
: renderWebcamConnecting()}
|
||||||
|
|
||||||
{shouldRenderReconnect && <Styled.Reconnecting animations={animations} />}
|
|
||||||
</Styled.Content>
|
</Styled.Content>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -109,29 +109,6 @@ const LoadingText = styled(TextElipsis)`
|
|||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Reconnecting = styled.div`
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
z-index: 1;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: transparent;
|
|
||||||
color: ${colorWhite};
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
font-family: 'bbb-icons' !important;
|
|
||||||
content: "\\e949";
|
|
||||||
/* ascii code for the ellipsis character */
|
|
||||||
display: inline-block;
|
|
||||||
${({ animations }) => animations && css`
|
|
||||||
animation: ${rotate360} 2s infinite linear;
|
|
||||||
`}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const VideoContainer = styled.div`
|
const VideoContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -180,7 +157,6 @@ export default {
|
|||||||
Content,
|
Content,
|
||||||
WebcamConnecting,
|
WebcamConnecting,
|
||||||
LoadingText,
|
LoadingText,
|
||||||
Reconnecting,
|
|
||||||
VideoContainer,
|
VideoContainer,
|
||||||
Video,
|
Video,
|
||||||
TopBar,
|
TopBar,
|
||||||
|
Loading…
Reference in New Issue
Block a user