Merge remote-tracking branch 'upstream/master' into userlist_dot

This commit is contained in:
JaeeunCho 2016-10-11 10:24:27 -07:00
commit fd38b2eb24
12 changed files with 297 additions and 33 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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"
}

View File

@ -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,
});
}
});

View File

@ -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>

View 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);

View File

@ -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;

View 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,
};

View File

@ -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) {

View File

@ -0,0 +1,3 @@
const EMOJI_STATUSES = ['away', 'raiseHand', 'neutral', 'confused', 'sad', 'happy'];
export { EMOJI_STATUSES };

View File

@ -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';

View File

@ -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",