fix(filmstrip) Add handlers for track streaming status on RN. (#11584)
* fix(filmstrip) Add handlers for track streaming status on RN. This is needed for switching between video and avatar when the track's streaming status changes in source-name signaling mode. * squash: Add comment.
This commit is contained in:
parent
6ea7ab2b46
commit
ad70f12cb4
|
@ -7,7 +7,7 @@ import { i18next } from '../../base/i18n';
|
|||
import { isStageFilmstripAvailable } from '../../filmstrip/functions';
|
||||
import { GRAVATAR_BASE_URL, isCORSAvatarURL } from '../avatar';
|
||||
import { getMultipleVideoSupportFeatureFlag, getSourceNameSignalingFeatureFlag } from '../config';
|
||||
import { JitsiParticipantConnectionStatus } from '../lib-jitsi-meet';
|
||||
import { JitsiParticipantConnectionStatus, JitsiTrackStreamingStatus } from '../lib-jitsi-meet';
|
||||
import { shouldRenderVideoTrack } from '../media';
|
||||
import { toState } from '../redux';
|
||||
import { getScreenShareTrack, getVideoTrackByParticipant } from '../tracks';
|
||||
|
@ -484,11 +484,21 @@ export function shouldRenderParticipantVideo(stateful: Object | Function, id: st
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Then check if the participant connection is active. */
|
||||
const connectionStatus = participant.connectionStatus || JitsiParticipantConnectionStatus.ACTIVE;
|
||||
/* Then check if the participant connection or track streaming status is active. */
|
||||
if (getSourceNameSignalingFeatureFlag(state)) {
|
||||
// Note that this will work only if a listener is registered for the track's TrackStreamingStatus.
|
||||
// The associated TrackStreamingStatusImpl instance is not created or disposed when there are zero listeners.
|
||||
if (videoTrack
|
||||
&& !videoTrack.local
|
||||
&& videoTrack.jitsiTrack?.getTrackStreamingStatus() !== JitsiTrackStreamingStatus.ACTIVE) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
const connectionStatus = participant.connectionStatus || JitsiParticipantConnectionStatus.ACTIVE;
|
||||
|
||||
if (connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE) {
|
||||
return false;
|
||||
if (connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Then check if audio-only mode is not active. */
|
||||
|
|
|
@ -4,7 +4,8 @@ import React, { PureComponent } from 'react';
|
|||
import { Image, View } from 'react-native';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { getMultipleVideoSupportFeatureFlag } from '../../../base/config';
|
||||
import { getMultipleVideoSupportFeatureFlag, getSourceNameSignalingFeatureFlag } from '../../../base/config';
|
||||
import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE } from '../../../base/media';
|
||||
import {
|
||||
PARTICIPANT_ROLE,
|
||||
|
@ -18,7 +19,11 @@ import {
|
|||
} from '../../../base/participants';
|
||||
import { Container } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
|
||||
import {
|
||||
getTrackByMediaTypeAndParticipant,
|
||||
getVideoTrackByParticipant,
|
||||
trackStreamingStatusChanged
|
||||
} from '../../../base/tracks';
|
||||
import { ConnectionIndicator } from '../../../connection-indicator';
|
||||
import { DisplayNameLabel } from '../../../display-name';
|
||||
import { getGifDisplayMode, getGifForParticipant } from '../../../gifs/functions';
|
||||
|
@ -109,6 +114,16 @@ type Props = {
|
|||
*/
|
||||
_renderModeratorIndicator: boolean,
|
||||
|
||||
/**
|
||||
* Whether source name signaling is enabled.
|
||||
*/
|
||||
_sourceNameSignalingEnabled: boolean,
|
||||
|
||||
/**
|
||||
* The video track that will be displayed in the thumbnail.
|
||||
*/
|
||||
_videoTrack: ?Object,
|
||||
|
||||
/**
|
||||
* Invoked to trigger state changes in Redux.
|
||||
*/
|
||||
|
@ -151,6 +166,7 @@ class Thumbnail extends PureComponent<Props> {
|
|||
|
||||
this._onClick = this._onClick.bind(this);
|
||||
this._onThumbnailLongPress = this._onThumbnailLongPress.bind(this);
|
||||
this.handleTrackStreamingStatusChanged = this.handleTrackStreamingStatusChanged.bind(this);
|
||||
}
|
||||
|
||||
_onClick: () => void;
|
||||
|
@ -245,6 +261,86 @@ class Thumbnail extends PureComponent<Props> {
|
|||
return indicators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts listening for track streaming status updates after the initial render.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
*/
|
||||
componentDidMount() {
|
||||
// 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()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops listening for track streaming status updates on the old track and starts listening instead on the new
|
||||
* track.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
*/
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
// 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
|
@ -289,7 +385,7 @@ class Thumbnail extends PureComponent<Props> {
|
|||
: <>
|
||||
<ParticipantView
|
||||
avatarSize = { tileView ? AVATAR_SIZE * 1.5 : AVATAR_SIZE }
|
||||
disableVideo = { isScreenShare || _isFakeParticipant }
|
||||
disableVideo = { (isScreenShare && !_isVirtualScreenshare) || _isFakeParticipant }
|
||||
participantId = { participantId }
|
||||
zOrder = { 1 } />
|
||||
{
|
||||
|
@ -317,7 +413,7 @@ function _mapStateToProps(state, ownProps) {
|
|||
const localParticipantId = getLocalParticipant(state).id;
|
||||
const id = participant?.id;
|
||||
const audioTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.AUDIO, id);
|
||||
const videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, id);
|
||||
const videoTrack = getVideoTrackByParticipant(tracks, participant);
|
||||
const isMultiStreamSupportEnabled = getMultipleVideoSupportFeatureFlag(state);
|
||||
const isScreenShare = videoTrack?.videoType === VIDEO_TYPE.DESKTOP;
|
||||
const participantCount = getParticipantCount(state);
|
||||
|
@ -341,7 +437,9 @@ function _mapStateToProps(state, ownProps) {
|
|||
_pinned: participant?.pinned,
|
||||
_raisedHand: hasRaisedHand(participant),
|
||||
_renderDominantSpeakerIndicator: renderDominantSpeakerIndicator,
|
||||
_renderModeratorIndicator: renderModeratorIndicator
|
||||
_renderModeratorIndicator: renderModeratorIndicator,
|
||||
_sourceNameSignalingEnabled: getSourceNameSignalingFeatureFlag(state),
|
||||
_videoTrack: videoTrack
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -422,7 +422,7 @@ class Thumbnail extends Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Starts listening for audio level updates after the initial render.
|
||||
* Starts listening for track streaming status updates after the initial render.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
|
@ -464,7 +464,7 @@ class Thumbnail extends Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stops listening for audio level updates on the old track and starts
|
||||
* Stops listening for track streaming status updates on the old track and starts
|
||||
* listening instead on the new track.
|
||||
*
|
||||
* @inheritdoc
|
||||
|
|
Loading…
Reference in New Issue