mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-08 13:44:53 +08:00
fix(salesforce): better message syncing
Summary: Fixes: T2196 While new incoming messages were syncing properly, a new message you sent was not getting synced. Since we re-fetch all of the `Messages` immediately after a send, we had to be sure that the `sendDraftSuccess` Action fired after the new Message had been persisted to the DB. Unfortunately, `_handleModelResponse` was returning before the persist happened. This makes `_handleModelResponse`, and by extension `NylasAPI::makeRequest`, resolve only after the new models have been persisted to the DB. We also were just dumping all of the HTML into the synced SalesforceObject thread, making it entirely unreadable. We now grab the `innerText` instead, which works great for basic conversations. It usually includes the `On {date} {person} wrote:` information, except for the first message, which we manually include. The next version will likely create individual tasks for each individual message, however, doing this properly will require a much more complex Message <-> SFObject syncing task, as well as tying into the QuotedText enging so we only sync the correct pieces. We'll also likely need a more sophisticated plain text interpreter other then `innerText`. I wish we could get access to the raw TEXT MIME part… Test Plan: manual Reviewers: bengotow Reviewed By: bengotow Subscribers: gleb Differential Revision: https://phab.nylas.com/D1766
This commit is contained in:
parent
a8effbc201
commit
a84722d38d
4 changed files with 42 additions and 22 deletions
|
@ -70,6 +70,10 @@ class Contact extends Model
|
|||
return "You" if @email is NamespaceStore.current()?.emailAddress
|
||||
@_nameParts().join(' ')
|
||||
|
||||
# Full Name <email@address.com>
|
||||
messageName: ->
|
||||
if @name then "#{@name} <#{@email}>" else @email
|
||||
|
||||
displayFirstName: ->
|
||||
return "You" if @email is NamespaceStore.current()?.emailAddress
|
||||
@firstName()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
_ = require 'underscore'
|
||||
moment = require 'moment'
|
||||
|
||||
File = require './file'
|
||||
Label = require './label'
|
||||
|
@ -234,4 +235,16 @@ class Message extends Model
|
|||
fileIds: ->
|
||||
_.map @files, (file) -> file.id
|
||||
|
||||
plainTextBody: ->
|
||||
if (@body ? "").trim().length is 0 then return ""
|
||||
(new DOMParser()).parseFromString(@body, "text/html").body.innerText
|
||||
|
||||
fromContact: ->
|
||||
@from?[0] ? new Contact(name: 'Unknown', email: 'Unknown')
|
||||
|
||||
replyAttributionLine: ->
|
||||
"On #{@formattedDate()}, #{@fromContact().messageName()} wrote:"
|
||||
|
||||
formattedDate: -> moment(@date).format("MMM D YYYY, [at] h:mm a")
|
||||
|
||||
module.exports = Message
|
||||
|
|
|
@ -187,17 +187,20 @@ class NylasAPI
|
|||
success = (body) =>
|
||||
if options.beforeProcessing
|
||||
body = options.beforeProcessing(body)
|
||||
return Promise.resolve(body)
|
||||
if options.returnsModel
|
||||
@_handleModelResponse(body)
|
||||
Promise.resolve(body)
|
||||
@_handleModelResponse(body).then (objects) ->
|
||||
return Promise.resolve(body)
|
||||
|
||||
error = (err) =>
|
||||
if err.response
|
||||
handlePromise = Promise.resolve()
|
||||
if err.response.statusCode is 404 and options.returnsModel
|
||||
@_handleModel404(options.url)
|
||||
handlePromise = @_handleModel404(options.url)
|
||||
if err.response.statusCode is 401
|
||||
@_handle401(options.url)
|
||||
Promise.reject(err)
|
||||
handlePromise = @_handle401(options.url)
|
||||
handlePromise.then ->
|
||||
Promise.reject(err)
|
||||
|
||||
req = new NylasAPIRequest(@, options)
|
||||
req.run().then(success, error)
|
||||
|
@ -221,7 +224,11 @@ class NylasAPI
|
|||
if klass and klassId and klassId.length > 0
|
||||
console.warn("Deleting #{klass.name}:#{klassId} due to API 404")
|
||||
DatabaseStore.find(klass, klassId).then (model) ->
|
||||
DatabaseStore.unpersistModel(model) if model
|
||||
if model
|
||||
return DatabaseStore.unpersistModel(model)
|
||||
else return Promise.resolve()
|
||||
else
|
||||
return Promise.resolve()
|
||||
|
||||
_handle401: (modelUrl) ->
|
||||
Actions.postNotification
|
||||
|
@ -241,6 +248,8 @@ class NylasAPI
|
|||
atom.logout()
|
||||
@_notificationUnlisten = Actions.notificationActionTaken.listen(handler, @)
|
||||
|
||||
return Promise.resolve()
|
||||
|
||||
_handleDeltas: (deltas) ->
|
||||
Actions.longPollReceivedRawDeltas(deltas)
|
||||
console.log("Processing Deltas")
|
||||
|
@ -289,6 +298,8 @@ class NylasAPI
|
|||
|
||||
Promise.settle(destroyPromises)
|
||||
|
||||
# Returns a Promsie that resolves when any parsed out models (if any)
|
||||
# have been created and persisted to the database.
|
||||
_handleModelResponse: (jsons) ->
|
||||
if not jsons
|
||||
return Promise.reject(new Error("handleModelResponse with no JSON provided"))
|
||||
|
@ -297,11 +308,11 @@ class NylasAPI
|
|||
if uniquedJSONs.length < jsons.length
|
||||
console.warn("NylasAPI.handleModelResponse: called with non-unique object set. Maybe an API request returned the same object more than once?")
|
||||
|
||||
return Promise.filter(uniquedJSONs, @_shouldAcceptModel)
|
||||
.map(modelFromJSON)
|
||||
.then (objects) ->
|
||||
DatabaseStore.persistModels(objects)
|
||||
return Promise.resolve(objects)
|
||||
Promise.filter(uniquedJSONs, @_shouldAcceptModel)
|
||||
.map(modelFromJSON)
|
||||
.then (objects) ->
|
||||
DatabaseStore.persistModels(objects).then ->
|
||||
return Promise.resolve(objects)
|
||||
|
||||
_shouldAcceptModel: (model) =>
|
||||
return Promise.resolve(false) unless model
|
||||
|
|
|
@ -258,25 +258,17 @@ class DraftStore
|
|||
attributes.subject ?= subjectWithPrefix(thread.subject, 'Re:')
|
||||
attributes.body ?= ""
|
||||
|
||||
# A few helpers for formatting
|
||||
contactString = (c) ->
|
||||
if c.name then "#{c.name} <#{c.email}>" else c.email
|
||||
contactStrings = (cs) ->
|
||||
_.map(cs, contactString).join(", ")
|
||||
messageDate = (d) ->
|
||||
moment(d).format("MMM D YYYY, [at] h:mm a")
|
||||
contactStrings = (cs) -> _.invoke(cs, "messageName").join(", ")
|
||||
|
||||
if attributes.replyToMessage
|
||||
msg = attributes.replyToMessage
|
||||
contact = msg.from[0] ? new Contact(name: 'Unknown', email:'Unknown')
|
||||
attribution = "On #{messageDate(msg.date)}, #{contactString(contact)} wrote:"
|
||||
|
||||
attributes.subject = subjectWithPrefix(msg.subject, 'Re:')
|
||||
attributes.replyToMessageId = msg.id
|
||||
attributes.body = """
|
||||
<br><br><blockquote class="gmail_quote"
|
||||
style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
|
||||
#{attribution}
|
||||
#{msg.replyAttributionLine()}
|
||||
<br>
|
||||
#{@_formatBodyForQuoting(msg.body)}
|
||||
</blockquote>"""
|
||||
|
@ -287,7 +279,7 @@ class DraftStore
|
|||
fields = []
|
||||
fields.push("From: #{contactStrings(msg.from)}") if msg.from.length > 0
|
||||
fields.push("Subject: #{msg.subject}")
|
||||
fields.push("Date: #{messageDate(msg.date)}")
|
||||
fields.push("Date: #{msg.formattedDate()}")
|
||||
fields.push("To: #{contactStrings(msg.to)}") if msg.to.length > 0
|
||||
fields.push("CC: #{contactStrings(msg.cc)}") if msg.cc.length > 0
|
||||
fields.push("BCC: #{contactStrings(msg.bcc)}") if msg.bcc.length > 0
|
||||
|
|
Loading…
Add table
Reference in a new issue