import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { withRouter } from 'react-router'; import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; import styles from './styles.scss'; import cx from 'classnames'; import { defineMessages, injectIntl } from 'react-intl'; import UserListItem from './user-list-item/component.jsx'; import ChatListItem from './chat-list-item/component.jsx'; import KEY_CODES from '/imports/utils/keyCodes'; const propTypes = { openChats: PropTypes.array.isRequired, users: PropTypes.array.isRequired, }; const defaultProps = { }; const listTransition = { enter: styles.enter, enterActive: styles.enterActive, appear: styles.appear, appearActive: styles.appearActive, leave: styles.leave, leaveActive: styles.leaveActive, }; class UserList extends Component { constructor(props) { super(props); this.state = { compact: this.props.compact, }; 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; let 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; } 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(); } } componentDidMount() { if (!this.state.compact) { this._msgsList.addEventListener('keydown', event => this.rovingIndex(event, "messages")); this._usersList.addEventListener('keydown', event => this.rovingIndex(event, "users")); } } render() { return (
{this.renderHeader()} {this.renderContent()}
); } renderHeader() { const { intl } = this.props; return (
{ !this.state.compact ?
{intl.formatMessage(intlMessages.participantsTitle)}
: null }
); } renderContent() { return (
{this.renderMessages()} {this.renderParticipants()}
); } renderMessages() { const { openChats, openChat, intl, } = this.props; return (
{ !this.state.compact ?
{intl.formatMessage(intlMessages.messagesTitle)}
:
}
{ this._msgsList = ref; }} >
{ this._msgItems = ref; }}> {openChats.map(chat => ( ))}
); } renderParticipants() { const { users, currentUser, isBreakoutRoom, intl, makeCall, meeting, } = this.props; const userActions = { openChat: { label: intl.formatMessage(intlMessages.ChatLabel), handler: (router, user) => router.push(`/users/chat/${user.id}`), icon: 'chat', }, clearStatus: { label: intl.formatMessage(intlMessages.ClearStatusLabel), handler: user => makeCall('setEmojiStatus', user.id, 'none'), icon: 'clear_status', }, setPresenter: { label: intl.formatMessage(intlMessages.MakePresenterLabel), handler: user => makeCall('assignPresenter', user.id), icon: 'presentation', }, kick: { label: intl.formatMessage(intlMessages.KickUserLabel), handler: user => makeCall('kickUser', user.id), icon: 'circle_close', }, mute: { label: intl.formatMessage(intlMessages.MuteUserAudioLabel), handler: user => makeCall('muteUser', user.id), icon: 'audio_off', }, unmute: { label: intl.formatMessage(intlMessages.UnmuteUserAudioLabel), handler: user => makeCall('unmuteUser', user.id), icon: 'audio_on', }, }; return (
{ !this.state.compact ?
{intl.formatMessage(intlMessages.usersTitle)}  ({users.length})
:
}
{ this._usersList = ref; }} >
{ this._userItems = ref; }}> { users.map(user => ( )) }
); } } 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', }, 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', }, }); UserList.propTypes = propTypes; export default withRouter(injectIntl(UserList));