mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-27 10:28:31 +08:00
feat(extension): async extensions
Summary: WIP: This is a quick patch for Drew to make extensions async We'll need to think through the upgrade/deprecation plan to roll out async extensions across all of our APIs. Test Plan: TODO Reviewers: drew, evan, bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D2392
This commit is contained in:
parent
2800cc0dc8
commit
11b731891f
7 changed files with 36 additions and 22 deletions
|
@ -41,5 +41,6 @@ class ProductsExtension extends ComposerExtension
|
|||
bodyWithWarning = draft.body += "<br>This email \
|
||||
contains competitor's product names \
|
||||
or trademarks used in context."
|
||||
session.changes.add(body: bodyWithWarning)
|
||||
return session.changes.add(body: bodyWithWarning)
|
||||
else return Promise.resolve()
|
||||
```
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
{ComposerExtension} = require 'nylas-exports'
|
||||
request = require 'request'
|
||||
post = Promise.promisify(request.post, multiArgs: true)
|
||||
|
||||
class AvailabilityComposerExtension extends ComposerExtension
|
||||
|
||||
# When subclassing the ComposerExtension, you can add your own custom logic
|
||||
# to execute before a draft is sent in the @finalizeSessionBeforeSending
|
||||
# method. Here, we're registering the events before we send the draft.
|
||||
@finalizeSessionBeforeSending: ({session}) ->
|
||||
@finalizeSessionBeforeSending: (session) ->
|
||||
body = session.draft().body
|
||||
participants = session.draft().participants()
|
||||
sender = session.draft().from
|
||||
|
@ -18,8 +19,19 @@ class AvailabilityComposerExtension extends ComposerExtension
|
|||
data.attendees = participants.map (p) ->
|
||||
name: p.name, email: p.email, isSender: p.isMe()
|
||||
serverUrl = "https://quickschedule.herokuapp.com/register-events"
|
||||
request.post {url: serverUrl, body: JSON.stringify(data)}, (error, resp, data) =>
|
||||
console.log(error,resp,data)
|
||||
post({url: serverUrl, body: JSON.stringify(data)})
|
||||
.then (args) =>
|
||||
data = args[1]
|
||||
return data
|
||||
.catch (error) ->
|
||||
dialog = require('remote').require('dialog')
|
||||
dialog.showErrorBox('Error creating QuickSchedule event',
|
||||
"There was a problem connecting to the QuickSchedule server. Make sure you're connected to the internet and "+
|
||||
"try sending again. If problems persist, contact the N1 team (using the blue question icon at the bottom right "+
|
||||
"of your inbox) and we'll get right on it!")
|
||||
Promise.reject(error)
|
||||
else
|
||||
Promise.resolve()
|
||||
|
||||
|
||||
module.exports = AvailabilityComposerExtension
|
|
@ -123,7 +123,7 @@ class SpellcheckComposerExtension extends ComposerExtension
|
|||
body = session.draft().body
|
||||
clean = body.replace(/<\/?spelling[^>]*>/g, '')
|
||||
if body != clean
|
||||
session.changes.add(body: clean)
|
||||
return session.changes.add(body: clean)
|
||||
|
||||
SpellcheckComposerExtension.SpellcheckCache = SpellcheckCache
|
||||
|
||||
|
|
|
@ -25,9 +25,10 @@ describe "SpellcheckComposerExtension", ->
|
|||
draft: ->
|
||||
body: expectedHTML
|
||||
changes:
|
||||
add: jasmine.createSpy('add')
|
||||
add: jasmine.createSpy('add').andReturn Promise.resolve()
|
||||
|
||||
SpellcheckComposerExtension.finalizeSessionBeforeSending({session})
|
||||
expect(session.changes.add).toHaveBeenCalledWith(body: initialHTML)
|
||||
waitsForPromise ->
|
||||
SpellcheckComposerExtension.finalizeSessionBeforeSending(session).then ->
|
||||
expect(session.changes.add).toHaveBeenCalledWith(body: initialHTML)
|
||||
|
||||
module.exports = SpellcheckComposerExtension
|
||||
|
|
|
@ -124,7 +124,7 @@ describe "ComposerView", ->
|
|||
# `componentWillMount`, we manually call sessionForClientId to make this
|
||||
# part of the test synchronous. We need to make the `then` block of the
|
||||
# sessionForClientId do nothing so `_setupSession` is not called twice!
|
||||
spyOn(DraftStore, "sessionForClientId").andCallFake -> then: ->
|
||||
spyOn(DraftStore, "sessionForClientId").andReturn then: -> then: ->
|
||||
|
||||
useFullDraft = ->
|
||||
useDraft.call @,
|
||||
|
|
|
@ -28,8 +28,8 @@ session you receive in {::finalizeSessionBeforeSending} is for the same
|
|||
draft you previously received in {::warningsForSending}, etc.
|
||||
|
||||
The ComposerExtension API does not currently expose any asynchronous or
|
||||
{Promise}-based APIs. This will likely change in the future. If you have
|
||||
a use-case for a ComposerExtension that is not possible with the current
|
||||
{Promise}-based APIs, except for finalizeSessionBeforeSending. This will likely
|
||||
change in the future. If you havea use-case for a ComposerExtension that is not possible with the current
|
||||
API, please let us know.
|
||||
|
||||
Section: Extensions
|
||||
|
@ -96,6 +96,8 @@ class ComposerExtension extends ContenteditableExtension
|
|||
the draft is sent. This method gives you an opportunity to make any
|
||||
final substitutions or changes after any {::warningsForSending} have
|
||||
been displayed.
|
||||
If you want to perform asynchronous work, you this method can return a promise,
|
||||
however, returning a Promise is not required.
|
||||
|
||||
- `session`: A {DraftStoreProxy} for the draft.
|
||||
|
||||
|
@ -110,7 +112,7 @@ class ComposerExtension extends ContenteditableExtension
|
|||
session.changes.add(body: clean)
|
||||
```
|
||||
###
|
||||
@finalizeSessionBeforeSending: ({session}) ->
|
||||
return
|
||||
@finalizeSessionBeforeSending: (session) ->
|
||||
return Promise.resolve(session)
|
||||
|
||||
module.exports = ComposerExtension
|
||||
|
|
|
@ -496,10 +496,9 @@ class DraftStore
|
|||
# point there are still unpersisted changes in the DraftStoreProxy. If
|
||||
# we `trigger`, we'll briefly display the wrong version of the draft
|
||||
# as if it was sending.
|
||||
|
||||
@sessionForClientId(draftClientId).then (session) =>
|
||||
@_runExtensionsBeforeSend(session)
|
||||
|
||||
@sessionForClientId(draftClientId)
|
||||
.then(@_runExtensionsBeforeSend)
|
||||
.then (session) =>
|
||||
# Immediately save any pending changes so we don't save after
|
||||
# sending
|
||||
#
|
||||
|
@ -511,7 +510,6 @@ class DraftStore
|
|||
# committed to the Database since we'll look them up again just
|
||||
# before send.
|
||||
session.changes.commit(force: true, noSyncback: true).then =>
|
||||
|
||||
# We unfortunately can't give the SendDraftTask the raw draft JSON
|
||||
# data because there may still be pending tasks (like a
|
||||
# {FileUploadTask}) that will continue to update the draft data.
|
||||
|
@ -532,10 +530,10 @@ class DraftStore
|
|||
NylasEnv.getWindowType() is "composer"
|
||||
|
||||
# Give third-party plugins an opportunity to sanitize draft data
|
||||
_runExtensionsBeforeSend: (session) ->
|
||||
for extension in @extensions()
|
||||
continue unless extension.finalizeSessionBeforeSending
|
||||
extension.finalizeSessionBeforeSending({session})
|
||||
_runExtensionsBeforeSend: (session) =>
|
||||
Promise.each @extensions(), (ext) ->
|
||||
ext.finalizeSessionBeforeSending(session)
|
||||
.return(session)
|
||||
|
||||
_onRemoveFile: ({file, messageClientId}) =>
|
||||
@sessionForClientId(messageClientId).then (session) ->
|
||||
|
|
Loading…
Reference in a new issue