Skip to content
Snippets Groups Projects
Commit b279dac9 authored by Tainan Felipe's avatar Tainan Felipe
Browse files

Add mobile version to sort user on breakout rooms

parent eb989ea6
No related branches found
No related tags found
No related merge requests found
......@@ -2,10 +2,13 @@ import React, { Component } from 'react';
import Modal from '/imports/ui/components/modal/fullscreen/component';
import { defineMessages, injectIntl } from 'react-intl';
import _ from 'lodash';
import cx from 'classnames';
import browser from 'browser-detect';
import Button from '/imports/ui/components/button/component';
import HoldButton from '/imports/ui/components/presentation/presentation-toolbar/zoom-tool/holdButton/component';
import SortList from './sort-user-list/component';
import { styles } from './styles';
import Icon from '../../icon/component';
import cx from 'classnames';
const intlMessages = defineMessages({
breakoutRoomTitle: {
......@@ -48,6 +51,22 @@ const intlMessages = defineMessages({
id: 'app.createBreakoutRoom.notAssigned',
description: 'Not assigned label',
},
breakoutRoomLabel: {
id: 'app.createBreakoutRoom.breakoutRoomLabel',
description: 'breakout room label',
},
addParticipantLabel: {
id: 'app.createBreakoutRoom.addParticipantLabel',
description: 'add Participant label',
},
nextLabel: {
id: 'app.createBreakoutRoom.nextLabel',
description: 'Next label',
},
backLabel: {
id: 'app.audio.backLabel',
description: 'Back label',
},
});
const MIN_BREAKOUT_ROOMS = 2;
const MAX_BREAKOUT_ROOMS = 8;
......@@ -68,6 +87,11 @@ class BreakoutRoom extends Component {
this.renderRoomsGrid = this.renderRoomsGrid.bind(this);
this.renderBreakoutForm = this.renderBreakoutForm.bind(this);
this.renderFreeJoinCheck = this.renderFreeJoinCheck.bind(this);
this.renderRoomSortList = this.renderRoomSortList.bind(this);
this.renderDesktop = this.renderDesktop.bind(this);
this.renderMobile = this.renderMobile.bind(this);
this.renderButtonSetLevel = this.renderButtonSetLevel.bind(this);
this.renderSelectUserScreen = this.renderSelectUserScreen.bind(this);
this.state = {
numberOfRooms: MIN_BREAKOUT_ROOMS,
......@@ -75,6 +99,8 @@ class BreakoutRoom extends Component {
users: [],
durationTime: 1,
freeJoin: false,
formFillLevel: 1,
roomSelected: 0,
};
}
......@@ -263,6 +289,18 @@ class BreakoutRoom extends Component {
);
}
renderSelectUserScreen() {
return (
<SortList
confirm={() => this.setState({ formFillLevel: 2 })}
users={this.state.users}
room={this.state.roomSelected}
onCheck={this.changeUserRoom}
onUncheck={userId => this.changeUserRoom(userId, 0)}
/>
);
}
renderFreeJoinCheck() {
const { intl } = this.props;
return (
......@@ -284,7 +322,8 @@ class BreakoutRoom extends Component {
this.setState({ seletedId: ev.target.id });
};
const dragEnd = (ev) => {
const dragEnd = () => {
this.setState({ seletedId: '' });
};
......@@ -305,9 +344,78 @@ class BreakoutRoom extends Component {
</p>));
}
renderRoomSortList() {
const { intl } = this.props;
const { numberOfRooms } = this.state;
const onClick = roomNumber => this.setState({ formFillLevel: 3, roomSelected: roomNumber });
return (
<div className={styles.listContainer}>
<span>
{
new Array(numberOfRooms).fill(1).map((room, idx) => (
<div className={styles.roomItem}>
<h2 className={styles.itemTitle}>
{intl.formatMessage(intlMessages.breakoutRoomLabel, { 0: idx + 1 })}
</h2>
<Button
className={styles.itemButton}
label={intl.formatMessage(intlMessages.addParticipantLabel)}
size="lg"
ghost
color="primary"
onClick={() => onClick(idx + 1)}
/>
</div>
))
}
</span>
{this.renderButtonSetLevel(1, intl.formatMessage(intlMessages.backLabel))}
</div>
);
}
renderDesktop() {
return [
this.renderBreakoutForm(),
this.renderRoomsGrid(),
];
}
renderMobile() {
const { intl } = this.props;
const { formFillLevel } = this.state;
if (formFillLevel === 2) {
return this.renderRoomSortList();
}
if (formFillLevel === 3) {
return this.renderSelectUserScreen();
}
return [
this.renderBreakoutForm(),
this.renderButtonSetLevel(2, intl.formatMessage(intlMessages.nextLabel)),
];
}
renderButtonSetLevel(level, label) {
return (
<Button
color="primary"
size="lg"
label={label}
onClick={() => this.setState({ formFillLevel: level })}
/>
);
}
render() {
const { intl } = this.props;
const BROWSER_RESULTS = browser();
const isMobileBrowser = BROWSER_RESULTS.mobile ||
BROWSER_RESULTS.os.includes('Android');
return (
<Modal
title={intl.formatMessage(intlMessages.breakoutRoomTitle)}
......@@ -322,9 +430,8 @@ class BreakoutRoom extends Component {
<p className={styles.subTitle}>
{intl.formatMessage(intlMessages.breakoutRoomDesc)}
</p>
{this.renderBreakoutForm()}
{this.renderFreeJoinCheck()}
{this.renderRoomsGrid()}
{isMobileBrowser ?
this.renderMobile() : this.renderDesktop()}
</div>
</Modal >
);
......
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import Button from '/imports/ui/components/button/component';
import { styles } from '../styles';
const propTypes = {
confirm: PropTypes.func.isRequired,
users: PropTypes.arrayOf(PropTypes.object).isRequired,
room: PropTypes.number.isRequired,
onCheck: PropTypes.func,
onUncheck: PropTypes.func,
};
const defaultProps = {
onCheck: () => {},
onUncheck: () => {},
};
const intlMessages = defineMessages({
breakoutRoomLabel: {
id: 'app.createBreakoutRoom.breakoutRoomLabel',
description: 'breakout room label',
},
doneLabel: {
id: 'app.createBreakoutRoom.doneLabel',
description: 'done label',
},
});
class SortUsers extends Component {
constructor(props) {
super(props);
this.setUsers = this.setUsers.bind(this);
this.renderUserItem = this.renderUserItem.bind(this);
this.onChage = this.onChage.bind(this);
this.state = {
users: [],
};
}
componentDidMount() {
this.setUsers(this.props.users);
}
onChage(userId, room) {
return (ev) => {
const check = ev.target.checked;
if (check) {
return this.props.onCheck(userId, room);
}
return this.props.onUncheck(userId, room);
};
}
setUsers(users) {
this.setState({ users: users.sort((a, b) => a.room - b.room) });
}
renderUserItem() {
const { room } = this.props;
return this.state.users
.map((user, idx) => (
<div id={user.userId} className={styles.selectUserContainer} key={`breakout-user-${user.userId}`}>
<span className={styles.round}>
<input
type="checkbox"
id={`itemId${idx}`}
defaultChecked={user.room === room}
onChange={this.onChage(user.userId, room)}
/>
<label htmlFor={`itemId${idx}`} />
</span>
<span className={styles.textName} >{user.userName}{user.room && !(user.room === room) ? `\t[${user.room}]` : ''}</span>
</div>));
}
render() {
const { intl } = this.props;
return (
<div className={styles.selectUserScreen}>
<header className={styles.header}>
<h2 className={styles.title}> {intl.formatMessage(intlMessages.breakoutRoomLabel, { 0: this.props.room })}</h2>
<Button
className={styles.buttonAdd}
size="md"
label={intl.formatMessage(intlMessages.doneLabel)}
color="primary"
onClick={this.props.confirm}
/>
</header>
{this.renderUserItem()}
</div>
);
}
}
SortUsers.propTypes = propTypes;
SortUsers.defaultProps = defaultProps;
export default injectIntl(SortUsers);
......@@ -132,4 +132,125 @@ input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-i
.selectedItem {
background-color: var(--color-primary);
color: var(--color-white)
}
/* mobile */
.listContainer {
display: flex;
justify-content: flex-start;
flex-direction: column;
}
.itemTitle {
color: var(--color-blue-light);
margin: 0;
}
.roomItem {
margin: 1rem 0 1rem 0;
}
.itemButton {
padding: 0;
outline: none !important;
span {
color: var(--color-blue-light);
}
}
.selectUserScreenContainer {
position: fixed;
z-index: 1002;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, .85);
}
.selectUserScreen {
position: fixed;
display: block;
height: 100vh;
width: 100%;
background-color: var(--color-white);
z-index: 1002;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.header {
display: flex;
padding: var(--line-height-computed) 0;
border-bottom: var(--border-size) solid var(--color-gray-lighter);
margin: 0 1rem 0 1rem;
}
.title {
@extend %text-elipsis;
align-content: flex-end;
flex: 1;
margin: 0;
font-weight: 400;
}
.buttonAdd {
flex: 0 1 35%;
}
.selectUserContainer {
margin: 1.5rem 1rem;
}
.textName {
@extend %text-elipsis;
margin-left: 1.5rem;
}
.round {
position: relative;
& label {
margin-top: -10px;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 50%;
cursor: pointer;
height: 28px;
left: 0;
position: absolute;
top: 0;
width: 28px;
}
& label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 7px;
opacity: 0;
position: absolute;
top: 8px;
transform: rotate(-45deg);
width: 12px;
}
& input[type="checkbox"] {
visibility: hidden;
}
& input[type="checkbox"]:checked + label {
background-color: #66bb6a;
border-color: #66bb6a;
}
& input[type="checkbox"]:checked + label:after {
opacity: 1;
}
}
\ No newline at end of file
......@@ -8,6 +8,7 @@
outline: none;
@include mq($small-only) {
width: 100%;
height: 100%;
}
}
......
......@@ -436,6 +436,7 @@
"app.videoDock.webcamUnfocusLabel": "Unfocus",
"app.videoDock.webcamUnfocusDesc": "Unfocus the selected webcam",
"app.createBreakoutRoom.title": "Breakout Rooms",
"app.createBreakoutRoom.breakoutRoomLabel": "Breakout Rooms {0}",
"app.createBreakoutRoom.generatingURL": "Generating URL",
"app.createBreakoutRoom.generatedURL": "Generated",
"app.createBreakoutRoom.duration": "Duration {0}",
......@@ -450,6 +451,9 @@
"app.createBreakoutRoom.randomlyAssign": "Randomly Assign",
"app.createBreakoutRoom.endAllBreakouts": "End All Breakout Rooms",
"app.createBreakoutRoom.roomName": "{0} (Room - {1})",
"app.createBreakoutRoom.doneLabel": "Done",
"app.createBreakoutRoom.nextLabel": "Next",
"app.createBreakoutRoom.addParticipantLabel": "+ Add participant",
"app.createBreakoutRoom.freeJoin": "Allow users to choose a breakout room to join",
"app.createBreakoutRoom.modalDesc": "Complete the steps below to create rooms in your session, To add participants to a room."
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment