bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/user-list/component.jsx

347 lines
9.6 KiB
React
Raw Normal View History

2016-06-29 03:52:03 +08:00
import React, { Component, PropTypes } from 'react';
import { withRouter } from 'react-router';
2016-06-28 21:10:20 +08:00
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import styles from './styles.scss';
2016-06-29 22:24:27 +08:00
import cx from 'classnames';
import { defineMessages, injectIntl } from 'react-intl';
2016-05-20 02:22:56 +08:00
import UserListItem from './user-list-item/component.jsx';
import ChatListItem from './chat-list-item/component.jsx';
import { findDOMNode } from 'react-dom';
2017-05-05 22:37:01 +08:00
import KEY_CODES from '/imports/utils/keyCodes';
2016-05-20 02:22:56 +08:00
2016-06-29 03:52:03 +08:00
const propTypes = {
openChats: PropTypes.array.isRequired,
users: PropTypes.array.isRequired,
};
const defaultProps = {
};
2016-06-28 21:10:20 +08:00
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 = {
2016-09-15 01:48:50 +08:00
compact: this.props.compact,
};
this.rovingIndex = this.rovingIndex.bind(this);
2017-05-05 22:37:01 +08:00
this.counter = 1;
}
2017-05-05 05:41:09 +08:00
rovingIndex(...Args) {
2017-05-05 05:58:33 +08:00
const {users, openChats} = this.props;
2017-05-05 22:37:01 +08:00
let active = document.activeElement;
function focusList() {
console.log("WORKING");
//console.log("count : " + count);
console.log("counter : " + this.counter);
active.tabIndex = -1;
list.tabIndex = 0;
this.counter = 0;
list.focus();
}
2017-05-05 05:41:09 +08:00
let list;
let items;
2017-05-05 05:58:33 +08:00
let count;
2017-05-05 05:41:09 +08:00
if (Args[1] === 'users'){
list = findDOMNode(this.refs.usersList);
items = findDOMNode(this.refs.userItems);
2017-05-05 05:58:33 +08:00
count = users.length;
2017-05-05 05:41:09 +08:00
}else if(Args[1] === 'messages'){
list = findDOMNode(this.refs.msgList);
items = findDOMNode(this.refs.msgItems);
2017-05-05 05:58:33 +08:00
count = openChats.length;
2017-05-05 05:41:09 +08:00
}
2017-05-05 22:37:01 +08:00
if (Args[0].keyCode === KEY_CODES.ENTER
|| Args[0].keyCode === KEY_CODES.ARROW_RIGHT
|| Args[0].keyCode === KEY_CODES.ARROW_LEFT) {
//active.firstChild.click();
console.log(items.childNodes[-1]);
}
if (Args[0].keyCode === KEY_CODES.ESCAPE) {
focusList();
//active.tabIndex = -1;
//list.tabIndex = 0;
//this.counter = 0;
//list.focus();
}
2017-05-05 22:37:01 +08:00
if (Args[0].keyCode === KEY_CODES.ARROW_DOWN) {
if (this.counter < count) {
active.tabIndex = -1;
2017-05-05 22:37:01 +08:00
items.childNodes[this.counter].tabIndex = 0;
let newFocus = items.childNodes[this.counter];
this.counter++;
newFocus.focus();
2017-05-05 22:37:01 +08:00
console.log("count : " + count);
console.log("counter : " + this.counter);
}else if(this.counter === 'undefined'){
active.tabIndex = -1;
2017-05-05 22:37:01 +08:00
this.counter = 1;
items.childNodes[this.counter].tabIndex = 0;
let newFocus = items.childNodes[this.counter];
newFocus.focus();
}else{
//this.counter = 0;
//active.tabIndex = -1;
//list.tabIndex = 0;
//list.focus();
focusList();
}
}
2017-05-05 22:37:01 +08:00
if (Args[0].keyCode === KEY_CODES.ARROW_UP) {
if (this.counter > 0) {
this.counter--;
active.tabIndex = -1;
2017-05-05 22:37:01 +08:00
items.childNodes[this.counter].tabIndex = 0;
let newFocus = items.childNodes[this.counter];
newFocus.focus();
2017-05-05 22:37:01 +08:00
console.log("count : " + count);
console.log("counter : " + this.counter);
}else if(this.counter == 0){
focusList();
this.counter = count;
items.childNodes[this.counter].tabIndex = 0;
let newFocus = items.childNodes[this.counter];
newFocus.focus();
}else{
//this.counter = count;
//active.tabIndex = -1;
//list.tabIndex = 0;
//list.focus();
focusList();
}
2017-05-05 22:37:01 +08:00
}
}
componentDidMount() {
2017-05-05 05:41:09 +08:00
let _this = this;
if (!this.state.compact) {
2017-05-05 05:41:09 +08:00
this.refs.msgList.addEventListener("keypress", function(event) {
_this.rovingIndex.call(this, event, "messages");
});
2017-05-05 05:41:09 +08:00
this.refs.usersList.addEventListener("keypress", function(event) {
_this.rovingIndex.call(this, event, "users");
});
}
}
2017-05-05 22:37:01 +08:00
componentWillUnmount() {
this.refs.msgList.removeEventListener("keypress", function(event){});
this.refs.usersList.removeEventListener("keypress", function(event){});
}
2016-05-20 02:22:56 +08:00
render() {
return (
<div className={styles.userList}>
2016-05-26 03:29:22 +08:00
{this.renderHeader()}
{this.renderContent()}
</div>
);
}
renderHeader() {
const { intl } = this.props;
2016-05-26 03:29:22 +08:00
return (
<div className={styles.header}>
2016-09-15 01:48:50 +08:00
{
!this.state.compact ?
<h2 className={styles.headerTitle}>
{intl.formatMessage(intlMessages.participantsTitle)}
</h2> : null
}
2016-05-26 03:29:22 +08:00
</div>
);
2016-05-26 03:29:22 +08:00
}
2016-05-20 02:22:56 +08:00
2016-05-26 03:29:22 +08:00
renderContent() {
return (
<div className={styles.content}>
{this.renderMessages()}
{this.renderParticipants()}
2016-05-20 02:22:56 +08:00
</div>
);
}
2016-05-26 03:29:22 +08:00
renderMessages() {
2016-06-29 03:52:03 +08:00
const {
openChats,
2016-06-30 22:45:19 +08:00
openChat,
intl,
2016-06-29 03:52:03 +08:00
} = this.props;
2016-05-26 03:29:22 +08:00
return (
<div className={styles.messages}>
2016-09-15 01:48:50 +08:00
{
!this.state.compact ?
<h3 className={styles.smallTitle}>
{intl.formatMessage(intlMessages.messagesTitle)}
</h3> : <hr className={styles.separator}></hr>
}
2017-05-05 05:43:48 +08:00
<div className={styles.scrollableList} tabIndex={0} ref={'msgList'}>
2016-06-28 21:10:20 +08:00
<ReactCSSTransitionGroup
transitionName={listTransition}
transitionAppear={true}
transitionEnter={true}
transitionLeave={false}
transitionAppearTimeout={0}
transitionEnterTimeout={0}
transitionLeaveTimeout={0}
component="ul"
2017-05-05 05:41:09 +08:00
className={cx(styles.chatsList, styles.scrollableList)} ref={'msgItems'}>
2016-06-29 03:52:03 +08:00
{openChats.map(chat => (
2016-06-28 21:10:20 +08:00
<ChatListItem
compact={this.state.compact}
2016-06-28 21:10:20 +08:00
key={chat.id}
2016-06-30 22:45:19 +08:00
openChat={openChat}
chat={chat}
tabIndex={-1} />
2016-06-28 21:10:20 +08:00
))}
</ReactCSSTransitionGroup>
</div>
2016-05-26 03:29:22 +08:00
</div>
);
2016-05-26 03:29:22 +08:00
}
renderParticipants() {
2016-06-29 03:52:03 +08:00
const {
users,
currentUser,
isBreakoutRoom,
intl,
callServer,
2016-06-29 03:52:03 +08:00
} = this.props;
2016-06-28 21:10:20 +08:00
2017-04-29 02:28:55 +08:00
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 => callServer('setEmojiStatus', user.id, 'none'),
icon: 'clear_status',
},
setPresenter: {
label: intl.formatMessage(intlMessages.MakePresenterLabel),
handler: user => callServer('assignPresenter', user.id),
icon: 'presentation',
},
kick: {
label: intl.formatMessage(intlMessages.KickUserLabel),
handler: user => callServer('kickUser', user.id),
icon: 'circle_close',
},
mute: {
label: intl.formatMessage(intlMessages.MuteUserAudioLabel),
handler: user => callServer('muteUser', user.id),
icon: 'audio_off',
},
unmute: {
label: intl.formatMessage(intlMessages.UnmuteUserAudioLabel),
handler: user => callServer('unmuteUser', user.id),
icon: 'audio_on',
},
};
2016-05-26 03:29:22 +08:00
return (
<div className={styles.participants}>
2016-09-15 01:48:50 +08:00
{
!this.state.compact ?
<h3 className={styles.smallTitle}>
{intl.formatMessage(intlMessages.usersTitle)}
2016-09-15 01:48:50 +08:00
&nbsp;({users.length})
</h3> : <hr className={styles.separator}></hr>
}
2017-05-05 05:43:48 +08:00
<div className={styles.scrollableList} tabIndex={0} ref={'usersList'}>
2016-06-28 21:10:20 +08:00
<ReactCSSTransitionGroup
transitionName={listTransition}
transitionAppear={true}
transitionEnter={true}
transitionLeave={true}
transitionAppearTimeout={0}
transitionEnterTimeout={0}
transitionLeaveTimeout={0}
component="ul"
2017-05-05 05:41:09 +08:00
className={cx(styles.participantsList, styles.scrollableList)} ref={'userItems'}>
2016-09-15 01:48:50 +08:00
{
users.map(user => (
2016-06-28 21:10:20 +08:00
<UserListItem
compact={this.state.compact}
2016-06-28 21:10:20 +08:00
key={user.id}
isBreakoutRoom={isBreakoutRoom}
2016-06-28 21:10:20 +08:00
user={user}
currentUser={currentUser}
2016-06-29 03:52:03 +08:00
userActions={userActions}
2016-06-28 21:10:20 +08:00
/>
))}
</ReactCSSTransitionGroup>
</div>
2016-05-26 03:29:22 +08:00
</div>
);
2016-05-26 03:29:22 +08:00
}
2016-05-20 02:22:56 +08:00
}
const intlMessages = defineMessages({
usersTitle: {
id: 'app.userlist.usersTitle',
2017-04-06 06:49:05 +08:00
description: 'Title for the Header',
},
messagesTitle: {
id: 'app.userlist.messagesTitle',
2017-04-06 06:49:05 +08:00
description: 'Title for the messages list',
},
participantsTitle: {
id: 'app.userlist.participantsTitle',
2017-04-06 06:49:05 +08:00
description: 'Title for the Users list',
},
2017-04-29 02:28:55 +08:00
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',
},
});
2016-06-29 03:52:03 +08:00
UserList.propTypes = propTypes;
export default withRouter(injectIntl(UserList));