diff --git a/config.js b/config.js index 6f6cce73..8095b556 100644 --- a/config.js +++ b/config.js @@ -10,6 +10,8 @@ module.exports = { INDEX: 'file://' + path.join(__dirname, 'renderer', 'index.html'), + IS_PRODUCTION: isProduction(), + SOUND_ADD: 'file://' + path.join(__dirname, 'static', 'sound', 'add.wav'), SOUND_DELETE: 'file://' + path.join(__dirname, 'static', 'sound', 'delete.wav'), SOUND_DISABLE: 'file://' + path.join(__dirname, 'static', 'sound', 'disable.wav'), @@ -19,3 +21,15 @@ module.exports = { SOUND_PLAY: 'file://' + path.join(__dirname, 'static', 'sound', 'play.wav'), SOUND_STARTUP: 'file://' + path.join(__dirname, 'static', 'sound', 'startup.wav') } + +function isProduction () { + if (process.platform === 'darwin') { + return !/\/Electron\.app\/Contents\/MacOS\/Electron$/.test(process.execPath) + } + if (process.platform === 'win32') { + return !/\\electron\.exe$/.test(process.execPath) + } + if (process.platform === 'linux') { + // TODO + } +} diff --git a/main/index.js b/main/index.js index 20fee9b7..9a6cae7d 100644 --- a/main/index.js +++ b/main/index.js @@ -1,10 +1,15 @@ var electron = require('electron') + +var app = electron.app + +var config = require('../config') var ipc = require('./ipc') var menu = require('./menu') +var registerProtocolHandler = require('./register-protocol-handler') var shortcuts = require('./shortcuts') var windows = require('./windows') -var app = electron.app +var argv = process.argv.slice(config.IS_PRODUCTION ? 1 : 2) app.on('open-file', onOpen) app.on('open-url', onOpen) @@ -16,6 +21,17 @@ app.on('ready', function () { menu.init() windows.createMainWindow() shortcuts.init() + registerProtocolHandler() +}) + +app.on('ipcReady', function () { + windows.main.send('log', 'IS_PRODUCTION:', config.IS_PRODUCTION) + if (argv.length) { + windows.main.send('log', 'command line args:', process.argv) + } + argv.forEach(function (torrentId) { + windows.main.send('dispatch', 'onOpen', torrentId) + }) }) app.on('before-quit', function () { @@ -41,12 +57,8 @@ ipc.init() function onOpen (e, torrentId) { e.preventDefault() if (app.ipcReady) { - onReadyOpen() - } else { - app.on('ipcReady', onReadyOpen) - } - function onReadyOpen () { windows.main.send('dispatch', 'onOpen', torrentId) - windows.main.focus() + } else { + argv.push(torrentId) } } diff --git a/main/ipc.js b/main/ipc.js index 08e305ff..8d7dd3ac 100644 --- a/main/ipc.js +++ b/main/ipc.js @@ -57,10 +57,6 @@ function init () { ipcMain.on('blockPowerSave', blockPowerSave) ipcMain.on('unblockPowerSave', unblockPowerSave) - - ipcMain.on('log', function (e, message) { - console.log(message) - }) } function setBounds (bounds) { diff --git a/main/register-protocol-handler.js b/main/register-protocol-handler.js new file mode 100644 index 00000000..6e43a03e --- /dev/null +++ b/main/register-protocol-handler.js @@ -0,0 +1,46 @@ +module.exports = function () { + if (process.platform === 'win32') { + registerProtocolHandler('magnet', 'BitTorrent Magnet URL', process.execPath) + } +} + +/** + * To add a protocol handler on Windows, the following keys must be added to the Windows + * registry: + * + * HKEY_CLASSES_ROOT + * $PROTOCOL + * (Default) = "URL:$NAME" + * URL Protocol = "" + * shell + * open + * command + * (Default) = "$COMMAND" "%1" + * + * Source: https://msdn.microsoft.com/en-us/library/aa767914.aspx + * + * However, the "HKEY_CLASSES_ROOT" key can only be written by the Administrator user. + * So, we instead write to "HKEY_CURRENT_USER\Software\Classes", which is inherited by + * "HKEY_CLASSES_ROOT" anyway, and can be written by unprivileged users. + */ + +function registerProtocolHandler (protocol, name, command) { + var Registry = require('winreg') + + var protocolKey = new Registry({ + hive: Registry.HKCU, // HKEY_CURRENT_USER + key: '\\Software\\Classes\\' + protocol + }) + protocolKey.set('', Registry.REG_SZ, 'URL:' + name, callback) + protocolKey.set('URL Protocol', Registry.REG_SZ, '', callback) + + var commandKey = new Registry({ + hive: Registry.HKCU, + key: '\\Software\\Classes\\' + protocol + '\\shell\\open\\command' + }) + commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', callback) + + function callback (err) { + if (err) console.error(err.message || err) + } +} diff --git a/package.json b/package.json index e4f60318..976664c7 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "prettier-bytes": "^1.0.1", "upload-element": "^1.0.1", "virtual-dom": "^2.1.1", - "webtorrent": "^0.86.0" + "webtorrent": "^0.86.0", + "winreg": "^1.0.1" }, "devDependencies": { "electron-packager": "^5.0.0", diff --git a/renderer/index.js b/renderer/index.js index 4ed209bb..9989eb75 100644 --- a/renderer/index.js +++ b/renderer/index.js @@ -257,9 +257,9 @@ function jumpToTime (time) { function setupIpc () { ipcRenderer.send('ipcReady') - ipcRenderer.on('dispatch', function (e, action, ...args) { - dispatch(action, ...args) - }) + ipcRenderer.on('log', (e, ...args) => console.log(...args)) + + ipcRenderer.on('dispatch', (e, ...args) => dispatch(...args)) ipcRenderer.on('showOpenTorrentAddress', function (e) { state.modal = 'open-torrent-address-modal' @@ -283,7 +283,7 @@ function setupIpc () { function loadState (callback) { cfg.read(function (err, data) { if (err) console.error(err) - ipcRenderer.send('log', 'loaded state from ' + cfg.filePath) + console.log('loaded state from ' + cfg.filePath) // populate defaults if they're not there state.saved = Object.assign({}, state.defaultSavedState, data) @@ -305,7 +305,7 @@ function resumeTorrents () { // Write state.saved to the JSON state file function saveState () { - ipcRenderer.send('log', 'saving state to ' + cfg.filePath) + console.log('saving state to ' + cfg.filePath) cfg.write(state.saved, function (err) { if (err) console.error(err) update()