// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import $ from 'jquery'; import AtMentionProvider from './suggestion/at_mention_provider.jsx'; import ChannelMentionProvider from './suggestion/channel_mention_provider.jsx'; import CommandProvider from './suggestion/command_provider.jsx'; import EmoticonProvider from './suggestion/emoticon_provider.jsx'; import SuggestionList from './suggestion/suggestion_list.jsx'; import SuggestionBox from './suggestion/suggestion_box.jsx'; import ErrorStore from 'stores/error_store.jsx'; import * as TextFormatting from 'utils/text_formatting.jsx'; import * as Utils from 'utils/utils.jsx'; import Constants from 'utils/constants.jsx'; import {FormattedMessage} from 'react-intl'; const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES; import React from 'react'; export default class Textbox extends React.Component { static propTypes = { id: React.PropTypes.string.isRequired, channelId: React.PropTypes.string, value: React.PropTypes.string.isRequired, onChange: React.PropTypes.func.isRequired, onKeyPress: React.PropTypes.func.isRequired, createMessage: React.PropTypes.string.isRequired, onKeyDown: React.PropTypes.func, onBlur: React.PropTypes.func, supportsCommands: React.PropTypes.bool.isRequired, handlePostError: React.PropTypes.func, suggestionListStyle: React.PropTypes.string, emojiEnabled: React.PropTypes.bool }; static defaultProps = { supportsCommands: true }; constructor(props) { super(props); this.focus = this.focus.bind(this); this.recalculateSize = this.recalculateSize.bind(this); this.onReceivedError = this.onReceivedError.bind(this); this.handleKeyPress = this.handleKeyPress.bind(this); this.handleKeyDown = this.handleKeyDown.bind(this); this.handleBlur = this.handleBlur.bind(this); this.handleHeightChange = this.handleHeightChange.bind(this); this.showPreview = this.showPreview.bind(this); this.handleChange = this.handleChange.bind(this); this.state = { connection: '' }; this.suggestionProviders = [ new AtMentionProvider(this.props.channelId), new ChannelMentionProvider(), new EmoticonProvider() ]; if (props.supportsCommands) { this.suggestionProviders.push(new CommandProvider()); } } componentDidMount() { ErrorStore.addChangeListener(this.onReceivedError); } componentWillMount() { this.checkMessageLength(this.props.value); } componentWillUnmount() { ErrorStore.removeChangeListener(this.onReceivedError); } onReceivedError() { const errorCount = ErrorStore.getConnectionErrorCount(); if (errorCount > 1) { this.setState({connection: 'bad-connection'}); } else { this.setState({connection: ''}); } } handleChange(e) { this.checkMessageLength(e.target.value); this.props.onChange(e); } checkMessageLength(message) { if (this.props.handlePostError) { if (message.length > Constants.CHARACTER_LIMIT) { const errorMessage = ( ); this.props.handlePostError(errorMessage); } else { this.props.handlePostError(null); } } } handleKeyPress(e) { this.props.onKeyPress(e); } handleKeyDown(e) { if (this.props.onKeyDown) { this.props.onKeyDown(e); } } handleBlur(e) { if (this.props.onBlur) { this.props.onBlur(e); } } handleHeightChange(height, maxHeight) { const wrapper = $(this.refs.wrapper); // Move over attachment icon to compensate for the scrollbar if (height > maxHeight) { wrapper.closest('.post-create').addClass('scroll'); } else { wrapper.closest('.post-create').removeClass('scroll'); } } focus() { const textbox = this.refs.message.getTextbox(); textbox.focus(); Utils.placeCaretAtEnd(textbox); } recalculateSize() { this.refs.message.recalculateSize(); } showPreview(e) { e.preventDefault(); e.target.blur(); this.setState({preview: !this.state.preview}); } hidePreview() { this.setState({preview: false}); } componentWillReceiveProps(nextProps) { if (nextProps.channelId !== this.props.channelId) { // Update channel id for AtMentionProvider. const providers = this.suggestionProviders; for (let i = 0; i < providers.length; i++) { if (providers[i] instanceof AtMentionProvider) { providers[i] = new AtMentionProvider(nextProps.channelId); } } } } render() { const hasText = this.props.value && this.props.value.length > 0; let previewLink = null; if (Utils.isFeatureEnabled(PreReleaseFeatures.MARKDOWN_PREVIEW)) { previewLink = ( {this.state.preview ? ( ) : ( )} ); } const helpText = (
{'~~'} {'~~ '}
); let textboxClassName = 'form-control custom-textarea'; if (this.props.emojiEnabled) { textboxClassName += ' custom-textarea--emoji-picker'; } if (this.state.connection) { textboxClassName += ' ' + this.state.connection; } return (
{helpText} {previewLink}
); } }