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:
parent
84dba0c251
commit
4aab1b21d8
@ -95,7 +95,8 @@ const AppContainer = (props) => {
|
|||||||
? (
|
? (
|
||||||
<App
|
<App
|
||||||
{...{
|
{...{
|
||||||
hideActionsBar: getFromUserSettings('bbb_hide_actions_bar', false),
|
hideActionsBar: getFromUserSettings('bbb_hide_actions_bar', false)
|
||||||
|
|| getFromUserSettings('bbb_hide_controls', false),
|
||||||
currentUserAway: currentUser.away,
|
currentUserAway: currentUser.away,
|
||||||
currentUserRaiseHand: currentUser.raiseHand,
|
currentUserRaiseHand: currentUser.raiseHand,
|
||||||
captionsStyle,
|
captionsStyle,
|
||||||
|
@ -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: {
|
case ACTIONS.SET_NAVBAR_OUTPUT: {
|
||||||
const {
|
const {
|
||||||
display, width, height, top, left, tabOrder, zIndex,
|
display, width, height, top, left, tabOrder, zIndex,
|
||||||
|
@ -56,6 +56,7 @@ export const ACTIONS = {
|
|||||||
SET_HIDE_NOTIFICATION_TOASTS: 'setHideNotificationToasts',
|
SET_HIDE_NOTIFICATION_TOASTS: 'setHideNotificationToasts',
|
||||||
|
|
||||||
SET_HAS_NAVBAR: 'setHasNavBar',
|
SET_HAS_NAVBAR: 'setHasNavBar',
|
||||||
|
SET_HIDE_NAVBAR_TOP_ROW: 'setHideNavBarTopRow',
|
||||||
SET_NAVBAR_OUTPUT: 'setNavBarOutput',
|
SET_NAVBAR_OUTPUT: 'setNavBarOutput',
|
||||||
|
|
||||||
SET_HAS_ACTIONBAR: 'setHasActionBar',
|
SET_HAS_ACTIONBAR: 'setHasActionBar',
|
||||||
|
@ -115,6 +115,7 @@ export const INITIAL_INPUT_STATE = {
|
|||||||
export const INITIAL_OUTPUT_STATE = {
|
export const INITIAL_OUTPUT_STATE = {
|
||||||
navBar: {
|
navBar: {
|
||||||
display: false,
|
display: false,
|
||||||
|
hideTopRow: false,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
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 DEFAULT_VALUES from '/imports/ui/components/layout/defaultValues';
|
||||||
import { LAYOUT_TYPE, DEVICE_TYPE } from '/imports/ui/components/layout/enums';
|
import { LAYOUT_TYPE, DEVICE_TYPE } from '/imports/ui/components/layout/enums';
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ const LayoutEngine = () => {
|
|||||||
const presentationInput = layoutSelectInput((i) => i.presentation);
|
const presentationInput = layoutSelectInput((i) => i.presentation);
|
||||||
const actionbarInput = layoutSelectInput((i) => i.actionBar);
|
const actionbarInput = layoutSelectInput((i) => i.actionBar);
|
||||||
const navBarInput = layoutSelectInput((i) => i.navBar);
|
const navBarInput = layoutSelectInput((i) => i.navBar);
|
||||||
|
const navBarOutput = layoutSelectOutput((i) => i.navBar);
|
||||||
const sidebarNavigationInput = layoutSelectInput((i) => i.sidebarNavigation);
|
const sidebarNavigationInput = layoutSelectInput((i) => i.sidebarNavigation);
|
||||||
const sidebarContentInput = layoutSelectInput((i) => i.sidebarContent);
|
const sidebarContentInput = layoutSelectInput((i) => i.sidebarContent);
|
||||||
const externalVideoInput = layoutSelectInput((i) => i.externalVideo);
|
const externalVideoInput = layoutSelectInput((i) => i.externalVideo);
|
||||||
@ -106,7 +107,9 @@ const LayoutEngine = () => {
|
|||||||
const calculatesNavbarHeight = () => {
|
const calculatesNavbarHeight = () => {
|
||||||
const { navBarHeight } = DEFAULT_VALUES;
|
const { navBarHeight } = DEFAULT_VALUES;
|
||||||
|
|
||||||
return navBarInput.hasNavBar ? navBarHeight : 0;
|
const finalHeight = navBarOutput.hideTopRow ? navBarHeight / 2 : navBarHeight;
|
||||||
|
|
||||||
|
return navBarInput.hasNavBar ? finalHeight : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const calculatesNavbarBounds = (mediaAreaBounds) => {
|
const calculatesNavbarBounds = (mediaAreaBounds) => {
|
||||||
|
@ -97,6 +97,7 @@ export interface GenericContentMainArea {
|
|||||||
}
|
}
|
||||||
interface NavBar {
|
interface NavBar {
|
||||||
hasNavBar?: boolean;
|
hasNavBar?: boolean;
|
||||||
|
hideTopRow: boolean;
|
||||||
height: number;
|
height: number;
|
||||||
display?: boolean;
|
display?: boolean;
|
||||||
left?: number;
|
left?: number;
|
||||||
|
@ -101,7 +101,13 @@ const LayoutObserver: React.FC = () => {
|
|||||||
|
|
||||||
layoutContextDispatch({
|
layoutContextDispatch({
|
||||||
type: ACTIONS.SET_HAS_ACTIONBAR,
|
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({
|
layoutContextDispatch({
|
||||||
|
@ -272,6 +272,7 @@ class NavBar extends Component {
|
|||||||
currentUserId,
|
currentUserId,
|
||||||
isDirectLeaveButtonEnabled,
|
isDirectLeaveButtonEnabled,
|
||||||
isMeteorConnected,
|
isMeteorConnected,
|
||||||
|
hideTopRow,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const hasNotification = hasUnreadMessages || (hasUnreadNotes && !isPinned);
|
const hasNotification = hasUnreadMessages || (hasUnreadNotes && !isPinned);
|
||||||
@ -312,58 +313,60 @@ class NavBar extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Styled.Top>
|
{!hideTopRow && (
|
||||||
<Styled.Left>
|
<Styled.Top>
|
||||||
{shouldShowNavBarToggleButton && isExpanded && document.dir === 'ltr'
|
<Styled.Left>
|
||||||
&& <Styled.ArrowLeft iconName="left_arrow" />}
|
{shouldShowNavBarToggleButton && isExpanded && document.dir === 'ltr'
|
||||||
{shouldShowNavBarToggleButton && !isExpanded && document.dir === 'rtl'
|
&& <Styled.ArrowLeft iconName="left_arrow" />}
|
||||||
&& <Styled.ArrowLeft iconName="left_arrow" />}
|
{shouldShowNavBarToggleButton && !isExpanded && document.dir === 'rtl'
|
||||||
{shouldShowNavBarToggleButton && (
|
&& <Styled.ArrowLeft iconName="left_arrow" />}
|
||||||
<Styled.NavbarToggleButton
|
{shouldShowNavBarToggleButton && (
|
||||||
tooltipplacement="right"
|
<Styled.NavbarToggleButton
|
||||||
onClick={this.handleToggleUserList}
|
tooltipplacement="right"
|
||||||
color={isPhone && isExpanded ? 'primary' : 'dark'}
|
onClick={this.handleToggleUserList}
|
||||||
size='md'
|
color={isPhone && isExpanded ? 'primary' : 'dark'}
|
||||||
circle
|
size='md'
|
||||||
hideLabel
|
circle
|
||||||
data-test={hasNotification ? 'hasUnreadMessages' : 'toggleUserList'}
|
hideLabel
|
||||||
label={intl.formatMessage(intlMessages.toggleUserListLabel)}
|
data-test={hasNotification ? 'hasUnreadMessages' : 'toggleUserList'}
|
||||||
tooltipLabel={intl.formatMessage(intlMessages.toggleUserListLabel)}
|
label={intl.formatMessage(intlMessages.toggleUserListLabel)}
|
||||||
aria-label={ariaLabel}
|
tooltipLabel={intl.formatMessage(intlMessages.toggleUserListLabel)}
|
||||||
icon="user"
|
aria-label={ariaLabel}
|
||||||
aria-expanded={isExpanded}
|
icon="user"
|
||||||
accessKey={TOGGLE_USERLIST_AK}
|
aria-expanded={isExpanded}
|
||||||
hasNotification={hasNotification}
|
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}
|
||||||
/>
|
/>
|
||||||
)}
|
{renderPluginItems(centerPluginItems)}
|
||||||
{shouldShowNavBarToggleButton && !isExpanded && document.dir === 'ltr'
|
</Styled.Center>
|
||||||
&& <Styled.ArrowRight iconName="right_arrow" />}
|
<Styled.Right>
|
||||||
{shouldShowNavBarToggleButton && isExpanded && document.dir === 'rtl'
|
{renderPluginItems(rightPluginItems)}
|
||||||
&& <Styled.ArrowRight iconName="right_arrow" />}
|
{ConnectionStatusService.isEnabled() ? <ConnectionStatusButton /> : null}
|
||||||
{renderPluginItems(leftPluginItems)}
|
{ConnectionStatusService.isEnabled() ? <ConnectionStatus /> : null}
|
||||||
</Styled.Left>
|
{isDirectLeaveButtonEnabled && isMeteorConnected
|
||||||
<Styled.Center>
|
? <LeaveMeetingButtonContainer amIModerator={amIModerator} /> : null}
|
||||||
<Styled.PresentationTitle data-test="presentationTitle">
|
<OptionsDropdownContainer
|
||||||
{presentationTitle}
|
amIModerator={amIModerator}
|
||||||
</Styled.PresentationTitle>
|
isDirectLeaveButtonEnabled={isDirectLeaveButtonEnabled}
|
||||||
<RecordingIndicator
|
/>
|
||||||
amIModerator={amIModerator}
|
</Styled.Right>
|
||||||
currentUserId={currentUserId}
|
</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>
|
<Styled.Bottom>
|
||||||
{enableTalkingIndicator ? <TalkingIndicator amIModerator={amIModerator} /> : null}
|
{enableTalkingIndicator ? <TalkingIndicator amIModerator={amIModerator} /> : null}
|
||||||
<TimerIndicatorContainer />
|
<TimerIndicatorContainer />
|
||||||
|
@ -3,7 +3,7 @@ import { defineMessages, useIntl } from 'react-intl';
|
|||||||
import Auth from '/imports/ui/services/auth';
|
import Auth from '/imports/ui/services/auth';
|
||||||
import getFromUserSettings from '/imports/ui/services/users-settings';
|
import getFromUserSettings from '/imports/ui/services/users-settings';
|
||||||
import NavBar from './component';
|
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 { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context';
|
||||||
import { PANELS } from '/imports/ui/components/layout/enums';
|
import { PANELS } from '/imports/ui/components/layout/enums';
|
||||||
import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser';
|
import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser';
|
||||||
@ -121,6 +121,7 @@ const NavBarContainer = ({ children, ...props }) => {
|
|||||||
isDirectLeaveButtonEnabled: IS_DIRECT_LEAVE_BUTTON_ENABLED,
|
isDirectLeaveButtonEnabled: IS_DIRECT_LEAVE_BUTTON_ENABLED,
|
||||||
// TODO: Remove/Replace
|
// TODO: Remove/Replace
|
||||||
isMeteorConnected: true,
|
isMeteorConnected: true,
|
||||||
|
hideTopRow: navBar.hideTopRow,
|
||||||
...props,
|
...props,
|
||||||
}}
|
}}
|
||||||
style={{ ...navBar }}
|
style={{ ...navBar }}
|
||||||
|
Loading…
Reference in New Issue
Block a user