diff --git a/bin/package.js b/bin/package.js index 3dede2f1..09a2dcea 100755 --- a/bin/package.js +++ b/bin/package.js @@ -327,11 +327,11 @@ function buildDarwin (cb) { } var dmg = appDmg(dmgOpts) - dmg.on('error', cb) + dmg.once('error', cb) dmg.on('progress', function (info) { if (info.type === 'step-begin') console.log(info.title + '...') }) - dmg.on('finish', function (info) { + dmg.once('finish', function (info) { console.log('OS X: Created dmg.') cb(null) }) diff --git a/main/index.js b/main/index.js index 2d2c8b93..1d120f86 100644 --- a/main/index.js +++ b/main/index.js @@ -55,7 +55,7 @@ function init () { ipc.init() - app.on('will-finish-launching', function () { + app.once('will-finish-launching', function () { crashReporter.init() }) @@ -70,7 +70,7 @@ function init () { setTimeout(delayedInit, config.DELAYED_INIT) }) - app.on('ipcReady', function () { + app.once('ipcReady', function () { log('Command line args:', argv) processArgv(argv) console.timeEnd('init') @@ -103,13 +103,12 @@ function onOpen (e, torrentId) { e.preventDefault() if (app.ipcReady) { - windows.main.dispatch('onOpen', torrentId) // Magnet links opened from Chrome won't focus the app without a setTimeout. // The confirmation dialog Chrome shows causes Chrome to steal back the focus. // Electron issue: https://github.com/atom/electron/issues/4338 - setTimeout(function () { - windows.main.show() - }, 100) + setTimeout(() => windows.main.show(), 100) + + processArgv([ torrentId ]) } else { argv.push(torrentId) } @@ -117,7 +116,6 @@ function onOpen (e, torrentId) { function onAppOpen (newArgv) { newArgv = sliceArgv(newArgv) - console.log(newArgv) if (app.ipcReady) { log('Second app instance opened, but was prevented:', newArgv) @@ -134,7 +132,7 @@ function sliceArgv (argv) { } function processArgv (argv) { - var paths = [] + var torrentIds = [] argv.forEach(function (arg) { if (arg === '-n') { dialog.openSeedDirectory() @@ -146,10 +144,10 @@ function processArgv (argv) { // Ignore OS X launchd "process serial number" argument // Issue: https://github.com/feross/webtorrent-desktop/issues/214 } else { - paths.push(arg) + torrentIds.push(arg) } }) - if (paths.length > 0) { - windows.main.dispatch('onOpen', paths) + if (torrentIds.length > 0) { + windows.main.dispatch('onOpen', torrentIds) } } diff --git a/main/ipc.js b/main/ipc.js index 479e00e4..8a81853f 100644 --- a/main/ipc.js +++ b/main/ipc.js @@ -25,13 +25,12 @@ var vlcProcess function init () { var ipc = electron.ipcMain - ipc.on('ipcReady', function (e) { - windows.main.show() + ipc.once('ipcReady', function (e) { app.ipcReady = true app.emit('ipcReady') }) - ipc.on('ipcReadyWebTorrent', function (e) { + ipc.once('ipcReadyWebTorrent', function (e) { app.ipcReadyWebTorrent = true log('sending %d queued messages from the main win to the webtorrent window', messageQueueMainToWebTorrent.length) diff --git a/main/log.js b/main/log.js index e8a05924..1c6eb0c6 100644 --- a/main/log.js +++ b/main/log.js @@ -17,7 +17,7 @@ function log (...args) { if (app.ipcReady) { windows.main.send('log', ...args) } else { - app.on('ipcReady', () => windows.main.send('log', ...args)) + app.once('ipcReady', () => windows.main.send('log', ...args)) } } @@ -25,6 +25,6 @@ function error (...args) { if (app.ipcReady) { windows.main.send('error', ...args) } else { - app.on('ipcReady', () => windows.main.send('error', ...args)) + app.once('ipcReady', () => windows.main.send('error', ...args)) } } diff --git a/main/windows/about.js b/main/windows/about.js index 7fba55d1..0a29d51d 100644 --- a/main/windows/about.js +++ b/main/windows/about.js @@ -31,7 +31,6 @@ function init () { // No menu on the About window win.setMenu(null) - // TODO: can this be removed? win.webContents.on('did-finish-load', function () { win.show() }) diff --git a/main/windows/main.js b/main/windows/main.js index b0f3d04b..52b5b041 100644 --- a/main/windows/main.js +++ b/main/windows/main.js @@ -36,7 +36,6 @@ function init () { icon: getIconPath(), // Window icon (Windows, Linux) minWidth: config.WINDOW_MIN_WIDTH, minHeight: config.WINDOW_MIN_HEIGHT, - show: false, // Hide window until renderer sends 'ipcReady' title: config.APP_WINDOW_TITLE, titleBarStyle: 'hidden-inset', // Hide title bar (OS X) useContentSize: true, // Specify web page size without OS chrome diff --git a/renderer/main.css b/renderer/main.css index 0ccc7705..c7dc91dc 100644 --- a/renderer/main.css +++ b/renderer/main.css @@ -65,7 +65,7 @@ table { display: flex; flex-flow: column; background: rgb(40, 40, 40); - animation: fadein 1s; + animation: fadein 0.5s; } .app:not(.is-focused) { diff --git a/renderer/main.js b/renderer/main.js index 1d66f848..f8d2718a 100644 --- a/renderer/main.js +++ b/renderer/main.js @@ -3,18 +3,9 @@ console.time('init') var crashReporter = require('../crash-reporter') crashReporter.init() -var electron = require('electron') - -// Electron apps have two processes: a main process (node) runs first and starts -// a renderer process (essentially a Chrome window). We're in the renderer process, -// and this IPC channel receives from and sends messages to the main process -var ipcRenderer = electron.ipcRenderer - -// Listen for messages from the main process -setupIpc() - var appConfig = require('application-config')('WebTorrent') var dragDrop = require('drag-drop') +var electron = require('electron') var fs = require('fs-extra') var mainLoop = require('main-loop') var parallel = require('run-parallel') @@ -46,6 +37,11 @@ var vdomLoop var state = State.getInitialState() state.location.go({ url: 'home' }) // Add first page to location history +// Electron apps have two processes: a main process (node) runs first and starts +// a renderer process (essentially a Chrome window). We're in the renderer process, +// and this IPC channel receives from and sends messages to the main process +var ipcRenderer = electron.ipcRenderer + // All state lives in state.js. `state.saved` is read from and written to a file. // All other state is ephemeral. First we load state.saved then initialize the app. loadState(init) @@ -90,6 +86,9 @@ function init () { }) document.body.appendChild(vdomLoop.target) + // Listen for messages from the main process + setupIpc() + // Calling update() updates the UI given the current state // Do this at least once a second to give every file in every torrentSummary // a progress bar and to keep the cursor in sync when playing a video @@ -106,9 +105,9 @@ function init () { window.addEventListener('focus', onFocus) window.addEventListener('blur', onBlur) - // Done! Ideally we want to get here <100ms after the user clicks the app sound.play('STARTUP') + // Done! Ideally we want to get here < 500ms after the user clicks the app console.timeEnd('init') } @@ -139,7 +138,7 @@ function render (state) { // Calls render() to go from state -> UI, then applies to vdom to the real DOM. function update () { showOrHidePlayerControls() - if (vdomLoop) vdomLoop.update(state) + vdomLoop.update(state) updateElectron() } @@ -458,8 +457,6 @@ function isCasting () { } function setupIpc () { - ipcRenderer.send('ipcReady') - ipcRenderer.on('log', (e, ...args) => console.log(...args)) ipcRenderer.on('error', (e, ...args) => console.error(...args)) @@ -486,13 +483,15 @@ function setupIpc () { ipcRenderer.on('wt-poster', (e, ...args) => torrentPosterSaved(...args)) ipcRenderer.on('wt-audio-metadata', (e, ...args) => torrentAudioMetadata(...args)) ipcRenderer.on('wt-server-running', (e, ...args) => torrentServerRunning(...args)) + + ipcRenderer.send('ipcReady') } // Starts all torrents that aren't paused on program startup function resumeTorrents () { state.saved.torrents - .filter((x) => x.status !== 'paused') - .forEach((x) => startTorrentingSummary(x)) + .filter((torrentSummary) => torrentSummary.status !== 'paused') + .forEach((torrentSummary) => startTorrentingSummary(torrentSummary)) } // Updates a single property in the UNSAVED prefs diff --git a/renderer/webtorrent.js b/renderer/webtorrent.js index 642f5fa1..3dd5ec2c 100644 --- a/renderer/webtorrent.js +++ b/renderer/webtorrent.js @@ -270,7 +270,7 @@ function getTorrentProgress () { function startServer (infoHash, index) { var torrent = client.get(infoHash) if (torrent.ready) startServerFromReadyTorrent(torrent, index) - else torrent.on('ready', () => startServerFromReadyTorrent(torrent, index)) + else torrent.once('ready', () => startServerFromReadyTorrent(torrent, index)) } function startServerFromReadyTorrent (torrent, index, cb) {