fix: disabled connectStatusIndicatorIcon cause video not displayed (#11377)

* add and remove JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED listener in middlewares

* add/remove listeners in components that use track streaming status

* remove track streaming status handler from ConnectionIndicatorIcon and ConnectionIndicatorContent

* check video track change before hanlding track streaming status
This commit is contained in:
pangrr 2022-04-26 16:33:50 -04:00 committed by GitHub
parent 0ae2693116
commit c03d86e0e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 5 deletions

View File

@ -11,13 +11,15 @@ import { Avatar } from '../../../react/features/base/avatar';
import theme from '../../../react/features/base/components/themes/participantsPaneTheme.json';
import { getSourceNameSignalingFeatureFlag } from '../../../react/features/base/config';
import { i18next } from '../../../react/features/base/i18n';
import { JitsiTrackEvents } from '../../../react/features/base/lib-jitsi-meet';
import { VIDEO_TYPE } from '../../../react/features/base/media';
import {
getParticipantById,
getParticipantDisplayName
} from '../../../react/features/base/participants';
import {
getVideoTrackByParticipant
getVideoTrackByParticipant,
trackStreamingStatusChanged
} from '../../../react/features/base/tracks';
import { CHAT_SIZE } from '../../../react/features/chat';
import {
@ -116,6 +118,14 @@ export default class LargeVideoManager {
*/
this._videoAspectRatio = 0;
/**
* The video track in effect.
* This is used to add and remove listeners on track streaming status change.
*
* @type {Object}
*/
this.videoTrack = undefined;
this.$container = $('#largeVideoContainer');
this.$container.css({
@ -242,6 +252,26 @@ export default class LargeVideoManager {
const tracks = state['features/base/tracks'];
const videoTrack = getVideoTrackByParticipant(tracks, participant);
// Remove track streaming status listener from the old track and add it to the new track,
// in order to stop updating track streaming status for the old track and start it for the new track.
// TODO: when this class is converted to a function react component,
// use a custom hook to update a local track streaming status.
if (this.videoTrack?.jitsiTrack?.getSourceName() !== videoTrack?.jitsiTrack?.getSourceName()) {
if (this.videoTrack) {
this.videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
this.handleTrackStreamingStatusChanged);
APP.store.dispatch(trackStreamingStatusChanged(this.videoTrack.jitsiTrack,
this.videoTrack.jitsiTrack.getTrackStreamingStatus()));
}
if (videoTrack && !videoTrack.local) {
this.videoTrack = videoTrack;
this.videoTrack.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
this.handleTrackStreamingStatusChanged);
APP.store.dispatch(trackStreamingStatusChanged(this.videoTrack.jitsiTrack,
this.videoTrack.jitsiTrack.getTrackStreamingStatus()));
}
}
isVideoRenderable = !isVideoMuted && (
APP.conference.isLocalId(id)
|| participant?.isLocalScreenShare
@ -340,6 +370,19 @@ export default class LargeVideoManager {
});
}
/**
* Handle track streaming status change event by
* by dispatching an action to update track streaming status for the given track in app state.
*
* @param {JitsiTrack} jitsiTrack the track with streaming status updated
* @param {JitsiTrackStreamingStatus} streamingStatus the updated track streaming status
*
* @private
*/
handleTrackStreamingStatusChanged(jitsiTrack, streamingStatus) {
APP.store.dispatch(trackStreamingStatusChanged(jitsiTrack, streamingStatus));
}
/**
* Shows/hides notification about participant's connectivity issues to be
* shown on the large video area.

View File

@ -52,12 +52,14 @@ export const ConnectionIndicatorIcon = ({
}: Props) => {
const sourceNameSignalingEnabled = useSelector(state => getSourceNameSignalingFeatureFlag(state));
const dispatch = useDispatch();
const sourceName = track?.jitsiTrack?.getSourceName?.();
const sourceName = track?.jitsiTrack?.getSourceName();
const handleTrackStreamingStatusChanged = streamingStatus => {
dispatch(trackStreamingStatusChanged(track.jitsiTrack, streamingStatus));
};
// TODO: replace this with a custom hook to be reused where track streaming status is needed.
// TODO: In the hood the listener should updates a local track streaming status instead of that in redux store.
useEffect(() => {
if (track && !track.local && sourceNameSignalingEnabled) {
track.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED, handleTrackStreamingStatusChanged);

View File

@ -9,6 +9,7 @@ import { createScreenSharingIssueEvent, sendAnalytics } from '../../../analytics
import { Avatar } from '../../../base/avatar';
import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
import { isMobileBrowser } from '../../../base/environment/utils';
import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet';
import { MEDIA_TYPE, VideoTrack } from '../../../base/media';
import {
getLocalParticipant,
@ -24,7 +25,8 @@ import {
getLocalVideoTrack,
getTrackByMediaTypeAndParticipant,
getFakeScreenshareParticipantTrack,
updateLastTrackVideoMediaEvent
updateLastTrackVideoMediaEvent,
trackStreamingStatusChanged
} from '../../../base/tracks';
import { getVideoObjectPosition } from '../../../face-landmarks/functions';
import { hideGif, showGif } from '../../../gifs/actions';
@ -54,6 +56,7 @@ import ThumbnailAudioIndicator from './ThumbnailAudioIndicator';
import ThumbnailBottomIndicators from './ThumbnailBottomIndicators';
import ThumbnailTopIndicators from './ThumbnailTopIndicators';
declare var interfaceConfig: Object;
/**
@ -244,7 +247,12 @@ export type Props = {|
/**
* Styles that will be set to the Thumbnail's main span element.
*/
style?: ?Object
style?: ?Object,
/**
* Whether source name signaling is enabled.
*/
_sourceNameSignalingEnabled: boolean
|};
const defaultStyles = theme => {
@ -404,6 +412,7 @@ class Thumbnail extends Component<Props, State> {
this._hidePopover = this._hidePopover.bind(this);
this._onGifMouseEnter = this._onGifMouseEnter.bind(this);
this._onGifMouseLeave = this._onGifMouseLeave.bind(this);
this.handleTrackStreamingStatusChanged = this.handleTrackStreamingStatusChanged.bind(this);
}
/**
@ -414,6 +423,38 @@ class Thumbnail extends Component<Props, State> {
*/
componentDidMount() {
this._onDisplayModeChanged();
// Listen to track streaming status changed event to keep it updated.
// TODO: after converting this component to a react function component,
// use a custom hook to update local track streaming status.
const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
if (_sourceNameSignalingEnabled && _videoTrack && !_videoTrack.local) {
_videoTrack.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
this.handleTrackStreamingStatusChanged);
dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
_videoTrack.jitsiTrack.getTrackStreamingStatus()));
}
}
/**
* Remove listeners for track streaming status update.
*
* @inheritdoc
* @returns {void}
*/
componentWillUnmount() {
// TODO: after converting this component to a react function component,
// use a custom hook to update local track streaming status.
const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
if (_sourceNameSignalingEnabled && _videoTrack && !_videoTrack.local) {
_videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
this.handleTrackStreamingStatusChanged);
dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
_videoTrack.jitsiTrack.getTrackStreamingStatus()));
}
}
/**
@ -427,6 +468,38 @@ class Thumbnail extends Component<Props, State> {
if (prevState.displayMode !== this.state.displayMode) {
this._onDisplayModeChanged();
}
// TODO: after converting this component to a react function component,
// use a custom hook to update local track streaming status.
const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
if (_sourceNameSignalingEnabled
&& prevProps._videoTrack?.jitsiTrack?.getSourceName() !== _videoTrack?.jitsiTrack?.getSourceName()) {
if (prevProps._videoTrack && !prevProps._videoTrack.local) {
prevProps._videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
this.handleTrackStreamingStatusChanged);
dispatch(trackStreamingStatusChanged(prevProps._videoTrack.jitsiTrack,
prevProps._videoTrack.jitsiTrack.getTrackStreamingStatus()));
}
if (_videoTrack && !_videoTrack.local) {
_videoTrack.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
this.handleTrackStreamingStatusChanged);
dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
_videoTrack.jitsiTrack.getTrackStreamingStatus()));
}
}
}
/**
* Handle track streaming status change event by
* by dispatching an action to update track streaming status for the given track in app state.
*
* @param {JitsiTrack} jitsiTrack - The track with streaming status updated.
* @param {JitsiTrackStreamingStatus} streamingStatus - The updated track streaming status.
* @returns {void}
*/
handleTrackStreamingStatusChanged(jitsiTrack, streamingStatus) {
this.props.dispatch(trackStreamingStatusChanged(jitsiTrack, streamingStatus));
}
/**
@ -1212,7 +1285,8 @@ function _mapStateToProps(state, ownProps): Object {
_videoObjectPosition: getVideoObjectPosition(state, participant?.id),
_videoTrack,
...size,
_gifSrc: mode === 'chat' ? null : gifSrc
_gifSrc: mode === 'chat' ? null : gifSrc,
_sourceNameSignalingEnabled: sourceNameSignalingEnabled
};
}