From e3f5975433d5a511ad6dd2feb4f3b152e2e27122 Mon Sep 17 00:00:00 2001 From: bogdandarie Date: Thu, 3 Nov 2022 10:41:14 +0200 Subject: [PATCH] fix(disableSelfView) enable disable self view when alone in meeting --- modules/UI/videolayout/VideoContainer.js | 38 ++++++++++++++++++- react/features/base/settings/functions.any.ts | 11 ------ react/features/filmstrip/actions.web.ts | 6 +-- .../filmstrip/components/native/Filmstrip.js | 4 +- .../filmstrip/components/native/TileView.js | 4 +- .../filmstrip/components/web/Filmstrip.tsx | 4 +- .../components/web/ThumbnailWrapper.js | 4 +- react/features/filmstrip/functions.native.ts | 6 +-- react/features/filmstrip/functions.web.ts | 4 +- react/features/filmstrip/subscriber.web.ts | 4 +- .../large-video/components/LargeVideo.web.js | 36 ++++++++++++++++-- 11 files changed, 87 insertions(+), 34 deletions(-) diff --git a/modules/UI/videolayout/VideoContainer.js b/modules/UI/videolayout/VideoContainer.js index 6b79dfee8..da83fccdc 100644 --- a/modules/UI/videolayout/VideoContainer.js +++ b/modules/UI/videolayout/VideoContainer.js @@ -6,7 +6,10 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { browser } from '../../../react/features/base/lib-jitsi-meet'; +import { getParticipantCount } from '../../../react/features/base/participants'; +import { getHideSelfView } from '../../../react/features/base/settings/functions.any'; import { isTestModeEnabled } from '../../../react/features/base/testing'; +import { isLocalCameraTrackMuted } from '../../../react/features/base/tracks'; import { FILMSTRIP_BREAKPOINT } from '../../../react/features/filmstrip'; import { LargeVideoBackground, ORIENTATION, updateLastLargeVideoMediaEvent } from '../../../react/features/large-video'; import { setLargeVideoDimensions } from '../../../react/features/large-video/actions.any'; @@ -558,12 +561,37 @@ export class VideoContainer extends LargeContainer { * @param {boolean} show */ showAvatar(show) { - this.$avatar.css('visibility', show ? 'visible' : 'hidden'); + const state = APP.store.getState(); + const aloneInTheMeeting = getParticipantCount(state) === 1; + + const visibility = aloneInTheMeeting + ? this.setAvatarVisibility(state) + : show ? 'visible' : 'hidden'; + + this.$avatar.css('visibility', visibility); this.avatarDisplayed = show; APP.API.notifyLargeVideoVisibilityChanged(show); } + /** + * Set Avatar Visibility. + * @param {object} state - App state. + */ + setAvatarVisibility(state) { + const hideSelfView = getHideSelfView(state); + let visibility = 'hidden'; + + if (!hideSelfView) { + const tracks = state['features/base/tracks']; + const isVideoMuted = isLocalCameraTrackMuted(tracks); + + visibility = isVideoMuted ? 'visible' : 'hidden'; + } + + return visibility; + } + /** * We are doing fadeOut/fadeIn animations on parent div which wraps * largeVideo, because when Temasys plugin is in use it replaces @@ -575,7 +603,13 @@ export class VideoContainer extends LargeContainer { */ show() { return new Promise(resolve => { - this.$wrapperParent.css('visibility', 'visible').fadeTo( + const state = APP.store.getState(); + const aloneInTheMeeting = getParticipantCount(state) === 1; + const hideSelfView = getHideSelfView(state); + + const visibility = aloneInTheMeeting && hideSelfView ? 'hidden' : 'visible'; + + this.$wrapperParent.css('visibility', visibility).fadeTo( FADE_DURATION_MS, 1, () => { diff --git a/react/features/base/settings/functions.any.ts b/react/features/base/settings/functions.any.ts index b7ba4dd2f..18322c728 100644 --- a/react/features/base/settings/functions.any.ts +++ b/react/features/base/settings/functions.any.ts @@ -3,7 +3,6 @@ import { IStateful } from '../app/types'; import CONFIG_WHITELIST from '../config/configWhitelist'; import { IConfigState } from '../config/reducer'; import { IJwtState } from '../jwt/reducer'; -import { getParticipantCount } from '../participants/functions'; import { toState } from '../redux/functions'; import { parseURLParams } from '../util/parseURLParams'; @@ -114,16 +113,6 @@ export function shouldHideShareAudioHelper(state: IReduxState): boolean | undefi return state['features/base/settings'].hideShareAudioHelper; } -/** - * Whether we should hide self view. - * - * @param {Object} state - Redux state. - * @returns {boolean} - */ -export function shouldHideSelfView(state: IReduxState) { - return getParticipantCount(state) === 1 ? false : getHideSelfView(state); -} - /** * Gets the disable self view setting. * diff --git a/react/features/filmstrip/actions.web.ts b/react/features/filmstrip/actions.web.ts index 85024b3ff..15f59311c 100644 --- a/react/features/filmstrip/actions.web.ts +++ b/react/features/filmstrip/actions.web.ts @@ -5,7 +5,7 @@ import { getParticipantById, getRemoteParticipantCountWithFake } from '../base/participants/functions'; -import { shouldHideSelfView } from '../base/settings/functions.web'; +import { getHideSelfView } from '../base/settings/functions.any'; import { getMaxColumnCount } from '../video-layout/functions.web'; import { @@ -146,7 +146,7 @@ export function setVerticalViewDimensions() { const state = getState(); const { clientHeight = 0, clientWidth = 0 } = state['features/base/responsive-ui']; const { width: filmstripWidth } = state['features/filmstrip']; - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const resizableFilmstrip = isFilmstripResizable(state); const _verticalViewGrid = showGridInVerticalView(state); const numberOfRemoteParticipants = getRemoteParticipantCountWithFake(state); @@ -255,7 +255,7 @@ export function setHorizontalViewDimensions() { return (dispatch: IStore['dispatch'], getState: IStore['getState']) => { const state = getState(); const { clientHeight = 0, clientWidth = 0 } = state['features/base/responsive-ui']; - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const thumbnails = calculateThumbnailSizeForHorizontalView(clientHeight); const remoteVideosContainerWidth = clientWidth - (disableSelfView ? 0 : thumbnails?.local?.width) - HORIZONTAL_FILMSTRIP_MARGIN; diff --git a/react/features/filmstrip/components/native/Filmstrip.js b/react/features/filmstrip/components/native/Filmstrip.js index 23a3b7d32..d13f48a82 100644 --- a/react/features/filmstrip/components/native/Filmstrip.js +++ b/react/features/filmstrip/components/native/Filmstrip.js @@ -8,7 +8,7 @@ import { getLocalParticipant } from '../../../base/participants'; import { Platform } from '../../../base/react'; import { connect } from '../../../base/redux'; import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants'; -import { shouldHideSelfView } from '../../../base/settings/functions.any'; +import { getHideSelfView } from '../../../base/settings/functions.any'; import { isToolboxVisible } from '../../../toolbox/functions'; import { setVisibleRemoteParticipants } from '../../actions'; import { @@ -320,7 +320,7 @@ class Filmstrip extends PureComponent { */ function _mapStateToProps(state) { const { enabled, remoteParticipants } = state['features/filmstrip']; - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const showRemoteVideos = shouldRemoteVideosBeVisible(state); const responsiveUI = state['features/base/responsive-ui']; diff --git a/react/features/filmstrip/components/native/TileView.js b/react/features/filmstrip/components/native/TileView.js index ad7004f53..55ac35a1a 100644 --- a/react/features/filmstrip/components/native/TileView.js +++ b/react/features/filmstrip/components/native/TileView.js @@ -11,7 +11,7 @@ import type { Dispatch } from 'redux'; import { getLocalParticipant, getParticipantCountWithFake } from '../../../base/participants'; import { connect } from '../../../base/redux'; -import { shouldHideSelfView } from '../../../base/settings/functions.any'; +import { getHideSelfView } from '../../../base/settings/functions.any'; import { setVisibleRemoteParticipants } from '../../actions.web'; import Thumbnail from './Thumbnail'; @@ -283,7 +283,7 @@ class TileView extends PureComponent { function _mapStateToProps(state, ownProps) { const responsiveUi = state['features/base/responsive-ui']; const { remoteParticipants, tileViewDimensions } = state['features/filmstrip']; - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const { height } = tileViewDimensions.thumbnailSize; const { columns } = tileViewDimensions; diff --git a/react/features/filmstrip/components/web/Filmstrip.tsx b/react/features/filmstrip/components/web/Filmstrip.tsx index fa387ce8b..7d1725361 100644 --- a/react/features/filmstrip/components/web/Filmstrip.tsx +++ b/react/features/filmstrip/components/web/Filmstrip.tsx @@ -16,7 +16,7 @@ import Icon from '../../../base/icons/components/Icon'; import { IconArrowDown, IconArrowUp } from '../../../base/icons/svg'; import { IParticipant } from '../../../base/participants/types'; import { connect } from '../../../base/redux/functions'; -import { shouldHideSelfView } from '../../../base/settings/functions.web'; +import { getHideSelfView } from '../../../base/settings/functions.any'; import { showToolbox } from '../../../toolbox/actions.web'; import { isButtonEnabled, isToolboxVisible } from '../../../toolbox/functions.web'; import { LAYOUTS } from '../../../video-layout/constants'; @@ -877,7 +877,7 @@ function _mapStateToProps(state: IReduxState, ownProps: Partial) { const reduceHeight = state['features/toolbox'].visible && toolbarButtons.length; const remoteVideosVisible = shouldRemoteVideosBeVisible(state); const { isOpen: shiftRight } = state['features/chat']; - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const { clientWidth, clientHeight } = state['features/base/responsive-ui']; const collapseTileView = reduceHeight diff --git a/react/features/filmstrip/components/web/ThumbnailWrapper.js b/react/features/filmstrip/components/web/ThumbnailWrapper.js index 272b121d9..40a7fb044 100644 --- a/react/features/filmstrip/components/web/ThumbnailWrapper.js +++ b/react/features/filmstrip/components/web/ThumbnailWrapper.js @@ -4,7 +4,7 @@ import { shouldComponentUpdate } from 'react-window'; import { getLocalParticipant } from '../../../base/participants'; import { connect } from '../../../base/redux'; -import { shouldHideSelfView } from '../../../base/settings/functions.any'; +import { getHideSelfView } from '../../../base/settings/functions.any'; import { LAYOUTS, getCurrentLayout } from '../../../video-layout'; import { FILMSTRIP_TYPE, TILE_ASPECT_RATIO, TILE_HORIZONTAL_MARGIN } from '../../constants'; import { getActiveParticipantsIds, showGridInVerticalView } from '../../functions'; @@ -152,7 +152,7 @@ function _mapStateToProps(state, ownProps) { const _currentLayout = getCurrentLayout(state); const { remoteParticipants: remote } = state['features/filmstrip']; const activeParticipants = getActiveParticipantsIds(state); - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const _verticalViewGrid = showGridInVerticalView(state); const filmstripType = ownProps.data?.filmstripType; const stageFilmstrip = filmstripType === FILMSTRIP_TYPE.STAGE; diff --git a/react/features/filmstrip/functions.native.ts b/react/features/filmstrip/functions.native.ts index 634d1adc6..fdeba9889 100644 --- a/react/features/filmstrip/functions.native.ts +++ b/react/features/filmstrip/functions.native.ts @@ -10,7 +10,7 @@ import { import Platform from '../base/react/Platform.native'; import { toState } from '../base/redux/functions'; import { ASPECT_RATIO_NARROW } from '../base/responsive-ui/constants'; -import { shouldHideSelfView } from '../base/settings/functions.native'; +import { getHideSelfView } from '../base/settings/functions.any'; // eslint-disable-next-line lines-around-comment // @ts-ignore import conferenceStyles from '../conference/components/native/styles'; @@ -104,7 +104,7 @@ export function getPinnedActiveParticipants(_state: any) { */ export function getTileViewParticipantCount(stateful: IStateful) { const state = toState(stateful); - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const localParticipant = getLocalParticipant(state); const participantCount = getParticipantCountWithFake(state) - (disableSelfView && localParticipant ? 1 : 0); @@ -152,7 +152,7 @@ export function isFilmstripScrollVisible(state: IReduxState) { const { aspectRatio, clientWidth, clientHeight, safeAreaInsets = {} } = state['features/base/responsive-ui']; const isNarrowAspectRatio = aspectRatio === ASPECT_RATIO_NARROW; - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const localParticipant = Boolean(getLocalParticipant(state)); const localParticipantVisible = localParticipant && !disableSelfView; const participantCount diff --git a/react/features/filmstrip/functions.web.ts b/react/features/filmstrip/functions.web.ts index b25f7c3a6..963d4caa6 100644 --- a/react/features/filmstrip/functions.web.ts +++ b/react/features/filmstrip/functions.web.ts @@ -11,7 +11,7 @@ import { isScreenShareParticipant } from '../base/participants/functions'; import { toState } from '../base/redux/functions'; -import { shouldHideSelfView } from '../base/settings/functions.web'; +import { getHideSelfView } from '../base/settings/functions.any'; import { getVideoTrackByParticipant, isLocalTrackMuted, @@ -218,7 +218,7 @@ export function getTileDefaultAspectRatio(disableResponsiveTiles: boolean, */ export function getNumberOfPartipantsForTileView(state: IReduxState) { const { iAmRecorder } = state['features/base/config']; - const disableSelfView = shouldHideSelfView(state); + const disableSelfView = getHideSelfView(state); const { localScreenShare } = state['features/base/participants']; const localParticipantsCount = localScreenShare ? 2 : 1; const numberOfParticipants = getParticipantCountWithFake(state) diff --git a/react/features/filmstrip/subscriber.web.ts b/react/features/filmstrip/subscriber.web.ts index bfc262b1b..34ccfded2 100644 --- a/react/features/filmstrip/subscriber.web.ts +++ b/react/features/filmstrip/subscriber.web.ts @@ -2,7 +2,7 @@ import { pinParticipant } from '../base/participants/actions'; import { getParticipantCountWithFake } from '../base/participants/functions'; import StateListenerRegistry from '../base/redux/StateListenerRegistry'; import { clientResized, setNarrowLayout } from '../base/responsive-ui/actions'; -import { shouldHideSelfView } from '../base/settings/functions.web'; +import { getHideSelfView } from '../base/settings/functions.any'; import { selectParticipantInLargeVideo } from '../large-video/actions.any'; import { getParticipantsPaneOpen } from '../participants-pane/functions'; import { setOverflowDrawer } from '../toolbox/actions.web'; @@ -37,7 +37,7 @@ StateListenerRegistry.register( /* selector */ state => { return { numberOfParticipants: getParticipantCountWithFake(state), - disableSelfView: shouldHideSelfView(state), + disableSelfView: getHideSelfView(state), localScreenShare: state['features/base/participants'].localScreenShare }; }, diff --git a/react/features/large-video/components/LargeVideo.web.js b/react/features/large-video/components/LargeVideo.web.js index d4eb33b24..65f6221df 100644 --- a/react/features/large-video/components/LargeVideo.web.js +++ b/react/features/large-video/components/LargeVideo.web.js @@ -4,9 +4,10 @@ import React, { Component } from 'react'; import VideoLayout from '../../../../modules/UI/videolayout/VideoLayout'; import { VIDEO_TYPE } from '../../base/media'; -import { getLocalParticipant } from '../../base/participants'; +import { getLocalParticipant, getParticipantCount } from '../../base/participants'; import { Watermarks } from '../../base/react'; import { connect } from '../../base/redux'; +import { getHideSelfView } from '../../base/settings/functions.any'; import { getVideoTrackByParticipant } from '../../base/tracks'; import { setColorAlpha } from '../../base/util'; import { StageParticipantNameLabel } from '../../display-name'; @@ -105,6 +106,21 @@ type Props = { */ _whiteboardEnabled: boolean; + /** + * Whether or not the hideSelfView is enabled. + */ + _hideSelfView: boolean; + + /** + * Whether or not is only 1 participant in the meeting. + */ + _aloneInTheMeeting: boolean; + + /** + * Local Participant id. + */ + _localParticipantId: string; + /** * The Redux dispatch function. */ @@ -146,7 +162,14 @@ class LargeVideo extends Component { * @inheritdoc */ componentDidUpdate(prevProps: Props) { - const { _visibleFilmstrip, _isScreenSharing, _seeWhatIsBeingShared, _largeVideoParticipantId } = this.props; + const { + _visibleFilmstrip, + _isScreenSharing, + _seeWhatIsBeingShared, + _largeVideoParticipantId, + _hideSelfView, + _localParticipantId, + _aloneInTheMeeting } = this.props; if (prevProps._visibleFilmstrip !== _visibleFilmstrip) { this._updateLayout(); @@ -159,6 +182,10 @@ class LargeVideo extends Component { if (_isScreenSharing && _seeWhatIsBeingShared) { VideoLayout.updateLargeVideo(_largeVideoParticipantId, true, true); } + + if (_aloneInTheMeeting && prevProps._hideSelfView !== _hideSelfView) { + VideoLayout.updateLargeVideo(_localParticipantId, true, false); + } } /** @@ -361,7 +388,10 @@ function _mapStateToProps(state) { _verticalFilmstripWidth: verticalFilmstripWidth.current, _verticalViewMaxWidth: getVerticalViewMaxWidth(state), _visibleFilmstrip: visible, - _whiteboardEnabled: isWhiteboardEnabled(state) + _whiteboardEnabled: isWhiteboardEnabled(state), + _hideSelfView: getHideSelfView(state), + _localParticipantId: localParticipantId, + _aloneInTheMeeting: getParticipantCount(state) === 1 }; }