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:
Evan Morikawa 2015-03-10 09:52:47 -07:00
parent 2189f4f2b7
commit 6ec84561c4
6 changed files with 41 additions and 11 deletions

View file

@ -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

View file

@ -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

View file

@ -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 = {}
@ -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) ->

View file

@ -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()

View file

@ -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)