ref(StatusIndicators): Use video muted from redux.
This commit is contained in:
parent
3657c19e60
commit
ca2343c31a
|
@ -3039,7 +3039,7 @@ export default {
|
||||||
* @param {boolean} muted - New muted status.
|
* @param {boolean} muted - New muted status.
|
||||||
*/
|
*/
|
||||||
setVideoMuteStatus(muted) {
|
setVideoMuteStatus(muted) {
|
||||||
APP.UI.setVideoMuted(this.getMyUserId(), muted);
|
APP.UI.setVideoMuted(this.getMyUserId());
|
||||||
APP.API.notifyVideoMutedStatusChanged(muted);
|
APP.API.notifyVideoMutedStatusChanged(muted);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -366,8 +366,8 @@ UI.setAudioMuted = function(id, muted) {
|
||||||
/**
|
/**
|
||||||
* Sets muted video state for participant
|
* Sets muted video state for participant
|
||||||
*/
|
*/
|
||||||
UI.setVideoMuted = function(id, muted) {
|
UI.setVideoMuted = function(id) {
|
||||||
VideoLayout.onVideoMute(id, muted);
|
VideoLayout.onVideoMute(id);
|
||||||
if (APP.conference.isLocalId(id)) {
|
if (APP.conference.isLocalId(id)) {
|
||||||
APP.conference.updateVideoIconEnabled();
|
APP.conference.updateVideoIconEnabled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ export default class SharedVideoThumb extends SmallVideo {
|
||||||
this.$container = $(this.container);
|
this.$container = $(this.container);
|
||||||
this._setThumbnailSize();
|
this._setThumbnailSize();
|
||||||
this.bindHoverHandler();
|
this.bindHoverHandler();
|
||||||
this.isVideoMuted = true;
|
|
||||||
this.updateDisplayName();
|
this.updateDisplayName();
|
||||||
this.container.onclick = this._onContainerClick;
|
this.container.onclick = this._onContainerClick;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ export default class LocalVideo extends SmallVideo {
|
||||||
|
|
||||||
this.addAudioLevelIndicator();
|
this.addAudioLevelIndicator();
|
||||||
this.updateIndicators();
|
this.updateIndicators();
|
||||||
|
this.updateStatusBar();
|
||||||
|
|
||||||
this.container.onclick = this._onContainerClick;
|
this.container.onclick = this._onContainerClick;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,13 @@ import { i18next } from '../../../react/features/base/i18n';
|
||||||
import {
|
import {
|
||||||
JitsiParticipantConnectionStatus
|
JitsiParticipantConnectionStatus
|
||||||
} from '../../../react/features/base/lib-jitsi-meet';
|
} from '../../../react/features/base/lib-jitsi-meet';
|
||||||
|
import { MEDIA_TYPE } from '../../../react/features/base/media';
|
||||||
import {
|
import {
|
||||||
|
getParticipantById,
|
||||||
getPinnedParticipant,
|
getPinnedParticipant,
|
||||||
pinParticipant
|
pinParticipant
|
||||||
} from '../../../react/features/base/participants';
|
} from '../../../react/features/base/participants';
|
||||||
|
import { isRemoteTrackMuted } from '../../../react/features/base/tracks';
|
||||||
import { PresenceLabel } from '../../../react/features/presence-status';
|
import { PresenceLabel } from '../../../react/features/presence-status';
|
||||||
import {
|
import {
|
||||||
REMOTE_CONTROL_MENU_STATES,
|
REMOTE_CONTROL_MENU_STATES,
|
||||||
|
@ -310,11 +313,10 @@ export default class RemoteVideo extends SmallVideo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Video muted status changed handler.
|
||||||
* @override
|
|
||||||
*/
|
*/
|
||||||
setVideoMutedView(isMuted) {
|
onVideoMute() {
|
||||||
super.setVideoMutedView(isMuted);
|
super.updateView();
|
||||||
|
|
||||||
// Update 'mutedWhileDisconnected' flag
|
// Update 'mutedWhileDisconnected' flag
|
||||||
this._figureOutMutedWhileDisconnected();
|
this._figureOutMutedWhileDisconnected();
|
||||||
|
@ -328,10 +330,12 @@ export default class RemoteVideo extends SmallVideo {
|
||||||
*/
|
*/
|
||||||
_figureOutMutedWhileDisconnected() {
|
_figureOutMutedWhileDisconnected() {
|
||||||
const isActive = this.isConnectionActive();
|
const isActive = this.isConnectionActive();
|
||||||
|
const isVideoMuted
|
||||||
|
= isRemoteTrackMuted(APP.store.getState()['features/base/tracks'], MEDIA_TYPE.VIDEO, this.id);
|
||||||
|
|
||||||
if (!isActive && this.isVideoMuted) {
|
if (!isActive && isVideoMuted) {
|
||||||
this.mutedWhileDisconnected = true;
|
this.mutedWhileDisconnected = true;
|
||||||
} else if (isActive && !this.isVideoMuted) {
|
} else if (isActive && !isVideoMuted) {
|
||||||
this.mutedWhileDisconnected = false;
|
this.mutedWhileDisconnected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,15 @@ import { Provider } from 'react-redux';
|
||||||
import { AudioLevelIndicator } from '../../../react/features/audio-level-indicator';
|
import { AudioLevelIndicator } from '../../../react/features/audio-level-indicator';
|
||||||
import { Avatar as AvatarDisplay } from '../../../react/features/base/avatar';
|
import { Avatar as AvatarDisplay } from '../../../react/features/base/avatar';
|
||||||
import { i18next } from '../../../react/features/base/i18n';
|
import { i18next } from '../../../react/features/base/i18n';
|
||||||
|
import { MEDIA_TYPE } from '../../../react/features/base/media';
|
||||||
import {
|
import {
|
||||||
|
getLocalParticipant,
|
||||||
|
getParticipantById,
|
||||||
getParticipantCount,
|
getParticipantCount,
|
||||||
getPinnedParticipant,
|
getPinnedParticipant,
|
||||||
pinParticipant
|
pinParticipant
|
||||||
} from '../../../react/features/base/participants';
|
} from '../../../react/features/base/participants';
|
||||||
|
import { isLocalTrackMuted, isRemoteTrackMuted } from '../../../react/features/base/tracks';
|
||||||
import { ConnectionIndicator } from '../../../react/features/connection-indicator';
|
import { ConnectionIndicator } from '../../../react/features/connection-indicator';
|
||||||
import { DisplayName } from '../../../react/features/display-name';
|
import { DisplayName } from '../../../react/features/display-name';
|
||||||
import {
|
import {
|
||||||
|
@ -82,7 +86,6 @@ export default class SmallVideo {
|
||||||
*/
|
*/
|
||||||
constructor(VideoLayout) {
|
constructor(VideoLayout) {
|
||||||
this.isAudioMuted = false;
|
this.isAudioMuted = false;
|
||||||
this.isVideoMuted = false;
|
|
||||||
this.isScreenSharing = false;
|
this.isScreenSharing = false;
|
||||||
this.videoStream = null;
|
this.videoStream = null;
|
||||||
this.audioStream = null;
|
this.audioStream = null;
|
||||||
|
@ -242,19 +245,6 @@ export default class SmallVideo {
|
||||||
this.updateStatusBar();
|
this.updateStatusBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows video muted indicator over small videos and disables/enables avatar
|
|
||||||
* if video muted.
|
|
||||||
*
|
|
||||||
* @param {boolean} isMuted indicates if we should set the view to muted view
|
|
||||||
* or not
|
|
||||||
*/
|
|
||||||
setVideoMutedView(isMuted) {
|
|
||||||
this.isVideoMuted = isMuted;
|
|
||||||
this.updateView();
|
|
||||||
this.updateStatusBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create or updates the ReactElement for displaying status indicators about
|
* Create or updates the ReactElement for displaying status indicators about
|
||||||
* audio mute, video mute, and moderator status.
|
* audio mute, video mute, and moderator status.
|
||||||
|
@ -274,7 +264,6 @@ export default class SmallVideo {
|
||||||
<StatusIndicators
|
<StatusIndicators
|
||||||
showAudioMutedIndicator = { this.isAudioMuted }
|
showAudioMutedIndicator = { this.isAudioMuted }
|
||||||
showScreenShareIndicator = { this.isScreenSharing }
|
showScreenShareIndicator = { this.isScreenSharing }
|
||||||
showVideoMutedIndicator = { this.isVideoMuted }
|
|
||||||
participantID = { this.id } />
|
participantID = { this.id } />
|
||||||
</I18nextProvider>
|
</I18nextProvider>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
|
@ -449,7 +438,18 @@ export default class SmallVideo {
|
||||||
* or <tt>false</tt> otherwise.
|
* or <tt>false</tt> otherwise.
|
||||||
*/
|
*/
|
||||||
isVideoPlayable() {
|
isVideoPlayable() {
|
||||||
return this.videoStream && !this.isVideoMuted && !APP.conference.isAudioOnly();
|
const state = APP.store.getState();
|
||||||
|
const tracks = state['features/base/tracks'];
|
||||||
|
const participant = this.id ? getParticipantById(state, this.id) : getLocalParticipant(state);
|
||||||
|
let isVideoMuted = true;
|
||||||
|
|
||||||
|
if (participant?.local) {
|
||||||
|
isVideoMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.VIDEO);
|
||||||
|
} else if (!participant?.isFakeParticipant) { // remote participants excluding shared video
|
||||||
|
isVideoMuted = isRemoteTrackMuted(tracks, MEDIA_TYPE.VIDEO, this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.videoStream && !isVideoMuted && !APP.conference.isAudioOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -490,7 +490,6 @@ export default class SmallVideo {
|
||||||
mutedWhileDisconnected: this.mutedWhileDisconnected,
|
mutedWhileDisconnected: this.mutedWhileDisconnected,
|
||||||
canPlayEventReceived: this._canPlayEventReceived,
|
canPlayEventReceived: this._canPlayEventReceived,
|
||||||
videoStream: Boolean(this.videoStream),
|
videoStream: Boolean(this.videoStream),
|
||||||
isVideoMuted: this.isVideoMuted,
|
|
||||||
isScreenSharing: this.isScreenSharing,
|
isScreenSharing: this.isScreenSharing,
|
||||||
videoStreamMuted: this.videoStream ? this.videoStream.isMuted() : 'no stream'
|
videoStreamMuted: this.videoStream ? this.videoStream.isMuted() : 'no stream'
|
||||||
};
|
};
|
||||||
|
|
|
@ -176,7 +176,7 @@ const VideoLayout = {
|
||||||
if (stream.getType() === 'audio') {
|
if (stream.getType() === 'audio') {
|
||||||
this.onAudioMute(id, stream.isMuted());
|
this.onAudioMute(id, stream.isMuted());
|
||||||
} else {
|
} else {
|
||||||
this.onVideoMute(id, stream.isMuted());
|
this.onVideoMute(id);
|
||||||
remoteVideo.setScreenSharing(stream.videoType === 'desktop');
|
remoteVideo.setScreenSharing(stream.videoType === 'desktop');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -210,7 +210,7 @@ const VideoLayout = {
|
||||||
if (mediaType === 'audio') {
|
if (mediaType === 'audio') {
|
||||||
APP.UI.setAudioMuted(participantId, true);
|
APP.UI.setAudioMuted(participantId, true);
|
||||||
} else if (mediaType === 'video') {
|
} else if (mediaType === 'video') {
|
||||||
APP.UI.setVideoMuted(participantId, true);
|
APP.UI.setVideoMuted(participantId);
|
||||||
} else {
|
} else {
|
||||||
logger.error(`Unsupported media type: ${mediaType}`);
|
logger.error(`Unsupported media type: ${mediaType}`);
|
||||||
}
|
}
|
||||||
|
@ -350,14 +350,14 @@ const VideoLayout = {
|
||||||
/**
|
/**
|
||||||
* On video muted event.
|
* On video muted event.
|
||||||
*/
|
*/
|
||||||
onVideoMute(id, value) {
|
onVideoMute(id) {
|
||||||
if (APP.conference.isLocalId(id)) {
|
if (APP.conference.isLocalId(id)) {
|
||||||
localVideoThumbnail && localVideoThumbnail.setVideoMutedView(value);
|
localVideoThumbnail && localVideoThumbnail.updateView();
|
||||||
} else {
|
} else {
|
||||||
const remoteVideo = remoteVideos[id];
|
const remoteVideo = remoteVideos[id];
|
||||||
|
|
||||||
if (remoteVideo) {
|
if (remoteVideo) {
|
||||||
remoteVideo.setVideoMutedView(value);
|
remoteVideo.onVideoMute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
} else if (jitsiTrack.isLocal()) {
|
} else if (jitsiTrack.isLocal()) {
|
||||||
APP.conference.setVideoMuteStatus(muted);
|
APP.conference.setVideoMuteStatus(muted);
|
||||||
} else {
|
} else {
|
||||||
APP.UI.setVideoMuted(participantID, muted);
|
APP.UI.setVideoMuted(participantID);
|
||||||
}
|
}
|
||||||
APP.UI.onPeerVideoTypeChanged(participantID, jitsiTrack.videoType);
|
APP.UI.onPeerVideoTypeChanged(participantID, jitsiTrack.videoType);
|
||||||
} else if (jitsiTrack.isLocal()) {
|
} else if (jitsiTrack.isLocal()) {
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import { MEDIA_TYPE } from '../../../base/media';
|
||||||
import { getLocalParticipant, getParticipantById, PARTICIPANT_ROLE } from '../../../base/participants';
|
import { getLocalParticipant, getParticipantById, PARTICIPANT_ROLE } from '../../../base/participants';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux';
|
||||||
|
import { isLocalTrackMuted, isRemoteTrackMuted } from '../../../base/tracks';
|
||||||
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
|
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
|
||||||
|
|
||||||
import AudioMutedIndicator from './AudioMutedIndicator';
|
import AudioMutedIndicator from './AudioMutedIndicator';
|
||||||
|
@ -28,6 +30,11 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_showModeratorIndicator: Boolean,
|
_showModeratorIndicator: Boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the video muted indicator should be visible or not.
|
||||||
|
*/
|
||||||
|
_showVideoMutedIndicator: Boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the audio muted indicator should be visible or not.
|
* Indicates if the audio muted indicator should be visible or not.
|
||||||
*/
|
*/
|
||||||
|
@ -38,11 +45,6 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
showScreenShareIndicator: Boolean,
|
showScreenShareIndicator: Boolean,
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the video muted indicator should be visible or not.
|
|
||||||
*/
|
|
||||||
showVideoMutedIndicator: Boolean,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ID of the participant for which the status bar is rendered.
|
* The ID of the participant for which the status bar is rendered.
|
||||||
*/
|
*/
|
||||||
|
@ -67,7 +69,7 @@ class StatusIndicators extends Component<Props> {
|
||||||
_showModeratorIndicator,
|
_showModeratorIndicator,
|
||||||
showAudioMutedIndicator,
|
showAudioMutedIndicator,
|
||||||
showScreenShareIndicator,
|
showScreenShareIndicator,
|
||||||
showVideoMutedIndicator
|
_showVideoMutedIndicator
|
||||||
} = this.props;
|
} = this.props;
|
||||||
let tooltipPosition;
|
let tooltipPosition;
|
||||||
|
|
||||||
|
@ -86,7 +88,7 @@ class StatusIndicators extends Component<Props> {
|
||||||
<div>
|
<div>
|
||||||
{ showAudioMutedIndicator ? <AudioMutedIndicator tooltipPosition = { tooltipPosition } /> : null }
|
{ showAudioMutedIndicator ? <AudioMutedIndicator tooltipPosition = { tooltipPosition } /> : null }
|
||||||
{ showScreenShareIndicator ? <ScreenShareIndicator tooltipPosition = { tooltipPosition } /> : null }
|
{ showScreenShareIndicator ? <ScreenShareIndicator tooltipPosition = { tooltipPosition } /> : null }
|
||||||
{ showVideoMutedIndicator ? <VideoMutedIndicator tooltipPosition = { tooltipPosition } /> : null }
|
{ _showVideoMutedIndicator ? <VideoMutedIndicator tooltipPosition = { tooltipPosition } /> : null }
|
||||||
{ _showModeratorIndicator ? <ModeratorIndicator tooltipPosition = { tooltipPosition } /> : null }
|
{ _showModeratorIndicator ? <ModeratorIndicator tooltipPosition = { tooltipPosition } /> : null }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -101,7 +103,8 @@ class StatusIndicators extends Component<Props> {
|
||||||
* @private
|
* @private
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* _currentLayout: string,
|
* _currentLayout: string,
|
||||||
* _showModeratorIndicator: boolean
|
* _showModeratorIndicator: boolean,
|
||||||
|
* _showVideoMutedIndicator: boolean
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
function _mapStateToProps(state, ownProps) {
|
function _mapStateToProps(state, ownProps) {
|
||||||
|
@ -110,10 +113,20 @@ function _mapStateToProps(state, ownProps) {
|
||||||
// Only the local participant won't have id for the time when the conference is not yet joined.
|
// Only the local participant won't have id for the time when the conference is not yet joined.
|
||||||
const participant = participantID ? getParticipantById(state, participantID) : getLocalParticipant(state);
|
const participant = participantID ? getParticipantById(state, participantID) : getLocalParticipant(state);
|
||||||
|
|
||||||
|
const tracks = state['features/base/tracks'];
|
||||||
|
let isVideoMuted = true;
|
||||||
|
|
||||||
|
if (participant?.local) {
|
||||||
|
isVideoMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.VIDEO);
|
||||||
|
} else if (!participant?.isFakeParticipant) { // remote participants excluding shared video
|
||||||
|
isVideoMuted = isRemoteTrackMuted(tracks, MEDIA_TYPE.VIDEO, participantID);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_currentLayout: getCurrentLayout(state),
|
_currentLayout: getCurrentLayout(state),
|
||||||
_showModeratorIndicator:
|
_showModeratorIndicator:
|
||||||
!interfaceConfig.DISABLE_FOCUS_INDICATOR && participant && participant.role === PARTICIPANT_ROLE.MODERATOR
|
!interfaceConfig.DISABLE_FOCUS_INDICATOR && participant && participant.role === PARTICIPANT_ROLE.MODERATOR,
|
||||||
|
_showVideoMutedIndicator: isVideoMuted
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue