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 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>
); );
}; };

View File

@ -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,