Skip to content

Commit

Permalink
Merge pull request #3171 from oswaldoacauan/feature-chat-2
Browse files Browse the repository at this point in the history
User List Sorting & Chat Lock
  • Loading branch information
antobinary committed Jun 14, 2016
2 parents 59fca31 + 6414d63 commit dddcc06
Show file tree
Hide file tree
Showing 15 changed files with 260 additions and 50 deletions.
5 changes: 4 additions & 1 deletion bigbluebutton-html5/imports/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
"app.userlist.presenter": "Presenter",
"app.userlist.you": "You",
"app.chat.submitLabel": "Send Message",
"app.chat.inputLabel": "Message input for chat {name}"
"app.chat.inputLabel": "Message input for chat {name}",
"app.chat.titlePublic": "Public Chat",
"app.chat.titlePrivate": "Private Chat with {name}",
"app.chat.partnerDisconnected": "{name} has left the meeting"
}
5 changes: 4 additions & 1 deletion bigbluebutton-html5/imports/locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
"app.userlist.presenter": "Apresentador",
"app.userlist.you": "Você",
"app.chat.submitLabel": "Enviar Mensagem",
"app.chat.inputLabel": "Campo de mensagem para conversa {name}"
"app.chat.inputLabel": "Campo de mensagem para conversa {name}",
"app.chat.titlePublic": "Conversa Publíca",
"app.chat.titlePrivate": "Conversa Privada com {name}",
"app.chat.partnerDisconnected": "{name} saiu da sala"
}
2 changes: 2 additions & 0 deletions bigbluebutton-html5/imports/ui/components/chat/component.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default class Chat extends Component {
const {
title,
messages,
isChatLocked,
actions,
} = this.props;

Expand All @@ -36,6 +37,7 @@ export default class Chat extends Component {
aria-relevant="additions"
/>
<MessageForm
disabled={isChatLocked}
chatAreaId={ELEMENT_ID}
chatTitle={title}
handleSendMessage={actions.handleSendMessage}
Expand Down
42 changes: 38 additions & 4 deletions bigbluebutton-html5/imports/ui/components/chat/container.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import React, { Component, PropTypes } from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import { createContainer } from 'meteor/react-meteor-data';

import Chat from './component';
import ChatService from './service';

const PUBLIC_CHAT_KEY = 'public';

const intlMessages = defineMessages({
titlePublic: {
id: 'app.chat.titlePublic',
defaultMessage: 'Public Chat',
description: 'Public chat title',
},
titlePrivate: {
id: 'app.chat.titlePrivate',
defaultMessage: 'Private Chat with {name}',
description: 'Private chat title',
},
partnerDisconnected: {
id: 'app.chat.partnerDisconnected',
defaultMessage: '{name} has left the meeting',
description: 'System chat message when the private chat partnet disconnect from the meeting',
},
});

class ChatContainer extends Component {
constructor(props) {
super(props);
Expand All @@ -20,24 +39,39 @@ class ChatContainer extends Component {
}
}

export default createContainer(({ params }) => {
export default injectIntl(createContainer(({ params, intl }) => {
const chatID = params.chatID || PUBLIC_CHAT_KEY;

let messages = [];
let isChatLocked = ChatService.isChatLocked(chatID);

if (chatID === PUBLIC_CHAT_KEY) {
messages = ChatService.getPublicMessages();
title = 'Public';
title = intl.formatMessage(intlMessages.titlePublic);
} else {
messages = ChatService.getPrivateMessages(chatID);
title = ChatService.getChatTitle(chatID);
let user = ChatService.getUser(chatID);

if (user) {
title = intl.formatMessage(intlMessages.titlePrivate, { name: user.name });
} else {
// let partnerName = messages.find(m => m.user && m.user.id === chatID).map(m => m.user.name);
let partnerName = '{{NAME}}'; // placeholder until the server sends the name
messages.push({
content: [intl.formatMessage(intlMessages.partnerDisconnected, { name: partnerName })],
time: Date.now(),
sender: null,
});
isChatLocked = true;
}
}

return {
title,
messages,
isChatLocked,
actions: {
handleSendMessage: message => ChatService.sendMessage(chatID, message),
},
};
}, ChatContainer);
}, ChatContainer));
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { findDOMNode } from 'react-dom';
import cx from 'classnames';
import styles from './styles';

import Button from '../../button/component';
import MessageFormActions from './message-form-actions/component';
import TextareaAutosize from 'react-autosize-textarea';

const propTypes = {
Expand Down Expand Up @@ -55,6 +55,12 @@ class MessageForm extends Component {
handleSubmit(e) {
e.preventDefault();

const { disabled } = this.props;

if (disabled) {
return false;
}

let message = this.state.message.trim();

// Sanitize. See: http://shebang.brandonmintern.com/foolproof-html-escaping-in-javascript/
Expand All @@ -72,22 +78,19 @@ class MessageForm extends Component {
}

render() {
const { intl, chatTitle } = this.props;
const { intl, chatTitle, disabled } = this.props;

return (
<form
{...this.props}
ref="form"
className={cx(this.props.className, styles.form)}
onSubmit={this.handleSubmit}>
<div className={styles.actions}>
<Button
onClick={() => alert('Not supported yet...')}
icon={'circle-add'}
size={'sm'}
circle={true}
/>
</div>
<MessageFormActions
onClick={() => alert('Not supported yet...')}
className={styles.actions}
disabled={disabled}
/>
<TextareaAutosize
className={styles.input}
id="message-input"
Expand All @@ -97,6 +100,7 @@ class MessageForm extends Component {
autocorrect="off"
autocomplete="off"
spellcheck="true"
disabled={disabled}
value={this.state.message}
onChange={this.handleMessageChange}
onKeyUp={this.handleMessageKeyUp}
Expand All @@ -105,6 +109,7 @@ class MessageForm extends Component {
ref="btnSubmit"
className={'sr-only'}
type="submit"
disabled={disabled}
value={ intl.formatMessage(messages.submitLabel) }
/>
</form>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { PropTypes } from 'react';
import styles from './styles';

import Icon from '../../../icon/component';
import BaseButton from '../../../button/base/component';

const propTypes = {
...BaseButton.propTypes,
};

const defaultProps = {
...BaseButton.defaultProps,
};

export default class MessageFormActions extends BaseButton {
constructor(props) {
super(props);
}

render() {
return (
<BaseButton {...this.props}>
<Icon iconName={'circle-add'} />
</BaseButton>
);
}
};

MessageFormActions.propTypes = propTypes;
MessageFormActions.defaultProps = defaultProps;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "imports/ui/stylesheets/variables/_all";
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,22 @@
border: $border-size solid $color-gray-lighter;
background: #fff;
border-radius: $border-radius 0 0 $border-radius;
color: $color-gray-lighter;
color: $color-gray-light;
padding: $sm-padding-y $sm-padding-x;
transition: background .3s;
cursor: pointer;

&:hover,
&:focus {
background-color: fade-out($color-gray-lighter, .75);
}

&:disabled,
&[disabled] {
cursor: not-allowed;
opacity: .75;
background-color: fade-out($color-gray-lighter, .75);
}
}

.input {
Expand All @@ -33,11 +47,18 @@
-webkit-appearance: none;
box-shadow: none;
outline: 0;
padding: $sm-padding-y $sm-padding-x;
padding: $sm-padding-y*2 $sm-padding-x;
resize: none;
transition: none;
border-radius: 0 $border-radius $border-radius 0;
font-size: $font-size-base * .90;
min-height: 4rem;
max-height: 10rem;

&:disabled,
&[disabled] {
cursor: not-allowed;
opacity: .75;
background-color: fade-out($color-gray-lighter, .75);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
min-width: 0;
font-weight: 600;
color: $color-gray;
text-transform: capitalize;

> span {
@extend %text-elipsis;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
flex-shrink: 1;
margin-right: -$line-height-computed;
padding-right: $line-height-computed;
padding-top: $line-height-computed;
padding-bottom: $line-height-computed;
}
26 changes: 21 additions & 5 deletions bigbluebutton-html5/imports/ui/components/chat/service.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Chats from '/imports/api/chat';
import Users from '/imports/api/users';
import Meetings from '/imports/api/meetings';

import Auth from '/imports/ui/services/auth';

import { callServer } from '/imports/ui/services/api';
Expand All @@ -24,6 +26,7 @@ const mapUser = (user) => ({
isMuted: user.voiceUser.muted,
isListenOnly: user.listenOnly,
isSharingWebcam: user.webcam_stream.length,
isLocked: user.locked,
});

const mapMessage = (message) => {
Expand Down Expand Up @@ -65,7 +68,7 @@ const getUser = (userID) => {
if (user) {
return mapUser(user.user);
} else {
throw `User ${userID} not found`;
return null;
}
};

Expand Down Expand Up @@ -102,9 +105,21 @@ const getPrivateMessages = (userID) => {
.reduce(reduceMessages, []);
};

const getChatTitle = (userID) => {
const user = getUser(userID);
return user.name;
const isChatLocked = (receiverID) => {
const isPublic = receiverID === PUBLIC_CHAT_ID;
const currentUser = getUser(Auth.getUser());
const meeting = Meetings.findOne({});

const lockSettings = meeting.roomLockSettings || {
disablePublicChat: false,
disablePrivateChat: false,
};

if (!currentUser.isLocked || currentUser.isPresenter) {
return false;
}

return isPublic ? lockSettings.disablePublicChat : lockSettings.disablePrivateChat;
};

const sendMessage = (receiverID, message) => {
Expand Down Expand Up @@ -139,6 +154,7 @@ const sendMessage = (receiverID, message) => {
export default {
getPublicMessages,
getPrivateMessages,
getChatTitle,
getUser,
isChatLocked,
sendMessage,
};
1 change: 1 addition & 0 deletions bigbluebutton-html5/imports/ui/components/chat/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

.closeChat {
text-decoration: none;
text-transform: capitalize;
}

.header {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class UserListContainer extends Component {
}
}

export default createContainer(() => {
const data = Service.mapUsers();
return data;
}, UserListContainer);
export default createContainer(() => ({
users: Service.getUsers(),
}), UserListContainer);
Loading

0 comments on commit dddcc06

Please sign in to comment.