Merge pull request #6535 from KDSBrowne/2.2-add-create-br-to-manage-user-menu
Add create breakout room option to manage user menu
This commit is contained in:
commit
7349fcabb5
@ -2,6 +2,4 @@ import { Meteor } from 'meteor/meteor';
|
||||
|
||||
const Streamer = new Meteor.Streamer('videos');
|
||||
|
||||
export default Streamer
|
||||
|
||||
|
||||
export default Streamer;
|
||||
|
@ -145,8 +145,6 @@ class ActionsDropdown extends Component {
|
||||
pollBtnDesc,
|
||||
presentationLabel,
|
||||
presentationDesc,
|
||||
startRecording,
|
||||
stopRecording,
|
||||
createBreakoutRoom,
|
||||
createBreakoutRoomDesc,
|
||||
invitationItem,
|
||||
@ -158,6 +156,10 @@ class ActionsDropdown extends Component {
|
||||
formatMessage,
|
||||
} = intl;
|
||||
|
||||
const canCreateBreakout = isUserModerator
|
||||
&& !meetingIsBreakout
|
||||
&& !hasBreakoutRoom;
|
||||
|
||||
const canInviteUsers = isUserModerator
|
||||
&& !meetingIsBreakout
|
||||
&& hasBreakoutRoom
|
||||
@ -209,12 +211,12 @@ class ActionsDropdown extends Component {
|
||||
/>
|
||||
)
|
||||
: null),
|
||||
(isUserModerator && !meetingIsBreakout && !hasBreakoutRoom
|
||||
(canCreateBreakout
|
||||
? (
|
||||
<DropdownListItem
|
||||
icon="rooms"
|
||||
label={intl.formatMessage(intlMessages.createBreakoutRoom)}
|
||||
description={intl.formatMessage(intlMessages.createBreakoutRoomDesc)}
|
||||
label={formatMessage(createBreakoutRoom)}
|
||||
description={formatMessage(createBreakoutRoomDesc)}
|
||||
key={this.createBreakoutRoomId}
|
||||
onClick={this.onCreateBreakouts}
|
||||
/>
|
||||
|
@ -127,6 +127,10 @@ class BreakoutRoom extends Component {
|
||||
preventClosing: true,
|
||||
valid: true,
|
||||
};
|
||||
|
||||
this.breakoutFormId = _.uniqueId('breakout-form-');
|
||||
this.freeJoinId = _.uniqueId('free-join-check-');
|
||||
this.btnLevelId = _.uniqueId('btn-set-level-');
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -295,7 +299,7 @@ class BreakoutRoom extends Component {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.boxContainer}>
|
||||
<div className={styles.boxContainer} key="rooms-grid-">
|
||||
<label htmlFor="BreakoutRoom" className={!valid ? styles.changeToWarn : null}>
|
||||
<p
|
||||
className={styles.freeJoinLabel}
|
||||
@ -340,7 +344,7 @@ class BreakoutRoom extends Component {
|
||||
if (isInvitation) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.breakoutSettings}>
|
||||
<div className={styles.breakoutSettings} key={this.breakoutFormId}>
|
||||
<label htmlFor="numberOfRooms">
|
||||
<p className={styles.labelText}>{intl.formatMessage(intlMessages.numberOfRooms)}</p>
|
||||
<select
|
||||
@ -422,7 +426,7 @@ class BreakoutRoom extends Component {
|
||||
if (isInvitation) return null;
|
||||
const { freeJoin } = this.state;
|
||||
return (
|
||||
<label htmlFor="freeJoinCheckbox" className={styles.freeJoinLabel}>
|
||||
<label htmlFor="freeJoinCheckbox" className={styles.freeJoinLabel} key={this.freeJoinId}>
|
||||
<input
|
||||
type="checkbox"
|
||||
className={styles.freeJoinCheckbox}
|
||||
@ -534,6 +538,7 @@ class BreakoutRoom extends Component {
|
||||
size="lg"
|
||||
label={label}
|
||||
onClick={() => this.setState({ formFillLevel: level })}
|
||||
key={this.btnLevelId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import DropdownContent from '/imports/ui/components/dropdown/content/component';
|
||||
import DropdownList from '/imports/ui/components/dropdown/list/component';
|
||||
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
|
||||
import LockViewersContainer from '/imports/ui/components/lock-viewers/container';
|
||||
import BreakoutRoom from '/imports/ui/components/actions-bar/create-breakout-room/component';
|
||||
import { styles } from './styles';
|
||||
|
||||
const propTypes = {
|
||||
@ -21,6 +22,11 @@ const propTypes = {
|
||||
toggleMuteAllUsersExceptPresenter: PropTypes.func.isRequired,
|
||||
toggleStatus: PropTypes.func.isRequired,
|
||||
mountModal: PropTypes.func.isRequired,
|
||||
users: PropTypes.arrayOf(Object).isRequired,
|
||||
meetingName: PropTypes.string.isRequired,
|
||||
createBreakoutRoom: PropTypes.func.isRequired,
|
||||
meetingIsBreakout: PropTypes.bool.isRequired,
|
||||
hasBreakoutRoom: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
@ -68,6 +74,18 @@ const intlMessages = defineMessages({
|
||||
id: 'app.userList.userOptions.muteAllExceptPresenterDesc',
|
||||
description: 'Mute all except presenter description',
|
||||
},
|
||||
createBreakoutRoom: {
|
||||
id: 'app.actionsBar.actionsDropdown.createBreakoutRoom',
|
||||
description: 'Create breakout room option',
|
||||
},
|
||||
createBreakoutRoomDesc: {
|
||||
id: 'app.actionsBar.actionsDropdown.createBreakoutRoomDesc',
|
||||
description: 'Description of create breakout room option',
|
||||
},
|
||||
invitationItem: {
|
||||
id: 'app.invitation.title',
|
||||
description: 'invitation to breakout title',
|
||||
},
|
||||
});
|
||||
|
||||
class UserOptions extends PureComponent {
|
||||
@ -78,55 +96,19 @@ class UserOptions extends PureComponent {
|
||||
isUserOptionsOpen: false,
|
||||
};
|
||||
|
||||
this.clearStatusId = _.uniqueId('list-item-');
|
||||
this.muteId = _.uniqueId('list-item-');
|
||||
this.muteAllId = _.uniqueId('list-item-');
|
||||
this.lockId = _.uniqueId('list-item-');
|
||||
this.createBreakoutId = _.uniqueId('list-item-');
|
||||
|
||||
this.onActionsShow = this.onActionsShow.bind(this);
|
||||
this.onActionsHide = this.onActionsHide.bind(this);
|
||||
this.alterMenu = this.alterMenu.bind(this);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const {
|
||||
intl,
|
||||
isMeetingMuted,
|
||||
mountModal,
|
||||
toggleStatus,
|
||||
toggleMuteAllUsers,
|
||||
toggleMuteAllUsersExceptPresenter,
|
||||
} = this.props;
|
||||
|
||||
this.menuItems = _.compact([
|
||||
(<DropdownListItem
|
||||
key={_.uniqueId('list-item-')}
|
||||
icon="clear_status"
|
||||
label={intl.formatMessage(intlMessages.clearAllLabel)}
|
||||
description={intl.formatMessage(intlMessages.clearAllDesc)}
|
||||
onClick={toggleStatus}
|
||||
/>),
|
||||
(<DropdownListItem
|
||||
key={_.uniqueId('list-item-')}
|
||||
icon="mute"
|
||||
label={intl.formatMessage(intlMessages.muteAllLabel)}
|
||||
description={intl.formatMessage(intlMessages.muteAllDesc)}
|
||||
onClick={toggleMuteAllUsers}
|
||||
/>),
|
||||
(<DropdownListItem
|
||||
key={_.uniqueId('list-item-')}
|
||||
icon="mute"
|
||||
label={intl.formatMessage(intlMessages.muteAllExceptPresenterLabel)}
|
||||
description={intl.formatMessage(intlMessages.muteAllExceptPresenterDesc)}
|
||||
onClick={toggleMuteAllUsersExceptPresenter}
|
||||
/>),
|
||||
(<DropdownListItem
|
||||
key={_.uniqueId('list-item-')}
|
||||
icon="lock"
|
||||
label={intl.formatMessage(intlMessages.lockViewersLabel)}
|
||||
description={intl.formatMessage(intlMessages.lockViewersDesc)}
|
||||
onClick={() => mountModal(<LockViewersContainer />)}
|
||||
/>),
|
||||
]);
|
||||
|
||||
if (isMeetingMuted) {
|
||||
this.alterMenu();
|
||||
}
|
||||
this.handleCreateBreakoutRoomClick = this.handleCreateBreakoutRoomClick.bind(this);
|
||||
this.onCreateBreakouts = this.onCreateBreakouts.bind(this);
|
||||
this.onInvitationUsers = this.onInvitationUsers.bind(this);
|
||||
this.renderMenuItems = this.renderMenuItems.bind(this);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
@ -148,6 +130,40 @@ class UserOptions extends PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
onCreateBreakouts() {
|
||||
return this.handleCreateBreakoutRoomClick(false);
|
||||
}
|
||||
|
||||
onInvitationUsers() {
|
||||
return this.handleCreateBreakoutRoomClick(true);
|
||||
}
|
||||
|
||||
handleCreateBreakoutRoomClick(isInvitation) {
|
||||
const {
|
||||
createBreakoutRoom,
|
||||
mountModal,
|
||||
meetingName,
|
||||
users,
|
||||
getUsersNotAssigned,
|
||||
getBreakouts,
|
||||
sendInvitation,
|
||||
} = this.props;
|
||||
|
||||
return mountModal(
|
||||
<BreakoutRoom
|
||||
{...{
|
||||
createBreakoutRoom,
|
||||
meetingName,
|
||||
users,
|
||||
getUsersNotAssigned,
|
||||
isInvitation,
|
||||
getBreakouts,
|
||||
sendInvitation,
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
alterMenu() {
|
||||
const {
|
||||
intl,
|
||||
@ -186,9 +202,92 @@ class UserOptions extends PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
renderMenuItems() {
|
||||
const {
|
||||
intl,
|
||||
isMeetingMuted,
|
||||
mountModal,
|
||||
toggleStatus,
|
||||
toggleMuteAllUsers,
|
||||
toggleMuteAllUsersExceptPresenter,
|
||||
meetingIsBreakout,
|
||||
hasBreakoutRoom,
|
||||
getUsersNotAssigned,
|
||||
isUserModerator,
|
||||
users,
|
||||
} = this.props;
|
||||
|
||||
const canCreateBreakout = isUserModerator
|
||||
&& !meetingIsBreakout
|
||||
&& !hasBreakoutRoom;
|
||||
|
||||
const canInviteUsers = isUserModerator
|
||||
&& !meetingIsBreakout
|
||||
&& hasBreakoutRoom
|
||||
&& getUsersNotAssigned(users).length;
|
||||
|
||||
this.menuItems = _.compact([
|
||||
(<DropdownListItem
|
||||
key={this.clearStatusId}
|
||||
icon="clear_status"
|
||||
label={intl.formatMessage(intlMessages.clearAllLabel)}
|
||||
description={intl.formatMessage(intlMessages.clearAllDesc)}
|
||||
onClick={toggleStatus}
|
||||
/>),
|
||||
(<DropdownListItem
|
||||
key={this.muteAllId}
|
||||
icon="mute"
|
||||
label={intl.formatMessage(intlMessages.muteAllLabel)}
|
||||
description={intl.formatMessage(intlMessages.muteAllDesc)}
|
||||
onClick={toggleMuteAllUsers}
|
||||
/>),
|
||||
(<DropdownListItem
|
||||
key={this.muteId}
|
||||
icon="mute"
|
||||
label={intl.formatMessage(intlMessages.muteAllExceptPresenterLabel)}
|
||||
description={intl.formatMessage(intlMessages.muteAllExceptPresenterDesc)}
|
||||
onClick={toggleMuteAllUsersExceptPresenter}
|
||||
/>),
|
||||
(<DropdownListItem
|
||||
key={this.lockId}
|
||||
icon="lock"
|
||||
label={intl.formatMessage(intlMessages.lockViewersLabel)}
|
||||
description={intl.formatMessage(intlMessages.lockViewersDesc)}
|
||||
onClick={() => mountModal(<LockViewersContainer />)}
|
||||
/>),
|
||||
(canCreateBreakout
|
||||
? (
|
||||
<DropdownListItem
|
||||
key={this.createBreakoutId}
|
||||
icon="rooms"
|
||||
label={intl.formatMessage(intlMessages.createBreakoutRoom)}
|
||||
description={intl.formatMessage(intlMessages.createBreakoutRoomDesc)}
|
||||
onClick={this.onCreateBreakouts}
|
||||
/>
|
||||
) : null
|
||||
),
|
||||
(canInviteUsers
|
||||
? (
|
||||
<DropdownListItem
|
||||
icon="rooms"
|
||||
label={intl.formatMessage(intlMessages.invitationItem)}
|
||||
key={this.createBreakoutId}
|
||||
onClick={this.onInvitationUsers}
|
||||
/>
|
||||
)
|
||||
: null),
|
||||
]);
|
||||
|
||||
if (isMeetingMuted) {
|
||||
this.alterMenu();
|
||||
}
|
||||
|
||||
return this.menuItems;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props;
|
||||
const { isUserOptionsOpen } = this.state;
|
||||
const { intl } = this.props;
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
@ -217,7 +316,7 @@ class UserOptions extends PureComponent {
|
||||
>
|
||||
<DropdownList>
|
||||
{
|
||||
this.menuItems
|
||||
this.renderMenuItems()
|
||||
}
|
||||
</DropdownList>
|
||||
</DropdownContent>
|
||||
|
@ -1,67 +1,47 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import PropTypes from 'prop-types';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import Service from '/imports/ui/components/actions-bar/service';
|
||||
import UserOptions from './component';
|
||||
|
||||
|
||||
const propTypes = {
|
||||
users: PropTypes.arrayOf(Object).isRequired,
|
||||
muteAllUsers: PropTypes.func.isRequired,
|
||||
muteAllExceptPresenter: PropTypes.func.isRequired,
|
||||
setEmojiStatus: PropTypes.func.isRequired,
|
||||
meeting: PropTypes.shape({}).isRequired,
|
||||
currentUser: PropTypes.shape({
|
||||
isModerator: PropTypes.bool.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default class UserOptionsContainer extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const UserOptionsContainer = withTracker((props) => {
|
||||
const {
|
||||
meeting,
|
||||
users,
|
||||
setEmojiStatus,
|
||||
muteAllExceptPresenter,
|
||||
muteAllUsers,
|
||||
} = props;
|
||||
|
||||
const { meeting } = this.props;
|
||||
|
||||
this.state = {
|
||||
meetingMuted: meeting.voiceProp.muteOnStart,
|
||||
return {
|
||||
toggleMuteAllUsers: () => muteAllUsers(Auth.userID),
|
||||
toggleMuteAllUsersExceptPresenter: () => muteAllExceptPresenter(Auth.userID),
|
||||
toggleStatus: () => users.forEach(id => setEmojiStatus(id, 'none')),
|
||||
isMeetingMuted: meeting.voiceProp.muteOnStart,
|
||||
isUserPresenter: Service.isUserPresenter(),
|
||||
isUserModerator: Service.isUserModerator(),
|
||||
createBreakoutRoom: Service.createBreakoutRoom,
|
||||
meetingIsBreakout: Service.meetingIsBreakout(),
|
||||
hasBreakoutRoom: Service.hasBreakoutRoom(),
|
||||
meetingName: Service.meetingName(),
|
||||
users: Service.users(),
|
||||
getBreakouts: Service.getBreakouts,
|
||||
sendInvitation: Service.sendInvitation,
|
||||
getUsersNotAssigned: Service.getUsersNotAssigned,
|
||||
};
|
||||
|
||||
this.muteMeeting = this.muteMeeting.bind(this);
|
||||
this.muteAllUsersExceptPresenter = this.muteAllUsersExceptPresenter.bind(this);
|
||||
this.handleClearStatus = this.handleClearStatus.bind(this);
|
||||
}
|
||||
|
||||
muteMeeting() {
|
||||
const { muteAllUsers } = this.props;
|
||||
muteAllUsers(Auth.userID);
|
||||
}
|
||||
|
||||
muteAllUsersExceptPresenter() {
|
||||
const { muteAllExceptPresenter } = this.props;
|
||||
muteAllExceptPresenter(Auth.userID);
|
||||
}
|
||||
|
||||
handleClearStatus() {
|
||||
const { users, setEmojiStatus } = this.props;
|
||||
|
||||
users.forEach((id) => {
|
||||
setEmojiStatus(id, 'none');
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { currentUser } = this.props;
|
||||
const currentUserIsModerator = currentUser.isModerator;
|
||||
|
||||
const { meetingMuted } = this.state;
|
||||
|
||||
return (
|
||||
currentUserIsModerator
|
||||
? (
|
||||
<UserOptions
|
||||
toggleMuteAllUsers={this.muteMeeting}
|
||||
toggleMuteAllUsersExceptPresenter={this.muteAllUsersExceptPresenter}
|
||||
toggleStatus={this.handleClearStatus}
|
||||
isMeetingMuted={meetingMuted}
|
||||
/>) : null
|
||||
);
|
||||
}
|
||||
}
|
||||
})(UserOptions);
|
||||
|
||||
UserOptionsContainer.propTypes = propTypes;
|
||||
|
||||
export default UserOptionsContainer;
|
||||
|
@ -53,13 +53,13 @@ export function canGenerateIceCandidates() {
|
||||
Session.set('canGenerateIceCandidates', true);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pc.onicegatheringstatechange = function (e) {
|
||||
if (e.currentTarget.iceGatheringState == 'complete' && countIceCandidates == 0) reject();
|
||||
}
|
||||
};
|
||||
|
||||
setTimeout(function () {
|
||||
setTimeout(() => {
|
||||
pc.close();
|
||||
if (!countIceCandidates) reject();
|
||||
}, 5000);
|
||||
@ -75,7 +75,7 @@ export function tryGenerateIceCandidates() {
|
||||
canGenerateIceCandidates().then((ok) => {
|
||||
resolve();
|
||||
}).catch((e) => {
|
||||
navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(function (stream) {
|
||||
navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then((stream) => {
|
||||
canGenerateIceCandidates().then((ok) => {
|
||||
resolve();
|
||||
}).catch((e) => {
|
||||
|
Loading…
Reference in New Issue
Block a user