mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-04 11:44:47 +08:00
fix(bodies): Move loading into component, add retry, loading spinner
This commit is contained in:
parent
a53f2ade75
commit
7a31da9fc9
4 changed files with 58 additions and 43 deletions
|
@ -2,11 +2,12 @@ React = require 'react'
|
|||
_ = require 'underscore'
|
||||
EmailFrame = require './email-frame'
|
||||
{Utils,
|
||||
NylasAPI,
|
||||
MessageUtils,
|
||||
MessageBodyProcessor,
|
||||
QuotedHTMLTransformer,
|
||||
FileDownloadStore} = require 'nylas-exports'
|
||||
{InjectedComponentSet} = require 'nylas-component-kit'
|
||||
{InjectedComponentSet, RetinaImg} = require 'nylas-component-kit'
|
||||
|
||||
TransparentPixel = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNikAQAACIAHF/uBd8AAAAASUVORK5CYII="
|
||||
|
||||
|
@ -17,19 +18,25 @@ class MessageItemBody extends React.Component
|
|||
downloads: React.PropTypes.object.isRequired
|
||||
|
||||
constructor: (@props) ->
|
||||
@_unmounted = false
|
||||
@state =
|
||||
showQuotedText: Utils.isForwardedMessage(@props.message)
|
||||
processedBody: undefined
|
||||
processedBody: null
|
||||
error: null
|
||||
|
||||
componentWillMount: =>
|
||||
@_unsub = MessageBodyProcessor.processAndSubscribe(@props.message, @_onBodyChanged)
|
||||
@_unsub = MessageBodyProcessor.subscribe(@props.message, @_onBodyProcessed)
|
||||
|
||||
componentDidMount: =>
|
||||
@_onFetchBody() if not _.isString(@props.message.body)
|
||||
|
||||
componentWillReceiveProps: (nextProps) ->
|
||||
if nextProps.message.id isnt @props.message.id
|
||||
@_unsub?()
|
||||
@_unsub = MessageBodyProcessor.processAndSubscribe(nextProps.message, @_onBodyChanged)
|
||||
@_unsub = MessageBodyProcessor.subscribe(nextProps.message, @_onBodyProcessed)
|
||||
|
||||
componentWillUnmount: =>
|
||||
@_unmounted = true
|
||||
@_unsub?()
|
||||
|
||||
render: =>
|
||||
|
@ -44,8 +51,20 @@ class MessageItemBody extends React.Component
|
|||
</span>
|
||||
|
||||
_renderBody: =>
|
||||
return null unless @state.processedBody?
|
||||
<EmailFrame showQuotedText={@state.showQuotedText} content={@state.processedBody}/>
|
||||
if _.isString(@props.message.body) and @state.processedBody
|
||||
<EmailFrame showQuotedText={@state.showQuotedText} content={@state.processedBody}/>
|
||||
else if @state.error
|
||||
<div className="message-body-error">
|
||||
Sorry, this message could not be loaded. (Status code {@state.error.statusCode})
|
||||
<a onClick={@_onFetchBody}>Try Again</a>
|
||||
</div>
|
||||
else
|
||||
<div className="message-body-loading">
|
||||
<RetinaImg
|
||||
name="inline-loading-spinner.gif"
|
||||
mode={RetinaImg.Mode.ContentDark}
|
||||
style={{width: 14, height: 14}}/>
|
||||
</div>
|
||||
|
||||
_renderQuotedTextControl: =>
|
||||
return null unless QuotedHTMLTransformer.hasQuotedHTML(@props.message.body)
|
||||
|
@ -58,7 +77,21 @@ class MessageItemBody extends React.Component
|
|||
@setState
|
||||
showQuotedText: !@state.showQuotedText
|
||||
|
||||
_onBodyChanged: (body) =>
|
||||
_onFetchBody: =>
|
||||
NylasAPI.makeRequest
|
||||
path: "/messages/#{@props.message.id}"
|
||||
accountId: @props.message.accountId
|
||||
returnsModel: true
|
||||
.then =>
|
||||
return if @_unmounted
|
||||
@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 if @_unmounted
|
||||
@setState({error})
|
||||
|
||||
_onBodyProcessed: (body) =>
|
||||
downloadingSpinnerPath = Utils.imageNamed('inline-loading-spinner.gif')
|
||||
|
||||
# Replace cid:// references with the paths to downloaded files
|
||||
|
|
|
@ -150,6 +150,23 @@ body.platform-win32 {
|
|||
a { float: right; }
|
||||
}
|
||||
|
||||
.message-body-error {
|
||||
background-color: @background-secondary;
|
||||
border: 1px solid darken(@background-secondary, 8%);
|
||||
color: @text-color-very-subtle;
|
||||
margin-top: @padding-large-vertical;
|
||||
cursor: default;
|
||||
padding: @padding-base-vertical @padding-base-horizontal;
|
||||
a { float: right; }
|
||||
}
|
||||
|
||||
.message-body-loading {
|
||||
height: 1em;
|
||||
align-content: center;
|
||||
margin-top: @padding-large-vertical;
|
||||
margin-bottom: @padding-large-vertical;
|
||||
}
|
||||
|
||||
.message-subject-wrap {
|
||||
width: calc(~"100% - 12px");
|
||||
max-width: @message-max-width;
|
||||
|
|
|
@ -135,7 +135,6 @@ describe "MessageStore", ->
|
|||
describe "when toggling expansion of all messages", ->
|
||||
beforeEach ->
|
||||
MessageStore._items = [testMessage1, testMessage2, testMessage3]
|
||||
spyOn(MessageStore, '_fetchExpandedBodies')
|
||||
spyOn(MessageStore, '_fetchExpandedAttachments')
|
||||
|
||||
it 'should expand all when at default state', ->
|
||||
|
|
|
@ -4,7 +4,6 @@ Message = require "../models/message"
|
|||
Thread = require "../models/thread"
|
||||
Utils = require '../models/utils'
|
||||
DatabaseStore = require "./database-store"
|
||||
AccountStore = require "./account-store"
|
||||
FocusedPerspectiveStore = require './focused-perspective-store'
|
||||
FocusedContentStore = require "./focused-content-store"
|
||||
ChangeUnreadTask = require '../tasks/change-unread-task'
|
||||
|
@ -96,7 +95,6 @@ class MessageStore extends NylasStore
|
|||
@_itemsLoading = false
|
||||
@_showingHiddenItems = false
|
||||
@_thread = null
|
||||
@_inflight = {}
|
||||
|
||||
_registerListeners: ->
|
||||
@listenTo ExtensionRegistry.MessageView, @_onExtensionsChanged
|
||||
|
@ -212,7 +210,6 @@ class MessageStore extends NylasStore
|
|||
_onToggleHiddenMessages: =>
|
||||
@_showingHiddenItems = !@_showingHiddenItems
|
||||
@_expandItemsToDefault()
|
||||
@_fetchExpandedBodies(@_items)
|
||||
@_fetchExpandedAttachments(@_items)
|
||||
@trigger()
|
||||
|
||||
|
@ -228,7 +225,6 @@ class MessageStore extends NylasStore
|
|||
|
||||
_expandItem: (item) =>
|
||||
@_itemsExpanded[item.id] = "explicit"
|
||||
@_fetchExpandedBodies([item])
|
||||
@_fetchExpandedAttachments([item])
|
||||
|
||||
_collapseItem: (item) =>
|
||||
|
@ -262,12 +258,6 @@ class MessageStore extends NylasStore
|
|||
# Download the attachments on expanded messages.
|
||||
@_fetchExpandedAttachments(@_items)
|
||||
|
||||
# Check that expanded messages have bodies. We won't mark ourselves
|
||||
# as loaded until they're all available. Note that items can be manually
|
||||
# expanded so this logic must be separate from above.
|
||||
if @_fetchExpandedBodies(@_items)
|
||||
loaded = false
|
||||
|
||||
# Normally, we would trigger often and let the view's
|
||||
# shouldComponentUpdate decide whether to re-render, but if we
|
||||
# know we're not ready, don't even bother. Trigger once at start
|
||||
|
@ -278,15 +268,6 @@ class MessageStore extends NylasStore
|
|||
@_markAsRead()
|
||||
@trigger(@)
|
||||
|
||||
_fetchExpandedBodies: (items) ->
|
||||
startedAFetch = false
|
||||
for item in items
|
||||
continue unless @_itemsExpanded[item.id]
|
||||
if not _.isString(item.body)
|
||||
@_fetchMessageIdFromAPI(item.id)
|
||||
startedAFetch = true
|
||||
startedAFetch
|
||||
|
||||
_fetchExpandedAttachments: (items) ->
|
||||
policy = NylasEnv.config.get('core.attachments.downloadPolicy')
|
||||
return if policy is 'manually'
|
||||
|
@ -304,22 +285,7 @@ class MessageStore extends NylasStore
|
|||
@_itemsExpanded[item.id] = "default"
|
||||
|
||||
_fetchMessages: ->
|
||||
account = AccountStore.accountForId(@_thread.accountId)
|
||||
NylasAPI.getCollection account.id, 'messages', {thread_id: @_thread.id}
|
||||
|
||||
_fetchMessageIdFromAPI: (id) ->
|
||||
return if @_inflight[id]
|
||||
|
||||
@_inflight[id] = true
|
||||
account = AccountStore.accountForId(@_thread.accountId)
|
||||
NylasAPI.makeRequest
|
||||
path: "/messages/#{id}"
|
||||
accountId: account.id
|
||||
returnsModel: true
|
||||
success: =>
|
||||
delete @_inflight[id]
|
||||
error: =>
|
||||
delete @_inflight[id]
|
||||
NylasAPI.getCollection(@_thread.accountId, 'messages', {thread_id: @_thread.id})
|
||||
|
||||
_sortItemsForDisplay: (items) ->
|
||||
# Re-sort items in the list so that drafts appear after the message that
|
||||
|
|
Loading…
Add table
Reference in a new issue