2015-10-08 12:27:09 -04:00
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
2015-06-14 23:53:32 -08:00
// See License.txt for license information.
2016-03-14 08:50:46 -04:00
import ReactDOM from 'react-dom' ;
2015-11-19 21:12:56 -05:00
import MsgTyping from './msg_typing.jsx' ;
import Textbox from './textbox.jsx' ;
import FileUpload from './file_upload.jsx' ;
import FilePreview from './file_preview.jsx' ;
2016-02-18 10:31:44 -05:00
import PostDeletedModal from './post_deleted_modal.jsx' ;
2015-11-19 21:12:56 -05:00
import TutorialTip from './tutorial/tutorial_tip.jsx' ;
2015-10-30 11:35:16 -04:00
2015-11-19 21:12:56 -05:00
import AppDispatcher from '../dispatcher/app_dispatcher.jsx' ;
2016-05-26 09:46:18 -04:00
import * as GlobalActions from 'actions/global_actions.jsx' ;
2016-04-21 22:37:01 -07:00
import Client from 'utils/web_client.jsx' ;
2016-03-14 08:50:46 -04:00
import * as Utils from 'utils/utils.jsx' ;
2016-06-02 15:43:00 -07:00
import * as ChannelActions from 'actions/channel_actions.jsx' ;
2015-10-30 11:35:16 -04:00
2016-03-14 08:50:46 -04:00
import ChannelStore from 'stores/channel_store.jsx' ;
import PostStore from 'stores/post_store.jsx' ;
import UserStore from 'stores/user_store.jsx' ;
import PreferenceStore from 'stores/preference_store.jsx' ;
2015-08-31 11:31:55 -04:00
2016-03-14 08:50:46 -04:00
import Constants from 'utils/constants.jsx' ;
2015-11-18 17:29:06 -05:00
2016-03-14 08:50:46 -04:00
import { intlShape , injectIntl , defineMessages , FormattedHTMLMessage } from 'react-intl' ;
2016-03-24 11:05:13 -04:00
import { browserHistory } from 'react-router' ;
2016-02-03 00:46:56 -03:00
2015-10-30 11:35:16 -04:00
const Preferences = Constants . Preferences ;
const TutorialSteps = Constants . TutorialSteps ;
2015-08-31 11:31:55 -04:00
const ActionTypes = Constants . ActionTypes ;
2015-10-15 02:13:48 +02:00
const KeyCodes = Constants . KeyCodes ;
2015-08-31 11:31:55 -04:00
2016-02-03 00:46:56 -03:00
const holders = defineMessages ( {
comment : {
id : 'create_post.comment' ,
defaultMessage : 'Comment'
} ,
post : {
id : 'create_post.post' ,
defaultMessage : 'Post'
} ,
write : {
id : 'create_post.write' ,
defaultMessage : 'Write a message...'
}
} ) ;
2016-03-14 08:50:46 -04:00
import React from 'react' ;
2016-02-03 00:46:56 -03:00
class CreatePost extends React . Component {
2015-08-31 11:31:55 -04:00
constructor ( props ) {
super ( props ) ;
this . lastTime = 0 ;
2015-09-22 16:00:44 -07:00
this . getCurrentDraft = this . getCurrentDraft . bind ( this ) ;
2015-08-31 11:31:55 -04:00
this . handleSubmit = this . handleSubmit . bind ( this ) ;
this . postMsgKeyPress = this . postMsgKeyPress . bind ( this ) ;
this . handleUserInput = this . handleUserInput . bind ( this ) ;
2016-02-04 11:05:59 -05:00
this . handleUploadClick = this . handleUploadClick . bind ( this ) ;
2015-08-31 11:31:55 -04:00
this . handleUploadStart = this . handleUploadStart . bind ( this ) ;
this . handleFileUploadComplete = this . handleFileUploadComplete . bind ( this ) ;
this . handleUploadError = this . handleUploadError . bind ( this ) ;
this . removePreview = this . removePreview . bind ( this ) ;
this . onChange = this . onChange . bind ( this ) ;
2015-10-30 11:35:16 -04:00
this . onPreferenceChange = this . onPreferenceChange . bind ( this ) ;
2015-08-31 11:31:55 -04:00
this . getFileCount = this . getFileCount . bind ( this ) ;
2015-10-26 22:05:26 +01:00
this . handleKeyDown = this . handleKeyDown . bind ( this ) ;
2015-10-25 23:55:50 +01:00
this . sendMessage = this . sendMessage . bind ( this ) ;
2016-02-05 12:22:39 -05:00
this . focusTextbox = this . focusTextbox . bind ( this ) ;
2016-02-18 10:31:44 -05:00
this . showPostDeletedModal = this . showPostDeletedModal . bind ( this ) ;
this . hidePostDeletedModal = this . hidePostDeletedModal . bind ( this ) ;
2016-06-02 15:43:00 -07:00
this . showShortcuts = this . showShortcuts . bind ( this ) ;
2015-08-31 11:31:55 -04:00
PostStore . clearDraftUploads ( ) ;
2015-09-22 16:00:44 -07:00
const draft = this . getCurrentDraft ( ) ;
2015-08-31 11:31:55 -04:00
this . state = {
channelId : ChannelStore . getCurrentId ( ) ,
2015-09-22 16:00:44 -07:00
messageText : draft . messageText ,
2016-05-12 07:48:29 -04:00
lastMessage : '' ,
2015-09-22 16:00:44 -07:00
uploadsInProgress : draft . uploadsInProgress ,
previews : draft . previews ,
2015-08-31 11:31:55 -04:00
submitting : false ,
2015-10-16 12:32:19 +03:00
initialText : draft . messageText ,
2015-12-15 11:47:52 -05:00
ctrlSend : false ,
2016-04-21 09:56:11 -04:00
centerTextbox : PreferenceStore . get ( Preferences . CATEGORY _DISPLAY _SETTINGS , Preferences . CHANNEL _DISPLAY _MODE , Preferences . CHANNEL _DISPLAY _MODE _DEFAULT ) === Preferences . CHANNEL _DISPLAY _MODE _CENTERED ,
2016-02-18 10:31:44 -05:00
showTutorialTip : false ,
showPostDeletedModal : false
2015-08-31 11:31:55 -04:00
} ;
2015-10-26 22:05:26 +01:00
}
2015-09-22 16:00:44 -07:00
getCurrentDraft ( ) {
const draft = PostStore . getCurrentDraft ( ) ;
const safeDraft = { previews : [ ] , messageText : '' , uploadsInProgress : [ ] } ;
if ( draft ) {
if ( draft . message ) {
safeDraft . messageText = draft . message ;
}
if ( draft . previews ) {
safeDraft . previews = draft . previews ;
}
if ( draft . uploadsInProgress ) {
safeDraft . uploadsInProgress = draft . uploadsInProgress ;
}
}
return safeDraft ;
}
2015-08-31 11:31:55 -04:00
handleSubmit ( e ) {
2015-06-14 23:53:32 -08:00
e . preventDefault ( ) ;
2015-08-10 14:01:11 -04:00
if ( this . state . uploadsInProgress . length > 0 || this . state . submitting ) {
return ;
}
2015-06-14 23:53:32 -08:00
2015-09-25 11:41:08 -04:00
const post = { } ;
2015-06-14 23:53:32 -08:00
post . filenames = [ ] ;
post . message = this . state . messageText ;
2015-06-18 17:39:12 -04:00
if ( post . message . trim ( ) . length === 0 && this . state . previews . length === 0 ) {
2015-06-14 23:53:32 -08:00
return ;
}
if ( post . message . length > Constants . CHARACTER _LIMIT ) {
2015-08-31 11:31:55 -04:00
this . setState ( { postError : ` Post length must be less than ${ Constants . CHARACTER _LIMIT } characters. ` } ) ;
2015-06-14 23:53:32 -08:00
return ;
}
2015-08-10 14:01:11 -04:00
this . setState ( { submitting : true , serverError : null } ) ;
2016-05-12 07:48:29 -04:00
this . setState ( { lastMessage : this . state . messageText } ) ;
2015-08-10 14:01:11 -04:00
if ( post . message . indexOf ( '/' ) === 0 ) {
2016-06-02 15:43:00 -07:00
ChannelActions . executeCommand (
2015-08-10 14:01:11 -04:00
this . state . channelId ,
2015-06-14 23:53:32 -08:00
post . message ,
false ,
2015-09-25 11:41:08 -04:00
( data ) => {
2016-03-07 15:57:43 -05:00
PostStore . storeDraft ( this . state . channelId , null ) ;
2015-08-10 14:01:11 -04:00
this . setState ( { messageText : '' , submitting : false , postError : null , previews : [ ] , serverError : null } ) ;
2015-06-14 23:53:32 -08:00
2016-01-08 12:41:26 -06:00
if ( data . goto _location && data . goto _location . length > 0 ) {
2016-03-24 11:05:13 -04:00
browserHistory . push ( data . goto _location ) ;
2015-06-14 23:53:32 -08:00
}
2015-09-25 11:41:08 -04:00
} ,
( err ) => {
2015-10-25 23:55:50 +01:00
if ( err . sendMessage ) {
this . sendMessage ( post ) ;
2015-07-23 09:39:29 -04:00
} else {
2015-10-25 23:55:50 +01:00
const state = { } ;
state . serverError = err . message ;
state . submitting = false ;
this . setState ( state ) ;
2015-07-23 09:39:29 -04:00
}
2015-09-25 11:41:08 -04:00
}
2015-06-14 23:53:32 -08:00
) ;
2015-10-25 23:55:50 +01:00
} else {
this . sendMessage ( post ) ;
2015-06-14 23:53:32 -08:00
}
2015-08-31 11:31:55 -04:00
}
2015-10-25 23:55:50 +01:00
sendMessage ( post ) {
post . channel _id = this . state . channelId ;
post . filenames = this . state . previews ;
const time = Utils . getTimestamp ( ) ;
const userId = UserStore . getCurrentId ( ) ;
post . pending _post _id = ` ${ userId } : ${ time } ` ;
post . user _id = userId ;
post . create _at = time ;
post . parent _id = this . state . parentId ;
2016-02-08 07:26:10 -05:00
GlobalActions . emitUserPostedEvent ( post ) ;
2015-10-25 23:55:50 +01:00
this . setState ( { messageText : '' , submitting : false , postError : null , previews : [ ] , serverError : null } ) ;
2016-04-21 22:37:01 -07:00
Client . createPost ( post ,
2016-05-04 10:10:19 -04:00
( ) => {
// DO nothing. Websockets will handle this.
2015-10-25 23:55:50 +01:00
} ,
( err ) => {
2016-01-22 08:04:02 -06:00
if ( err . id === 'api.post.create_post.root_id.app_error' ) {
2016-02-18 10:31:44 -05:00
// this should never actually happen since you can't reply from this textbox
this . showPostDeletedModal ( ) ;
2015-10-25 23:55:50 +01:00
PostStore . removePendingPost ( post . pending _post _id ) ;
} else {
post . state = Constants . POST _FAILED ;
PostStore . updatePendingPost ( post ) ;
}
2016-02-18 10:31:44 -05:00
this . setState ( {
submitting : false
} ) ;
2015-10-25 23:55:50 +01:00
}
) ;
}
2016-02-05 12:22:39 -05:00
focusTextbox ( ) {
if ( ! Utils . isMobile ( ) ) {
this . refs . textbox . focus ( ) ;
}
}
2015-08-31 11:31:55 -04:00
postMsgKeyPress ( e ) {
2015-12-15 11:36:14 -05:00
if ( this . state . ctrlSend && e . ctrlKey || ! this . state . ctrlSend ) {
2015-10-26 22:05:26 +01:00
if ( e . which === KeyCodes . ENTER && ! e . shiftKey && ! e . altKey ) {
e . preventDefault ( ) ;
ReactDOM . findDOMNode ( this . refs . textbox ) . blur ( ) ;
this . handleSubmit ( e ) ;
}
2015-06-14 23:53:32 -08:00
}
2016-03-23 10:20:52 -04:00
GlobalActions . emitLocalUserTypingEvent ( this . state . channelId , '' ) ;
2015-08-31 11:31:55 -04:00
}
handleUserInput ( messageText ) {
2015-09-25 11:41:08 -04:00
this . setState ( { messageText } ) ;
2015-07-16 15:25:28 -04:00
2015-09-25 11:41:08 -04:00
const draft = PostStore . getCurrentDraft ( ) ;
2015-08-31 11:31:55 -04:00
draft . message = messageText ;
2015-06-14 23:53:32 -08:00
PostStore . storeCurrentDraft ( draft ) ;
2015-08-31 11:31:55 -04:00
}
2016-02-04 11:05:59 -05:00
handleUploadClick ( ) {
2016-02-05 12:22:39 -05:00
this . focusTextbox ( ) ;
2015-08-31 11:31:55 -04:00
}
handleUploadStart ( clientIds , channelId ) {
2015-09-25 11:41:08 -04:00
const draft = PostStore . getDraft ( channelId ) ;
2015-06-14 23:53:32 -08:00
2015-08-31 11:31:55 -04:00
draft . uploadsInProgress = draft . uploadsInProgress . concat ( clientIds ) ;
2015-08-10 14:01:11 -04:00
PostStore . storeDraft ( channelId , draft ) ;
2015-06-14 23:53:32 -08:00
2015-08-31 11:31:55 -04:00
this . setState ( { uploadsInProgress : draft . uploadsInProgress } ) ;
2016-02-04 11:32:39 -05:00
// this is a bit redundant with the code that sets focus when the file input is clicked,
// but this also resets the focus after a drag and drop
2016-02-05 12:22:39 -05:00
this . focusTextbox ( ) ;
2015-08-31 11:31:55 -04:00
}
handleFileUploadComplete ( filenames , clientIds , channelId ) {
2015-09-25 11:41:08 -04:00
const draft = PostStore . getDraft ( channelId ) ;
2015-06-14 23:53:32 -08:00
2015-08-07 16:24:13 -04:00
// remove each finished file from uploads
2015-08-31 11:31:55 -04:00
for ( let i = 0 ; i < clientIds . length ; i ++ ) {
const index = draft . uploadsInProgress . indexOf ( clientIds [ i ] ) ;
2015-08-07 16:24:13 -04:00
2015-08-10 14:01:11 -04:00
if ( index !== - 1 ) {
2015-08-31 11:31:55 -04:00
draft . uploadsInProgress . splice ( index , 1 ) ;
2015-08-07 16:24:13 -04:00
}
2015-06-14 23:53:32 -08:00
}
2015-08-07 16:24:13 -04:00
2015-08-31 11:31:55 -04:00
draft . previews = draft . previews . concat ( filenames ) ;
2015-08-10 14:01:11 -04:00
PostStore . storeDraft ( channelId , draft ) ;
2015-08-07 16:24:13 -04:00
2016-05-03 11:00:06 -04:00
if ( channelId === this . state . channelId ) {
this . setState ( { uploadsInProgress : draft . uploadsInProgress , previews : draft . previews } ) ;
}
2015-08-31 11:31:55 -04:00
}
2016-05-03 11:00:06 -04:00
handleUploadError ( err , clientId , channelId ) {
2015-10-26 14:15:07 -04:00
let message = err ;
if ( message && typeof message !== 'string' ) {
// err is an AppError from the server
message = err . message ;
}
2016-03-07 11:11:08 -05:00
if ( clientId !== - 1 ) {
2016-05-03 11:00:06 -04:00
const draft = PostStore . getDraft ( channelId ) ;
2015-08-10 13:15:01 -04:00
2015-08-31 11:31:55 -04:00
const index = draft . uploadsInProgress . indexOf ( clientId ) ;
2015-08-13 15:44:38 -07:00
if ( index !== - 1 ) {
2015-08-31 11:31:55 -04:00
draft . uploadsInProgress . splice ( index , 1 ) ;
2015-08-13 15:44:38 -07:00
}
2015-08-10 13:15:01 -04:00
2016-05-03 11:00:06 -04:00
PostStore . storeDraft ( channelId , draft ) ;
2015-08-10 13:15:01 -04:00
2016-05-03 11:00:06 -04:00
if ( channelId === this . state . channelId ) {
this . setState ( { uploadsInProgress : draft . uploadsInProgress } ) ;
}
2015-08-13 15:44:38 -07:00
}
2016-03-07 11:11:08 -05:00
this . setState ( { serverError : message } ) ;
2015-08-31 11:31:55 -04:00
}
removePreview ( id ) {
2015-09-25 11:41:08 -04:00
const previews = Object . assign ( [ ] , this . state . previews ) ;
const uploadsInProgress = this . state . uploadsInProgress ;
2015-08-10 08:41:18 -04:00
2015-08-10 12:05:45 -04:00
// id can either be the path of an uploaded file or the client id of an in progress upload
2015-08-31 11:31:55 -04:00
let index = previews . indexOf ( id ) ;
2015-10-05 09:58:42 -04:00
if ( index === - 1 ) {
2015-08-10 12:05:45 -04:00
index = uploadsInProgress . indexOf ( id ) ;
2015-08-10 08:41:18 -04:00
if ( index !== - 1 ) {
uploadsInProgress . splice ( index , 1 ) ;
2016-02-17 14:32:25 -05:00
this . refs . fileUpload . getWrappedInstance ( ) . cancelUpload ( id ) ;
2015-06-14 23:53:32 -08:00
}
2015-10-05 09:58:42 -04:00
} else {
previews . splice ( index , 1 ) ;
2015-06-14 23:53:32 -08:00
}
2015-08-10 08:41:18 -04:00
2015-09-25 11:41:08 -04:00
const draft = PostStore . getCurrentDraft ( ) ;
2015-08-31 11:31:55 -04:00
draft . previews = previews ;
draft . uploadsInProgress = uploadsInProgress ;
2015-06-14 23:53:32 -08:00
PostStore . storeCurrentDraft ( draft ) ;
2015-08-10 08:41:18 -04:00
2015-09-25 11:41:08 -04:00
this . setState ( { previews , uploadsInProgress } ) ;
2015-08-31 11:31:55 -04:00
}
2015-12-15 11:47:52 -05:00
componentWillMount ( ) {
const tutorialStep = PreferenceStore . getInt ( Preferences . TUTORIAL _STEP , UserStore . getCurrentId ( ) , 999 ) ;
// wait to load these since they may have changed since the component was constructed (particularly in the case of skipping the tutorial)
this . setState ( {
2016-04-21 09:56:11 -04:00
ctrlSend : PreferenceStore . getBool ( Preferences . CATEGORY _ADVANCED _SETTINGS , 'send_on_ctrl_enter' ) ,
centerTextbox : PreferenceStore . get ( Preferences . CATEGORY _DISPLAY _SETTINGS , Preferences . CHANNEL _DISPLAY _MODE , Preferences . CHANNEL _DISPLAY _MODE _DEFAULT ) === Preferences . CHANNEL _DISPLAY _MODE _CENTERED ,
2015-12-15 11:47:52 -05:00
showTutorialTip : tutorialStep === TutorialSteps . POST _POPOVER
} ) ;
}
2015-08-31 11:31:55 -04:00
componentDidMount ( ) {
ChannelStore . addChangeListener ( this . onChange ) ;
2015-10-30 11:35:16 -04:00
PreferenceStore . addChangeListener ( this . onPreferenceChange ) ;
2016-02-05 12:22:39 -05:00
this . focusTextbox ( ) ;
2016-06-02 15:43:00 -07:00
document . addEventListener ( 'keydown' , this . showShortcuts ) ;
2016-02-04 11:05:59 -05:00
}
componentDidUpdate ( prevProps , prevState ) {
if ( prevState . channelId !== this . state . channelId ) {
2016-02-05 12:22:39 -05:00
this . focusTextbox ( ) ;
2016-02-04 11:05:59 -05:00
}
2015-08-31 11:31:55 -04:00
}
componentWillUnmount ( ) {
ChannelStore . removeChangeListener ( this . onChange ) ;
2015-10-30 11:35:16 -04:00
PreferenceStore . removeChangeListener ( this . onPreferenceChange ) ;
2016-06-02 15:43:00 -07:00
document . removeEventListener ( 'keydown' , this . showShortcuts ) ;
}
showShortcuts ( e ) {
if ( ( e . ctrlKey || e . metaKey ) && e . keyCode === Constants . KeyCodes . FORWARD _SLASH ) {
e . preventDefault ( ) ;
ChannelActions . executeCommand (
this . state . channelId ,
'/shortcuts ' ,
false ,
null ,
( err ) => {
this . setState ( {
serverError : err . message ,
submitting : false
} ) ;
}
) ;
}
2015-08-31 11:31:55 -04:00
}
onChange ( ) {
const channelId = ChannelStore . getCurrentId ( ) ;
2015-08-10 14:01:11 -04:00
if ( this . state . channelId !== channelId ) {
2015-09-22 16:00:44 -07:00
const draft = this . getCurrentDraft ( ) ;
2015-07-23 12:45:08 -04:00
2015-09-25 11:41:08 -04:00
this . setState ( { channelId , messageText : draft . messageText , initialText : draft . messageText , submitting : false , serverError : null , postError : null , previews : draft . previews , uploadsInProgress : draft . uploadsInProgress } ) ;
2015-06-14 23:53:32 -08:00
}
2015-08-31 11:31:55 -04:00
}
2015-10-30 11:35:16 -04:00
onPreferenceChange ( ) {
2015-12-15 11:36:14 -05:00
const tutorialStep = PreferenceStore . getInt ( Preferences . TUTORIAL _STEP , UserStore . getCurrentId ( ) , 999 ) ;
2015-10-30 11:35:16 -04:00
this . setState ( {
2015-12-15 11:36:14 -05:00
showTutorialTip : tutorialStep === TutorialSteps . POST _POPOVER ,
2016-04-21 09:56:11 -04:00
ctrlSend : PreferenceStore . getBool ( Preferences . CATEGORY _ADVANCED _SETTINGS , 'send_on_ctrl_enter' ) ,
centerTextbox : PreferenceStore . get ( Preferences . CATEGORY _DISPLAY _SETTINGS , Preferences . CHANNEL _DISPLAY _MODE , Preferences . CHANNEL _DISPLAY _MODE _DEFAULT ) === Preferences . CHANNEL _DISPLAY _MODE _CENTERED
2015-10-30 11:35:16 -04:00
} ) ;
}
2015-08-31 11:31:55 -04:00
getFileCount ( channelId ) {
2015-08-10 14:01:11 -04:00
if ( channelId === this . state . channelId ) {
2015-08-07 16:24:13 -04:00
return this . state . previews . length + this . state . uploadsInProgress . length ;
2015-06-14 23:53:32 -08:00
}
2015-08-31 11:31:55 -04:00
const draft = PostStore . getDraft ( channelId ) ;
return draft . previews . length + draft . uploadsInProgress . length ;
}
2015-10-26 22:05:26 +01:00
handleKeyDown ( e ) {
2015-12-15 11:36:14 -05:00
if ( this . state . ctrlSend && e . keyCode === KeyCodes . ENTER && e . ctrlKey === true ) {
2015-10-26 22:05:26 +01:00
this . postMsgKeyPress ( e ) ;
return ;
}
2016-05-16 19:08:59 -04:00
if ( ! e . ctrlKey && ! e . metaKey && ! e . altKey && ! e . shiftKey && e . keyCode === KeyCodes . UP && this . state . messageText === '' ) {
2015-10-15 02:13:48 +02:00
e . preventDefault ( ) ;
const channelId = ChannelStore . getCurrentId ( ) ;
const lastPost = PostStore . getCurrentUsersLatestPost ( channelId ) ;
2015-10-15 21:22:08 +02:00
if ( ! lastPost ) {
return ;
}
2016-02-03 00:46:56 -03:00
const { formatMessage } = this . props . intl ;
var type = ( lastPost . root _id && lastPost . root _id . length > 0 ) ? formatMessage ( holders . comment ) : formatMessage ( holders . post ) ;
2015-10-15 02:13:48 +02:00
AppDispatcher . handleViewAction ( {
2016-02-08 10:33:59 -05:00
type : ActionTypes . RECEIVED _EDIT _POST ,
2015-10-15 21:22:08 +02:00
refocusId : '#post_textbox' ,
2015-10-15 02:13:48 +02:00
title : type ,
message : lastPost . message ,
2015-10-15 21:22:08 +02:00
postId : lastPost . id ,
2015-11-13 12:20:33 -05:00
channelId : lastPost . channel _id ,
comments : PostStore . getCommentCount ( lastPost )
2015-10-15 02:13:48 +02:00
} ) ;
}
2016-05-12 07:48:29 -04:00
2016-05-16 19:08:59 -04:00
if ( ( e . ctrlKey || e . metaKey ) && ! e . altKey && ! e . shiftKey && e . keyCode === KeyCodes . UP ) {
2016-05-12 07:48:29 -04:00
const channelId = ChannelStore . getCurrentId ( ) ;
const lastPost = PostStore . getCurrentUsersLatestPost ( channelId ) ;
2016-05-30 07:00:20 -07:00
if ( ! lastPost || this . state . messageText !== '' ) {
2016-05-12 07:48:29 -04:00
return ;
}
2016-05-30 07:00:20 -07:00
e . preventDefault ( ) ;
2016-05-12 07:48:29 -04:00
let message = lastPost . message ;
if ( this . state . lastMessage !== '' ) {
message = this . state . lastMessage ;
}
this . setState ( { messageText : message } ) ;
}
2015-10-15 02:13:48 +02:00
}
2016-02-18 10:31:44 -05:00
showPostDeletedModal ( ) {
this . setState ( {
showPostDeletedModal : true
} ) ;
}
hidePostDeletedModal ( ) {
this . setState ( {
showPostDeletedModal : false
} ) ;
}
2015-10-30 11:35:16 -04:00
createTutorialTip ( ) {
const screens = [ ] ;
screens . push (
< div >
2016-02-03 00:46:56 -03:00
< FormattedHTMLMessage
id = 'create_post.tutorialTip'
defaultMessage = '<h4>Sending Messages</h4><p>Type here to write a message and press <strong>Enter</strong> to post it.</p><p>Click the <strong>Attachment</strong> button to upload an image or a file.</p>'
/ >
2015-10-30 11:35:16 -04:00
< / div >
) ;
return (
< TutorialTip
placement = 'top'
screens = { screens }
2015-11-02 09:21:08 -05:00
overlayClass = 'tip-overlay--chat'
2015-10-30 11:35:16 -04:00
/ >
) ;
}
2015-08-31 11:31:55 -04:00
render ( ) {
let serverError = null ;
2015-08-10 14:01:11 -04:00
if ( this . state . serverError ) {
serverError = (
< div className = 'has-error' >
< label className = 'control-label' > { this . state . serverError } < / label >
< / div >
) ;
}
2015-06-14 23:53:32 -08:00
2015-08-31 11:31:55 -04:00
let postError = null ;
2015-08-10 14:01:11 -04:00
if ( this . state . postError ) {
postError = < label className = 'control-label' > { this . state . postError } < / label > ;
}
2015-08-31 11:31:55 -04:00
let preview = null ;
2015-08-07 16:24:13 -04:00
if ( this . state . previews . length > 0 || this . state . uploadsInProgress . length > 0 ) {
2015-06-14 23:53:32 -08:00
preview = (
< FilePreview
files = { this . state . previews }
onRemove = { this . removePreview }
2015-09-03 10:49:36 -04:00
uploadsInProgress = { this . state . uploadsInProgress }
/ >
2015-06-14 23:53:32 -08:00
) ;
}
2015-08-31 11:31:55 -04:00
let postFooterClassName = 'post-create-footer' ;
2015-08-10 14:01:11 -04:00
if ( postError ) {
postFooterClassName += ' has-error' ;
}
2015-10-30 11:35:16 -04:00
let tutorialTip = null ;
if ( this . state . showTutorialTip ) {
tutorialTip = this . createTutorialTip ( ) ;
}
2016-04-21 09:56:11 -04:00
let centerClass = '' ;
if ( this . state . centerTextbox ) {
centerClass = 'center' ;
}
2015-06-14 23:53:32 -08:00
return (
2015-08-31 11:31:55 -04:00
< form
id = 'create_post'
ref = 'topDiv'
role = 'form'
2016-04-21 09:56:11 -04:00
className = { centerClass }
2015-08-31 11:31:55 -04:00
onSubmit = { this . handleSubmit }
>
2015-08-10 14:01:11 -04:00
< div className = 'post-create' >
< div className = 'post-create-body' >
2015-09-08 15:47:15 -04:00
< div className = 'post-body__cell' >
< Textbox
onUserInput = { this . handleUserInput }
onKeyPress = { this . postMsgKeyPress }
2015-10-26 22:05:26 +01:00
onKeyDown = { this . handleKeyDown }
2015-09-08 15:47:15 -04:00
messageText = { this . state . messageText }
2016-02-03 00:46:56 -03:00
createMessage = { this . props . intl . formatMessage ( holders . write ) }
2015-09-08 15:47:15 -04:00
channelId = { this . state . channelId }
id = 'post_textbox'
ref = 'textbox'
/ >
< FileUpload
ref = 'fileUpload'
getFileCount = { this . getFileCount }
2016-02-04 11:05:59 -05:00
onClick = { this . handleUploadClick }
2015-09-08 15:47:15 -04:00
onUploadStart = { this . handleUploadStart }
onFileUpload = { this . handleFileUploadComplete }
onUploadError = { this . handleUploadError }
postType = 'post'
channelId = ''
/ >
< / div >
< a
className = 'send-button theme'
onClick = { this . handleSubmit }
>
2016-02-22 08:31:10 -05:00
< i className = 'fa fa-paper-plane' / >
2015-09-08 15:47:15 -04:00
< / a >
2015-10-30 11:35:16 -04:00
{ tutorialTip }
2015-06-14 23:53:32 -08:00
< / div >
2015-08-10 14:01:11 -04:00
< div className = { postFooterClassName } >
2015-08-31 11:31:55 -04:00
< MsgTyping
channelId = { this . state . channelId }
parentId = ''
/ >
2015-12-08 22:42:59 +05:00
{ preview }
{ postError }
{ serverError }
2015-06-14 23:53:32 -08:00
< / div >
< / div >
2016-02-18 10:31:44 -05:00
< PostDeletedModal
show = { this . state . showPostDeletedModal }
onHide = { this . hidePostDeletedModal }
/ >
2015-06-14 23:53:32 -08:00
< / form >
) ;
}
2015-08-31 11:31:55 -04:00
}
2016-02-03 00:46:56 -03:00
CreatePost . propTypes = {
intl : intlShape . isRequired
} ;
2016-02-02 15:34:22 -05:00
export default injectIntl ( CreatePost ) ;