React = require 'react'
_ = require 'underscore-plus'
{Actions,
FileUploadStore,
ComponentRegistry} = require 'inbox-exports'
FileUploads = require './file-uploads.cjsx'
DraftStoreProxy = require './draft-store-proxy'
ContenteditableToolbar = require './contenteditable-toolbar.cjsx'
ContenteditableComponent = require './contenteditable-component.cjsx'
ParticipantsTextField = require './participants-text-field.cjsx'
# The ComposerView is a unique React component because it (currently) is a
# singleton. Normally, the React way to do things would be to re-render the
# Composer with new props. As an alternative, we can call `setProps` to
# simulate the effect of the parent re-rendering us
module.exports =
ComposerView = React.createClass
getInitialState: ->
# A majority of the initial state is set in `_setInitialState` because
# those getters are asynchronous while `getInitialState` is
# synchronous.
state = @getComponentRegistryState()
_.extend state,
populated: false
to: undefined
cc: undefined
bcc: undefined
body: undefined
subject: undefined
state
getComponentRegistryState: ->
ResizableComponent: ComponentRegistry.findViewByName 'ResizableComponent'
MessageAttachment: ComponentRegistry.findViewByName 'MessageAttachment'
FooterComponents: ComponentRegistry.findAllViewsByRole 'Composer:Footer'
componentWillMount: ->
@_prepareForDraft()
componentWillUnmount: ->
@_teardownForDraft()
componentWillReceiveProps: (newProps) ->
if newProps.localId != @props.localId
# When we're given a new draft localId, we have to stop listening to our
# current DraftStoreProxy, create a new one and listen to that. The simplest
# way to do this is to just re-call registerListeners.
@_teardownForDraft()
@_prepareForDraft()
_prepareForDraft: ->
@_proxy = new DraftStoreProxy(@props.localId)
@unlisteners = []
@unlisteners.push @_proxy.listen(@_onDraftChanged)
@unlisteners.push ComponentRegistry.listen (event) =>
@setState(@getComponentRegistryState())
_teardownForDraft: ->
unlisten() for unlisten in @unlisteners
@_proxy.changes.commit()
render: ->
ResizableComponent = @state.ResizableComponent
if @props.mode is "inline" and ResizableComponent?
{@_renderComposer()}
else
{@_renderComposer()}
_wrapClasses: ->
"composer-outer-wrap #{@props.containerClass ? ""}"
_renderComposer: ->
# Do not render the composer unless we have loaded our draft.
# Otherwise the Scribe component is initialized with HTML = ""
return if @state.body == undefined