feat(layout): add userdata bbb_hide_controls (#21410)

* feat(layout): add `hideTopRow` to nav bar context

Adds the `hideTopRow` property to the navbar in the layout context, allowing
the top row of the navigation bar to be hidden. Only the row with the
talking indicators and timer indicator will remain visible when this
option is used.

* feat(layout): add userdata `bbb_hide_controls`

Introduces the userdata join parameter `bbb_hide_controls`, which hides
the action bar and the top row of the navigation bar (including the close
sidebar button, room title, connectivity indicator, and leave meeting button)
while keeping the row with the talking indicator and timer indicator visible.

* fix(layout): has actions bar boolean expression
This commit is contained in:
Arthur B. Grossi 2024-10-23 09:06:44 -03:00 committed by GitHub
parent 84dba0c251
commit 4aab1b21d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 90 additions and 56 deletions

View File

@ -95,7 +95,8 @@ const AppContainer = (props) => {
? (
<App
{...{
hideActionsBar: getFromUserSettings('bbb_hide_actions_bar', false),
hideActionsBar: getFromUserSettings('bbb_hide_actions_bar', false)
|| getFromUserSettings('bbb_hide_controls', false),
currentUserAway: currentUser.away,
currentUserRaiseHand: currentUser.raiseHand,
captionsStyle,

View File

@ -242,6 +242,23 @@ const reducer = (state, action) => {
};
}
case ACTIONS.SET_HIDE_NAVBAR_TOP_ROW: {
const { navBar } = state.output;
if (navBar.hideTopRow === action.value) {
return state;
}
return {
...state,
output: {
...state.output,
navBar: {
...navBar,
hideTopRow: action.value,
},
},
};
}
case ACTIONS.SET_NAVBAR_OUTPUT: {
const {
display, width, height, top, left, tabOrder, zIndex,

View File

@ -56,6 +56,7 @@ export const ACTIONS = {
SET_HIDE_NOTIFICATION_TOASTS: 'setHideNotificationToasts',
SET_HAS_NAVBAR: 'setHasNavBar',
SET_HIDE_NAVBAR_TOP_ROW: 'setHideNavBarTopRow',
SET_NAVBAR_OUTPUT: 'setNavBarOutput',
SET_HAS_ACTIONBAR: 'setHasActionBar',

View File

@ -115,6 +115,7 @@ export const INITIAL_INPUT_STATE = {
export const INITIAL_OUTPUT_STATE = {
navBar: {
display: false,
hideTopRow: false,
width: 0,
height: 0,
top: 0,

View File

@ -1,5 +1,5 @@
import React from 'react';
import { layoutSelect, layoutSelectInput } from '/imports/ui/components/layout/context';
import { layoutSelect, layoutSelectInput, layoutSelectOutput } from '/imports/ui/components/layout/context';
import DEFAULT_VALUES from '/imports/ui/components/layout/defaultValues';
import { LAYOUT_TYPE, DEVICE_TYPE } from '/imports/ui/components/layout/enums';
@ -22,6 +22,7 @@ const LayoutEngine = () => {
const presentationInput = layoutSelectInput((i) => i.presentation);
const actionbarInput = layoutSelectInput((i) => i.actionBar);
const navBarInput = layoutSelectInput((i) => i.navBar);
const navBarOutput = layoutSelectOutput((i) => i.navBar);
const sidebarNavigationInput = layoutSelectInput((i) => i.sidebarNavigation);
const sidebarContentInput = layoutSelectInput((i) => i.sidebarContent);
const externalVideoInput = layoutSelectInput((i) => i.externalVideo);
@ -106,7 +107,9 @@ const LayoutEngine = () => {
const calculatesNavbarHeight = () => {
const { navBarHeight } = DEFAULT_VALUES;
return navBarInput.hasNavBar ? navBarHeight : 0;
const finalHeight = navBarOutput.hideTopRow ? navBarHeight / 2 : navBarHeight;
return navBarInput.hasNavBar ? finalHeight : 0;
};
const calculatesNavbarBounds = (mediaAreaBounds) => {

View File

@ -97,6 +97,7 @@ export interface GenericContentMainArea {
}
interface NavBar {
hasNavBar?: boolean;
hideTopRow: boolean;
height: number;
display?: boolean;
left?: number;

View File

@ -101,7 +101,13 @@ const LayoutObserver: React.FC = () => {
layoutContextDispatch({
type: ACTIONS.SET_HAS_ACTIONBAR,
value: !getFromUserSettings('bbb_hide_actions_bar', false),
value: !(getFromUserSettings('bbb_hide_actions_bar', false)
|| getFromUserSettings('bbb_hide_controls', false)),
});
layoutContextDispatch({
type: ACTIONS.SET_HIDE_NAVBAR_TOP_ROW,
value: getFromUserSettings('bbb_hide_controls', false),
});
layoutContextDispatch({

View File

@ -272,6 +272,7 @@ class NavBar extends Component {
currentUserId,
isDirectLeaveButtonEnabled,
isMeteorConnected,
hideTopRow,
} = this.props;
const hasNotification = hasUnreadMessages || (hasUnreadNotes && !isPinned);
@ -312,58 +313,60 @@ class NavBar extends Component {
}
}
>
<Styled.Top>
<Styled.Left>
{shouldShowNavBarToggleButton && isExpanded && document.dir === 'ltr'
&& <Styled.ArrowLeft iconName="left_arrow" />}
{shouldShowNavBarToggleButton && !isExpanded && document.dir === 'rtl'
&& <Styled.ArrowLeft iconName="left_arrow" />}
{shouldShowNavBarToggleButton && (
<Styled.NavbarToggleButton
tooltipplacement="right"
onClick={this.handleToggleUserList}
color={isPhone && isExpanded ? 'primary' : 'dark'}
size='md'
circle
hideLabel
data-test={hasNotification ? 'hasUnreadMessages' : 'toggleUserList'}
label={intl.formatMessage(intlMessages.toggleUserListLabel)}
tooltipLabel={intl.formatMessage(intlMessages.toggleUserListLabel)}
aria-label={ariaLabel}
icon="user"
aria-expanded={isExpanded}
accessKey={TOGGLE_USERLIST_AK}
hasNotification={hasNotification}
{!hideTopRow && (
<Styled.Top>
<Styled.Left>
{shouldShowNavBarToggleButton && isExpanded && document.dir === 'ltr'
&& <Styled.ArrowLeft iconName="left_arrow" />}
{shouldShowNavBarToggleButton && !isExpanded && document.dir === 'rtl'
&& <Styled.ArrowLeft iconName="left_arrow" />}
{shouldShowNavBarToggleButton && (
<Styled.NavbarToggleButton
tooltipplacement="right"
onClick={this.handleToggleUserList}
color={isPhone && isExpanded ? 'primary' : 'dark'}
size='md'
circle
hideLabel
data-test={hasNotification ? 'hasUnreadMessages' : 'toggleUserList'}
label={intl.formatMessage(intlMessages.toggleUserListLabel)}
tooltipLabel={intl.formatMessage(intlMessages.toggleUserListLabel)}
aria-label={ariaLabel}
icon="user"
aria-expanded={isExpanded}
accessKey={TOGGLE_USERLIST_AK}
hasNotification={hasNotification}
/>
)}
{shouldShowNavBarToggleButton && !isExpanded && document.dir === 'ltr'
&& <Styled.ArrowRight iconName="right_arrow" />}
{shouldShowNavBarToggleButton && isExpanded && document.dir === 'rtl'
&& <Styled.ArrowRight iconName="right_arrow" />}
{renderPluginItems(leftPluginItems)}
</Styled.Left>
<Styled.Center>
<Styled.PresentationTitle data-test="presentationTitle">
{presentationTitle}
</Styled.PresentationTitle>
<RecordingIndicator
amIModerator={amIModerator}
currentUserId={currentUserId}
/>
)}
{shouldShowNavBarToggleButton && !isExpanded && document.dir === 'ltr'
&& <Styled.ArrowRight iconName="right_arrow" />}
{shouldShowNavBarToggleButton && isExpanded && document.dir === 'rtl'
&& <Styled.ArrowRight iconName="right_arrow" />}
{renderPluginItems(leftPluginItems)}
</Styled.Left>
<Styled.Center>
<Styled.PresentationTitle data-test="presentationTitle">
{presentationTitle}
</Styled.PresentationTitle>
<RecordingIndicator
amIModerator={amIModerator}
currentUserId={currentUserId}
/>
{renderPluginItems(centerPluginItems)}
</Styled.Center>
<Styled.Right>
{renderPluginItems(rightPluginItems)}
{ConnectionStatusService.isEnabled() ? <ConnectionStatusButton /> : null}
{ConnectionStatusService.isEnabled() ? <ConnectionStatus /> : null}
{isDirectLeaveButtonEnabled && isMeteorConnected
? <LeaveMeetingButtonContainer amIModerator={amIModerator} /> : null}
<OptionsDropdownContainer
amIModerator={amIModerator}
isDirectLeaveButtonEnabled={isDirectLeaveButtonEnabled}
/>
</Styled.Right>
</Styled.Top>
{renderPluginItems(centerPluginItems)}
</Styled.Center>
<Styled.Right>
{renderPluginItems(rightPluginItems)}
{ConnectionStatusService.isEnabled() ? <ConnectionStatusButton /> : null}
{ConnectionStatusService.isEnabled() ? <ConnectionStatus /> : null}
{isDirectLeaveButtonEnabled && isMeteorConnected
? <LeaveMeetingButtonContainer amIModerator={amIModerator} /> : null}
<OptionsDropdownContainer
amIModerator={amIModerator}
isDirectLeaveButtonEnabled={isDirectLeaveButtonEnabled}
/>
</Styled.Right>
</Styled.Top>
)}
<Styled.Bottom>
{enableTalkingIndicator ? <TalkingIndicator amIModerator={amIModerator} /> : null}
<TimerIndicatorContainer />

View File

@ -3,7 +3,7 @@ import { defineMessages, useIntl } from 'react-intl';
import Auth from '/imports/ui/services/auth';
import getFromUserSettings from '/imports/ui/services/users-settings';
import NavBar from './component';
import { layoutSelectInput, layoutSelectOutput, layoutDispatch } from '../layout/context';
import { layoutSelectInput, layoutDispatch, layoutSelectOutput } from '../layout/context';
import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context';
import { PANELS } from '/imports/ui/components/layout/enums';
import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser';
@ -121,6 +121,7 @@ const NavBarContainer = ({ children, ...props }) => {
isDirectLeaveButtonEnabled: IS_DIRECT_LEAVE_BUTTON_ENABLED,
// TODO: Remove/Replace
isMeteorConnected: true,
hideTopRow: navBar.hideTopRow,
...props,
}}
style={{ ...navBar }}