ref(thumbnail): use connectionStatus from redux.

pull/8007/head jitsi-meet_5204
Hristo Terezov 4 years ago
parent 1f4cd22875
commit f45af351d8
  1. 14
      conference.js
  2. 10
      modules/UI/videolayout/LargeVideoManager.js
  3. 41
      modules/UI/videolayout/RemoteVideo.js
  4. 25
      modules/UI/videolayout/SmallVideo.js
  5. 1
      react/features/base/conference/functions.js
  6. 47
      react/features/connection-indicator/components/web/ConnectionIndicator.js

@ -1134,20 +1134,6 @@ export default {
return room ? room.getParticipantById(id) : null;
},
/**
* Get participant connection status for the participant.
*
* @param {string} id participant's identifier(MUC nickname)
*
* @returns {ParticipantConnectionStatus|null} the status of the participant
* or null if no such participant is found or participant is the local user.
*/
getParticipantConnectionStatus(id) {
const participant = this.getParticipantById(id);
return participant ? participant.getConnectionStatus() : null;
},
/**
* Gets the display name foe the <tt>JitsiParticipant</tt> identified by
* the given <tt>id</tt>.

@ -12,6 +12,7 @@ import {
JitsiParticipantConnectionStatus
} from '../../../react/features/base/lib-jitsi-meet';
import { VIDEO_TYPE } from '../../../react/features/base/media';
import { getParticipantById } from '../../../react/features/base/participants';
import { CHAT_SIZE } from '../../../react/features/chat';
import {
updateKnownLargeVideoResolution
@ -224,9 +225,8 @@ export default class LargeVideoManager {
const wasUsersImageCached
= !isUserSwitch && container.wasVideoRendered;
const isVideoMuted = !stream || stream.isMuted();
const connectionStatus
= APP.conference.getParticipantConnectionStatus(id);
const participant = getParticipantById(APP.store.getState(), id);
const connectionStatus = participant?.connectionStatus;
const isVideoRenderable
= !isVideoMuted
&& (APP.conference.isLocalId(id)
@ -479,8 +479,8 @@ export default class LargeVideoManager {
*/
showRemoteConnectionMessage(show) {
if (typeof show !== 'boolean') {
const connStatus
= APP.conference.getParticipantConnectionStatus(this.id);
const participant = getParticipantById(APP.store.getState(), this.id);
const connStatus = participant?.connectionStatus;
// eslint-disable-next-line no-param-reassign
show = !APP.conference.isLocalId(this.id)

@ -323,9 +323,11 @@ export default class RemoteVideo extends SmallVideo {
* @private
*/
_figureOutMutedWhileDisconnected() {
const isActive = this.isConnectionActive();
const isVideoMuted
= isRemoteTrackMuted(APP.store.getState()['features/base/tracks'], MEDIA_TYPE.VIDEO, this.id);
const state = APP.store.getState();
const participant = getParticipantById(state, this.id);
const connectionState = participant?.connectionStatus;
const isActive = connectionState === JitsiParticipantConnectionStatus.ACTIVE;
const isVideoMuted = isRemoteTrackMuted(state['features/base/tracks'], MEDIA_TYPE.VIDEO, this.id);
if (!isActive && isVideoMuted) {
this.mutedWhileDisconnected = true;
@ -364,17 +366,6 @@ export default class RemoteVideo extends SmallVideo {
this.updateView();
}
/**
* Checks whether the remote user associated with this <tt>RemoteVideo</tt>
* has connectivity issues.
*
* @return {boolean} <tt>true</tt> if the user's connection is fine or
* <tt>false</tt> otherwise.
*/
isConnectionActive() {
return this.user.getConnectionStatus() === JitsiParticipantConnectionStatus.ACTIVE;
}
/**
* The remote video is considered "playable" once the can play event has been received. It will be allowed to
* display video also in {@link JitsiParticipantConnectionStatus.INTERRUPTED} if the video has received the canplay
@ -386,7 +377,8 @@ export default class RemoteVideo extends SmallVideo {
* @override
*/
isVideoPlayable() {
const connectionState = APP.conference.getParticipantConnectionStatus(this.id);
const participant = getParticipantById(APP.store.getState(), this.id);
const connectionState = participant?.connectionStatus;
return super.isVideoPlayable()
&& this._canPlayEventReceived
@ -399,25 +391,8 @@ export default class RemoteVideo extends SmallVideo {
*/
updateView() {
this.$container.toggleClass('audio-only', APP.conference.isAudioOnly());
this.updateConnectionStatusIndicator();
// This must be called after 'updateConnectionStatusIndicator' because it
// affects the display mode by modifying 'mutedWhileDisconnected' flag
super.updateView();
}
/**
* Updates the UI to reflect user's connectivity status.
*/
updateConnectionStatusIndicator() {
const connectionStatus = this.user.getConnectionStatus();
logger.debug(`${this.id} thumbnail connection status: ${connectionStatus}`);
// FIXME rename 'mutedWhileDisconnected' to 'mutedWhileNotRendering'
// Update 'mutedWhileDisconnected' flag
this._figureOutMutedWhileDisconnected();
this.updateConnectionStatus(connectionStatus);
super.updateView();
}
/**

@ -95,16 +95,6 @@ export default class SmallVideo {
this.videoIsHovered = false;
this.videoType = undefined;
/**
* The current state of the user's bridge connection. The value should be
* a string as enumerated in the library's participantConnectionStatus
* constants.
*
* @private
* @type {string|null}
*/
this._connectionStatus = null;
/**
* Whether or not the connection indicator should be displayed.
*
@ -210,16 +200,6 @@ export default class SmallVideo {
this.updateIndicators();
}
/**
* Updates the connectionStatus stat which displays in the ConnectionIndicator.
* @returns {void}
*/
updateConnectionStatus(connectionStatus) {
this._connectionStatus = connectionStatus;
this.updateIndicators();
}
/**
* Create or updates the ReactElement for displaying status indicators about
* audio mute, video mute, and moderator status.
@ -453,6 +433,7 @@ export default class SmallVideo {
*/
computeDisplayModeInput() {
let isScreenSharing = false;
let connectionStatus;
const state = APP.store.getState();
const participant = getParticipantById(state, this.id);
@ -461,6 +442,7 @@ export default class SmallVideo {
const track = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, this.id);
isScreenSharing = typeof track !== 'undefined' && track.videoType === 'desktop';
connectionStatus = participant.connectionStatus;
}
return {
@ -470,7 +452,7 @@ export default class SmallVideo {
tileViewActive: shouldDisplayTileView(state),
isVideoPlayable: this.isVideoPlayable(),
hasVideo: Boolean(this.selectVideoElement().length),
connectionStatus: APP.conference.getParticipantConnectionStatus(this.id),
connectionStatus,
mutedWhileDisconnected: this.mutedWhileDisconnected,
canPlayEventReceived: this._canPlayEventReceived,
videoStream: Boolean(this.videoStream),
@ -714,7 +696,6 @@ export default class SmallVideo {
{ this._showConnectionIndicator
? <ConnectionIndicator
alwaysVisible = { showConnectionIndicator }
connectionStatus = { this._connectionStatus }
iconSize = { iconSize }
isLocalVideo = { this.isLocal }
enableStatsDisplay = { !interfaceConfig.filmStripOnly }

@ -73,6 +73,7 @@ export function commonUserJoinedHandling(
} else {
dispatch(participantJoined({
botType: user.getBotType(),
connectionStatus: user.getConnectionStatus(),
conference,
id,
name: displayName,

@ -7,6 +7,7 @@ import { translate } from '../../../base/i18n';
import { Icon, IconConnectionActive, IconConnectionInactive } from '../../../base/icons';
import { JitsiParticipantConnectionStatus } from '../../../base/lib-jitsi-meet';
import { MEDIA_TYPE } from '../../../base/media';
import { getLocalParticipant, getParticipantById } from '../../../base/participants';
import { Popover } from '../../../base/popover';
import { connect } from '../../../base/redux';
import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
@ -61,6 +62,12 @@ const QUALITY_TO_WIDTH: Array<Object> = [
*/
type Props = AbstractProps & {
/**
* The current condition of the user's connection, matching one of the
* enumerated values in the library.
*/
_connectionStatus: string,
/**
* Whether or not the component should ignore setting a visibility class for
* hiding the component when the connection quality is not strong.
@ -72,12 +79,6 @@ type Props = AbstractProps & {
*/
audioSsrc: number,
/**
* The current condition of the user's connection, matching one of the
* enumerated values in the library.
*/
connectionStatus: string,
/**
* The Redux dispatch function.
*/
@ -200,13 +201,13 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
* @returns {string}
*/
_getConnectionColorClass() {
const { connectionStatus } = this.props;
const { _connectionStatus } = this.props;
const { percent } = this.state.stats;
const { INACTIVE, INTERRUPTED } = JitsiParticipantConnectionStatus;
if (connectionStatus === INACTIVE) {
if (_connectionStatus === INACTIVE) {
return 'status-other';
} else if (connectionStatus === INTERRUPTED) {
} else if (_connectionStatus === INTERRUPTED) {
return 'status-lost';
} else if (typeof percent === 'undefined') {
return 'status-high';
@ -224,7 +225,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
_getConnectionStatusTip() {
let tipKey;
switch (this.props.connectionStatus) {
switch (this.props._connectionStatus) {
case JitsiParticipantConnectionStatus.INTERRUPTED:
tipKey = 'connectionindicator.quality.lost';
break;
@ -275,12 +276,12 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
* @returns {string}
*/
_getVisibilityClass() {
const { connectionStatus } = this.props;
const { _connectionStatus } = this.props;
return this.state.showIndicator
|| this.props.alwaysVisible
|| connectionStatus === JitsiParticipantConnectionStatus.INTERRUPTED
|| connectionStatus === JitsiParticipantConnectionStatus.INACTIVE
|| _connectionStatus === JitsiParticipantConnectionStatus.INTERRUPTED
|| _connectionStatus === JitsiParticipantConnectionStatus.INACTIVE
? 'show-connection-indicator' : 'hide-connection-indicator';
}
@ -304,7 +305,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
* @returns {ReactElement}
*/
_renderIcon() {
if (this.props.connectionStatus
if (this.props._connectionStatus
=== JitsiParticipantConnectionStatus.INACTIVE) {
return (
<span className = 'connection_ninja'>
@ -319,7 +320,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
let iconWidth;
let emptyIconWrapperClassName = 'connection_empty';
if (this.props.connectionStatus
if (this.props._connectionStatus
=== JitsiParticipantConnectionStatus.INTERRUPTED) {
// emptyIconWrapperClassName is used by the torture tests to
@ -434,21 +435,29 @@ export function _mapDispatchToProps(dispatch: Dispatch<any>) {
* @returns {Props}
*/
export function _mapStateToProps(state: Object, ownProps: Props) {
const { participantId } = ownProps;
const conference = state['features/base/conference'].conference;
const participant
= typeof participantId === 'undefined' ? getLocalParticipant(state) : getParticipantById(state, participantId);
const props = {
_connectionStatus: participant?.connectionStatus
};
if (conference) {
const firstVideoTrack = getTrackByMediaTypeAndParticipant(
state['features/base/tracks'], MEDIA_TYPE.VIDEO, ownProps.participantId);
state['features/base/tracks'], MEDIA_TYPE.VIDEO, participantId);
const firstAudioTrack = getTrackByMediaTypeAndParticipant(
state['features/base/tracks'], MEDIA_TYPE.AUDIO, ownProps.participantId);
state['features/base/tracks'], MEDIA_TYPE.AUDIO, participantId);
return {
...props,
audioSsrc: firstAudioTrack ? conference.getSsrcByTrack(firstAudioTrack.jitsiTrack) : undefined,
videoSsrc: firstVideoTrack ? conference.getSsrcByTrack(firstVideoTrack.jitsiTrack) : undefined
};
}
return {};
return {
...props
};
}
export default translate(connect(_mapStateToProps, _mapDispatchToProps)(ConnectionIndicator));

Loading…
Cancel
Save