Mailspring/internal_packages/message-list/lib/message-controls.cjsx

151 lines
5.1 KiB
Plaintext
Raw Normal View History

React = require 'react'
{remote} = require 'electron'
{Actions, NylasAPI, AccountStore} = require 'nylas-exports'
{RetinaImg, ButtonDropdown, Menu} = require 'nylas-component-kit'
class MessageControls extends React.Component
@displayName: "MessageControls"
@propTypes:
thread: React.PropTypes.object.isRequired
message: React.PropTypes.object.isRequired
constructor: (@props) ->
render: =>
items = @_items()
<div className="message-actions-wrap">
<ButtonDropdown
primaryItem={<RetinaImg name={items[0].image} mode={RetinaImg.Mode.ContentIsMask}/>}
primaryTitle={items[0].name}
primaryClick={items[0].select}
menu={@_dropdownMenu(items[1..-1])}/>
<div className="message-actions-ellipsis" onClick={@_onShowActionsMenu}>
<RetinaImg name={"message-actions-ellipsis.png"} mode={RetinaImg.Mode.ContentIsMask}/>
</div>
</div>
_items: ->
reply =
name: 'Reply',
image: 'ic-dropdown-reply.png'
select: @_onReply
replyAll =
name: 'Reply All',
image: 'ic-dropdown-replyall.png'
select: @_onReplyAll
forward =
name: 'Forward',
image: 'ic-dropdown-forward.png'
select: @_onForward
if @props.message.canReplyAll()
refactor(env): new NylasEnv global Converted all references of global atom to NylasEnv Temporary rename atom.io find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.io/temporaryAtomIoReplacement/g' atom.config to NylasEnv.config find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.config/NylasEnv.config/g' atom.packages -> NylasEnv.packages atom.commands -> NylasEnv.commands atom.getLoadSettings find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.commands/NylasEnv.commands/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.getLoadSettings/NylasEnv.getLoadSettings/g' More common atom methods find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.styles/NylasEnv.styles/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.emitError/NylasEnv.emitError/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.inSpecMode/NylasEnv.inSpecMode/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.inDevMode/NylasEnv.inDevMode/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.getWindowType/NylasEnv.getWindowType/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.displayWindow/NylasEnv.displayWindow/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.quit/NylasEnv.quit/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.close/NylasEnv.close/g' More atom method changes find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.keymaps/NylasEnv.keymaps/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.hide/NylasEnv.hide/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.getCurrentWindow/NylasEnv.getCurrentWindow/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.menu/NylasEnv.menu/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.getConfigDirPath/NylasEnv.getConfigDirPath/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.isMainWindow/NylasEnv.isMainWindow/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.finishUnload/NylasEnv.finishUnload/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.isWorkWindow/NylasEnv.isWorkWindow/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.showSaveDialog/NylasEnv.showSaveDialog/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.append/NylasEnv.append/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.confirm/NylasEnv.confirm/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.clipboard/NylasEnv.clipboard/g' find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed -i "" 's/atom.getVersion/NylasEnv.getVersion/g' More atom renaming Rename atom methods More atom methods Fix grunt config variable Change atom.cmd to N1.cmd Rename atom.coffee and atom.js to nylas-env.coffee nylas-env.js Fix atom global reference in specs manually Fix atom requires Change engine from atom to nylas got rid of global/nylas-env rename to nylas-win-bootup Fix onWindowPropsChanged to onWindowPropsReceived fix nylas-workspace atom-text-editor to nylas-theme-wrap atom-text-editor -> nylas-theme-wrap Replacing atom keyword AtomWindow -> NylasWindow Replace Atom -> N1 Rename atom items nylas.asar -> atom.asar Remove more atom references Remove 6to5 references Remove license exception for atom
2015-11-12 02:25:11 +08:00
defaultReplyType = NylasEnv.config.get('core.sending.defaultReplyType')
if defaultReplyType is 'reply-all'
return [replyAll, reply, forward]
else
return [reply, replyAll, forward]
else
return [reply, forward]
_account: =>
AccountStore.accountForId(@props.message.accountId)
_dropdownMenu: (items) ->
itemContent = (item) ->
<span>
<RetinaImg name={item.image} mode={RetinaImg.Mode.ContentIsMask}/>
&nbsp;&nbsp;{item.name}
</span>
<Menu items={items}
itemKey={ (item) -> item.name }
itemContent={itemContent}
onSelect={ (item) => item.select() }
/>
_onReply: =>
Actions.composeReply(thread: @props.thread, message: @props.message)
_onReplyAll: =>
Actions.composeReplyAll(thread: @props.thread, message: @props.message)
_onForward: =>
Actions.composeForward(thread: @props.thread, message: @props.message)
_onShowActionsMenu: =>
SystemMenu = remote.require('menu')
SystemMenuItem = remote.require('menu-item')
# Todo: refactor this so that message actions are provided
# dynamically. Waiting to see if this will be used often.
menu = new SystemMenu()
menu.append(new SystemMenuItem({ label: 'Report Issue: Quoted Text', click: => @_onReport('Quoted Text')}))
menu.append(new SystemMenuItem({ label: 'Report Issue: Rendering', click: => @_onReport('Rendering')}))
menu.append(new SystemMenuItem({ type: 'separator'}))
menu.append(new SystemMenuItem({ label: 'Show Original', click: => @_onShowOriginal()}))
menu.append(new SystemMenuItem({ label: 'Copy Debug Info to Clipboard', click: => @_onCopyToClipboard()}))
menu.append(new SystemMenuItem({ label: 'Log Data', click: => @_onLogData()}))
menu.popup(remote.getCurrentWindow())
_onReport: (issueType) =>
{Contact, Message, DatabaseStore, AccountStore} = require 'nylas-exports'
draft = new Message
from: [@_account().me()]
to: [new Contact(name: "Nylas Team", email: "n1-support@nylas.com")]
date: (new Date)
draft: true
subject: "Feedback - Message Display Issue (#{issueType})"
accountId: @_account().id
body: @props.message.body
feat(transactions): Explicit (and faster) database transactions Summary: Until now, we've been hiding transactions beneath the surface. When you call persistModel, you're implicitly creating a transaction. You could explicitly create them with `atomically`..., but there were several critical problems that are fixed in this diff: - Calling persistModel / unpersistModel within a transaction could cause the DatabaseStore to trigger. This could result in other parts of the app making queries /during/ the transaction, potentially before the COMMIT occurred and saved the changes. The new, explicit inTransaction syntax holds all changes until after COMMIT and then triggers. - Calling atomically and then calling persistModel inside that resulted in us having to check whether a transaction was present and was gross. - Many parts of the code ran extensive logic inside a promise chained within `atomically`: BAD: ``` DatabaseStore.atomically => DatabaseStore.persistModel(draft) => GoMakeANetworkRequestThatReturnsAPromise ``` OVERWHELMINGLY BETTER: ``` DatabaseStore.inTransaction (t) => t.persistModel(draft) .then => GoMakeANetworkRequestThatReturnsAPromise ``` Having explicit transactions also puts us on equal footing with Sequelize and other ORMs. Note that you /have/ to call DatabaseStore.inTransaction (t) =>. There is no other way to access the methods that let you alter the database. :-) Other changes: - This diff removes Message.labels and the Message-Labels table. We weren't using Message-level labels anywhere, and the table could grow very large. - This diff changes the page size during initial sync from 250 => 200 in an effort to make transactions a bit faster. Test Plan: Run tests! Reviewers: juan, evan Reviewed By: juan, evan Differential Revision: https://phab.nylas.com/D2353
2015-12-18 03:46:05 +08:00
DatabaseStore.inTransaction (t) =>
t.persistModel(draft)
.then =>
Actions.sendDraft(draft.clientId)
dialog = remote.require('dialog')
dialog.showMessageBox remote.getCurrentWindow(), {
type: 'warning'
buttons: ['OK'],
message: "Thank you."
detail: "The contents of this message have been sent to the N1 team and we added to a test suite."
}
_onShowOriginal: =>
fs = require 'fs'
path = require 'path'
BrowserWindow = remote.require('browser-window')
app = remote.require('app')
tmpfile = path.join(app.getPath('temp'), @props.message.id)
NylasAPI.makeRequest
headers:
Accept: 'message/rfc822'
path: "/messages/#{@props.message.id}"
accountId: @props.message.accountId
json:false
success: (body) =>
fs.writeFile tmpfile, body, =>
window = new BrowserWindow(width: 800, height: 600, title: "#{@props.message.subject} - RFC822")
window.loadURL('file://'+tmpfile)
_onLogData: =>
console.log @props.message
window.__message = @props.message
window.__thread = @props.thread
console.log "Also now available in window.__message and window.__thread"
_onCopyToClipboard: =>
clipboard = require('electron').clipboard
data = "AccountID: #{@props.message.accountId}\n"+
"Message ID: #{@props.message.serverId}\n"+
"Message Metadata: #{JSON.stringify(@props.message.pluginMetadata, null, ' ')}\n"+
"Thread ID: #{@props.thread.serverId}\n"+
"Thread Metadata: #{JSON.stringify(@props.thread.pluginMetadata, null, ' ')}\n"
clipboard.writeText(data)
module.exports = MessageControls