import React, { Component } from 'react'; import { defineMessages, injectIntl } from 'react-intl'; import PropTypes from 'prop-types'; import { withRouter } from 'react-router'; import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; import cx from 'classnames'; import KEY_CODES from '/imports/utils/keyCodes'; import Button from '/imports/ui/components/button/component'; import styles from './styles.scss'; import UserListItem from './user-list-item/component'; import ChatListItem from './chat-list-item/component'; const propTypes = { openChats: PropTypes.array.isRequired, users: PropTypes.array.isRequired, compact: PropTypes.bool, }; const defaultProps = { compact: false, }; const listTransition = { enter: styles.enter, enterActive: styles.enterActive, appear: styles.appear, appearActive: styles.appearActive, leave: styles.leave, leaveActive: styles.leaveActive, }; const intlMessages = defineMessages({ usersTitle: { id: 'app.userList.usersTitle', description: 'Title for the Header', }, messagesTitle: { id: 'app.userList.messagesTitle', description: 'Title for the messages list', }, participantsTitle: { id: 'app.userList.participantsTitle', description: 'Title for the Users list', }, toggleCompactView: { id: 'app.userList.toggleCompactView.label', description: 'Toggle user list view mode', }, ChatLabel: { id: 'app.userList.menu.chat.label', description: 'Save the changes and close the settings menu', }, ClearStatusLabel: { id: 'app.userList.menu.clearStatus.label', description: 'Clear the emoji status of this user', }, MakePresenterLabel: { id: 'app.userList.menu.makePresenter.label', description: 'Set this user to be the presenter in this meeting', }, KickUserLabel: { id: 'app.userList.menu.kickUser.label', description: 'Forcefully remove this user from the meeting', }, MuteUserAudioLabel: { id: 'app.userList.menu.muteUserAudio.label', description: 'Forcefully mute this user', }, UnmuteUserAudioLabel: { id: 'app.userList.menu.unmuteUserAudio.label', description: 'Forcefully unmute this user', }, }); class UserList extends Component { constructor(props) { super(props); this.state = { compact: this.props.compact, }; this.handleToggleCompactView = this.handleToggleCompactView.bind(this); this.rovingIndex = this.rovingIndex.bind(this); this.focusList = this.focusList.bind(this); this.focusedItemIndex = -1; } focusList(list) { document.activeElement.tabIndex = -1; this.focusedItemIndex = -1; list.tabIndex = 0; list.focus(); } rovingIndex(event, listType) { const { users, openChats } = this.props; const active = document.activeElement; let list; let items; let numberOfItems; const focusElement = () => { active.tabIndex = -1; items.childNodes[this.focusedItemIndex].tabIndex = 0; items.childNodes[this.focusedItemIndex].focus(); }; switch (listType) { case 'users': list = this._usersList; items = this._userItems; numberOfItems = users.length; break; case 'messages': list = this._msgsList; items = this._msgItems; numberOfItems = openChats.length; break; default: break; } if (event.keyCode === KEY_CODES.ESCAPE || this.focusedItemIndex < 0 || this.focusedItemIndex > numberOfItems) { this.focusList(list); } if ([KEY_CODES.ARROW_RIGHT, KEY_CODES.ARROW_SPACE].includes(event.keyCode)) { active.firstChild.click(); } if (event.keyCode === KEY_CODES.ARROW_DOWN) { this.focusedItemIndex += 1; if (this.focusedItemIndex === numberOfItems) { this.focusedItemIndex = 0; } focusElement(); } if (event.keyCode === KEY_CODES.ARROW_UP) { this.focusedItemIndex -= 1; if (this.focusedItemIndex < 0) { this.focusedItemIndex = numberOfItems - 1; } focusElement(); } } handleToggleCompactView() { this.setState({ compact: !this.state.compact }); } componentDidMount() { if (!this.state.compact) { this._msgsList.addEventListener('keydown', event => this.rovingIndex(event, 'messages')); this._usersList.addEventListener('keydown', event => this.rovingIndex(event, 'users')); } // to let the whiteboard know that the presentation area's size has changed window.dispatchEvent(new Event('resize')); } componentWillUnmount() { // to let the whiteboard know that the presentation area's size has changed window.dispatchEvent(new Event('resize')); } renderHeader() { const { intl } = this.props; return (