diff options
Diffstat (limited to 'resources/app/node_modules/electron-dl/index.js')
-rw-r--r-- | resources/app/node_modules/electron-dl/index.js | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/resources/app/node_modules/electron-dl/index.js b/resources/app/node_modules/electron-dl/index.js new file mode 100644 index 0000000..e335ab3 --- /dev/null +++ b/resources/app/node_modules/electron-dl/index.js @@ -0,0 +1,146 @@ +'use strict'; +const path = require('path'); +const {app, BrowserWindow, shell, dialog} = require('electron'); +const unusedFilename = require('unused-filename'); +const pupa = require('pupa'); +const extName = require('ext-name'); + +function getFilenameFromMime(name, mime) { + const exts = extName.mime(mime); + + if (exts.length !== 1) { + return name; + } + + return `${name}.${exts[0].ext}`; +} + +function registerListener(session, options, cb = () => {}) { + const downloadItems = new Set(); + let receivedBytes = 0; + let completedBytes = 0; + let totalBytes = 0; + const activeDownloadItems = () => downloadItems.size; + const progressDownloadItems = () => receivedBytes / totalBytes; + + options = Object.assign({ + showBadge: true + }, options); + + const listener = (e, item, webContents) => { + downloadItems.add(item); + totalBytes += item.getTotalBytes(); + + let hostWebContents = webContents; + if (webContents.getType() === 'webview') { + ({hostWebContents} = webContents); + } + + const win = BrowserWindow.fromWebContents(hostWebContents); + + const dir = options.directory || app.getPath('downloads'); + let filePath; + if (options.filename) { + filePath = path.join(dir, options.filename); + } else { + const filename = item.getFilename(); + const name = path.extname(filename) ? filename : getFilenameFromMime(filename, item.getMimeType()); + + filePath = unusedFilename.sync(path.join(dir, name)); + } + + const errorMessage = options.errorMessage || 'The download of {filename} was interrupted'; + const errorTitle = options.errorTitle || 'Download Error'; + + if (!options.saveAs) { + item.setSavePath(filePath); + } + + if (typeof options.onStarted === 'function') { + options.onStarted(item); + } + + item.on('updated', () => { + receivedBytes = [...downloadItems].reduce((receivedBytes, item) => { + receivedBytes += item.getReceivedBytes(); + return receivedBytes; + }, completedBytes); + + if (options.showBadge && ['darwin', 'linux'].includes(process.platform)) { + app.setBadgeCount(activeDownloadItems()); + } + + if (!win.isDestroyed()) { + win.setProgressBar(progressDownloadItems()); + } + + if (typeof options.onProgress === 'function') { + options.onProgress(progressDownloadItems()); + } + }); + + item.on('done', (event, state) => { + completedBytes += item.getTotalBytes(); + downloadItems.delete(item); + + if (options.showBadge && ['darwin', 'linux'].includes(process.platform)) { + app.setBadgeCount(activeDownloadItems()); + } + + if (!win.isDestroyed() && !activeDownloadItems()) { + win.setProgressBar(-1); + receivedBytes = 0; + completedBytes = 0; + totalBytes = 0; + } + + if (options.unregisterWhenDone) { + session.removeListener('will-download', listener); + } + + if (state === 'cancelled') { + if (typeof options.onCancel === 'function') { + options.onCancel(item); + } + } else if (state === 'interrupted') { + const message = pupa(errorMessage, {filename: item.getFilename()}); + dialog.showErrorBox(errorTitle, message); + cb(new Error(message)); + } else if (state === 'completed') { + if (process.platform === 'darwin') { + app.dock.downloadFinished(filePath); + } + + if (options.openFolderWhenDone) { + shell.showItemInFolder(path.join(dir, item.getFilename())); + } + + cb(null, item); + } + }); + }; + + session.on('will-download', listener); +} + +module.exports = (options = {}) => { + app.on('session-created', session => { + registerListener(session, options); + }); +}; + +module.exports.default = module.exports; + +module.exports.download = (win, url, options) => new Promise((resolve, reject) => { + options = Object.assign({}, options, {unregisterWhenDone: true}); + + registerListener(win.webContents.session, options, (err, item) => { + if (err) { + reject(err); + } else { + resolve(item); + } + }); + + win.webContents.downloadURL(url); +}); |