mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-26 06:25:33 +08:00
Inits FileUploadStore from current state in the filesystem
- Removes uploads when draft is deleted - Misc fixes and renaming
This commit is contained in:
parent
752a749da7
commit
63d36a78c3
5 changed files with 60 additions and 26 deletions
|
@ -441,7 +441,7 @@ class ComposerView extends React.Component
|
|||
|
||||
<button className="btn btn-toolbar btn-attach" style={order: 50}
|
||||
title="Attach file"
|
||||
onClick={@_selectFileForUpload}><RetinaImg name="icon-composer-attachment.png" mode={RetinaImg.Mode.ContentIsMask} /></button>
|
||||
onClick={@_selectAttachment}><RetinaImg name="icon-composer-attachment.png" mode={RetinaImg.Mode.ContentIsMask} /></button>
|
||||
|
||||
<div style={order: 0, flex: 1} />
|
||||
|
||||
|
@ -506,6 +506,7 @@ class ComposerView extends React.Component
|
|||
files: draft.files
|
||||
subject: draft.subject
|
||||
accounts: @_getAccountsForSend()
|
||||
uploads: FileUploadStore.uploadsForMessage(@props.draftClientId) ? []
|
||||
|
||||
if !@state.populated
|
||||
_.extend state,
|
||||
|
@ -615,14 +616,14 @@ class ComposerView extends React.Component
|
|||
_onDrop: (e) =>
|
||||
# Accept drops of real files from other applications
|
||||
for file in e.dataTransfer.files
|
||||
Actions.attachFile({filePath: file.path, messageClientId: @props.draftClientId})
|
||||
Actions.addAttachment({filePath: file.path, messageClientId: @props.draftClientId})
|
||||
|
||||
# Accept drops from attachment components / images within the app
|
||||
if (uri = @_nonNativeFilePathForDrop(e))
|
||||
Actions.attachFile({filePath: uri, messageClientId: @props.draftClientId})
|
||||
Actions.addAttachment({filePath: uri, messageClientId: @props.draftClientId})
|
||||
|
||||
_onFilePaste: (path) =>
|
||||
Actions.attachFile({filePath: path, messageClientId: @props.draftClientId})
|
||||
Actions.addAttachment({filePath: path, messageClientId: @props.draftClientId})
|
||||
|
||||
_onChangeParticipants: (changes={}) =>
|
||||
@_addToProxy(changes)
|
||||
|
@ -744,8 +745,8 @@ class ComposerView extends React.Component
|
|||
_destroyDraft: =>
|
||||
Actions.destroyDraft(@props.draftClientId)
|
||||
|
||||
_selectFileForUpload: =>
|
||||
Actions.selectFileForUpload({messageClientId: @props.draftClientId})
|
||||
_selectAttachment: =>
|
||||
Actions.selectAttachment({messageClientId: @props.draftClientId})
|
||||
|
||||
undo: (event) =>
|
||||
event.preventDefault()
|
||||
|
|
|
@ -27,7 +27,7 @@ class FileUpload extends React.Component
|
|||
</div>
|
||||
|
||||
_onClickRemove: =>
|
||||
Actions.removeFileFromUpload @props.upload
|
||||
Actions.removeAttachment @props.upload
|
||||
|
||||
_extension: =>
|
||||
path.extname(@props.upload.filename)[1..-1]
|
||||
|
|
|
@ -445,9 +445,9 @@ class Actions
|
|||
|
||||
# File Actions
|
||||
# Some file actions only need to be processed in their current window
|
||||
@attachFile: ActionScopeWindow
|
||||
@selectFileForUpload: ActionScopeWindow
|
||||
@removeFileFromUpload: ActionScopeWindow
|
||||
@addAttachment: ActionScopeWindow
|
||||
@selectAttachment: ActionScopeWindow
|
||||
@removeAttachment: ActionScopeWindow
|
||||
@fetchAndOpenFile: ActionScopeWindow
|
||||
@fetchAndSaveFile: ActionScopeWindow
|
||||
@fetchFile: ActionScopeWindow
|
||||
|
|
|
@ -5,14 +5,16 @@ mkdirp = require 'mkdirp'
|
|||
NylasStore = require 'nylas-store'
|
||||
Actions = require '../actions'
|
||||
Utils = require '../models/utils'
|
||||
Message = require '../models/message'
|
||||
DatabaseStore = require './database-store'
|
||||
|
||||
|
||||
UPLOAD_DIR = path.join(NylasEnv.getConfigDirPath(), 'uploads')
|
||||
|
||||
class Upload
|
||||
|
||||
constructor: (@messageClientId, @originPath, @stats, @uploadDir = UPLOAD_DIR) ->
|
||||
@id = Utils.generateTempId()
|
||||
constructor: (@messageClientId, @originPath, @stats, @id, @uploadDir = UPLOAD_DIR) ->
|
||||
@id ?= Utils.generateTempId()
|
||||
@filename = path.basename(@originPath)
|
||||
@draftUploadDir = path.join(@uploadDir, @messageClientId)
|
||||
@targetDir = path.join(@draftUploadDir, @id)
|
||||
|
@ -23,30 +25,38 @@ class Upload
|
|||
class FileUploadStore extends NylasStore
|
||||
|
||||
constructor: ->
|
||||
@listenTo Actions.selectFileForUpload, @_onSelectFileForUpload
|
||||
@listenTo Actions.attachFile, @_onAttachFile
|
||||
@listenTo Actions.removeFileFromUpload, @_onRemoveUpload
|
||||
@listenTo Actions.selectAttachment, @_onSelectAttachment
|
||||
@listenTo Actions.addAttachment, @_onAddAttachment
|
||||
@listenTo Actions.removeAttachment, @_onRemoveAttachment
|
||||
@listenTo DatabaseStore, @_onDataChanged
|
||||
|
||||
# We don't save uploads to the DB, we keep it in memory in the store.
|
||||
# The key is the messageClientId. The value is a hash of paths and
|
||||
# corresponding upload data.
|
||||
@_fileUploads = {}
|
||||
mkdirp(UPLOAD_DIR)
|
||||
mkdirp.sync(UPLOAD_DIR)
|
||||
@_fileUploads = @_getFileUploadsFromFs()
|
||||
|
||||
uploadsForMessage: (messageClientId) ->
|
||||
@_fileUploads[messageClientId] ? []
|
||||
|
||||
_onSelectFileForUpload: ({messageClientId}) ->
|
||||
|
||||
# Handlers
|
||||
|
||||
_onDataChanged: (change) =>
|
||||
return unless change.objectClass is Message.name and change.type is 'unpersist'
|
||||
change.objects.forEach (message) =>
|
||||
uploads = @_fileUploads[message.clientId]
|
||||
if uploads?
|
||||
uploads.forEach (upload) => @_onRemoveAttachment(upload)
|
||||
|
||||
_onSelectAttachment: ({messageClientId}) ->
|
||||
@_verifyId(messageClientId)
|
||||
# When the dialog closes, it triggers `Actions.attachFile`
|
||||
# When the dialog closes, it triggers `Actions.addAttachment`
|
||||
NylasEnv.showOpenDialog {properties: ['openFile', 'multiSelections']}, (pathsToOpen) ->
|
||||
return if not pathsToOpen?
|
||||
pathsToOpen = [pathsToOpen] if _.isString(pathsToOpen)
|
||||
|
||||
pathsToOpen.forEach (filePath) ->
|
||||
Actions.attachFile({messageClientId, filePath})
|
||||
Actions.addAttachment({messageClientId, filePath})
|
||||
|
||||
_onAttachFile: ({messageClientId, filePath}) ->
|
||||
_onAddAttachment: ({messageClientId, filePath}) ->
|
||||
@_verifyId(messageClientId)
|
||||
@_getFileStats({messageClientId, filePath})
|
||||
.then(@_makeUpload)
|
||||
|
@ -56,7 +66,7 @@ class FileUploadStore extends NylasStore
|
|||
.then(@_saveUpload)
|
||||
.catch(@_onAttachFileError)
|
||||
|
||||
_onRemoveUpload: (upload) ->
|
||||
_onRemoveAttachment: (upload) ->
|
||||
return unless (@_fileUploads[upload.messageClientId] ? []).length > 0
|
||||
@_deleteUpload(upload)
|
||||
.then (upload) =>
|
||||
|
@ -77,6 +87,29 @@ class FileUploadStore extends NylasStore
|
|||
message: 'Cannot Attach File',
|
||||
detail: message
|
||||
|
||||
# Helpers
|
||||
|
||||
_getTempIdDirsFor: (path) ->
|
||||
fs.readdirSync(path).filter((dir) -> Utils.isTempId(dir))
|
||||
|
||||
_getFileUploadsFromFs: (rootDir = UPLOAD_DIR)->
|
||||
# TODO This function makes my eyes hurt. Refactor
|
||||
uploads = {}
|
||||
dirs = @_getTempIdDirsFor(rootDir)
|
||||
for messageClientId in dirs
|
||||
uploads[messageClientId] = []
|
||||
messageDir = path.join(rootDir, messageClientId)
|
||||
uploadIds = @_getTempIdDirsFor(messageDir)
|
||||
for uploadId in uploadIds
|
||||
uploadDir = path.join(messageDir, uploadId)
|
||||
for filename in fs.readdirSync(uploadDir)
|
||||
uploadPath = path.join(uploadDir, filename)
|
||||
stats = fs.statSync(uploadPath)
|
||||
uploads[messageClientId].push(
|
||||
new Upload(messageClientId, uploadPath, stats, uploadId)
|
||||
)
|
||||
return uploads
|
||||
|
||||
_verifyId: (messageClientId) ->
|
||||
if messageClientId.blank?
|
||||
throw new Error "You need to pass the ID of the message (draft) this Action refers to"
|
||||
|
|
|
@ -169,7 +169,7 @@ class SendDraftTask extends Task
|
|||
# Remove attachments we were waiting to upload
|
||||
# Call the Action to do this
|
||||
for upload in @uploads
|
||||
Actions.removeFileFromUpload(upload.messageClientId, upload.id)
|
||||
Actions.removeAttachment(upload.messageClientId, upload.id)
|
||||
|
||||
return Promise.resolve(Task.Status.Success)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue