React = require 'react' ReactDOM = require 'react-dom' classNames = require 'classnames' _ = require 'underscore' MessageParticipants = require "./message-participants" MessageItemBody = require "./message-item-body" MessageTimestamp = require("./message-timestamp").default MessageControls = require './message-controls' {Utils, Actions, MessageUtils, AccountStore, MessageBodyProcessor, QuotedHTMLTransformer, ComponentRegistry, FileDownloadStore} = require 'nylas-exports' {RetinaImg, InjectedComponentSet, InjectedComponent} = require 'nylas-component-kit' TransparentPixel = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNikAQAACIAHF/uBd8AAAAASUVORK5CYII=" class MessageItem extends React.Component @displayName = 'MessageItem' @propTypes = thread: React.PropTypes.object.isRequired message: React.PropTypes.object.isRequired messages: React.PropTypes.array.isRequired collapsed: React.PropTypes.bool onLoad: React.PropTypes.func constructor: (@props) -> fileIds = @props.message.fileIds() @state = # Holds the downloadData (if any) for all of our files. It's a hash # keyed by a fileId. The value is the downloadData. downloads: FileDownloadStore.getDownloadDataForFiles(fileIds) filePreviewPaths: FileDownloadStore.previewPathsForFiles(fileIds) detailedHeaders: false detailedHeadersTogglePos: {top: 18} componentDidMount: => @_storeUnlisten = FileDownloadStore.listen(@_onDownloadStoreChange) @_setDetailedHeadersTogglePos() componentDidUpdate: => @_setDetailedHeadersTogglePos() componentWillUnmount: => @_storeUnlisten() if @_storeUnlisten shouldComponentUpdate: (nextProps, nextState) => not Utils.isEqualReact(nextProps, @props) or not Utils.isEqualReact(nextState, @state) render: => if @props.collapsed @_renderCollapsed() else @_renderFull() _renderCollapsed: => attachmentIcon = [] if Utils.showIconForAttachments(@props.message.files) attachmentIcon =
{@props.message.from?[0]?.displayName(compact: true)}
{@props.message.snippet}
{attachmentIcon}
_renderFull: =>
{@_renderHeader()} {@_renderAttachments()} {@_renderFooterStatus()}
_renderHeader: => classes = classNames "message-header": true "pending": @props.pending
{@_renderFolder()} {@_renderHeaderDetailToggle()}
_renderFolder: => return [] unless @state.detailedHeaders acct = AccountStore.accountForId(@props.message.accountId) acctUsesFolders = acct and acct.usesFolders() folder = @props.message.categories?[0] return unless folder and acctUsesFolders
Folder: 
{folder.displayName}
_onClickParticipants: (e) => el = e.target while el isnt e.currentTarget if "collapsed-participants" in el.classList @setState(detailedHeaders: true) e.stopPropagation() return el = el.parentElement return _onClickHeader: (e) => return if @state.detailedHeaders el = e.target while el isnt e.currentTarget wl = ["message-header-right", "collapsed-participants", "header-toggle-control"] if "message-header-right" in el.classList then return if "collapsed-participants" in el.classList then return el = el.parentElement @_toggleCollapsed() _onDownloadAll: => Actions.fetchAndSaveAllFiles(@props.message.files) _renderDownloadAllButton: =>
{@props.message.files.length} attachments
-
Download all
_renderAttachments: => files = (@props.message.files ? []).filter((f) => @_isRealFile(f)) messageClientId = @props.message.clientId {filePreviewPaths, downloads} = @state if files.length > 0
{if files.length > 1 then @_renderDownloadAllButton()}
else
_renderFooterStatus: => _setDetailedHeadersTogglePos: => header = ReactDOM.findDOMNode(@refs.header) if !header return fromNode = header.querySelector('.participant-name.from-contact,.participant-primary') if !fromNode return fromRect = fromNode.getBoundingClientRect() topPos = Math.floor(fromNode.offsetTop + (fromRect.height / 2) - 10) if topPos isnt @state.detailedHeadersTogglePos.top @setState({detailedHeadersTogglePos: {top: topPos}}) _renderHeaderDetailToggle: => return null if @props.pending {top} = @state.detailedHeadersTogglePos if @state.detailedHeaders
@setState(detailedHeaders: false); e.stopPropagation()} >
else
@setState(detailedHeaders: true); e.stopPropagation()} >
_toggleCollapsed: => return if @props.isLastMsg Actions.toggleMessageIdExpanded(@props.message.id) _isRealFile: (file) -> hasCIDInBody = file.contentId? and @props.message.body?.indexOf(file.contentId) > 0 return not hasCIDInBody _onDownloadStoreChange: => fileIds = @props.message.fileIds() @setState downloads: FileDownloadStore.getDownloadDataForFiles(fileIds) filePreviewPaths: FileDownloadStore.previewPathsForFiles(fileIds) module.exports = MessageItem