mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-27 10:28:31 +08:00
feat(composer): popout only closes when message sending succeeds
Summary: This is a WIP to fix the blatant case of messages dissapearing when there's an error. It's pending a better through through notification UI Test Plan: edgehill --test Reviewers: bengotow Reviewed By: bengotow Differential Revision: https://review.inboxapp.com/D1270
This commit is contained in:
parent
2189f4f2b7
commit
6ec84561c4
6 changed files with 41 additions and 11 deletions
|
@ -47,6 +47,8 @@ NotificationStore = Reflux.createStore
|
|||
@_removeNotification(notification)()
|
||||
@listenTo Actions.postNotification, (data) =>
|
||||
@_postNotification(new Notification(data))
|
||||
@listenTo Actions.multiWindowNotification, (data={}, context={}) =>
|
||||
@_postNotification(new Notification(data)) if @_inWindowContext(context)
|
||||
|
||||
######### PUBLIC #######################################################
|
||||
|
||||
|
@ -82,3 +84,8 @@ NotificationStore = Reflux.createStore
|
|||
console.log "Removed #{notification}" if VERBOSE
|
||||
delete @_notifications[notification.id]
|
||||
@trigger()
|
||||
|
||||
# If the window matches the given context then we can show a
|
||||
# notification.
|
||||
_inWindowContext: (context={}) ->
|
||||
return true
|
||||
|
|
|
@ -465,7 +465,7 @@ class AtomApplication
|
|||
if parts.protocol is 'mailto:'
|
||||
query = qs.parse(parts.query)
|
||||
query.to = "#{parts.auth}@#{parts.host}"
|
||||
|
||||
|
||||
json = {
|
||||
subject: query.subject || '',
|
||||
body: query.body || '',
|
||||
|
|
|
@ -16,7 +16,15 @@ globalActions = [
|
|||
"uploadStateChanged",
|
||||
"fileAborted",
|
||||
"downloadStateChanged",
|
||||
"fileUploaded"
|
||||
"fileUploaded",
|
||||
|
||||
"multiWindowNotification",
|
||||
|
||||
# Draft actions
|
||||
"sendDraftSuccess",
|
||||
"sendDraftError",
|
||||
"destroyDraftSuccess",
|
||||
"destroyDraftError"
|
||||
]
|
||||
|
||||
# These actions are rebroadcast through the ActionBridge to the
|
||||
|
@ -71,7 +79,7 @@ windowActions = [
|
|||
# Notification actions
|
||||
"postNotification",
|
||||
"notificationActionTaken",
|
||||
|
||||
|
||||
# FullContact Sidebar
|
||||
"getFullContactDetails",
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ DraftStore = Reflux.createStore
|
|||
@listenTo Actions.removeFile, @_onRemoveFile
|
||||
@listenTo Actions.attachFileComplete, @_onAttachFileComplete
|
||||
|
||||
@listenTo Actions.sendDraftSuccess, @_closeWindow
|
||||
@listenTo Actions.destroyDraftSuccess, @_closeWindow
|
||||
@_drafts = []
|
||||
@_draftSessions = {}
|
||||
|
||||
|
@ -66,7 +68,7 @@ DraftStore = Reflux.createStore
|
|||
else
|
||||
# Continue closing
|
||||
return true
|
||||
|
||||
|
||||
DatabaseStore.findAll(Message, draft: true).then (drafts) =>
|
||||
@_drafts = drafts
|
||||
@trigger({})
|
||||
|
@ -154,6 +156,12 @@ DraftStore = Reflux.createStore
|
|||
|
||||
DatabaseStore.persistModel(draft)
|
||||
|
||||
# We only want to close the popout window if we're sure various draft
|
||||
# actions succeeded.
|
||||
_closeWindow: (draftLocalId) ->
|
||||
if atom.state.mode is "composer" and @_draftSessions[draftLocalId]?
|
||||
atom.close()
|
||||
|
||||
# The logic to create a new Draft used to be in the DraftStore (which is
|
||||
# where it should be). It got moved to composer/lib/main.cjsx becaues
|
||||
# of an obscure atom-shell/Chrome bug whereby database requests firing right
|
||||
|
@ -173,7 +181,6 @@ DraftStore = Reflux.createStore
|
|||
|
||||
# Queue the task to destroy the draft
|
||||
Actions.queueTask(new DestroyDraftTask(draftLocalId))
|
||||
atom.close() if atom.state.mode is "composer"
|
||||
|
||||
_onSendDraft: (draftLocalId) ->
|
||||
# Immediately save any pending changes so we don't save after sending
|
||||
|
@ -181,7 +188,6 @@ DraftStore = Reflux.createStore
|
|||
save.then ->
|
||||
# Queue the task to send the draft
|
||||
Actions.queueTask(new SendDraftTask(draftLocalId))
|
||||
atom.close() if atom.state.mode is "composer"
|
||||
|
||||
_onAttachFileComplete: ({file, messageLocalId}) ->
|
||||
@sessionForLocalId(messageLocalId).prepare().then (proxy) ->
|
||||
|
|
|
@ -42,7 +42,9 @@ class DestroyDraftTask extends Task
|
|||
body:
|
||||
version: @draft.version
|
||||
returnsModel: false
|
||||
success: resolve
|
||||
success: (args...) =>
|
||||
Actions.destroyDraftSuccess(@draftLocalId)
|
||||
resolve(args...)
|
||||
error: reject
|
||||
|
||||
onAPIError: (apiError) ->
|
||||
|
@ -55,6 +57,7 @@ class DestroyDraftTask extends Task
|
|||
# do but finish
|
||||
return true
|
||||
else
|
||||
Actions.destroyDraftError(@draftLocalId)
|
||||
@_rollbackLocal()
|
||||
|
||||
onOtherError: -> Promise.resolve()
|
||||
|
|
|
@ -23,13 +23,14 @@ class SendDraftTask extends Task
|
|||
# already sent when they haven't!
|
||||
return Promise.reject("Attempt to call SendDraftTask.performLocal without @draftLocalId") unless @draftLocalId
|
||||
Actions.postNotification({message: "Sending message…", type: 'info'})
|
||||
|
||||
Promise.resolve()
|
||||
|
||||
performRemote: ->
|
||||
new Promise (resolve, reject) =>
|
||||
# Fetch the latest draft data to make sure we make the request with the most
|
||||
# recent draft version
|
||||
DatabaseStore.findByLocalId(Message, @draftLocalId).then (draft) ->
|
||||
DatabaseStore.findByLocalId(Message, @draftLocalId).then (draft) =>
|
||||
# The draft may have been deleted by another task. Nothing we can do.
|
||||
return reject(new Error("We couldn't find the saved draft.")) unless draft
|
||||
|
||||
|
@ -45,25 +46,30 @@ class SendDraftTask extends Task
|
|||
method: 'POST'
|
||||
body: body
|
||||
returnsModel: true
|
||||
success: ->
|
||||
success: =>
|
||||
atom.playSound('mail_sent.ogg')
|
||||
Actions.postNotification({message: "Sent!", type: 'success'})
|
||||
Actions.sendDraftSuccess(@draftLocalId)
|
||||
DatabaseStore.unpersistModel(draft).then(resolve)
|
||||
error: reject
|
||||
.catch(reject)
|
||||
|
||||
onAPIError: ->
|
||||
msg = "Our server is having problems. Your message has not been sent."
|
||||
onAPIError: (apiError) ->
|
||||
msg = apiError.message ? "Our server is having problems. Your message has not been sent."
|
||||
Actions.sendDraftError(@draftLocalId, msg)
|
||||
@notifyErrorMessage(msg)
|
||||
|
||||
onOtherError: ->
|
||||
msg = "We had a serious issue while sending. Your message has not been sent."
|
||||
Actions.sendDraftError(@draftLocalId, msg)
|
||||
@notifyErrorMessage(msg)
|
||||
|
||||
onTimeoutError: ->
|
||||
msg = "The server is taking an abnormally long time to respond. Your message has not been sent."
|
||||
Actions.sendDraftError(@draftLocalId, msg)
|
||||
@notifyErrorMessage(msg)
|
||||
|
||||
onOfflineError: ->
|
||||
msg = "You are offline. Your message has NOT been sent. Please send your message when you come back online."
|
||||
Actions.sendDraftError(@draftLocalId, msg)
|
||||
@notifyErrorMessage(msg)
|
||||
|
|
Loading…
Reference in a new issue