mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-28 10:57:47 +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)()
|
@_removeNotification(notification)()
|
||||||
@listenTo Actions.postNotification, (data) =>
|
@listenTo Actions.postNotification, (data) =>
|
||||||
@_postNotification(new Notification(data))
|
@_postNotification(new Notification(data))
|
||||||
|
@listenTo Actions.multiWindowNotification, (data={}, context={}) =>
|
||||||
|
@_postNotification(new Notification(data)) if @_inWindowContext(context)
|
||||||
|
|
||||||
######### PUBLIC #######################################################
|
######### PUBLIC #######################################################
|
||||||
|
|
||||||
|
@ -82,3 +84,8 @@ NotificationStore = Reflux.createStore
|
||||||
console.log "Removed #{notification}" if VERBOSE
|
console.log "Removed #{notification}" if VERBOSE
|
||||||
delete @_notifications[notification.id]
|
delete @_notifications[notification.id]
|
||||||
@trigger()
|
@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:'
|
if parts.protocol is 'mailto:'
|
||||||
query = qs.parse(parts.query)
|
query = qs.parse(parts.query)
|
||||||
query.to = "#{parts.auth}@#{parts.host}"
|
query.to = "#{parts.auth}@#{parts.host}"
|
||||||
|
|
||||||
json = {
|
json = {
|
||||||
subject: query.subject || '',
|
subject: query.subject || '',
|
||||||
body: query.body || '',
|
body: query.body || '',
|
||||||
|
|
|
@ -16,7 +16,15 @@ globalActions = [
|
||||||
"uploadStateChanged",
|
"uploadStateChanged",
|
||||||
"fileAborted",
|
"fileAborted",
|
||||||
"downloadStateChanged",
|
"downloadStateChanged",
|
||||||
"fileUploaded"
|
"fileUploaded",
|
||||||
|
|
||||||
|
"multiWindowNotification",
|
||||||
|
|
||||||
|
# Draft actions
|
||||||
|
"sendDraftSuccess",
|
||||||
|
"sendDraftError",
|
||||||
|
"destroyDraftSuccess",
|
||||||
|
"destroyDraftError"
|
||||||
]
|
]
|
||||||
|
|
||||||
# These actions are rebroadcast through the ActionBridge to the
|
# These actions are rebroadcast through the ActionBridge to the
|
||||||
|
@ -71,7 +79,7 @@ windowActions = [
|
||||||
# Notification actions
|
# Notification actions
|
||||||
"postNotification",
|
"postNotification",
|
||||||
"notificationActionTaken",
|
"notificationActionTaken",
|
||||||
|
|
||||||
# FullContact Sidebar
|
# FullContact Sidebar
|
||||||
"getFullContactDetails",
|
"getFullContactDetails",
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ DraftStore = Reflux.createStore
|
||||||
@listenTo Actions.removeFile, @_onRemoveFile
|
@listenTo Actions.removeFile, @_onRemoveFile
|
||||||
@listenTo Actions.attachFileComplete, @_onAttachFileComplete
|
@listenTo Actions.attachFileComplete, @_onAttachFileComplete
|
||||||
|
|
||||||
|
@listenTo Actions.sendDraftSuccess, @_closeWindow
|
||||||
|
@listenTo Actions.destroyDraftSuccess, @_closeWindow
|
||||||
@_drafts = []
|
@_drafts = []
|
||||||
@_draftSessions = {}
|
@_draftSessions = {}
|
||||||
|
|
||||||
|
@ -66,7 +68,7 @@ DraftStore = Reflux.createStore
|
||||||
else
|
else
|
||||||
# Continue closing
|
# Continue closing
|
||||||
return true
|
return true
|
||||||
|
|
||||||
DatabaseStore.findAll(Message, draft: true).then (drafts) =>
|
DatabaseStore.findAll(Message, draft: true).then (drafts) =>
|
||||||
@_drafts = drafts
|
@_drafts = drafts
|
||||||
@trigger({})
|
@trigger({})
|
||||||
|
@ -154,6 +156,12 @@ DraftStore = Reflux.createStore
|
||||||
|
|
||||||
DatabaseStore.persistModel(draft)
|
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
|
# 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
|
# 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
|
# 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
|
# Queue the task to destroy the draft
|
||||||
Actions.queueTask(new DestroyDraftTask(draftLocalId))
|
Actions.queueTask(new DestroyDraftTask(draftLocalId))
|
||||||
atom.close() if atom.state.mode is "composer"
|
|
||||||
|
|
||||||
_onSendDraft: (draftLocalId) ->
|
_onSendDraft: (draftLocalId) ->
|
||||||
# Immediately save any pending changes so we don't save after sending
|
# Immediately save any pending changes so we don't save after sending
|
||||||
|
@ -181,7 +188,6 @@ DraftStore = Reflux.createStore
|
||||||
save.then ->
|
save.then ->
|
||||||
# Queue the task to send the draft
|
# Queue the task to send the draft
|
||||||
Actions.queueTask(new SendDraftTask(draftLocalId))
|
Actions.queueTask(new SendDraftTask(draftLocalId))
|
||||||
atom.close() if atom.state.mode is "composer"
|
|
||||||
|
|
||||||
_onAttachFileComplete: ({file, messageLocalId}) ->
|
_onAttachFileComplete: ({file, messageLocalId}) ->
|
||||||
@sessionForLocalId(messageLocalId).prepare().then (proxy) ->
|
@sessionForLocalId(messageLocalId).prepare().then (proxy) ->
|
||||||
|
|
|
@ -42,7 +42,9 @@ class DestroyDraftTask extends Task
|
||||||
body:
|
body:
|
||||||
version: @draft.version
|
version: @draft.version
|
||||||
returnsModel: false
|
returnsModel: false
|
||||||
success: resolve
|
success: (args...) =>
|
||||||
|
Actions.destroyDraftSuccess(@draftLocalId)
|
||||||
|
resolve(args...)
|
||||||
error: reject
|
error: reject
|
||||||
|
|
||||||
onAPIError: (apiError) ->
|
onAPIError: (apiError) ->
|
||||||
|
@ -55,6 +57,7 @@ class DestroyDraftTask extends Task
|
||||||
# do but finish
|
# do but finish
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
|
Actions.destroyDraftError(@draftLocalId)
|
||||||
@_rollbackLocal()
|
@_rollbackLocal()
|
||||||
|
|
||||||
onOtherError: -> Promise.resolve()
|
onOtherError: -> Promise.resolve()
|
||||||
|
|
|
@ -23,13 +23,14 @@ class SendDraftTask extends Task
|
||||||
# already sent when they haven't!
|
# already sent when they haven't!
|
||||||
return Promise.reject("Attempt to call SendDraftTask.performLocal without @draftLocalId") unless @draftLocalId
|
return Promise.reject("Attempt to call SendDraftTask.performLocal without @draftLocalId") unless @draftLocalId
|
||||||
Actions.postNotification({message: "Sending message…", type: 'info'})
|
Actions.postNotification({message: "Sending message…", type: 'info'})
|
||||||
|
|
||||||
Promise.resolve()
|
Promise.resolve()
|
||||||
|
|
||||||
performRemote: ->
|
performRemote: ->
|
||||||
new Promise (resolve, reject) =>
|
new Promise (resolve, reject) =>
|
||||||
# Fetch the latest draft data to make sure we make the request with the most
|
# Fetch the latest draft data to make sure we make the request with the most
|
||||||
# recent draft version
|
# 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.
|
# 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
|
return reject(new Error("We couldn't find the saved draft.")) unless draft
|
||||||
|
|
||||||
|
@ -45,25 +46,30 @@ class SendDraftTask extends Task
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
body: body
|
body: body
|
||||||
returnsModel: true
|
returnsModel: true
|
||||||
success: ->
|
success: =>
|
||||||
atom.playSound('mail_sent.ogg')
|
atom.playSound('mail_sent.ogg')
|
||||||
Actions.postNotification({message: "Sent!", type: 'success'})
|
Actions.postNotification({message: "Sent!", type: 'success'})
|
||||||
|
Actions.sendDraftSuccess(@draftLocalId)
|
||||||
DatabaseStore.unpersistModel(draft).then(resolve)
|
DatabaseStore.unpersistModel(draft).then(resolve)
|
||||||
error: reject
|
error: reject
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
|
|
||||||
onAPIError: ->
|
onAPIError: (apiError) ->
|
||||||
msg = "Our server is having problems. Your message has not been sent."
|
msg = apiError.message ? "Our server is having problems. Your message has not been sent."
|
||||||
|
Actions.sendDraftError(@draftLocalId, msg)
|
||||||
@notifyErrorMessage(msg)
|
@notifyErrorMessage(msg)
|
||||||
|
|
||||||
onOtherError: ->
|
onOtherError: ->
|
||||||
msg = "We had a serious issue while sending. Your message has not been sent."
|
msg = "We had a serious issue while sending. Your message has not been sent."
|
||||||
|
Actions.sendDraftError(@draftLocalId, msg)
|
||||||
@notifyErrorMessage(msg)
|
@notifyErrorMessage(msg)
|
||||||
|
|
||||||
onTimeoutError: ->
|
onTimeoutError: ->
|
||||||
msg = "The server is taking an abnormally long time to respond. Your message has not been sent."
|
msg = "The server is taking an abnormally long time to respond. Your message has not been sent."
|
||||||
|
Actions.sendDraftError(@draftLocalId, msg)
|
||||||
@notifyErrorMessage(msg)
|
@notifyErrorMessage(msg)
|
||||||
|
|
||||||
onOfflineError: ->
|
onOfflineError: ->
|
||||||
msg = "You are offline. Your message has NOT been sent. Please send your message when you come back online."
|
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)
|
@notifyErrorMessage(msg)
|
||||||
|
|
Loading…
Reference in a new issue