bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
Oleksandr Zhurbenko a0224dcffc Replaced String refs with callback refs
String refs will be deprecated in the next React releases, since they have some performance issues
2017-06-03 16:58:27 -07:00

170 lines
4.6 KiB
JavaScript
Executable File

import React, { Component, PropTypes } from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import { findDOMNode } from 'react-dom';
import cx from 'classnames';
import styles from './styles';
import MessageFormActions from './message-form-actions/component';
import TextareaAutosize from 'react-autosize-textarea';
import Button from '../../button/component';
const propTypes = {
};
const defaultProps = {
};
const messages = defineMessages({
submitLabel: {
id: 'app.chat.submitLabel',
description: 'Chat submit button label',
},
inputLabel: {
id: 'app.chat.inputLabel',
description: 'Chat message input label',
},
inputPlaceholder: {
id: 'app.chat.inputPlaceholder',
description: 'Chat message input placeholder',
},
errorMinMessageLength: {
id: 'app.chat.errorMinMessageLength',
},
errorMaxMessageLength: {
id: 'app.chat.errorMaxMessageLength',
},
});
class MessageForm extends Component {
constructor(props) {
super(props);
this.state = {
message: '',
error: '',
hasErrors: false,
};
this.handleMessageChange = this.handleMessageChange.bind(this);
this.handleMessageKeyDown = this.handleMessageKeyDown.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleMessageKeyDown(e) {
//TODO Prevent send message pressing enter on mobile and/or virtual keyboard
if (e.keyCode === 13 && !e.shiftKey) {
e.preventDefault();
let event = new Event('submit', {
bubbles: true,
cancelable: true,
});
this.form.dispatchEvent(event);
}
}
handleMessageChange(e) {
const { intl } = this.props;
const message = e.target.value;
let error = '';
const { minMessageLength, maxMessageLength, } = this.props;
if (message.length < minMessageLength) {
error = intl.formatMessage(messages.errorMinMessageLength,
{ 0: minMessageLength - message.length });
}
if (message.length > maxMessageLength) {
error = intl.formatMessage(messages.errorMaxMessageLength,
{ 0: message.length - maxMessageLength });
}
this.setState({
message,
error,
});
}
handleSubmit(e) {
e.preventDefault();
const { disabled, minMessageLength, maxMessageLength, } = this.props;
let message = this.state.message.trim();
if (disabled
|| message.length === 0
|| message.length < minMessageLength
|| message.length > maxMessageLength) {
this.setState({ hasErrors: true, });
return false;
}
// Sanitize. See: http://shebang.brandonmintern.com/foolproof-html-escaping-in-javascript/
let div = document.createElement('div');
div.appendChild(document.createTextNode(message));
message = div.innerHTML;
return this.props.handleSendMessage(message)
.then(() => this.setState({
message: '',
hasErrors: false,
}));
}
render() {
const { intl, chatTitle, chatName, disabled,
minMessageLength, maxMessageLength, } = this.props;
const { hasErrors, error } = this.state;
return (
<form
ref={(ref) => { this.form = ref; }}
className={cx(this.props.className, styles.form)}
onSubmit={this.handleSubmit}>
<div className={styles.wrapper}>
<TextareaAutosize
className={styles.input}
id="message-input"
placeholder={intl.formatMessage(messages.inputPlaceholder, { 0: chatName })}
aria-controls={this.props.chatAreaId}
aria-label={intl.formatMessage(messages.inputLabel, { 0: chatTitle })}
aria-invalid={ hasErrors ? 'true' : 'false' }
aria-describedby={ hasErrors ? 'message-input-error' : null }
autoCorrect="off"
autoComplete="off"
spellCheck="true"
disabled={disabled}
value={this.state.message}
onChange={this.handleMessageChange}
onKeyDown={this.handleMessageKeyDown}
/>
<Button
className={styles.sendButton}
aria-label={intl.formatMessage(messages.submitLabel)}
type="submit"
disabled={disabled}
label={intl.formatMessage(messages.submitLabel)}
hideLabel={true}
icon="send"
onClick={() => null}
/>
</div>
<div className={styles.info}>
{ hasErrors ? <span id="message-input-error">{error}</span> : null }
</div>
</form>
);
}
}
MessageForm.propTypes = propTypes;
MessageForm.defaultProps = defaultProps;
export default injectIntl(MessageForm);