summary refs log tree commit diff
path: root/resources/app/node_modules/electron-dl/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/app/node_modules/electron-dl/index.js')
-rw-r--r--resources/app/node_modules/electron-dl/index.js146
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);
+});