React = require 'react' _ = require 'underscore' EmailFrame = require('./email-frame').default {encodedAttributeForFile} = require('./inline-download-prompts') { DraftHelpers, CanvasUtils, NylasAPI, NylasAPIRequest, MessageUtils, MessageBodyProcessor, QuotedHTMLTransformer, FileDownloadStore } = require 'nylas-exports' { InjectedComponentSet, RetinaImg } = require 'nylas-component-kit' TransparentPixel = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNikAQAACIAHF/uBd8AAAAASUVORK5CYII=" class MessageItemBody extends React.Component @displayName: 'MessageItemBody' @propTypes: message: React.PropTypes.object.isRequired downloads: React.PropTypes.object.isRequired constructor: (@props) -> @_mounted = false @state = showQuotedText: DraftHelpers.isForwardedMessage(@props.message) processedBody: null error: null componentWillMount: => @_unsub = MessageBodyProcessor.subscribe @props.message, (processedBody) => @setState({processedBody}) componentDidMount: => @_mounted = true @_onFetchBody() if not _.isString(@props.message.body) componentWillReceiveProps: (nextProps) -> if nextProps.message.id isnt @props.message.id @_unsub?() @_unsub = MessageBodyProcessor.subscribe nextProps.message, (processedBody) => @setState({processedBody}) componentWillUnmount: => @_mounted = false @_unsub?() render: => {@_renderBody()} {@_renderQuotedTextControl()} _renderBody: => if _.isString(@props.message.body) and _.isString(@state.processedBody) else if @state.error
Sorry, this message could not be loaded. (Status code {@state.error.statusCode}) Try Again
else
_renderQuotedTextControl: => return null unless QuotedHTMLTransformer.hasQuotedHTML(@props.message.body) ••• _toggleQuotedText: => @setState showQuotedText: !@state.showQuotedText _onFetchBody: => request = new NylasAPIRequest api: NylasAPI options: path: "/messages/#{@props.message.id}" accountId: @props.message.accountId returnsModel: true request.run() .then => return unless @_mounted @setState({error: null}) # message will be put into the database and the MessageBodyProcessor # will provide us with the new body once it's been processed. .catch (error) => return unless @_mounted @setState({error}) _mergeBodyWithFiles: (body) => # Replace cid: references with the paths to downloaded files for file in @props.message.files download = @props.downloads[file.id] # Note: I don't like doing this with RegExp before the body is inserted into # the DOM, but we want to avoid "could not load cid://" in the console. if download and download.state isnt 'finished' inlineImgRegexp = new RegExp("<\s*img.*src=['\"]cid:#{file.contentId}['\"][^>]*>", 'gi') # Render a spinner body = body.replace inlineImgRegexp, => 'spinner.gif' else # Render the completed download. We include data-nylas-file so that if the image fails # to load, we can parse the file out and call `Actions.fetchFile` to retrieve it. # (Necessary when attachment download mode is set to "manual") cidRegexp = new RegExp("cid:#{file.contentId}(['\"])", 'gi') body = body.replace cidRegexp, (text, quoteCharacter) -> "file://#{FileDownloadStore.pathForFile(file)}#{quoteCharacter} data-nylas-file=\"#{encodedAttributeForFile(file)}\" " # Replace remaining cid: references - we will not display them since they'll # throw "unknown ERR_UNKNOWN_URL_SCHEME". Show a transparent pixel so that there's # no "missing image" region shown, just a space. body = body.replace(MessageUtils.cidRegex, "src=\"#{TransparentPixel}\"") return body module.exports = MessageItemBody