diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/component.jsx index 359a7a790aab66c01d74d76e8929174c7a9c59d2..5b8ca67b475375a945bdb8a52a9f7c9a2434c54c 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/component.jsx @@ -203,29 +203,68 @@ class BreakoutRoom extends PureComponent { const { users } = this.state; if (activeListSibling) { const text = activeListSibling.getElementsByTagName('p')[0].innerText; - const roomNumber = text.match(/\d/g).join(""); - users.forEach(u => { - const { childNodes } = document.activeElement; - if (!childNodes[childNodes.length - 1]) return; - if (u.userId === childNodes[childNodes.length - 1].id) { + const roomNumber = text.match(/\d/g).join(''); + users.forEach((u) => { + if (u.userId === document.activeElement.id) { u.room = text.substr(text.length - 1).includes(')') ? 0 : parseInt(roomNumber); } - }) + }); } } handleMoveEvent(event) { if (this.listOfUsers) { - const { parentElement } = document.activeElement; - if (event.key.includes('ArrowRight')) this.handleShiftUser(parentElement.nextSibling); - if (event.key.includes('ArrowLeft')) this.handleShiftUser(parentElement.previousSibling); + const { activeElement } = document; + + if (event.key.includes('ArrowDown')) { + const { + nextElementSibling, className, childNodes, parentElement, + } = activeElement; + if (className.includes('breakoutBox')) return childNodes[0].focus(); + + if (className.includes('roomUserItem')) { + if (!nextElementSibling) { + return parentElement.firstElementChild.focus(); + } + return nextElementSibling.focus(); + } + } + + if (event.key.includes('ArrowUp')) { + const { + previousElementSibling, className, childNodes, parentElement, + } = activeElement; + if (className.includes('breakoutBox')) return childNodes[childNodes.length - 1].focus(); + + if (className.includes('roomUserItem')) { + if (!previousElementSibling) { + return parentElement.lastElementChild.focus(); + } + return previousElementSibling.focus(); + } + } + + if (event.key.includes('ArrowRight')) { + const { parentElement: listContainer } = activeElement; + if (listContainer.className.includes('breakoutBox')) { + this.handleShiftUser(listContainer.parentElement.nextSibling); + } + } + + if (event.key.includes('ArrowLeft')) { + const { parentElement: listContainer } = activeElement; + if (listContainer.className.includes('breakoutBox')) { + this.handleShiftUser(listContainer.parentElement.previousSibling); + } + } + this.setRoomUsers(); } } componentWillUnmount() { if (this.listOfUsers) { - for(let i = 0; i < this.listOfUsers.children.length; i++) { + for (let i = 0; i < this.listOfUsers.children.length; i++) { const roomList = this.listOfUsers.children[i].getElementsByTagName('div')[0]; roomList.removeEventListener('keydown', this.handleMoveEvent, true); } @@ -234,7 +273,7 @@ class BreakoutRoom extends PureComponent { componentDidUpdate(prevProps, prevstate) { if (this.listOfUsers) { - for(let i = 0; i < this.listOfUsers.children.length; i++) { + for (let i = 0; i < this.listOfUsers.children.length; i++) { const roomList = this.listOfUsers.children[i].getElementsByTagName('div')[0]; roomList.addEventListener('keydown', this.handleMoveEvent, true); } @@ -281,8 +320,8 @@ class BreakoutRoom extends PureComponent { this.setState({ preventClosing: false }); const { numberOfRooms, durationTime } = this.state; - const rooms = _.range(1, numberOfRooms + 1).map(value => ({ - users: this.getUserByRoom(value).map(u => u.userId), + const rooms = _.range(1, numberOfRooms + 1).map((value) => ({ + users: this.getUserByRoom(value).map((u) => u.userId), name: intl.formatMessage(intlMessages.roomName, { 0: meetingName, 1: value, @@ -307,7 +346,7 @@ class BreakoutRoom extends PureComponent { breakouts.forEach((breakout) => { const { breakoutId } = breakout; const breakoutUsers = this.getUserByRoom(breakout.sequence); - breakoutUsers.forEach(user => sendInvitation(breakoutId, user.userId)); + breakoutUsers.forEach((user) => sendInvitation(breakoutId, user.userId)); }); this.setState({ preventClosing: false }); @@ -318,7 +357,7 @@ class BreakoutRoom extends PureComponent { const { users } = this.state; // We only want to assign viewers so filter out the moderators. We also want to get // all users each run so that clicking the button again will reshuffle - const viewers = users.filter(user => !user.isModerator); + const viewers = users.filter((user) => !user.isModerator); // We want to keep assigning users until all viewers have been assigned a room while (viewers.length > 0) { // We cycle through the rooms picking one user for each room so that the rooms @@ -333,7 +372,6 @@ class BreakoutRoom extends PureComponent { } } - setInvitationConfig() { const { getBreakouts } = this.props; this.setState({ @@ -345,10 +383,10 @@ class BreakoutRoom extends PureComponent { setRoomUsers() { const { users, getUsersNotAssigned } = this.props; const { users: stateUsers } = this.state; - const stateUsersId = stateUsers.map(user => user.userId); + const stateUsersId = stateUsers.map((user) => user.userId); const roomUsers = getUsersNotAssigned(users) - .filter(user => !stateUsersId.includes(user.userId)) - .map(user => ({ + .filter((user) => !stateUsersId.includes(user.userId)) + .map((user) => ({ userId: user.userId, userName: user.name, isModerator: user.role === ROLE_MODERATOR, @@ -373,20 +411,20 @@ class BreakoutRoom extends PureComponent { getUserByRoom(room) { const { users } = this.state; - return users.filter(user => user.room === room); + return users.filter((user) => user.room === room); } getUsersByRoomSequence(sequence) { const { breakoutJoinedUsers } = this.state; if (!breakoutJoinedUsers) return []; - return breakoutJoinedUsers.filter(room => room.sequence === sequence)[0].joinedUsers || []; + return breakoutJoinedUsers.filter((room) => room.sequence === sequence)[0].joinedUsers || []; } removeRoomUsers() { const { users } = this.props; const { users: stateUsers } = this.state; - const userIds = users.map(user => user.userId); - const removeUsers = stateUsers.filter(user => userIds.includes(user.userId)); + const userIds = users.map((user) => user.userId); + const removeUsers = stateUsers.filter((user) => userIds.includes(user.userId)); this.setState({ users: removeUsers, @@ -407,14 +445,14 @@ class BreakoutRoom extends PureComponent { resetUserWhenRoomsChange(rooms) { const { users } = this.state; - const filtredUsers = users.filter(u => u.room > rooms); - filtredUsers.forEach(u => this.changeUserRoom(u.userId, 0)); + const filtredUsers = users.filter((u) => u.room > rooms); + filtredUsers.forEach((u) => this.changeUserRoom(u.userId, 0)); } changeUserRoom(userId, room) { const { users } = this.state; - const idxUser = users.findIndex(user => user.userId === userId); + const idxUser = users.findIndex((user) => user.userId === userId); const usersCopy = [...users]; @@ -468,7 +506,7 @@ class BreakoutRoom extends PureComponent { ev.preventDefault(); }; - const drop = room => (ev) => { + const drop = (room) => (ev) => { ev.preventDefault(); const data = ev.dataTransfer.getData('text'); this.changeUserRoom(data, room); @@ -476,7 +514,7 @@ class BreakoutRoom extends PureComponent { }; return ( - <div className={styles.boxContainer} key="rooms-grid-" ref={r => this.listOfUsers = r }> + <div className={styles.boxContainer} key="rooms-grid-" ref={(r) => this.listOfUsers = r}> <div className={!valid ? styles.changeToWarn : null}> <p className={styles.freeJoinLabel}> {intl.formatMessage(intlMessages.notAssigned, { 0: this.getUserByRoom(0).length })} @@ -489,7 +527,7 @@ class BreakoutRoom extends PureComponent { </span> </div> { - _.range(1, rooms + 1).map(value => ( + _.range(1, rooms + 1).map((value) => ( <div key={`room-${value}`}> <p className={styles.freeJoinLabel}> {intl.formatMessage(intlMessages.roomLabel, { 0: (value) })} @@ -538,7 +576,7 @@ class BreakoutRoom extends PureComponent { aria-label={intl.formatMessage(intlMessages.numberOfRooms)} > { - _.range(MIN_BREAKOUT_ROOMS, MAX_BREAKOUT_ROOMS + 1).map(item => (<option key={_.uniqueId('value-')}>{item}</option>)) + _.range(MIN_BREAKOUT_ROOMS, MAX_BREAKOUT_ROOMS + 1).map((item) => (<option key={_.uniqueId('value-')}>{item}</option>)) } </select> </div> @@ -628,7 +666,7 @@ class BreakoutRoom extends PureComponent { room={roomSelected} breakoutJoinedUsers={isInvitation && breakoutJoinedUsers} onCheck={this.changeUserRoom} - onUncheck={userId => this.changeUserRoom(userId, 0)} + onUncheck={(userId) => this.changeUserRoom(userId, 0)} /> ); } @@ -691,33 +729,33 @@ class BreakoutRoom extends PureComponent { } }; - const dragEnd = () => { this.setState({ seletedId: '' }); }; return this.getUserByRoom(room) - .map(user => ( + .map((user) => ( <p + tabIndex={0} id={user.userId} key={user.userId} className={cx( styles.roomUserItem, seletedId === user.userId ? styles.selectedItem : null, - ) - } + )} draggable onDragStart={dragStart} onDragEnd={dragEnd} > {user.userName} <i>{(isMe(user.userId)) ? ` (${intl.formatMessage(intlMessages.you)})` : ''}</i> - </p>)); + </p> + )); } renderJoinedUsers(room) { return this.getUsersByRoomSequence(room) - .map(user => ( + .map((user) => ( <p id={user.userId} key={user.userId} @@ -725,8 +763,7 @@ class BreakoutRoom extends PureComponent { className={cx( styles.roomUserItem, styles.disableItem, - ) - } + )} > {user.name} <span className={styles.lockIcon} /> @@ -737,7 +774,7 @@ class BreakoutRoom extends PureComponent { renderRoomSortList() { const { intl, isInvitation } = this.props; const { numberOfRooms } = this.state; - const onClick = roomNumber => this.setState({ formFillLevel: 3, roomSelected: roomNumber }); + const onClick = (roomNumber) => this.setState({ formFillLevel: 3, roomSelected: roomNumber }); return ( <div className={styles.listContainer}> <span> @@ -773,18 +810,20 @@ class BreakoutRoom extends PureComponent { numberOfRoomsIsValid, } = this.state; return ( - <React.Fragment> + <> {!valid && ( <span className={styles.withError}> {intl.formatMessage(intlMessages.leastOneWarnBreakout)} - </span>)} + </span> + )} {!numberOfRoomsIsValid && ( <span className={styles.withError}> {intl.formatMessage(intlMessages.numberOfRoomsIsValid)} - </span>)} - </React.Fragment> + </span> + )} + </> ); }