Merge pull request #12474 from Tainan404/refactor-dropdown
refactor: Decrease amount of imports in dropdown
This commit is contained in:
commit
9395f50b99
@ -4,13 +4,8 @@ import PropTypes from 'prop-types';
|
|||||||
import { defineMessages } from 'react-intl';
|
import { defineMessages } from 'react-intl';
|
||||||
import Button from '/imports/ui/components/button/component';
|
import Button from '/imports/ui/components/button/component';
|
||||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
|
||||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
|
||||||
import { withModalMounter } from '/imports/ui/components/modal/service';
|
import { withModalMounter } from '/imports/ui/components/modal/service';
|
||||||
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
|
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
|
||||||
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
|
|
||||||
import ExternalVideoModal from '/imports/ui/components/external-video-player/modal/container';
|
import ExternalVideoModal from '/imports/ui/components/external-video-player/modal/container';
|
||||||
import RandomUserSelectContainer from '/imports/ui/components/modal/random-user/container';
|
import RandomUserSelectContainer from '/imports/ui/components/modal/random-user/container';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
@ -145,7 +140,7 @@ class ActionsDropdown extends PureComponent {
|
|||||||
return _.compact([
|
return _.compact([
|
||||||
(amIPresenter && isPollingEnabled
|
(amIPresenter && isPollingEnabled
|
||||||
? (
|
? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
icon="polling"
|
icon="polling"
|
||||||
data-test="polling"
|
data-test="polling"
|
||||||
label={formatMessage(pollBtnLabel)}
|
label={formatMessage(pollBtnLabel)}
|
||||||
@ -170,7 +165,7 @@ class ActionsDropdown extends PureComponent {
|
|||||||
: null),
|
: null),
|
||||||
(!amIPresenter
|
(!amIPresenter
|
||||||
? (
|
? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
icon="presentation"
|
icon="presentation"
|
||||||
label={formatMessage(takePresenter)}
|
label={formatMessage(takePresenter)}
|
||||||
description={formatMessage(takePresenterDesc)}
|
description={formatMessage(takePresenterDesc)}
|
||||||
@ -181,7 +176,7 @@ class ActionsDropdown extends PureComponent {
|
|||||||
: null),
|
: null),
|
||||||
(amIPresenter
|
(amIPresenter
|
||||||
? (
|
? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
data-test="uploadPresentation"
|
data-test="uploadPresentation"
|
||||||
icon="presentation"
|
icon="presentation"
|
||||||
label={formatMessage(presentationLabel)}
|
label={formatMessage(presentationLabel)}
|
||||||
@ -193,7 +188,7 @@ class ActionsDropdown extends PureComponent {
|
|||||||
: null),
|
: null),
|
||||||
(amIPresenter && allowExternalVideo
|
(amIPresenter && allowExternalVideo
|
||||||
? (
|
? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
icon="video"
|
icon="video"
|
||||||
label={!isSharingVideo ? intl.formatMessage(intlMessages.startExternalVideoLabel)
|
label={!isSharingVideo ? intl.formatMessage(intlMessages.startExternalVideoLabel)
|
||||||
: intl.formatMessage(intlMessages.stopExternalVideoLabel)}
|
: intl.formatMessage(intlMessages.stopExternalVideoLabel)}
|
||||||
@ -205,7 +200,7 @@ class ActionsDropdown extends PureComponent {
|
|||||||
: null),
|
: null),
|
||||||
(amIPresenter && isSelectRandomUserEnabled
|
(amIPresenter && isSelectRandomUserEnabled
|
||||||
? (
|
? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
icon="user"
|
icon="user"
|
||||||
label={intl.formatMessage(intlMessages.selectRandUserLabel)}
|
label={intl.formatMessage(intlMessages.selectRandUserLabel)}
|
||||||
description={intl.formatMessage(intlMessages.selectRandUserDesc)}
|
description={intl.formatMessage(intlMessages.selectRandUserDesc)}
|
||||||
@ -238,7 +233,7 @@ class ActionsDropdown extends PureComponent {
|
|||||||
itemStyles[styles.isCurrent] = p.current;
|
itemStyles[styles.isCurrent] = p.current;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
className={cx(itemStyles)}
|
className={cx(itemStyles)}
|
||||||
icon="file"
|
icon="file"
|
||||||
iconRight={p.current ? 'check' : null}
|
iconRight={p.current ? 'check' : null}
|
||||||
@ -252,7 +247,7 @@ class ActionsDropdown extends PureComponent {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
presentationItemElements.push(<DropdownListSeparator key={_.uniqueId('list-separator-')} />);
|
presentationItemElements.push(<Dropdown.DropdownListSeparator key={_.uniqueId('list-separator-')} />);
|
||||||
return presentationItemElements;
|
return presentationItemElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +283,7 @@ class ActionsDropdown extends PureComponent {
|
|||||||
className={styles.dropdown}
|
className={styles.dropdown}
|
||||||
ref={(ref) => { this._dropdown = ref; }}
|
ref={(ref) => { this._dropdown = ref; }}
|
||||||
>
|
>
|
||||||
<DropdownTrigger tabIndex={0} accessKey={OPEN_ACTIONS_AK}>
|
<Dropdown.DropdownTrigger tabIndex={0} accessKey={OPEN_ACTIONS_AK}>
|
||||||
<Button
|
<Button
|
||||||
className={isDropdownOpen ? styles.hideDropdownButton : ''}
|
className={isDropdownOpen ? styles.hideDropdownButton : ''}
|
||||||
hideLabel
|
hideLabel
|
||||||
@ -300,12 +295,12 @@ class ActionsDropdown extends PureComponent {
|
|||||||
circle
|
circle
|
||||||
onClick={() => null}
|
onClick={() => null}
|
||||||
/>
|
/>
|
||||||
</DropdownTrigger>
|
</Dropdown.DropdownTrigger>
|
||||||
<DropdownContent placement="top left">
|
<Dropdown.DropdownContent placement="top left">
|
||||||
<DropdownList className={styles.scrollableList}>
|
<Dropdown.DropdownList className={styles.scrollableList}>
|
||||||
{children}
|
{children}
|
||||||
</DropdownList>
|
</Dropdown.DropdownList>
|
||||||
</DropdownContent>
|
</Dropdown.DropdownContent>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,6 @@ import { defineMessages } from 'react-intl';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Button from '/imports/ui/components/button/component';
|
import Button from '/imports/ui/components/button/component';
|
||||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
|
||||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
|
||||||
import { styles } from '../styles';
|
import { styles } from '../styles';
|
||||||
import { PANELS, ACTIONS } from '../../layout/enums';
|
import { PANELS, ACTIONS } from '../../layout/enums';
|
||||||
|
|
||||||
@ -111,7 +107,7 @@ const getAvailableQuickPolls = (
|
|||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
label={itemLabel}
|
label={itemLabel}
|
||||||
key={_.uniqueId('quick-poll-item')}
|
key={_.uniqueId('quick-poll-item')}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -210,14 +206,14 @@ class QuickPollDropdown extends Component {
|
|||||||
|
|
||||||
dropdown = (
|
dropdown = (
|
||||||
<Dropdown className={className}>
|
<Dropdown className={className}>
|
||||||
<DropdownTrigger tabIndex={0}>
|
<Dropdown.DropdownTrigger tabIndex={0}>
|
||||||
{btn}
|
{btn}
|
||||||
</DropdownTrigger>
|
</Dropdown.DropdownTrigger>
|
||||||
<DropdownContent placement="top left">
|
<Dropdown.DropdownContent placement="top left">
|
||||||
<DropdownList>
|
<Dropdown.DropdownList>
|
||||||
{quickPolls}
|
{quickPolls}
|
||||||
</DropdownList>
|
</Dropdown.DropdownList>
|
||||||
</DropdownContent>
|
</Dropdown.DropdownContent>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,6 @@ import { defineMessages, injectIntl } from 'react-intl';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Button from '/imports/ui/components/button/component';
|
import Button from '/imports/ui/components/button/component';
|
||||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
|
||||||
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
|
|
||||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
|
||||||
import DropdownListTitle from '/imports/ui/components/dropdown/list/title/component';
|
|
||||||
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
|
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
@ -222,14 +216,14 @@ class InputStreamLiveSelector extends Component {
|
|||||||
const listLenght = list ? list.length : -1;
|
const listLenght = list ? list.length : -1;
|
||||||
|
|
||||||
const listTitle = [
|
const listTitle = [
|
||||||
<DropdownListTitle key={`audioDeviceList-${deviceKind}`}>
|
<Dropdown.DropdownListTitle key={`audioDeviceList-${deviceKind}`}>
|
||||||
{title}
|
{title}
|
||||||
</DropdownListTitle>,
|
</Dropdown.DropdownListTitle>,
|
||||||
];
|
];
|
||||||
|
|
||||||
const deviceList = (listLenght > 0)
|
const deviceList = (listLenght > 0)
|
||||||
? list.map((device) => (
|
? list.map((device) => (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key={`${device.deviceId}-${deviceKind}`}
|
key={`${device.deviceId}-${deviceKind}`}
|
||||||
label={InputStreamLiveSelector.truncateDeviceName(device.label)}
|
label={InputStreamLiveSelector.truncateDeviceName(device.label)}
|
||||||
onClick={() => this.onDeviceListClick(device.deviceId, deviceKind,
|
onClick={() => this.onDeviceListClick(device.deviceId, deviceKind,
|
||||||
@ -239,7 +233,7 @@ class InputStreamLiveSelector extends Component {
|
|||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
: [
|
: [
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key={`noDeviceFoundKey-${deviceKind}-`}
|
key={`noDeviceFoundKey-${deviceKind}-`}
|
||||||
className={styles.disableDeviceSelection}
|
className={styles.disableDeviceSelection}
|
||||||
label={
|
label={
|
||||||
@ -251,7 +245,7 @@ class InputStreamLiveSelector extends Component {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const listSeparator = [
|
const listSeparator = [
|
||||||
<DropdownListSeparator key={`audioDeviceListSeparator-${deviceKind}`} />,
|
<Dropdown.DropdownListSeparator key={`audioDeviceListSeparator-${deviceKind}`} />,
|
||||||
];
|
];
|
||||||
|
|
||||||
return listTitle.concat(deviceList).concat(listSeparator);
|
return listTitle.concat(deviceList).concat(listSeparator);
|
||||||
@ -295,7 +289,7 @@ class InputStreamLiveSelector extends Component {
|
|||||||
|
|
||||||
const dropdownListComplete = inputDeviceList.concat(outputDeviceList)
|
const dropdownListComplete = inputDeviceList.concat(outputDeviceList)
|
||||||
.concat([
|
.concat([
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key="leaveAudioButtonKey"
|
key="leaveAudioButtonKey"
|
||||||
className={styles.stopButton}
|
className={styles.stopButton}
|
||||||
label={intl.formatMessage(intlMessages.leaveAudio)}
|
label={intl.formatMessage(intlMessages.leaveAudio)}
|
||||||
@ -306,7 +300,7 @@ class InputStreamLiveSelector extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown>
|
<Dropdown>
|
||||||
<DropdownTrigger>
|
<Dropdown.DropdownTrigger>
|
||||||
<Button
|
<Button
|
||||||
aria-label={intl.formatMessage(intlMessages.changeLeaveAudio)}
|
aria-label={intl.formatMessage(intlMessages.changeLeaveAudio)}
|
||||||
label={intl.formatMessage(intlMessages.changeLeaveAudio)}
|
label={intl.formatMessage(intlMessages.changeLeaveAudio)}
|
||||||
@ -317,12 +311,14 @@ class InputStreamLiveSelector extends Component {
|
|||||||
circle
|
circle
|
||||||
onClick={() => {}}
|
onClick={() => {}}
|
||||||
/>
|
/>
|
||||||
</DropdownTrigger>
|
</Dropdown.DropdownTrigger>
|
||||||
<DropdownContent className={styles.dropdownContent}>
|
<Dropdown.DropdownContent className={styles.dropdownContent}>
|
||||||
<DropdownList className={cx(styles.scrollableList, styles.dropdownListContainer)}>
|
<Dropdown.DropdownList
|
||||||
|
className={cx(styles.scrollableList, styles.dropdownListContainer)}
|
||||||
|
>
|
||||||
{dropdownListComplete}
|
{dropdownListComplete}
|
||||||
</DropdownList>
|
</Dropdown.DropdownList>
|
||||||
</DropdownContent>
|
</Dropdown.DropdownContent>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,6 @@ import { withModalMounter } from '/imports/ui/components/modal/service';
|
|||||||
import Clipboard from 'clipboard';
|
import Clipboard from 'clipboard';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
|
||||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
|
||||||
import Button from '/imports/ui/components/button/component';
|
import Button from '/imports/ui/components/button/component';
|
||||||
|
|
||||||
import ChatService from '../service';
|
import ChatService from '../service';
|
||||||
@ -89,7 +85,7 @@ class ChatDropdown extends PureComponent {
|
|||||||
const saveIcon = 'download';
|
const saveIcon = 'download';
|
||||||
const copyIcon = 'copy';
|
const copyIcon = 'copy';
|
||||||
return _.compact([
|
return _.compact([
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
data-test="chatSave"
|
data-test="chatSave"
|
||||||
icon={saveIcon}
|
icon={saveIcon}
|
||||||
label={intl.formatMessage(intlMessages.save)}
|
label={intl.formatMessage(intlMessages.save)}
|
||||||
@ -109,7 +105,7 @@ class ChatDropdown extends PureComponent {
|
|||||||
link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
|
link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
|
||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
data-test="chatCopy"
|
data-test="chatCopy"
|
||||||
icon={copyIcon}
|
icon={copyIcon}
|
||||||
id="clipboardButton"
|
id="clipboardButton"
|
||||||
@ -117,7 +113,7 @@ class ChatDropdown extends PureComponent {
|
|||||||
key={this.actionsKey[1]}
|
key={this.actionsKey[1]}
|
||||||
/>,
|
/>,
|
||||||
!meetingIsBreakout && amIModerator && isMeteorConnected ? (
|
!meetingIsBreakout && amIModerator && isMeteorConnected ? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
data-test="chatClear"
|
data-test="chatClear"
|
||||||
icon={clearIcon}
|
icon={clearIcon}
|
||||||
label={intl.formatMessage(intlMessages.clear)}
|
label={intl.formatMessage(intlMessages.clear)}
|
||||||
@ -140,7 +136,7 @@ class ChatDropdown extends PureComponent {
|
|||||||
onShow={this.onActionsShow}
|
onShow={this.onActionsShow}
|
||||||
onHide={this.onActionsHide}
|
onHide={this.onActionsHide}
|
||||||
>
|
>
|
||||||
<DropdownTrigger tabIndex={0}>
|
<Dropdown.DropdownTrigger tabIndex={0}>
|
||||||
<Button
|
<Button
|
||||||
data-test="chatDropdownTrigger"
|
data-test="chatDropdownTrigger"
|
||||||
icon="more"
|
icon="more"
|
||||||
@ -153,10 +149,10 @@ class ChatDropdown extends PureComponent {
|
|||||||
aria-label={intl.formatMessage(intlMessages.options)}
|
aria-label={intl.formatMessage(intlMessages.options)}
|
||||||
onClick={() => null}
|
onClick={() => null}
|
||||||
/>
|
/>
|
||||||
</DropdownTrigger>
|
</Dropdown.DropdownTrigger>
|
||||||
<DropdownContent placement="bottom right">
|
<Dropdown.DropdownContent placement="bottom right">
|
||||||
<DropdownList>{availableActions}</DropdownList>
|
<Dropdown.DropdownList>{availableActions}</Dropdown.DropdownList>
|
||||||
</DropdownContent>
|
</Dropdown.DropdownContent>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,13 @@ import Button from '/imports/ui/components/button/component';
|
|||||||
import screenreaderTrap from 'makeup-screenreader-trap';
|
import screenreaderTrap from 'makeup-screenreader-trap';
|
||||||
import { Session } from 'meteor/session';
|
import { Session } from 'meteor/session';
|
||||||
import { styles } from './styles';
|
import { styles } from './styles';
|
||||||
import DropdownTrigger from './trigger/component';
|
|
||||||
import DropdownContent from './content/component';
|
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
||||||
|
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
||||||
|
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
||||||
|
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
|
||||||
|
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
||||||
|
import DropdownListTitle from '/imports/ui/components/dropdown/list/title/component';
|
||||||
|
|
||||||
const intlMessages = defineMessages({
|
const intlMessages = defineMessages({
|
||||||
close: {
|
close: {
|
||||||
@ -33,8 +38,8 @@ const propTypes = {
|
|||||||
+ ` \`${componentName}\`. Validation failed.`);
|
+ ` \`${componentName}\`. Validation failed.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const trigger = children.find(x => x.type === DropdownTrigger);
|
const trigger = children.find((x) => x.type === DropdownTrigger);
|
||||||
const content = children.find(x => x.type === DropdownContent);
|
const content = children.find((x) => x.type === DropdownContent);
|
||||||
|
|
||||||
if (!trigger) {
|
if (!trigger) {
|
||||||
return new Error(`Invalid prop \`${propName}\` supplied to`
|
return new Error(`Invalid prop \`${propName}\` supplied to`
|
||||||
@ -53,11 +58,12 @@ const propTypes = {
|
|||||||
onHide: PropTypes.func,
|
onHide: PropTypes.func,
|
||||||
onShow: PropTypes.func,
|
onShow: PropTypes.func,
|
||||||
autoFocus: PropTypes.bool,
|
autoFocus: PropTypes.bool,
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
tethered: PropTypes.bool,
|
tethered: PropTypes.bool,
|
||||||
|
getContent: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
|
tethered: false,
|
||||||
children: null,
|
children: null,
|
||||||
onShow: noop,
|
onShow: noop,
|
||||||
onHide: noop,
|
onHide: noop,
|
||||||
@ -79,11 +85,19 @@ const targetAttachments = {
|
|||||||
class Dropdown extends Component {
|
class Dropdown extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { isOpen: false, isPortrait:deviceInfo.isPortrait() };
|
this.state = {
|
||||||
|
isOpen: false,
|
||||||
|
isPortrait: deviceInfo.isPortrait(),
|
||||||
|
};
|
||||||
this.handleShow = this.handleShow.bind(this);
|
this.handleShow = this.handleShow.bind(this);
|
||||||
this.handleHide = this.handleHide.bind(this);
|
this.handleHide = this.handleHide.bind(this);
|
||||||
this.handleToggle = this.handleToggle.bind(this);
|
this.handleToggle = this.handleToggle.bind(this);
|
||||||
this.handleWindowClick = this.handleWindowClick.bind(this);
|
this.handleWindowClick = this.handleWindowClick.bind(this);
|
||||||
|
this.updateOrientation = this.updateOrientation.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener('resize', this.updateOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
@ -92,8 +106,6 @@ class Dropdown extends Component {
|
|||||||
onHide,
|
onHide,
|
||||||
keepOpen,
|
keepOpen,
|
||||||
tethered,
|
tethered,
|
||||||
sidebarContentPanel,
|
|
||||||
sidebarNavPanel
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const { isOpen } = this.state;
|
const { isOpen } = this.state;
|
||||||
@ -113,16 +125,8 @@ class Dropdown extends Component {
|
|||||||
if (prevProps.keepOpen && !keepOpen) onHide();
|
if (prevProps.keepOpen && !keepOpen) onHide();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShow() {
|
componentWillUnmount() {
|
||||||
Session.set('dropdownOpen', true);
|
window.removeEventListener('resize', this.updateOrientation);
|
||||||
const {
|
|
||||||
onShow,
|
|
||||||
} = this.props;
|
|
||||||
this.setState({ isOpen: true }, () => {
|
|
||||||
const { addEventListener } = window;
|
|
||||||
onShow();
|
|
||||||
addEventListener('click', this.handleWindowClick, true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleHide() {
|
handleHide() {
|
||||||
@ -135,16 +139,17 @@ class Dropdown extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
handleShow() {
|
||||||
window.addEventListener('resize', this.updateOrientation);
|
Session.set('dropdownOpen', true);
|
||||||
|
const {
|
||||||
|
onShow,
|
||||||
|
} = this.props;
|
||||||
|
this.setState({ isOpen: true }, () => {
|
||||||
|
const { addEventListener } = window;
|
||||||
|
onShow();
|
||||||
|
addEventListener('click', this.handleWindowClick, true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
componentWillUnmount() {
|
|
||||||
window.removeEventListener('resize', this.updateOrientation);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateOrientation = () => {
|
|
||||||
this.setState({ isPortrait:deviceInfo.isPortrait() });
|
|
||||||
};
|
|
||||||
|
|
||||||
handleWindowClick(event) {
|
handleWindowClick(event) {
|
||||||
const { keepOpen, onHide } = this.props;
|
const { keepOpen, onHide } = this.props;
|
||||||
@ -187,6 +192,10 @@ class Dropdown extends Component {
|
|||||||
return isOpen ? this.handleHide() : this.handleShow();
|
return isOpen ? this.handleHide() : this.handleShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateOrientation() {
|
||||||
|
this.setState({ isPortrait: deviceInfo.isPortrait() });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
children,
|
children,
|
||||||
@ -198,7 +207,6 @@ class Dropdown extends Component {
|
|||||||
getContent,
|
getContent,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const { isOpen, isPortrait } = this.state;
|
const { isOpen, isPortrait } = this.state;
|
||||||
const { isPhone } = deviceInfo;
|
const { isPhone } = deviceInfo;
|
||||||
const placements = placement && placement.replace(' ', '-');
|
const placements = placement && placement.replace(' ', '-');
|
||||||
@ -212,8 +220,8 @@ class Dropdown extends Component {
|
|||||||
transform: '',
|
transform: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
let trigger = children.find(x => x.type === DropdownTrigger);
|
let trigger = children.find((x) => x.type === DropdownTrigger);
|
||||||
let content = children.find(x => x.type === DropdownContent);
|
let content = children.find((x) => x.type === DropdownContent);
|
||||||
|
|
||||||
trigger = React.cloneElement(trigger, {
|
trigger = React.cloneElement(trigger, {
|
||||||
ref: (ref) => { this.trigger = ref; },
|
ref: (ref) => { this.trigger = ref; },
|
||||||
@ -238,7 +246,6 @@ class Dropdown extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const showCloseBtn = (isOpen && keepOpen) || (isOpen && keepOpen === null);
|
const showCloseBtn = (isOpen && keepOpen) || (isOpen && keepOpen === null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(styles.dropdown, className)}
|
className={cx(styles.dropdown, className)}
|
||||||
@ -270,11 +277,12 @@ class Dropdown extends Component {
|
|||||||
to: 'scrollParent',
|
to: 'scrollParent',
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
renderTarget={ref => (
|
renderTarget={(ref) => (
|
||||||
<span ref={ref}>
|
<span ref={ref}>
|
||||||
{trigger}
|
{trigger}
|
||||||
</span>)}
|
</span>
|
||||||
renderElement={ref => (
|
)}
|
||||||
|
renderElement={(ref) => (
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
>
|
>
|
||||||
@ -290,11 +298,12 @@ class Dropdown extends Component {
|
|||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
)}
|
||||||
}
|
/>
|
||||||
/>)
|
)
|
||||||
: (
|
: (
|
||||||
<Fragment>
|
// Fix eslint rule https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-fragments.md
|
||||||
|
<>
|
||||||
{trigger}
|
{trigger}
|
||||||
{content}
|
{content}
|
||||||
{showCloseBtn
|
{showCloseBtn
|
||||||
@ -307,7 +316,7 @@ class Dropdown extends Component {
|
|||||||
onClick={this.handleHide}
|
onClick={this.handleHide}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</Fragment>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@ -317,4 +326,11 @@ class Dropdown extends Component {
|
|||||||
|
|
||||||
Dropdown.propTypes = propTypes;
|
Dropdown.propTypes = propTypes;
|
||||||
Dropdown.defaultProps = defaultProps;
|
Dropdown.defaultProps = defaultProps;
|
||||||
|
|
||||||
|
Dropdown.DropdownTrigger = DropdownTrigger;
|
||||||
|
Dropdown.DropdownContent = DropdownContent;
|
||||||
|
Dropdown.DropdownList = DropdownList;
|
||||||
|
Dropdown.DropdownListSeparator = DropdownListSeparator;
|
||||||
|
Dropdown.DropdownListItem = DropdownListItem;
|
||||||
|
Dropdown.DropdownListTitle = DropdownListTitle;
|
||||||
export default injectIntl(Dropdown, { forwardRef: true });
|
export default injectIntl(Dropdown, { forwardRef: true });
|
||||||
|
@ -11,9 +11,9 @@ const propTypes = {
|
|||||||
/* We should recheck this proptype, sometimes we need to create an container and send to
|
/* We should recheck this proptype, sometimes we need to create an container and send to
|
||||||
dropdown, but with this proptype, is not possible. */
|
dropdown, but with this proptype, is not possible. */
|
||||||
children: PropTypes.arrayOf((propValue, key, componentName, propFullName) => {
|
children: PropTypes.arrayOf((propValue, key, componentName, propFullName) => {
|
||||||
if (propValue[key].type !== ListItem &&
|
if (propValue[key].type !== ListItem
|
||||||
propValue[key].type !== ListSeparator &&
|
&& propValue[key].type !== ListSeparator
|
||||||
propValue[key].type !== ListTitle) {
|
&& propValue[key].type !== ListTitle) {
|
||||||
return new Error(`Invalid prop \`${propFullName}\` supplied to` +
|
return new Error(`Invalid prop \`${propFullName}\` supplied to` +
|
||||||
` \`${componentName}\`. Validation failed.`);
|
` \`${componentName}\`. Validation failed.`);
|
||||||
}
|
}
|
||||||
@ -41,14 +41,13 @@ export default class DropdownList extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this._menu.addEventListener('keydown', event => this.handleItemKeyDown(event));
|
this._menu.addEventListener('keydown', (event) => this.handleItemKeyDown(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
|
|
||||||
const { focusedIndex } = this.state;
|
const { focusedIndex } = this.state;
|
||||||
const children = [].slice.call(this._menu.children);
|
const children = [].slice.call(this._menu.children);
|
||||||
this.menuRefs = children.filter(child => child.getAttribute('role') === 'menuitem');
|
this.menuRefs = children.filter((child) => child.getAttribute('role') === 'menuitem');
|
||||||
|
|
||||||
const activeRef = this.menuRefs[focusedIndex];
|
const activeRef = this.menuRefs[focusedIndex];
|
||||||
|
|
||||||
@ -58,7 +57,10 @@ export default class DropdownList extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleItemKeyDown(event, callback) {
|
handleItemKeyDown(event, callback) {
|
||||||
const { getDropdownMenuParent } = this.props;
|
const {
|
||||||
|
getDropdownMenuParent,
|
||||||
|
horizontal,
|
||||||
|
} = this.props;
|
||||||
const { focusedIndex } = this.state;
|
const { focusedIndex } = this.state;
|
||||||
|
|
||||||
let nextFocusedIndex = focusedIndex > 0 ? focusedIndex : 0;
|
let nextFocusedIndex = focusedIndex > 0 ? focusedIndex : 0;
|
||||||
@ -67,7 +69,7 @@ export default class DropdownList extends Component {
|
|||||||
nextFocusedIndex = this.menuRefs.indexOf(document.activeElement);
|
nextFocusedIndex = this.menuRefs.indexOf(document.activeElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isHorizontal = this.props.horizontal;
|
const isHorizontal = horizontal;
|
||||||
const navigationKeys = {
|
const navigationKeys = {
|
||||||
previous: KEY_CODES[`ARROW_${isHorizontal ? 'LEFT' : 'UP'}`],
|
previous: KEY_CODES[`ARROW_${isHorizontal ? 'LEFT' : 'UP'}`],
|
||||||
next: KEY_CODES[`ARROW_${isHorizontal ? 'RIGHT' : 'DOWN'}`],
|
next: KEY_CODES[`ARROW_${isHorizontal ? 'RIGHT' : 'DOWN'}`],
|
||||||
@ -126,8 +128,14 @@ export default class DropdownList extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleItemClick(event, callback) {
|
handleItemClick(event, callback) {
|
||||||
const { getDropdownMenuParent, onActionsHide, dropdownHide, keepOpen} = this.props;
|
const {
|
||||||
if(!keepOpen) {
|
getDropdownMenuParent,
|
||||||
|
onActionsHide,
|
||||||
|
dropdownHide,
|
||||||
|
keepOpen,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
if (!keepOpen) {
|
||||||
if (getDropdownMenuParent) {
|
if (getDropdownMenuParent) {
|
||||||
onActionsHide();
|
onActionsHide();
|
||||||
} else {
|
} else {
|
||||||
@ -142,7 +150,12 @@ export default class DropdownList extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children, style, className } = this.props;
|
const {
|
||||||
|
children,
|
||||||
|
style,
|
||||||
|
className,
|
||||||
|
horizontal,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const boundChildren = Children.map(
|
const boundChildren = Children.map(
|
||||||
children,
|
children,
|
||||||
@ -173,7 +186,7 @@ export default class DropdownList extends Component {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const listDirection = this.props.horizontal ? styles.horizontalList : styles.verticalList;
|
const listDirection = horizontal ? styles.horizontalList : styles.verticalList;
|
||||||
return (
|
return (
|
||||||
<ul
|
<ul
|
||||||
style={style}
|
style={style}
|
||||||
|
@ -11,6 +11,7 @@ const propTypes = {
|
|||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
accessKey: PropTypes.string,
|
accessKey: PropTypes.string,
|
||||||
|
tabIndex: PropTypes.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
@ -52,13 +53,21 @@ class DropdownListItem extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
id, label, description, children, injectRef, tabIndex, onClick, onKeyDown,
|
id,
|
||||||
className, style, intl,
|
label,
|
||||||
|
description,
|
||||||
|
children,
|
||||||
|
injectRef,
|
||||||
|
tabIndex,
|
||||||
|
onClick,
|
||||||
|
onKeyDown,
|
||||||
|
className,
|
||||||
|
style,
|
||||||
|
intl,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const isSelected = className && className.includes('emojiSelected');
|
const isSelected = className && className.includes('emojiSelected');
|
||||||
const _label = isSelected ? `${label} (${intl.formatMessage(messages.activeAriaLabel)})` : label;
|
const _label = isSelected ? `${label} (${intl.formatMessage(messages.activeAriaLabel)})` : label;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
id={id}
|
id={id}
|
||||||
@ -71,7 +80,6 @@ class DropdownListItem extends Component {
|
|||||||
className={cx(styles.item, className)}
|
className={cx(styles.item, className)}
|
||||||
style={style}
|
style={style}
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
data-test={this.props['data-test']}
|
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
children || this.renderDefault()
|
children || this.renderDefault()
|
||||||
|
@ -3,10 +3,9 @@ import PropTypes from 'prop-types';
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { styles } from '../styles';
|
import { styles } from '../styles';
|
||||||
|
|
||||||
const DropdownListSeparator = ({ style, className }) =>
|
const DropdownListSeparator = ({ style, className }) => (
|
||||||
(
|
<li style={style} className={cx(styles.separator, className)} />
|
||||||
<li style={style} className={cx(styles.separator, className)} />
|
);
|
||||||
);
|
|
||||||
|
|
||||||
DropdownListSeparator.propTypes = {
|
DropdownListSeparator.propTypes = {
|
||||||
style: PropTypes.shape({}),
|
style: PropTypes.shape({}),
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { styles } from '../styles';
|
import { styles } from '../styles';
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
description: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class DropdownListTitle extends Component {
|
export default class DropdownListTitle extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -15,14 +10,15 @@ export default class DropdownListTitle extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { className } = this.props;
|
const {
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className={cx(styles.title, className)} aria-hidden>
|
<li className={cx(styles.title, className)} aria-hidden>
|
||||||
{this.props.children}
|
{children}
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DropdownListTitle.propTypes = propTypes;
|
|
||||||
|
@ -14,11 +14,12 @@ export default class DropdownTrigger extends Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.handleClick = this.handleClick.bind(this);
|
this.handleClick = this.handleClick.bind(this);
|
||||||
this.handleKeyDown = this.handleKeyDown.bind(this);
|
this.handleKeyDown = this.handleKeyDown.bind(this);
|
||||||
|
this.trigger = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClick() {
|
handleClick() {
|
||||||
const { dropdownToggle, onClick } = this.props;
|
const { dropdownToggle, onClick } = this.props;
|
||||||
onClick && onClick();
|
if (onClick) onClick();
|
||||||
return dropdownToggle();
|
return dropdownToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,20 +29,15 @@ export default class DropdownTrigger extends Component {
|
|||||||
if ([KEY_CODES.SPACE, KEY_CODES.ENTER].includes(event.which)) {
|
if ([KEY_CODES.SPACE, KEY_CODES.ENTER].includes(event.which)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
} else if ([KEY_CODES.ARROW_UP, KEY_CODES.ARROW_DOWN].includes(event.which)) {
|
||||||
return findDOMNode(this).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([KEY_CODES.ARROW_UP, KEY_CODES.ARROW_DOWN].includes(event.which)) {
|
|
||||||
dropdownShow();
|
dropdownShow();
|
||||||
}
|
} else if (KEY_CODES.ESCAPE === event.which) {
|
||||||
|
|
||||||
if (KEY_CODES.ESCAPE === event.which) {
|
|
||||||
dropdownHide();
|
dropdownHide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { dropdownIsOpen } = this.props;
|
||||||
const remainingProps = { ...this.props };
|
const remainingProps = { ...this.props };
|
||||||
delete remainingProps.dropdownToggle;
|
delete remainingProps.dropdownToggle;
|
||||||
delete remainingProps.dropdownShow;
|
delete remainingProps.dropdownShow;
|
||||||
@ -58,10 +54,11 @@ export default class DropdownTrigger extends Component {
|
|||||||
|
|
||||||
const TriggerComponentBounded = React.cloneElement(TriggerComponent, {
|
const TriggerComponentBounded = React.cloneElement(TriggerComponent, {
|
||||||
...restProps,
|
...restProps,
|
||||||
|
ref: (ref) => { this.trigger = ref; },
|
||||||
onClick: this.handleClick,
|
onClick: this.handleClick,
|
||||||
onKeyDown: this.handleKeyDown,
|
onKeyDown: this.handleKeyDown,
|
||||||
className: cx(children.props.className, className),
|
className: cx(children.props.className, className),
|
||||||
'aria-expanded': this.props.dropdownIsOpen,
|
'aria-expanded': dropdownIsOpen,
|
||||||
});
|
});
|
||||||
|
|
||||||
return TriggerComponentBounded;
|
return TriggerComponentBounded;
|
||||||
|
@ -9,11 +9,6 @@ import AboutContainer from '/imports/ui/components/about/container';
|
|||||||
import SettingsMenuContainer from '/imports/ui/components/settings/container';
|
import SettingsMenuContainer from '/imports/ui/components/settings/container';
|
||||||
import Button from '/imports/ui/components/button/component';
|
import Button from '/imports/ui/components/button/component';
|
||||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
|
||||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
|
||||||
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
|
|
||||||
import ShortcutHelpComponent from '/imports/ui/components/shortcut-help/component';
|
import ShortcutHelpComponent from '/imports/ui/components/shortcut-help/component';
|
||||||
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
|
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
|
||||||
import FullscreenService from '../../fullscreen-button/service';
|
import FullscreenService from '../../fullscreen-button/service';
|
||||||
@ -178,7 +173,7 @@ class SettingsDropdown extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key="list-item-fullscreen"
|
key="list-item-fullscreen"
|
||||||
icon={fullscreenIcon}
|
icon={fullscreenIcon}
|
||||||
label={fullscreenLabel}
|
label={fullscreenLabel}
|
||||||
@ -210,7 +205,7 @@ class SettingsDropdown extends PureComponent {
|
|||||||
} = Meteor.settings.public.app;
|
} = Meteor.settings.public.app;
|
||||||
|
|
||||||
const logoutOption = (
|
const logoutOption = (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key="list-item-logout"
|
key="list-item-logout"
|
||||||
data-test="logout"
|
data-test="logout"
|
||||||
icon="logout"
|
icon="logout"
|
||||||
@ -226,7 +221,7 @@ class SettingsDropdown extends PureComponent {
|
|||||||
|
|
||||||
return _.compact([
|
return _.compact([
|
||||||
this.getFullscreenItem(),
|
this.getFullscreenItem(),
|
||||||
(<DropdownListItem
|
(<Dropdown.DropdownListItem
|
||||||
key="list-item-settings"
|
key="list-item-settings"
|
||||||
icon="settings"
|
icon="settings"
|
||||||
data-test="settings"
|
data-test="settings"
|
||||||
@ -234,7 +229,7 @@ class SettingsDropdown extends PureComponent {
|
|||||||
description={intl.formatMessage(intlMessages.settingsDesc)}
|
description={intl.formatMessage(intlMessages.settingsDesc)}
|
||||||
onClick={() => mountModal(<SettingsMenuContainer />)}
|
onClick={() => mountModal(<SettingsMenuContainer />)}
|
||||||
/>),
|
/>),
|
||||||
(<DropdownListItem
|
(<Dropdown.DropdownListItem
|
||||||
key="list-item-about"
|
key="list-item-about"
|
||||||
icon="about"
|
icon="about"
|
||||||
label={intl.formatMessage(intlMessages.aboutLabel)}
|
label={intl.formatMessage(intlMessages.aboutLabel)}
|
||||||
@ -243,7 +238,7 @@ class SettingsDropdown extends PureComponent {
|
|||||||
/>),
|
/>),
|
||||||
!helpButton ? null
|
!helpButton ? null
|
||||||
: (
|
: (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key="list-item-help"
|
key="list-item-help"
|
||||||
icon="help"
|
icon="help"
|
||||||
iconRight="popout_window"
|
iconRight="popout_window"
|
||||||
@ -252,16 +247,16 @@ class SettingsDropdown extends PureComponent {
|
|||||||
onClick={() => window.open(`${helpLink}`)}
|
onClick={() => window.open(`${helpLink}`)}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
(<DropdownListItem
|
(<Dropdown.DropdownListItem
|
||||||
key="list-item-shortcuts"
|
key="list-item-shortcuts"
|
||||||
icon="shortcuts"
|
icon="shortcuts"
|
||||||
label={intl.formatMessage(intlMessages.hotkeysLabel)}
|
label={intl.formatMessage(intlMessages.hotkeysLabel)}
|
||||||
description={intl.formatMessage(intlMessages.hotkeysDesc)}
|
description={intl.formatMessage(intlMessages.hotkeysDesc)}
|
||||||
onClick={() => mountModal(<ShortcutHelpComponent />)}
|
onClick={() => mountModal(<ShortcutHelpComponent />)}
|
||||||
/>),
|
/>),
|
||||||
(isMeteorConnected ? <DropdownListSeparator key={_.uniqueId('list-separator-')} /> : null),
|
(isMeteorConnected ? <Dropdown.DropdownListSeparator key={_.uniqueId('list-separator-')} /> : null),
|
||||||
allowedToEndMeeting && isMeteorConnected
|
allowedToEndMeeting && isMeteorConnected
|
||||||
? (<DropdownListItem
|
? (<Dropdown.DropdownListItem
|
||||||
key="list-item-end-meeting"
|
key="list-item-end-meeting"
|
||||||
icon="application"
|
icon="application"
|
||||||
label={intl.formatMessage(intlMessages.endMeetingLabel)}
|
label={intl.formatMessage(intlMessages.endMeetingLabel)}
|
||||||
@ -291,7 +286,7 @@ class SettingsDropdown extends PureComponent {
|
|||||||
onShow={this.onActionsShow}
|
onShow={this.onActionsShow}
|
||||||
onHide={this.onActionsHide}
|
onHide={this.onActionsHide}
|
||||||
>
|
>
|
||||||
<DropdownTrigger tabIndex={0} accessKey={OPEN_OPTIONS_AK}>
|
<Dropdown.DropdownTrigger tabIndex={0} accessKey={OPEN_OPTIONS_AK}>
|
||||||
<Button
|
<Button
|
||||||
label={intl.formatMessage(intlMessages.optionsLabel)}
|
label={intl.formatMessage(intlMessages.optionsLabel)}
|
||||||
icon="more"
|
icon="more"
|
||||||
@ -304,12 +299,12 @@ class SettingsDropdown extends PureComponent {
|
|||||||
// even after the DropdownTrigger inject an onClick handler
|
// even after the DropdownTrigger inject an onClick handler
|
||||||
onClick={() => null}
|
onClick={() => null}
|
||||||
/>
|
/>
|
||||||
</DropdownTrigger>
|
</Dropdown.DropdownTrigger>
|
||||||
<DropdownContent placement="bottom right">
|
<Dropdown.DropdownContent placement="bottom right">
|
||||||
<DropdownList>
|
<Dropdown.DropdownList>
|
||||||
{this.renderMenuItems()}
|
{this.renderMenuItems()}
|
||||||
</DropdownList>
|
</Dropdown.DropdownList>
|
||||||
</DropdownContent>
|
</Dropdown.DropdownContent>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,6 @@ import PropTypes from 'prop-types';
|
|||||||
import { findDOMNode } from 'react-dom';
|
import { findDOMNode } from 'react-dom';
|
||||||
import UserAvatar from '/imports/ui/components/user-avatar/component';
|
import UserAvatar from '/imports/ui/components/user-avatar/component';
|
||||||
import Icon from '/imports/ui/components/icon/component';
|
import Icon from '/imports/ui/components/icon/component';
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
|
||||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
|
||||||
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
|
|
||||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||||
import lockContextContainer from '/imports/ui/components/lock-viewers/context/container';
|
import lockContextContainer from '/imports/ui/components/lock-viewers/context/container';
|
||||||
import { withModalMounter } from '/imports/ui/components/modal/service';
|
import { withModalMounter } from '/imports/ui/components/modal/service';
|
||||||
@ -293,7 +288,7 @@ class UserDropdown extends PureComponent {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.push(<DropdownListSeparator key={_.uniqueId('list-separator-')} />);
|
actions.push(<Dropdown.DropdownListSeparator key={_.uniqueId('list-separator-')} />);
|
||||||
|
|
||||||
const statuses = Object.keys(getEmojiList);
|
const statuses = Object.keys(getEmojiList);
|
||||||
statuses.map(status => actions.push(this.makeDropdownItem(
|
statuses.map(status => actions.push(this.makeDropdownItem(
|
||||||
@ -465,7 +460,7 @@ class UserDropdown extends PureComponent {
|
|||||||
makeDropdownItem(key, label, onClick, icon = null, iconRight = null) {
|
makeDropdownItem(key, label, onClick, icon = null, iconRight = null) {
|
||||||
const { getEmoji } = this.props;
|
const { getEmoji } = this.props;
|
||||||
return (
|
return (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
{...{
|
{...{
|
||||||
key,
|
key,
|
||||||
label,
|
label,
|
||||||
@ -672,24 +667,24 @@ class UserDropdown extends PureComponent {
|
|||||||
getContent={dropdownContent => this.dropdownContent = dropdownContent}
|
getContent={dropdownContent => this.dropdownContent = dropdownContent}
|
||||||
tethered
|
tethered
|
||||||
>
|
>
|
||||||
<DropdownTrigger>
|
<Dropdown.DropdownTrigger>
|
||||||
{contents}
|
{contents}
|
||||||
</DropdownTrigger>
|
</Dropdown.DropdownTrigger>
|
||||||
<DropdownContent
|
<Dropdown.DropdownContent
|
||||||
style={{
|
style={{
|
||||||
visibility: dropdownVisible ? 'visible' : 'hidden',
|
visibility: dropdownVisible ? 'visible' : 'hidden',
|
||||||
}}
|
}}
|
||||||
className={styles.dropdownContent}
|
className={styles.dropdownContent}
|
||||||
placement={placement}
|
placement={placement}
|
||||||
>
|
>
|
||||||
<DropdownList
|
<Dropdown.DropdownList
|
||||||
ref={(ref) => { this.list = ref; }}
|
ref={(ref) => { this.list = ref; }}
|
||||||
getDropdownMenuParent={this.getDropdownMenuParent}
|
getDropdownMenuParent={this.getDropdownMenuParent}
|
||||||
onActionsHide={this.onActionsHide}
|
onActionsHide={this.onActionsHide}
|
||||||
>
|
>
|
||||||
{actions}
|
{actions}
|
||||||
</DropdownList>
|
</Dropdown.DropdownList>
|
||||||
</DropdownContent>
|
</Dropdown.DropdownContent>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,281 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { findDOMNode } from 'react-dom';
|
|
||||||
import cx from 'classnames';
|
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
|
||||||
import deviceInfo from '/imports/utils/deviceInfo';
|
|
||||||
import Button from '/imports/ui/components/button/component';
|
|
||||||
import screenreaderTrap from 'makeup-screenreader-trap';
|
|
||||||
import TetherComponent from 'react-tether';
|
|
||||||
import { styles } from '/imports/ui/components/dropdown/styles';
|
|
||||||
|
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
|
|
||||||
const intlMessages = defineMessages({
|
|
||||||
close: {
|
|
||||||
id: 'app.dropdown.close',
|
|
||||||
description: 'Close button label',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const noop = () => { };
|
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
/**
|
|
||||||
* The dropdown needs a trigger and a content component as children
|
|
||||||
*/
|
|
||||||
children: (props, propName, componentName) => {
|
|
||||||
const children = props[propName];
|
|
||||||
|
|
||||||
if (!children || children.length < 2) {
|
|
||||||
return new Error(`Invalid prop \`${propName}\` supplied to`
|
|
||||||
+ ` \`${componentName}\`. Validation failed.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const trigger = children.find(x => x.type === DropdownTrigger);
|
|
||||||
const content = children.find(x => x.type === DropdownContent);
|
|
||||||
|
|
||||||
if (!trigger) {
|
|
||||||
return new Error(`Invalid prop \`${propName}\` supplied to`
|
|
||||||
+ ` \`${componentName}\`. Missing \`DropdownTrigger\`. Validation failed.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!content) {
|
|
||||||
return new Error(`Invalid prop \`${propName}\` supplied to`
|
|
||||||
+ ` \`${componentName}\`. Missing \`DropdownContent\`. Validation failed.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
isOpen: PropTypes.bool,
|
|
||||||
keepOpen: PropTypes.bool,
|
|
||||||
onHide: PropTypes.func,
|
|
||||||
onShow: PropTypes.func,
|
|
||||||
autoFocus: PropTypes.bool,
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultProps = {
|
|
||||||
children: null,
|
|
||||||
onShow: noop,
|
|
||||||
onHide: noop,
|
|
||||||
autoFocus: false,
|
|
||||||
isOpen: false,
|
|
||||||
keepOpen: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const attachments = {
|
|
||||||
'right-bottom': 'bottom left',
|
|
||||||
'right-top': 'bottom left',
|
|
||||||
};
|
|
||||||
|
|
||||||
const targetAttachments = {
|
|
||||||
'right-bottom': 'bottom right',
|
|
||||||
'right-top': 'top right',
|
|
||||||
};
|
|
||||||
|
|
||||||
class Dropdown extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = { isOpen: false };
|
|
||||||
this.handleShow = this.handleShow.bind(this);
|
|
||||||
this.handleHide = this.handleHide.bind(this);
|
|
||||||
this.handleToggle = this.handleToggle.bind(this);
|
|
||||||
this.handleWindowClick = this.handleWindowClick.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUpdate(nextProps, nextState) {
|
|
||||||
return nextState.isOpen ? screenreaderTrap.trap(this.dropdown) : screenreaderTrap.untrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
|
||||||
const {
|
|
||||||
onShow,
|
|
||||||
onHide,
|
|
||||||
keepOpen,
|
|
||||||
} = this.props;
|
|
||||||
const { isOpen } = this.state;
|
|
||||||
|
|
||||||
if (isOpen && !prevState.isOpen) { onShow(); }
|
|
||||||
|
|
||||||
if (!isOpen && prevState.isOpen) { onHide(); }
|
|
||||||
|
|
||||||
if (prevProps.keepOpen && !keepOpen) { onHide(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
handleShow() {
|
|
||||||
Session.set('dropdownOpen', true);
|
|
||||||
const {
|
|
||||||
onShow,
|
|
||||||
} = this.props;
|
|
||||||
this.setState({ isOpen: true }, () => {
|
|
||||||
const { addEventListener } = window;
|
|
||||||
onShow();
|
|
||||||
addEventListener('click', this.handleWindowClick, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleHide() {
|
|
||||||
Session.set('dropdownOpen', false);
|
|
||||||
const { onHide } = this.props;
|
|
||||||
this.setState({ isOpen: false }, () => {
|
|
||||||
const { removeEventListener } = window;
|
|
||||||
onHide();
|
|
||||||
removeEventListener('click', this.handleWindowClick, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleWindowClick(event) {
|
|
||||||
const { keepOpen, onHide } = this.props;
|
|
||||||
const { isOpen } = this.state;
|
|
||||||
const triggerElement = findDOMNode(this.trigger);
|
|
||||||
const contentElement = findDOMNode(this.content);
|
|
||||||
if (!(triggerElement && contentElement)) return;
|
|
||||||
if (triggerElement && triggerElement.contains(event.target)) {
|
|
||||||
if (keepOpen) {
|
|
||||||
onHide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isOpen) {
|
|
||||||
this.handleHide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keepOpen && isOpen && !contentElement.contains(event.target)) {
|
|
||||||
if (triggerElement) {
|
|
||||||
const { parentElement } = triggerElement;
|
|
||||||
if (parentElement) parentElement.focus();
|
|
||||||
}
|
|
||||||
onHide();
|
|
||||||
this.handleHide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keepOpen && triggerElement) {
|
|
||||||
const { parentElement } = triggerElement;
|
|
||||||
if (parentElement) parentElement.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keepOpen !== null) return;
|
|
||||||
this.handleHide();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleToggle() {
|
|
||||||
const { isOpen } = this.state;
|
|
||||||
return isOpen ? this.handleHide() : this.handleShow();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
children,
|
|
||||||
className,
|
|
||||||
intl,
|
|
||||||
keepOpen,
|
|
||||||
getContent,
|
|
||||||
placement,
|
|
||||||
...otherProps
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const { isOpen } = this.state;
|
|
||||||
|
|
||||||
const { isMobile } = deviceInfo;
|
|
||||||
|
|
||||||
let trigger = children.find(x => x.type === DropdownTrigger);
|
|
||||||
let content = children.find(x => x.type === DropdownContent);
|
|
||||||
|
|
||||||
trigger = React.cloneElement(trigger, {
|
|
||||||
ref: (ref) => { this.trigger = ref; },
|
|
||||||
dropdownIsOpen: isOpen,
|
|
||||||
dropdownToggle: this.handleToggle,
|
|
||||||
dropdownShow: this.handleShow,
|
|
||||||
dropdownHide: this.handleHide,
|
|
||||||
});
|
|
||||||
|
|
||||||
content = React.cloneElement(content, {
|
|
||||||
ref: (ref) => {
|
|
||||||
getContent(ref);
|
|
||||||
this.content = ref;
|
|
||||||
},
|
|
||||||
keepOpen,
|
|
||||||
'aria-expanded': isOpen,
|
|
||||||
dropdownIsOpen: isOpen,
|
|
||||||
dropdownToggle: this.handleToggle,
|
|
||||||
dropdownShow: this.handleShow,
|
|
||||||
dropdownHide: this.handleHide,
|
|
||||||
});
|
|
||||||
|
|
||||||
const showCloseBtn = (isOpen && keepOpen) || (isOpen && keepOpen === null);
|
|
||||||
const placements = placement.replace(' ', '-');
|
|
||||||
// workaround
|
|
||||||
const test = isMobile ? {
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
transform: 'translateY(0)',
|
|
||||||
} : {
|
|
||||||
width: '',
|
|
||||||
height: '',
|
|
||||||
transform: '',
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cx(styles.dropdown, className)}
|
|
||||||
aria-live={otherProps['aria-live']}
|
|
||||||
aria-relevant={otherProps['aria-relevant']}
|
|
||||||
aria-haspopup={otherProps['aria-haspopup']}
|
|
||||||
aria-label={otherProps['aria-label']}
|
|
||||||
ref={(node) => { this.dropdown = node; }}
|
|
||||||
tabIndex={-1}
|
|
||||||
>
|
|
||||||
<TetherComponent
|
|
||||||
style={{
|
|
||||||
zIndex: isOpen ? 15 : '',
|
|
||||||
...test,
|
|
||||||
}}
|
|
||||||
attachment={
|
|
||||||
isMobile ? 'middle bottom'
|
|
||||||
: attachments[placements]
|
|
||||||
}
|
|
||||||
targetAttachment={
|
|
||||||
isMobile ? ''
|
|
||||||
: targetAttachments[placements]
|
|
||||||
}
|
|
||||||
|
|
||||||
constraints={[
|
|
||||||
{
|
|
||||||
to: 'scrollParent',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
|
|
||||||
renderTarget={ref => (
|
|
||||||
<span ref={ref}>
|
|
||||||
{trigger}
|
|
||||||
</span>)}
|
|
||||||
renderElement={ref => (
|
|
||||||
<div
|
|
||||||
ref={ref}
|
|
||||||
>
|
|
||||||
{content}
|
|
||||||
{showCloseBtn
|
|
||||||
? (
|
|
||||||
<Button
|
|
||||||
className={styles.close}
|
|
||||||
label={intl.formatMessage(intlMessages.close)}
|
|
||||||
size="lg"
|
|
||||||
color="default"
|
|
||||||
onClick={this.handleHide}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Dropdown.propTypes = propTypes;
|
|
||||||
Dropdown.defaultProps = defaultProps;
|
|
||||||
export default injectIntl(Dropdown);
|
|
@ -5,16 +5,11 @@ import _ from 'lodash';
|
|||||||
import { withModalMounter } from '/imports/ui/components/modal/service';
|
import { withModalMounter } from '/imports/ui/components/modal/service';
|
||||||
import Button from '/imports/ui/components/button/component';
|
import Button from '/imports/ui/components/button/component';
|
||||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
|
||||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
|
||||||
import LockViewersContainer from '/imports/ui/components/lock-viewers/container';
|
import LockViewersContainer from '/imports/ui/components/lock-viewers/container';
|
||||||
import GuestPolicyContainer from '/imports/ui/components/waiting-users/guest-policy/container';
|
import GuestPolicyContainer from '/imports/ui/components/waiting-users/guest-policy/container';
|
||||||
import BreakoutRoom from '/imports/ui/components/actions-bar/create-breakout-room/container';
|
import BreakoutRoom from '/imports/ui/components/actions-bar/create-breakout-room/container';
|
||||||
import CaptionsService from '/imports/ui/components/captions/service';
|
import CaptionsService from '/imports/ui/components/captions/service';
|
||||||
import CaptionsWriterMenu from '/imports/ui/components/captions/writer-menu/container';
|
import CaptionsWriterMenu from '/imports/ui/components/captions/writer-menu/container';
|
||||||
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
|
|
||||||
import { styles } from './styles';
|
import { styles } from './styles';
|
||||||
import { getUserNamesLink } from '/imports/ui/components/user-list/service';
|
import { getUserNamesLink } from '/imports/ui/components/user-list/service';
|
||||||
|
|
||||||
@ -244,7 +239,7 @@ class UserOptions extends PureComponent {
|
|||||||
|
|
||||||
this.menuItems = _.compact([
|
this.menuItems = _.compact([
|
||||||
(isMeteorConnected ? (
|
(isMeteorConnected ? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key={this.clearStatusId}
|
key={this.clearStatusId}
|
||||||
icon="clear_status"
|
icon="clear_status"
|
||||||
label={intl.formatMessage(intlMessages.clearAllLabel)}
|
label={intl.formatMessage(intlMessages.clearAllLabel)}
|
||||||
@ -254,7 +249,7 @@ class UserOptions extends PureComponent {
|
|||||||
) : null
|
) : null
|
||||||
),
|
),
|
||||||
(!meetingIsBreakout && isMeteorConnected ? (
|
(!meetingIsBreakout && isMeteorConnected ? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key={this.muteAllId}
|
key={this.muteAllId}
|
||||||
icon={isMeetingMuted ? 'unmute' : 'mute'}
|
icon={isMeetingMuted ? 'unmute' : 'mute'}
|
||||||
label={intl.formatMessage(intlMessages[isMeetingMuted ? 'unmuteAllLabel' : 'muteAllLabel'])}
|
label={intl.formatMessage(intlMessages[isMeetingMuted ? 'unmuteAllLabel' : 'muteAllLabel'])}
|
||||||
@ -264,7 +259,7 @@ class UserOptions extends PureComponent {
|
|||||||
) : null
|
) : null
|
||||||
),
|
),
|
||||||
(!meetingIsBreakout && !isMeetingMuted && isMeteorConnected ? (
|
(!meetingIsBreakout && !isMeetingMuted && isMeteorConnected ? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key={this.muteId}
|
key={this.muteId}
|
||||||
icon="mute"
|
icon="mute"
|
||||||
label={intl.formatMessage(intlMessages.muteAllExceptPresenterLabel)}
|
label={intl.formatMessage(intlMessages.muteAllExceptPresenterLabel)}
|
||||||
@ -275,7 +270,7 @@ class UserOptions extends PureComponent {
|
|||||||
),
|
),
|
||||||
(amIModerator
|
(amIModerator
|
||||||
? (
|
? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
icon="download"
|
icon="download"
|
||||||
label={intl.formatMessage(intlMessages.saveUserNames)}
|
label={intl.formatMessage(intlMessages.saveUserNames)}
|
||||||
key={this.saveUsersNameId}
|
key={this.saveUsersNameId}
|
||||||
@ -285,7 +280,7 @@ class UserOptions extends PureComponent {
|
|||||||
: null
|
: null
|
||||||
),
|
),
|
||||||
(!meetingIsBreakout && isMeteorConnected ? (
|
(!meetingIsBreakout && isMeteorConnected ? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key={this.lockId}
|
key={this.lockId}
|
||||||
icon="lock"
|
icon="lock"
|
||||||
label={intl.formatMessage(intlMessages.lockViewersLabel)}
|
label={intl.formatMessage(intlMessages.lockViewersLabel)}
|
||||||
@ -295,7 +290,7 @@ class UserOptions extends PureComponent {
|
|||||||
) : null
|
) : null
|
||||||
),
|
),
|
||||||
(!meetingIsBreakout && isMeteorConnected && dynamicGuestPolicy ? (
|
(!meetingIsBreakout && isMeteorConnected && dynamicGuestPolicy ? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
key={this.guestPolicyId}
|
key={this.guestPolicyId}
|
||||||
icon="user"
|
icon="user"
|
||||||
label={intl.formatMessage(intlMessages.guestPolicyLabel)}
|
label={intl.formatMessage(intlMessages.guestPolicyLabel)}
|
||||||
@ -305,9 +300,9 @@ class UserOptions extends PureComponent {
|
|||||||
/>
|
/>
|
||||||
) : null
|
) : null
|
||||||
),
|
),
|
||||||
(isMeteorConnected ? <DropdownListSeparator key={_.uniqueId('list-separator-')} /> : null),
|
(isMeteorConnected ? <Dropdown.DropdownListSeparator key={_.uniqueId('list-separator-')} /> : null),
|
||||||
(canCreateBreakout && isMeteorConnected ? (
|
(canCreateBreakout && isMeteorConnected ? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
data-test="createBreakoutRooms"
|
data-test="createBreakoutRooms"
|
||||||
key={this.createBreakoutId}
|
key={this.createBreakoutId}
|
||||||
icon="rooms"
|
icon="rooms"
|
||||||
@ -318,7 +313,7 @@ class UserOptions extends PureComponent {
|
|||||||
) : null
|
) : null
|
||||||
),
|
),
|
||||||
(canInviteUsers && isMeteorConnected ? (
|
(canInviteUsers && isMeteorConnected ? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
data-test="inviteBreakoutRooms"
|
data-test="inviteBreakoutRooms"
|
||||||
icon="rooms"
|
icon="rooms"
|
||||||
label={intl.formatMessage(intlMessages.invitationItem)}
|
label={intl.formatMessage(intlMessages.invitationItem)}
|
||||||
@ -329,7 +324,7 @@ class UserOptions extends PureComponent {
|
|||||||
),
|
),
|
||||||
(amIModerator && CaptionsService.isCaptionsEnabled() && isMeteorConnected
|
(amIModerator && CaptionsService.isCaptionsEnabled() && isMeteorConnected
|
||||||
? (
|
? (
|
||||||
<DropdownListItem
|
<Dropdown.DropdownListItem
|
||||||
icon="closed_caption"
|
icon="closed_caption"
|
||||||
label={intl.formatMessage(intlMessages.captionsLabel)}
|
label={intl.formatMessage(intlMessages.captionsLabel)}
|
||||||
description={intl.formatMessage(intlMessages.captionsDesc)}
|
description={intl.formatMessage(intlMessages.captionsDesc)}
|
||||||
@ -356,7 +351,7 @@ class UserOptions extends PureComponent {
|
|||||||
onHide={this.onActionsHide}
|
onHide={this.onActionsHide}
|
||||||
className={styles.dropdown}
|
className={styles.dropdown}
|
||||||
>
|
>
|
||||||
<DropdownTrigger tabIndex={0}>
|
<Dropdown.DropdownTrigger tabIndex={0}>
|
||||||
<Button
|
<Button
|
||||||
label={intl.formatMessage(intlMessages.optionsLabel)}
|
label={intl.formatMessage(intlMessages.optionsLabel)}
|
||||||
data-test="manageUsers"
|
data-test="manageUsers"
|
||||||
@ -368,17 +363,17 @@ class UserOptions extends PureComponent {
|
|||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => null}
|
onClick={() => null}
|
||||||
/>
|
/>
|
||||||
</DropdownTrigger>
|
</Dropdown.DropdownTrigger>
|
||||||
<DropdownContent
|
<Dropdown.DropdownContent
|
||||||
className={styles.dropdownContent}
|
className={styles.dropdownContent}
|
||||||
placement="right top"
|
placement="right top"
|
||||||
>
|
>
|
||||||
<DropdownList>
|
<Dropdown.DropdownList>
|
||||||
{
|
{
|
||||||
this.renderMenuItems()
|
this.renderMenuItems()
|
||||||
}
|
}
|
||||||
</DropdownList>
|
</Dropdown.DropdownList>
|
||||||
</DropdownContent>
|
</Dropdown.DropdownContent>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,6 @@ import PropTypes from 'prop-types';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
|
||||||
import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
|
||||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
|
||||||
import DropdownListTitle from '/imports/ui/components/dropdown/list/title/component';
|
|
||||||
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
|
|
||||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
|
||||||
import Icon from '/imports/ui/components/icon/component';
|
import Icon from '/imports/ui/components/icon/component';
|
||||||
import FullscreenService from '/imports/ui/components/fullscreen-button/service';
|
import FullscreenService from '/imports/ui/components/fullscreen-button/service';
|
||||||
import FullscreenButtonContainer from '/imports/ui/components/fullscreen-button/container';
|
import FullscreenButtonContainer from '/imports/ui/components/fullscreen-button/container';
|
||||||
@ -141,9 +135,9 @@ class VideoListItem extends Component {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return _.compact([
|
return _.compact([
|
||||||
<DropdownListTitle className={styles.hiddenDesktop} key="name">{name}</DropdownListTitle>,
|
<Dropdown.DropdownListTitle className={styles.hiddenDesktop} key="name">{name}</Dropdown.DropdownListTitle>,
|
||||||
<DropdownListSeparator className={styles.hiddenDesktop} key="sep" />,
|
<Dropdown.DropdownListSeparator className={styles.hiddenDesktop} key="sep" />,
|
||||||
...actions.map(action => (<DropdownListItem key={`${cameraId}-${action.actionName}`} {...action} />)),
|
...actions.map(action => (<Dropdown.DropdownListItem key={`${cameraId}-${action.actionName}`} {...action} />)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,14 +236,14 @@ class VideoListItem extends Component {
|
|||||||
{enableVideoMenu && availableActions.length >= 3
|
{enableVideoMenu && availableActions.length >= 3
|
||||||
? (
|
? (
|
||||||
<Dropdown tethered={isTethered} placement="right bottom" className={isFirefox ? styles.dropdownFireFox : styles.dropdown}>
|
<Dropdown tethered={isTethered} placement="right bottom" className={isFirefox ? styles.dropdownFireFox : styles.dropdown}>
|
||||||
<DropdownTrigger className={styles.dropdownTrigger}>
|
<Dropdown.DropdownTrigger className={styles.dropdownTrigger}>
|
||||||
<span>{name}</span>
|
<span>{name}</span>
|
||||||
</DropdownTrigger>
|
</Dropdown.DropdownTrigger>
|
||||||
<DropdownContent placement="top left" className={styles.dropdownContent}>
|
<Dropdown.DropdownContent placement="top left" className={styles.dropdownContent}>
|
||||||
<DropdownList className={styles.dropdownList}>
|
<Dropdown.DropdownList className={styles.dropdownList}>
|
||||||
{availableActions}
|
{availableActions}
|
||||||
</DropdownList>
|
</Dropdown.DropdownList>
|
||||||
</DropdownContent>
|
</Dropdown.DropdownContent>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
)
|
)
|
||||||
: (
|
: (
|
||||||
|
Loading…
Reference in New Issue
Block a user