Merge remote-tracking branch 'upstream/master' into userlist_dot
This commit is contained in:
commit
fd38b2eb24
@ -1435,7 +1435,7 @@ if [ $CHECK ]; then
|
||||
echo
|
||||
echo "$FREESWITCH_EXTERNAL (FreeSWITCH)"
|
||||
echo " websocket port: $WEBRTC_SOCKET"
|
||||
WEBRTC_ENABLED=$(grep -i webrtc /var/www/bigbluebutton/client/conf/config.xml | cut -d '"' -f2)
|
||||
WEBRTC_ENABLED=$(grep -i useWebrtcIfAvailable /var/www/bigbluebutton/client/conf/config.xml | cut -d '"' -f2)
|
||||
echo " WebRTC enabled: $WEBRTC_ENABLED"
|
||||
|
||||
echo
|
||||
|
@ -53,10 +53,10 @@
|
||||
.icon-bbb-up-arrow:before {
|
||||
content: "\e907";
|
||||
}
|
||||
.icon-bbb-undecided:before {
|
||||
.icon-bbb-neutral:before {
|
||||
content: "\e908";
|
||||
}
|
||||
.icon-bbb-time:before {
|
||||
.icon-bbb-away:before {
|
||||
content: "\e909";
|
||||
}
|
||||
.icon-bbb-sad:before {
|
||||
@ -77,7 +77,7 @@
|
||||
.icon-bbb-happy:before {
|
||||
content: "\e90f";
|
||||
}
|
||||
.icon-bbb-hand:before {
|
||||
.icon-bbb-raiseHand:before {
|
||||
content: "\e910";
|
||||
}
|
||||
.icon-bbb-group-chat:before {
|
||||
@ -89,7 +89,7 @@
|
||||
.icon-bbb-close:before {
|
||||
content: "\e913";
|
||||
}
|
||||
.icon-bbb-clear-status:before {
|
||||
.icon-bbb-none:before {
|
||||
content: "\e914";
|
||||
}
|
||||
.icon-bbb-circle:before {
|
||||
|
@ -45,5 +45,20 @@
|
||||
"app.actionsBar.actionsDropdown.desktopShareLabel": "Share your screen",
|
||||
"app.actionsBar.actionsDropdown.presentationDesc": "Upload your presentation",
|
||||
"app.actionsBar.actionsDropdown.initPollDesc": "Initiate a poll",
|
||||
"app.actionsBar.actionsDropdown.desktopShareDesc": "Share your screen with others"
|
||||
"app.actionsBar.actionsDropdown.desktopShareDesc": "Share your screen with others",
|
||||
"app.actionsBar.emojiMenu.statusTriggerLabel": "Status",
|
||||
"app.actionsBar.emojiMenu.awayLabel": "Away",
|
||||
"app.actionsBar.emojiMenu.awayDesc": "Change your status to away",
|
||||
"app.actionsBar.emojiMenu.raiseLabel": "Raise",
|
||||
"app.actionsBar.emojiMenu.raiseDesc": "Raise your hand to ask a question",
|
||||
"app.actionsBar.emojiMenu.undecidedLabel": "Undecided",
|
||||
"app.actionsBar.emojiMenu.undecidedDesc": "Change your status to undecided",
|
||||
"app.actionsBar.emojiMenu.confusedLabel": "Confused",
|
||||
"app.actionsBar.emojiMenu.confusedDesc": "Change your status to confused",
|
||||
"app.actionsBar.emojiMenu.sadLabel": "Sad",
|
||||
"app.actionsBar.emojiMenu.sadDesc": "Change your status to sad",
|
||||
"app.actionsBar.emojiMenu.happyLabel": "Happy",
|
||||
"app.actionsBar.emojiMenu.happyDesc": "Change your status to happy",
|
||||
"app.actionsBar.emojiMenu.clearLabel": "Clear",
|
||||
"app.actionsBar.emojiMenu.clearDesc": "Clear your status"
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ let Logger = new Winston.Logger();
|
||||
|
||||
// Write logs to console
|
||||
Logger.add(Winston.transports.Console, {
|
||||
prettyPrint: true,
|
||||
humanReadableUnhandledException: true,
|
||||
colorize: true,
|
||||
prettyPrint: true,
|
||||
humanReadableUnhandledException: true,
|
||||
colorize: true,
|
||||
});
|
||||
|
||||
Meteor.startup(() => {
|
||||
@ -22,8 +22,8 @@ Meteor.startup(() => {
|
||||
}
|
||||
|
||||
Logger.add(Winston.transports.File, {
|
||||
filename: filename,
|
||||
prettyPrint: true,
|
||||
filename: filename,
|
||||
prettyPrint: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react';
|
||||
import styles from './styles.scss';
|
||||
|
||||
import Button from '../button/component';
|
||||
import EmojiContainer from './emoji-menu/container';
|
||||
|
||||
import ActionsDropdown from './actions-dropdown/component';
|
||||
|
||||
@ -36,14 +37,7 @@ export default class ActionsBar extends Component {
|
||||
size={'lg'}
|
||||
circle={true}
|
||||
/>
|
||||
<Button
|
||||
onClick={this.handleClick}
|
||||
label={'Raise'}
|
||||
color={'primary'}
|
||||
icon={'hand'}
|
||||
size={'lg'}
|
||||
circle={true}
|
||||
/>
|
||||
<EmojiContainer />
|
||||
</div>
|
||||
<div className={styles.right}>
|
||||
</div>
|
||||
|
179
bigbluebutton-html5/imports/ui/components/actions-bar/emoji-menu/component.jsx
Executable file
179
bigbluebutton-html5/imports/ui/components/actions-bar/emoji-menu/component.jsx
Executable file
@ -0,0 +1,179 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import Dropdown from '/imports/ui/components/dropdown/component';
|
||||
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
|
||||
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 DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
|
||||
|
||||
const propTypes = {
|
||||
// Emoji status of the current user
|
||||
userEmojiStatus: PropTypes.string.isRequired,
|
||||
actions: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
class EmojiMenu extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
userEmojiStatus,
|
||||
actions,
|
||||
intl,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Dropdown ref="dropdown">
|
||||
<DropdownTrigger>
|
||||
<Button
|
||||
role="button"
|
||||
label={intl.formatMessage(intlMessages.statusTriggerLabel)}
|
||||
icon="raiseHand"
|
||||
ghost={false}
|
||||
circle={true}
|
||||
hideLabel={false}
|
||||
color="primary"
|
||||
size="lg"
|
||||
|
||||
// FIXME: Without onClick react proptypes keep warning
|
||||
// even after the DropdownTrigger inject an onClick handler
|
||||
onClick={() => null}
|
||||
/>
|
||||
</DropdownTrigger>
|
||||
<DropdownContent placement="top left">
|
||||
<DropdownList>
|
||||
<DropdownListItem
|
||||
icon="away"
|
||||
label={intl.formatMessage(intlMessages.awayLabel)}
|
||||
description={intl.formatMessage(intlMessages.awayDesc)}
|
||||
onClick={() => actions.setEmojiHandler('away')}
|
||||
/>
|
||||
<DropdownListItem
|
||||
icon="raiseHand"
|
||||
label={intl.formatMessage(intlMessages.raiseLabel)}
|
||||
description={intl.formatMessage(intlMessages.raiseDesc)}
|
||||
onClick={() => actions.setEmojiHandler('raiseHand')}
|
||||
/>
|
||||
<DropdownListItem
|
||||
icon="neutral"
|
||||
label={intl.formatMessage(intlMessages.undecidedLabel)}
|
||||
description={intl.formatMessage(intlMessages.undecidedDesc)}
|
||||
onClick={() => actions.setEmojiHandler('neutral')}
|
||||
|
||||
/>
|
||||
<DropdownListItem
|
||||
icon="confused"
|
||||
label={intl.formatMessage(intlMessages.confusedLabel)}
|
||||
description={intl.formatMessage(intlMessages.confusedDesc)}
|
||||
onClick={() => actions.setEmojiHandler('confused')}
|
||||
/>
|
||||
<DropdownListItem
|
||||
icon="sad"
|
||||
label={intl.formatMessage(intlMessages.sadLabel)}
|
||||
description={intl.formatMessage(intlMessages.sadDesc)}
|
||||
onClick={() => actions.setEmojiHandler('sad')}
|
||||
/>
|
||||
<DropdownListItem
|
||||
icon="happy"
|
||||
label={intl.formatMessage(intlMessages.happyLabel)}
|
||||
description={intl.formatMessage(intlMessages.happyDesc)}
|
||||
onClick={() => actions.setEmojiHandler('happy')}
|
||||
/>
|
||||
<DropdownListSeparator/>
|
||||
<DropdownListItem
|
||||
icon="none"
|
||||
label={intl.formatMessage(intlMessages.clearLabel)}
|
||||
description={intl.formatMessage(intlMessages.clearDesc)}
|
||||
onClick={() => actions.setEmojiHandler('none')}
|
||||
/>
|
||||
</DropdownList>
|
||||
</DropdownContent>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
statusTriggerLabel: {
|
||||
id: 'app.actionsBar.emojiMenu.statusTriggerLabel',
|
||||
defaultMessage: 'Status',
|
||||
},
|
||||
|
||||
// For away status
|
||||
awayLabel: {
|
||||
id: 'app.actionsBar.emojiMenu.awayLabel',
|
||||
defaultMessage: 'Away',
|
||||
},
|
||||
awayDesc: {
|
||||
id: 'app.actionsBar.emojiMenu.awayDesc',
|
||||
defaultMessage: 'Change your status to away',
|
||||
},
|
||||
|
||||
// For raise hand status
|
||||
raiseLabel: {
|
||||
id: 'app.actionsBar.emojiMenu.raiseLabel',
|
||||
defaultMessage: 'Raise',
|
||||
},
|
||||
raiseDesc: {
|
||||
id: 'app.actionsBar.emojiMenu.raiseDesc',
|
||||
defaultMessage: 'Raise your hand to ask a question',
|
||||
},
|
||||
|
||||
// For undecided status
|
||||
undecidedLabel: {
|
||||
id: 'app.actionsBar.emojiMenu.undecidedLabel',
|
||||
defaultMessage: 'Undecided',
|
||||
},
|
||||
undecidedDesc: {
|
||||
id: 'app.actionsBar.emojiMenu.undecidedDesc',
|
||||
defaultMessage: 'Change your status to undecided',
|
||||
},
|
||||
|
||||
// For confused status
|
||||
confusedLabel: {
|
||||
id: 'app.actionsBar.emojiMenu.confusedLabel',
|
||||
defaultMessage: 'Confused',
|
||||
},
|
||||
confusedDesc: {
|
||||
id: 'app.actionsBar.emojiMenu.confusedDesc',
|
||||
defaultMessage: 'Change your status to confused',
|
||||
},
|
||||
|
||||
// For sad status
|
||||
sadLabel: {
|
||||
id: 'app.actionsBar.emojiMenu.sadLabel',
|
||||
defaultMessage: 'Sad',
|
||||
},
|
||||
sadDesc: {
|
||||
id: 'app.actionsBar.emojiMenu.sadDesc',
|
||||
defaultMessage: 'Change your status to sad',
|
||||
},
|
||||
|
||||
// For happy status
|
||||
happyLabel: {
|
||||
id: 'app.actionsBar.emojiMenu.happyLabel',
|
||||
defaultMessage: 'Happy',
|
||||
},
|
||||
happyDesc: {
|
||||
id: 'app.actionsBar.emojiMenu.happyDesc',
|
||||
defaultMessage: 'Change your status to happy',
|
||||
},
|
||||
|
||||
// For confused status
|
||||
clearLabel: {
|
||||
id: 'app.actionsBar.emojiMenu.clearLabel',
|
||||
defaultMessage: 'Clear',
|
||||
},
|
||||
clearDesc: {
|
||||
id: 'app.actionsBar.emojiMenu.clearDesc',
|
||||
defaultMessage: 'Clear your status',
|
||||
},
|
||||
});
|
||||
|
||||
EmojiMenu.propTypes = propTypes;
|
||||
export default injectIntl(EmojiMenu);
|
@ -0,0 +1,50 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { createContainer } from 'meteor/react-meteor-data';
|
||||
|
||||
import EmojiService from './service';
|
||||
import EmojiMenu from './component.jsx';
|
||||
|
||||
const propTypes = {
|
||||
// Emoji status of the current user
|
||||
userEmojiStatus: PropTypes.string.isRequired,
|
||||
actions: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
class EmojiContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
userEmojiStatus,
|
||||
actions,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<EmojiMenu userEmojiStatus={userEmojiStatus} actions={actions}/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default createContainer(() => {
|
||||
const data = EmojiService.getEmojiData();
|
||||
|
||||
const {
|
||||
userEmojiStatus,
|
||||
credentials,
|
||||
} = data;
|
||||
|
||||
const { requesterUserId: userId } = credentials;
|
||||
|
||||
return {
|
||||
userEmojiStatus,
|
||||
actions: {
|
||||
setEmojiHandler: (status) => {
|
||||
EmojiService.setEmoji(userId, status);
|
||||
},
|
||||
},
|
||||
};
|
||||
}, EmojiContainer);
|
||||
|
||||
EmojiContainer.propTypes = propTypes;
|
31
bigbluebutton-html5/imports/ui/components/actions-bar/emoji-menu/service.js
Executable file
31
bigbluebutton-html5/imports/ui/components/actions-bar/emoji-menu/service.js
Executable file
@ -0,0 +1,31 @@
|
||||
import Auth from '/imports/ui/services/auth/index.js';
|
||||
import Users from '/imports/api/users';
|
||||
import { callServer } from '/imports/ui/services/api/index.js';
|
||||
|
||||
let getEmojiData = () => {
|
||||
|
||||
// Get userId and meetingId
|
||||
const credentials = Auth.getCredentials();
|
||||
const { requesterUserId: userId, meetingId } = credentials;
|
||||
|
||||
// Find the Emoji Status of this specific meeting and userid
|
||||
const userEmojiStatus = Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId,
|
||||
}).user.emoji_status;
|
||||
|
||||
return {
|
||||
userEmojiStatus: userEmojiStatus,
|
||||
credentials: credentials,
|
||||
};
|
||||
};
|
||||
|
||||
// Below doesn't even need to receieve credentials
|
||||
const setEmoji = (toRaiseUserId, status) => {
|
||||
callServer('userSetEmoji', toRaiseUserId, status);
|
||||
};
|
||||
|
||||
export default {
|
||||
getEmojiData,
|
||||
setEmoji,
|
||||
};
|
@ -2,13 +2,13 @@ import Users from '/imports/api/users';
|
||||
import Chat from '/imports/api/chat';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import UnreadMessages from '/imports/ui/services/unread-messages';
|
||||
import { EMOJI_STATUSES } from '/imports/utils/statuses.js';
|
||||
|
||||
import { callServer } from '/imports/ui/services/api';
|
||||
|
||||
const CHAT_CONFIG = Meteor.settings.public.chat;
|
||||
const USER_CONFIG = Meteor.settings.public.user;
|
||||
const ROLE_MODERATOR = USER_CONFIG.role_moderator;
|
||||
const EMOJI_STATUSES = ['raiseHand', 'happy', 'smile', 'neutral', 'sad', 'confused', 'away'];
|
||||
const PRIVATE_CHAT_TYPE = CHAT_CONFIG.type_private;
|
||||
|
||||
/* TODO: Same map is done in the chat/service we should share this someway */
|
||||
@ -72,7 +72,7 @@ const sortUsersByEmoji = (a, b) => {
|
||||
|
||||
const sortUsersByModerator = (a, b) => {
|
||||
if (a.isModerator && b.isModerator) {
|
||||
return sortUsersByName(a, b);
|
||||
return sortUsersByEmoji(a, b);
|
||||
} else if (a.isModerator) {
|
||||
return -1;
|
||||
} else if (b.isModerator) {
|
||||
@ -95,10 +95,10 @@ const sortUsersByPhoneUser = (a, b) => {
|
||||
};
|
||||
|
||||
const sortUsers = (a, b) => {
|
||||
let sort = sortUsersByEmoji(a, b);
|
||||
let sort = sortUsersByModerator(a, b);
|
||||
|
||||
if (sort === 0) {
|
||||
sort = sortUsersByModerator(a, b);
|
||||
sort = sortUsersByEmoji(a, b);
|
||||
}
|
||||
|
||||
if (sort === 0) {
|
||||
|
3
bigbluebutton-html5/imports/utils/statuses.js
Executable file
3
bigbluebutton-html5/imports/utils/statuses.js
Executable file
@ -0,0 +1,3 @@
|
||||
const EMOJI_STATUSES = ['away', 'raiseHand', 'neutral', 'confused', 'sad', 'happy'];
|
||||
|
||||
export { EMOJI_STATUSES };
|
@ -1,9 +0,0 @@
|
||||
// used in Flash and HTML to show a legitimate break in the line
|
||||
this.BREAK_LINE = '<br/>';
|
||||
|
||||
// soft return in HTML to signify a broken line without
|
||||
//displaying the escaped '<br/>' line break text
|
||||
this.CARRIAGE_RETURN = '\r';
|
||||
|
||||
// handle this the same as carriage return, in case text copied has this
|
||||
this.NEW_LINE = '\n';
|
@ -11,10 +11,11 @@
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.3",
|
||||
"grunt-cli": "~1.2.0",
|
||||
"hiredis": "^0.5.0",
|
||||
"history": "^2.1.2",
|
||||
"image-size": "~0.5.0",
|
||||
"meteor-node-stubs": "^0.2.3",
|
||||
"node-sass": "^3.8.0",
|
||||
"node-sass": "~3.8.0",
|
||||
"react": "~15.3.1",
|
||||
"react-addons-css-transition-group": "~15.3.1",
|
||||
"react-addons-pure-render-mixin": "~15.3.1",
|
||||
|
Loading…
Reference in New Issue
Block a user