feat(config) add ability to hide speaker stats

pull/12399/head jitsi-meet_7952
bogdandarie 2 years ago committed by GitHub
parent ceb1cd9673
commit 485c875ee5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      config.js
  2. 8
      modules/keyboardshortcut/keyboardshortcut.js
  3. 5
      react/features/base/config/configType.ts
  4. 1
      react/features/base/config/configWhitelist.ts
  5. 19
      react/features/base/config/reducer.ts
  6. 11
      react/features/conference/components/web/ParticipantsCount.js
  7. 14
      react/features/speaker-stats/functions.js
  8. 12
      react/features/toolbox/components/native/OverflowMenu.js
  9. 53
      react/features/toolbox/components/web/Toolbox.tsx

@ -224,9 +224,29 @@ var config = {
// Specifies whether the raised hand will hide when someone becomes a dominant speaker or not
// disableRemoveRaisedHandOnFocus: false,
// speakerStats: {
// // Specifies whether the speaker stats is enable or not.
// disabled: false,
// // Specifies whether there will be a search field in speaker stats or not.
// disableSearch: false,
// // Specifies whether participants in speaker stats should be ordered or not, and with what priority.
// // 'role', <- Moderators on top.
// // 'name', <- Alphabetically by name.
// // 'hasLeft', <- The ones that have left in the bottom.
// order: [
// 'role',
// 'name',
// 'hasLeft',
// ],
// },
// DEPRECATED. Please use speakerStats.disableSearch instead.
// Specifies whether there will be a search field in speaker stats or not
// disableSpeakerStatsSearch: false,
// DEPRECATED. Please use speakerStats.order .
// Specifies whether participants in speaker stats should be ordered or not, and with what priority
// speakerStatsOrder: [
// 'role', <- Moderators on top

@ -12,7 +12,6 @@ import { toggleDialog } from '../../react/features/base/dialog';
import { clickOnVideo } from '../../react/features/filmstrip/actions';
import { KeyboardShortcutsDialog }
from '../../react/features/keyboard-shortcuts';
import { SpeakerStats } from '../../react/features/speaker-stats';
const logger = Logger.getLogger(__filename);
@ -249,13 +248,6 @@ const KeyboardShortcut = {
});
this._addShortcutToHelp('SPACE', 'keyboardShortcuts.pushToTalk');
this.registerShortcut('T', null, () => {
sendAnalytics(createShortcutEvent('speaker.stats'));
APP.store.dispatch(toggleDialog(SpeakerStats, {
conference: APP.conference
}));
}, 'keyboardShortcuts.showSpeakerStats');
/**
* FIXME: Currently focus keys are directly implemented below in
* onkeyup. They should be moved to the SmallVideo instead.

@ -428,6 +428,11 @@ export interface IConfig {
mode?: 'always' | 'recording';
};
serviceUrl?: string;
speakerStats?: {
disableSearch?: boolean;
disabled?: boolean;
order?: Array<'role' | 'name' | 'hasLeft'>;
};
speakerStatsOrder?: Array<'role' | 'name' | 'hasLeft'>;
startAudioMuted?: number;
startAudioOnly?: boolean;

@ -210,6 +210,7 @@ export default [
'resolution',
'salesforceUrl',
'screenshotCapture',
'speakerStats',
'startAudioMuted',
'startAudioOnly',
'startLastN',

@ -450,6 +450,25 @@ function _translateLegacyConfig(oldValue: IConfig) {
};
}
newValue.speakerStats = newValue.speakerStats || {};
if (oldValue.disableSpeakerStatsSearch !== undefined
&& newValue.speakerStats.disableSearch === undefined
) {
newValue.speakerStats = {
...newValue.speakerStats,
disableSearch: oldValue.disableSpeakerStatsSearch
};
}
if (oldValue.speakerStatsOrder !== undefined
&& newValue.speakerStats.order === undefined) {
newValue.speakerStats = {
...newValue.speakerStats,
order: oldValue.speakerStatsOrder
};
}
return newValue;
}

@ -10,6 +10,7 @@ import { COLORS } from '../../../base/label/constants';
import { getParticipantCount } from '../../../base/participants';
import { connect } from '../../../base/redux';
import { SpeakerStats } from '../../../speaker-stats';
import { isSpeakerStatsDisabled } from '../../../speaker-stats/functions';
/**
@ -31,6 +32,11 @@ type Props = {
* Invoked to open Speaker stats.
*/
dispatch: Dispatch<any>,
/**
* Weather or not the speaker stats is disabled.
*/
_isSpeakerStatsDisabled: Boolean,
};
/**
@ -83,7 +89,7 @@ class ParticipantsCount extends PureComponent<Props> {
<Label
color = { COLORS.white }
icon = { IconUserGroups }
onClick = { this._onClick }
onClick = { !this.props._isSpeakerStatsDisabled && this._onClick }
text = { count } />
);
}
@ -101,7 +107,8 @@ class ParticipantsCount extends PureComponent<Props> {
function mapStateToProps(state) {
return {
conference: state['features/base/conference'].conference,
count: getParticipantCount(state)
count: getParticipantCount(state),
_isSpeakerStatsDisabled: isSpeakerStatsDisabled(state)
};
}

@ -14,7 +14,17 @@ import {
* @returns {boolean} - True if the speaker stats search is disabled and false otherwise.
*/
export function isSpeakerStatsSearchDisabled(state: Object) {
return state['features/base/config']?.disableSpeakerStatsSearch;
return state['features/base/config']?.speakerStats.disableSearch;
}
/**
* Checks if the speaker stats is disabled.
*
* @param {*} state - The redux state.
* @returns {boolean} - True if the speaker stats search is disabled and false otherwise.
*/
export function isSpeakerStatsDisabled(state: Object) {
return state['features/base/config']?.speakerStats?.disabled;
}
/**
@ -24,7 +34,7 @@ export function isSpeakerStatsSearchDisabled(state: Object) {
* @returns {Array<string>} - The speaker stats order array or an empty array.
*/
export function getSpeakerStatsOrder(state: Object) {
return state['features/base/config']?.speakerStatsOrder ?? [
return state['features/base/config']?.speakerStats.order ?? [
'role',
'name',
'hasLeft'

@ -15,6 +15,7 @@ import SecurityDialogButton
from '../../../security/components/security-dialog/native/SecurityDialogButton';
import { SharedVideoButton } from '../../../shared-video/components';
import SpeakerStatsButton from '../../../speaker-stats/components/native/SpeakerStatsButton';
import { isSpeakerStatsDisabled } from '../../../speaker-stats/functions';
import { ClosedCaptionButton } from '../../../subtitles';
import { TileViewButton } from '../../../video-layout';
import styles from '../../../video-menu/components/native/styles';
@ -54,7 +55,12 @@ type Props = {
/**
* Used for hiding the dialog when the selection was completed.
*/
dispatch: Function
dispatch: Function,
/**
* Whether or not speaker stats is disable.
*/
_isSpeakerStatsDisabled: boolean
};
type State = {
@ -95,6 +101,7 @@ class OverflowMenu extends PureComponent<Props, State> {
*/
render() {
const {
_isSpeakerStatsDisabled,
_reactionsEnabled,
_width
} = this.props;
@ -135,7 +142,7 @@ class OverflowMenu extends PureComponent<Props, State> {
<Divider style = { styles.divider } />
<SharedVideoButton { ...buttonProps } />
{!toolbarButtons.has('screensharing') && <ScreenSharingButton { ...buttonProps } />}
<SpeakerStatsButton { ...buttonProps } />
{!_isSpeakerStatsDisabled && <SpeakerStatsButton { ...buttonProps } />}
{!toolbarButtons.has('tileview') && <TileViewButton { ...buttonProps } />}
<Divider style = { styles.divider } />
<ClosedCaptionButton { ...buttonProps } />
@ -176,6 +183,7 @@ class OverflowMenu extends PureComponent<Props, State> {
*/
function _mapStateToProps(state) {
return {
_isSpeakerStatsDisabled: isSpeakerStatsDisabled(state),
_reactionsEnabled: isReactionsEnabled(state),
_width: state['features/base/responsive-ui'].clientWidth
};

@ -6,6 +6,8 @@ import { batch } from 'react-redux';
// @ts-ignore
import keyboardShortcut from '../../../../../modules/keyboardshortcut/keyboardshortcut';
// @ts-ignore
import { isSpeakerStatsDisabled } from '../../../../features/speaker-stats/functions';
import { ACTION_SHORTCUT_TRIGGERED, createShortcutEvent, createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IState } from '../../../app/types';
@ -81,6 +83,7 @@ import { SettingsButton } from '../../../settings';
import { SharedVideoButton } from '../../../shared-video/components';
// @ts-ignore
import { SpeakerStatsButton } from '../../../speaker-stats/components/web';
import SpeakerStats from '../../../speaker-stats/components/web/SpeakerStats';
import {
ClosedCaptionButton
// @ts-ignore
@ -241,6 +244,12 @@ interface Props extends WithTranslation {
_isProfileDisabled: boolean;
/**
* Whether or not speaker stats is disable.
*/
_isSpeakerStatsDisabled: boolean;
/**
* Whether or not the current meeting belongs to a JaaS user.
*/
_isVpaasMeeting: boolean;
@ -399,6 +408,7 @@ class Toolbox extends Component<Props> {
this._onToolbarToggleRaiseHand = this._onToolbarToggleRaiseHand.bind(this);
this._onToolbarToggleScreenshare = this._onToolbarToggleScreenshare.bind(this);
this._onShortcutToggleTileView = this._onShortcutToggleTileView.bind(this);
this._onShortcutSpeakerStats = this._onShortcutSpeakerStats.bind(this);
this._onEscKey = this._onEscKey.bind(this);
}
@ -409,7 +419,8 @@ class Toolbox extends Component<Props> {
* @returns {void}
*/
componentDidMount() {
const { _toolbarButtons, t, dispatch, _reactionsEnabled, _gifsEnabled } = this.props;
const { _toolbarButtons, t, dispatch, _reactionsEnabled, _gifsEnabled, _isSpeakerStatsDisabled } = this.props;
const KEYBOARD_SHORTCUTS = [
isToolbarButtonEnabled('videoquality', _toolbarButtons) && {
character: 'A',
@ -445,6 +456,11 @@ class Toolbox extends Component<Props> {
character: 'W',
exec: this._onShortcutToggleTileView,
helpDescription: 'toolbar.tileViewToggle'
},
!_isSpeakerStatsDisabled && isToolbarButtonEnabled('stats', _toolbarButtons) && {
character: 'T',
exec: this._onShortcutSpeakerStats,
helpDescription: 'keyboardShortcuts.showSpeakerStats'
}
];
@ -698,9 +714,10 @@ class Toolbox extends Component<Props> {
_getAllButtons() {
const {
_feedbackConfigured,
_hasSalesforce,
_isIosMobile,
_isMobile,
_hasSalesforce,
_isSpeakerStatsDisabled,
_multiStreamModeEnabled,
_screenSharing,
_whiteboardEnabled
@ -864,7 +881,7 @@ class Toolbox extends Component<Props> {
group: 3
};
const speakerStats = {
const speakerStats = !_isSpeakerStatsDisabled && {
key: 'stats',
Content: SpeakerStatsButton,
group: 3
@ -1204,6 +1221,34 @@ class Toolbox extends Component<Props> {
this._doToggleScreenshare();
}
/**
* Creates an analytics keyboard shortcut event and dispatches an action for
* toggling speaker stats.
*
* @private
* @returns {void}
*/
_onShortcutSpeakerStats() {
sendAnalytics(createShortcutEvent(
'speaker.stats'
));
this._doToggleSpekearStats();
}
/**
* Dispatches an action to toggle speakerStats.
*
* @private
* @returns {void}
*/
_doToggleSpekearStats() {
const { dispatch } = this.props;
dispatch(toggleDialog(SpeakerStats, {
conference: APP.conference
}));
}
/**
* Toggle the toolbar visibility when tabbing into it.
@ -1481,6 +1526,7 @@ class Toolbox extends Component<Props> {
function _mapStateToProps(state: IState, ownProps: Partial<Props>) {
const { conference } = state['features/base/conference'];
const endConferenceSupported = conference?.isEndConferenceSupported();
const {
buttonsWithNotifyClick,
callStatsID,
@ -1516,6 +1562,7 @@ function _mapStateToProps(state: IState, ownProps: Partial<Props>) {
_isProfileDisabled: Boolean(disableProfile),
_isIosMobile: isIosMobileBrowser(),
_isMobile: isMobileBrowser(),
_isSpeakerStatsDisabled: isSpeakerStatsDisabled(state),
_isVpaasMeeting: isVpaasMeeting(state),
_jwtDisabledButons: getJwtDisabledButtons(state),
_hasSalesforce: isSalesforceEnabled(state),

Loading…
Cancel
Save