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:
prlanzarin 2023-02-14 17:44:45 -03:00
parent f2a3031b04
commit e9f0a7347c
2 changed files with 12 additions and 41 deletions

View File

@ -26,7 +26,7 @@ const VideoListItem = (props) => {
makeDragOperations, dragging, draggingOver, isRTL
} = props;
const [videoIsReady, setVideoIsReady] = useState(false);
const [videoDataLoaded, setVideoDataLoaded] = useState(false);
const [isStreamHealthy, setIsStreamHealthy] = useState(false);
const [isMirrored, setIsMirrored] = useState(VideoService.mirrorOwnWebcam(user?.userId));
const [isVideoSqueezed, setIsVideoSqueezed] = useState(false);
@ -41,7 +41,7 @@ const VideoListItem = (props) => {
const videoTag = useRef();
const videoContainer = useRef();
const shouldRenderReconnect = !isStreamHealthy && videoIsReady;
const videoIsReady = isStreamHealthy && videoDataLoaded;
const { animations } = Settings.application;
const talking = voiceUser?.talking;
@ -49,14 +49,11 @@ const VideoListItem = (props) => {
const { streamState } = e.detail;
const newHealthState = !isStreamStateUnhealthy(streamState);
e.stopPropagation();
if (newHealthState !== isStreamHealthy) {
setIsStreamHealthy(newHealthState);
}
setIsStreamHealthy(newHealthState);
};
const handleSetVideoIsReady = () => {
setVideoIsReady(true);
const onLoadedData = () => {
setVideoDataLoaded(true);
window.dispatchEvent(new Event('resize'));
/* used when re-sharing cameras after leaving a breakout room.
@ -71,10 +68,10 @@ const VideoListItem = (props) => {
onVideoItemMount(videoTag.current);
subscribeToStreamStateChange(cameraId, onStreamStateChange);
resizeObserver.observe(videoContainer.current);
videoTag?.current?.addEventListener('loadeddata', handleSetVideoIsReady);
videoTag?.current?.addEventListener('loadeddata', onLoadedData);
return () => {
videoTag?.current?.removeEventListener('loadeddata', handleSetVideoIsReady);
videoTag?.current?.removeEventListener('loadeddata', onLoadedData);
resizeObserver.disconnect();
};
}, []);
@ -96,10 +93,10 @@ const VideoListItem = (props) => {
// 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
// see https://bugs.chromium.org/p/chromium/issues/detail?id=382879
if (videoIsReady) {
if (videoDataLoaded) {
playElement(videoTag.current);
}
}, [videoIsReady]);
}, [videoDataLoaded]);
// component will unmount
useEffect(() => () => {
@ -130,7 +127,7 @@ const VideoListItem = (props) => {
<UserAvatarVideo
user={user}
voiceUser={voiceUser}
unhealthyStream={shouldRenderReconnect}
unhealthyStream={videoDataLoaded && !isStreamHealthy}
squeezed={false}
/>
<Styled.BottomBar>
@ -158,7 +155,7 @@ const VideoListItem = (props) => {
>
<UserAvatarVideo
user={user}
unhealthyStream={shouldRenderReconnect}
unhealthyStream={videoDataLoaded && !isStreamHealthy}
squeezed
/>
{renderSqueezedButton()}
@ -213,7 +210,7 @@ const VideoListItem = (props) => {
<Styled.VideoContainer>
<Styled.Video
mirrored={isMirrored}
unhealthyStream={shouldRenderReconnect}
unhealthyStream={videoDataLoaded && !isStreamHealthy}
data-test={isMirrored ? 'mirroredVideoContainer' : 'videoContainer'}
ref={videoTag}
autoPlay
@ -229,8 +226,6 @@ const VideoListItem = (props) => {
: (isVideoSqueezed)
? renderWebcamConnectingSqueezed()
: renderWebcamConnecting()}
{shouldRenderReconnect && <Styled.Reconnecting animations={animations} />}
</Styled.Content>
);
};

View File

@ -109,29 +109,6 @@ const LoadingText = styled(TextElipsis)`
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`
display: flex;
justify-content: center;
@ -180,7 +157,6 @@ export default {
Content,
WebcamConnecting,
LoadingText,
Reconnecting,
VideoContainer,
Video,
TopBar,