Skip to content

Commit c7ed26f

Browse files
authored
Merge pull request #1134 from substance/download-file
Download file improvements
2 parents 6cce387 + e062d42 commit c7ed26f

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

app/main.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const url = require('url')
55
const fsExtra = require('fs-extra')
66

77
const {
8-
app, dialog, shell, protocol,
8+
app, dialog, shell, protocol, session,
99
BrowserWindow, Menu, ipcMain
1010
} = electron
1111
const DEBUG = process.env.DEBUG
@@ -37,6 +37,18 @@ app.on('ready', () => {
3737
if (error) console.error('Failed to register protocol')
3838
})
3939

40+
// Download files
41+
session.defaultSession.on('will-download', (event, item) => {
42+
let location = dialog.showSaveDialog({ defaultPath: item.getFilename() })
43+
// If there is no location came from dialog it means cancelation and
44+
// we should prevent default action to close dialog without error
45+
if (location) {
46+
item.setSavePath(location)
47+
} else {
48+
event.preventDefault()
49+
}
50+
})
51+
4052
createMenu()
4153

4254
// look if there is a 'dar' file in the args that does exist

src/article/editor/DownloadSupplementaryFileCommand.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,23 @@ import { Command } from 'substance'
66
*/
77
export default class DownloadSupplementaryFileCommand extends Command {
88
getCommandState (params, context) {
9-
const xpath = params.selectionState.xpath
9+
const selectionState = params.selectionState
10+
const xpath = selectionState.xpath
1011
if (xpath.length > 0) {
1112
const selectedType = xpath[xpath.length - 1].type
12-
return { disabled: selectedType !== 'supplementary-file' }
13+
if (selectedType === 'supplementary-file') {
14+
return {
15+
disabled: false,
16+
// leaving the node, so that the tool can apply different
17+
// strategies for local vs remote files
18+
node: selectionState.node
19+
}
20+
}
1321
}
1422
return { disabled: true }
1523
}
1624

1725
execute (params, context) {
26+
// Nothing: downloading is implemented via native download hooks
1827
}
1928
}

src/article/editor/DownloadSupplementaryFileTool.js

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,24 @@ export default class DownloadSupplementaryFileTool extends Tool {
77
let link = $$('a').ref('link')
88
// ATTENTION: stop propagation, otherwise infinite loop
99
.on('click', domHelpers.stop)
10-
// Note: in the browser version we want to open the download in a new tab
11-
if (!platform.inElectron) {
10+
11+
// Downloading is a bit involved:
12+
// In electron, everything can be done with one solution,
13+
// handling a 'will-download' event, which is triggered when the `download`
14+
// attribute is present.
15+
// For the browser, the `download` attribute works only for files from the same
16+
// origin. For remote files the best we can do at the moment, is opening
17+
// a new tab, and let the browser deal with it.
18+
// TODO: if this feature is important, one idea is that the DAR server could
19+
// provide an end-point to provide download-urls, and act as a proxy to
20+
// cirvumvent the CORS problem.
21+
const isLocal = this._isLocal()
22+
if (platform.inElectron || isLocal) {
23+
link.attr('download', '')
24+
} else {
1225
link.attr('target', '_blank')
1326
}
27+
1428
el.append(link)
1529
return el
1630
}
@@ -27,10 +41,8 @@ export default class DownloadSupplementaryFileTool extends Tool {
2741

2842
_triggerDownload () {
2943
const archive = this.context.archive
30-
const editorSession = this.context.editorSession
31-
const selectionState = editorSession.getSelectionState()
32-
const node = selectionState.node
33-
const isLocal = !node.remote
44+
const node = this._getNode()
45+
const isLocal = this._isLocal()
3446
let url = node.href
3547
if (isLocal) {
3648
url = archive.getDownloadLink(node.href)
@@ -42,4 +54,13 @@ export default class DownloadSupplementaryFileTool extends Tool {
4254
this.refs.link.el.click()
4355
}
4456
}
57+
58+
_getNode () {
59+
return this.props.commandState.node
60+
}
61+
62+
_isLocal () {
63+
let node = this._getNode()
64+
return (!node || !node.remote)
65+
}
4566
}

0 commit comments

Comments
 (0)