From a8c25d705a0478736c5888f528c9b29ac1e88b8c Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Tue, 22 Mar 2016 03:10:20 -0700 Subject: [PATCH 01/14] OS X packager: build to dist/ folder --- bin/package.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/package.js b/bin/package.js index 18504a2b..4c9c8cee 100755 --- a/bin/package.js +++ b/bin/package.js @@ -208,13 +208,13 @@ function buildDarwin (cb) { if (err) return cb(err) // Create .zip file (used by the auto-updater) - var zipPath = path.join(buildPath[0], BUILD_NAME + '.zip') + var zipPath = path.join(config.ROOT_PATH, 'dist', BUILD_NAME + '.zip') cp.execSync(`pushd ${buildPath[0]} && zip -r -y ${zipPath} ${config.APP_NAME + '.app'} && popd`) // Create a .dmg (OS X disk image) file, for easy user installation. var dmgOpts = { basepath: config.ROOT_PATH, - target: path.join(buildPath[0], BUILD_NAME + '.dmg'), + target: path.join(config.ROOT_PATH, 'dist', BUILD_NAME + '.dmg'), specification: { title: config.APP_NAME, icon: config.APP_ICON + '.icns', From 5eef284c6dd9528cf8d86c7f2111acee7ad8ee7b Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Tue, 22 Mar 2016 04:57:51 -0700 Subject: [PATCH 02/14] Windows: Create installer .exe file --- bin/package.js | 29 ++++++++++++++++- config.js | 4 ++- main/{register-handlers.js => handlers.js} | 6 +++- main/index.js | 37 +++++++++++++++++++--- package.json | 1 + 5 files changed, 70 insertions(+), 7 deletions(-) rename main/{register-handlers.js => handlers.js} (98%) diff --git a/bin/package.js b/bin/package.js index 4c9c8cee..56918d32 100755 --- a/bin/package.js +++ b/bin/package.js @@ -210,6 +210,7 @@ function buildDarwin (cb) { // Create .zip file (used by the auto-updater) var zipPath = path.join(config.ROOT_PATH, 'dist', BUILD_NAME + '.zip') cp.execSync(`pushd ${buildPath[0]} && zip -r -y ${zipPath} ${config.APP_NAME + '.app'} && popd`) + console.log('Created OS X .zip file.') // Create a .dmg (OS X disk image) file, for easy user installation. var dmgOpts = { @@ -239,6 +240,7 @@ function buildDarwin (cb) { if (info.type === 'step-begin') console.log(info.title + '...') }) dmg.on('finish', function (info) { + console.log('Created OS X disk image (.dmg) file.') cb(null, buildPath) }) }) @@ -247,7 +249,32 @@ function buildDarwin (cb) { } function buildWin32 (cb) { - electronPackager(Object.assign({}, all, win32), cb) + var installer = require('electron-winstaller') + + electronPackager(Object.assign({}, all, win32), function (err, buildPath) { + if (err) return cb(err) + + installer.createWindowsInstaller({ + name: config.APP_NAME, + productName: config.APP_NAME, + title: config.APP_NAME, + exe: config.APP_NAME + '.exe', + + appDirectory: buildPath[0], + outputDirectory: path.join(config.ROOT_PATH, 'dist'), + version: pkg.version, + description: config.APP_NAME, + authors: config.APP_TEAM + // iconUrl: config.APP_ICON + '.ico', + // setupIcon: config.APP_ICON + '.ico', + // certificateFile: '', + // usePackageJson: false + // loadingGif: '', + }).then(function () { + console.log('Created Windows installer.') + cb(null, buildPath) + }).catch(cb) + }) } function buildLinux (cb) { diff --git a/config.js b/config.js index 3a88c94b..b0e6fbec 100644 --- a/config.js +++ b/config.js @@ -2,13 +2,15 @@ var applicationConfigPath = require('application-config-path') var path = require('path') var APP_NAME = 'WebTorrent' +var APP_TEAM = 'The WebTorrent Project' var APP_VERSION = require('./package.json').version module.exports = { - APP_COPYRIGHT: 'Copyright © 2014-2016 The WebTorrent Project', + APP_COPYRIGHT: 'Copyright © 2014-2016 ' + APP_TEAM, APP_FILE_ICON: path.join(__dirname, 'static', 'WebTorrentFile'), APP_ICON: path.join(__dirname, 'static', 'WebTorrent'), APP_NAME: APP_NAME, + APP_TEAM: APP_TEAM, APP_VERSION: APP_VERSION, AUTO_UPDATE_URL: 'https://webtorrent.io/app/update?version=' + APP_VERSION, diff --git a/main/register-handlers.js b/main/handlers.js similarity index 98% rename from main/register-handlers.js rename to main/handlers.js index 95e46c42..9413f84a 100644 --- a/main/register-handlers.js +++ b/main/handlers.js @@ -1,6 +1,10 @@ +module.exports = { + init +} + var log = require('./log') -module.exports = function () { +function init () { if (process.platform === 'win32') { var path = require('path') var iconPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'static', 'WebTorrentFile.ico') diff --git a/main/index.js b/main/index.js index cea72c7c..a9abf502 100644 --- a/main/index.js +++ b/main/index.js @@ -4,13 +4,44 @@ var app = electron.app var autoUpdater = require('./auto-updater') var config = require('../config') +var handlers = require('./handlers') var ipc = require('./ipc') var log = require('./log') var menu = require('./menu') -var registerProtocolHandler = require('./register-handlers') var shortcuts = require('./shortcuts') var windows = require('./windows') +var argv = sliceArgv(process.argv) + +if (process.platform === 'win32') { + var squirrelCmd = argv[0] + if (squirrelCmd === '--squirrel-install' || squirrelCmd === '--squirrel-updated') { + handlers.init() + + // TODO: + // - Install desktop and start menu shortcuts + // - Add explorer context menus + + // Always quit when done + app.quit() + } + if (squirrelCmd === '--squirrel-uninstall') { + // Undo anything we did in the --squirrel-install and --squirrel-updated handlers + + // TODO: implement this + + // Always quit when done + app.quit() + } + if (squirrelCmd === '--squirrel-obsolete') { + // This is called on the outgoing version of your app before we update to the new + // version - it's the opposite of --squirrel-updated + + // Always quit when done + app.quit() + } +} + // Prevent multiple instances of the app from running at the same time. New instances // signal this instance and exit. var shouldQuit = app.makeSingleInstance(function (newArgv) { @@ -32,8 +63,6 @@ if (shouldQuit) { app.quit() } -var argv = sliceArgv(process.argv) - app.on('open-file', onOpen) app.on('open-url', onOpen) app.on('will-finish-launching', function () { @@ -48,7 +77,7 @@ app.on('ready', function () { menu.init() windows.createMainWindow() shortcuts.init() - registerProtocolHandler() + if (process.platform !== 'win32') handlers.init() }) app.on('ipcReady', function () { diff --git a/package.json b/package.json index 197832ff..0a548050 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "electron-osx-sign": "^0.3.0", "electron-packager": "^5.0.0", "electron-prebuilt": "0.37.2", + "electron-winstaller": "^2.0.5", "gh-release": "^2.0.2", "path-exists": "^2.1.0", "plist": "^1.2.0", From 16165aa4a997cb840f322e805b8ab9fd3d8f6846 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Thu, 24 Mar 2016 20:58:12 -0700 Subject: [PATCH 03/14] simplify arguments to `npm run package` --- README.md | 2 +- bin/package.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8b1fc99d..cf5cc007 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ To build for one platform: $ npm run package -- [platform] ``` -Where `[platform]` is `--darwin`, `--linux`, or `--win32`. +Where `[platform]` is `darwin`, `linux`, or `win32`. #### Windows build notes diff --git a/bin/package.js b/bin/package.js index 56918d32..d78865b6 100755 --- a/bin/package.js +++ b/bin/package.js @@ -15,11 +15,11 @@ var BUILD_NAME = config.APP_NAME + '-v' + config.APP_VERSION function build () { var platform = process.argv[2] - if (platform === '--darwin') { + if (platform === 'darwin') { buildDarwin(printDone) - } else if (platform === '--win32') { + } else if (platform === 'win32') { buildWin32(printDone) - } else if (platform === '--linux') { + } else if (platform === 'linux') { buildLinux(printDone) } else { buildDarwin(function (err, buildPath) { From 4bfe218317ce8b03dc132928ff93cecadd1f7107 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Thu, 24 Mar 2016 23:04:56 -0700 Subject: [PATCH 04/14] package: conditionally require darwin packages --- bin/package.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/package.js b/bin/package.js index d78865b6..ede110af 100755 --- a/bin/package.js +++ b/bin/package.js @@ -137,9 +137,7 @@ var linux = { build() function buildDarwin (cb) { - var appDmg = require('appdmg') var plist = require('plist') - var sign = require('electron-osx-sign') electronPackager(Object.assign({}, all, darwin), function (err, buildPath) { if (err) return cb(err) @@ -185,6 +183,9 @@ function buildDarwin (cb) { cp.execSync(`cp ${config.APP_FILE_ICON + '.icns'} ${resourcesPath}`) if (process.platform === 'darwin') { + var appDmg = require('appdmg') + var sign = require('electron-osx-sign') + /* * Sign the app with Apple Developer ID certificate. We sign the app for 2 reasons: * - So the auto-updater (Squirrrel.Mac) can check that app updates are signed by From a0370e39da523e5d2b02999d76e8a9dfeaf06b56 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Thu, 24 Mar 2016 23:45:20 -0700 Subject: [PATCH 05/14] Windows installer: include icon url, setup icon, loading gif --- bin/package.js | 11 ++++++----- static/loading.gif | Bin 0 -> 34401 bytes 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 static/loading.gif diff --git a/bin/package.js b/bin/package.js index ede110af..5a9cee16 100755 --- a/bin/package.js +++ b/bin/package.js @@ -255,6 +255,7 @@ function buildWin32 (cb) { electronPackager(Object.assign({}, all, win32), function (err, buildPath) { if (err) return cb(err) + console.log('Creating Windows installer...') installer.createWindowsInstaller({ name: config.APP_NAME, productName: config.APP_NAME, @@ -265,12 +266,12 @@ function buildWin32 (cb) { outputDirectory: path.join(config.ROOT_PATH, 'dist'), version: pkg.version, description: config.APP_NAME, - authors: config.APP_TEAM - // iconUrl: config.APP_ICON + '.ico', - // setupIcon: config.APP_ICON + '.ico', - // certificateFile: '', + authors: config.APP_TEAM, + iconUrl: config.APP_ICON + '.ico', + setupIcon: config.APP_ICON + '.ico', + // certificateFile: '', // TODO // usePackageJson: false - // loadingGif: '', + loadingGif: path.join(config.STATIC_PATH, 'loading.gif') }).then(function () { console.log('Created Windows installer.') cb(null, buildPath) diff --git a/static/loading.gif b/static/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..355cfc83d593a9acfbbe552a09e3945dc58424e3 GIT binary patch literal 34401 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 aA};2lF76^P_M$KTA}|J{Fz!e|002Ar)NJJd literal 0 HcmV?d00001 From ecb408357bdf67dd7f0affa218fd90aaff910a28 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Thu, 24 Mar 2016 23:56:32 -0700 Subject: [PATCH 06/14] Prevent --squirrel arguments from getting added as torrents --- main/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main/index.js b/main/index.js index a9abf502..5cb2757b 100644 --- a/main/index.js +++ b/main/index.js @@ -40,6 +40,9 @@ if (process.platform === 'win32') { // Always quit when done app.quit() } + if (squirrelCmd === '--squirrel-firstrun') { + argv.shift() + } } // Prevent multiple instances of the app from running at the same time. New instances From 27f9bf1cc64dab0510c533d24f8368446c05b56c Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Fri, 25 Mar 2016 00:03:57 -0700 Subject: [PATCH 07/14] Windows/linux: Don't autohide top menu bar (it's important) --- main/windows.js | 1 - 1 file changed, 1 deletion(-) diff --git a/main/windows.js b/main/windows.js index c3541ec7..e43830f3 100644 --- a/main/windows.js +++ b/main/windows.js @@ -13,7 +13,6 @@ var menu = require('./menu') function createMainWindow () { var win = windows.main = new electron.BrowserWindow({ - autoHideMenuBar: true, // Hide top menu bar unless Alt key is pressed (Windows, Linux) backgroundColor: '#282828', darkTheme: true, // Forces dark theme (GTK+3) icon: config.APP_ICON + '.png', From 212cd23c4f5a4e5f454a71648dc8f75b1d7ec2e1 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Fri, 25 Mar 2016 00:26:48 -0700 Subject: [PATCH 08/14] Move --squirrel-xxxx handling to new file --- main/index.js | 176 +++++++++++++++++++---------------------- main/squirrel-win32.js | 51 ++++++++++++ 2 files changed, 132 insertions(+), 95 deletions(-) create mode 100644 main/squirrel-win32.js diff --git a/main/index.js b/main/index.js index 5cb2757b..b0a1e88c 100644 --- a/main/index.js +++ b/main/index.js @@ -9,49 +9,101 @@ var ipc = require('./ipc') var log = require('./log') var menu = require('./menu') var shortcuts = require('./shortcuts') +var squirrelWin32 = require('./squirrel-win32') var windows = require('./windows') +var shouldQuit = false var argv = sliceArgv(process.argv) if (process.platform === 'win32') { - var squirrelCmd = argv[0] - if (squirrelCmd === '--squirrel-install' || squirrelCmd === '--squirrel-updated') { - handlers.init() + shouldQuit = squirrelWin32.handleArgv(argv[0]) - // TODO: - // - Install desktop and start menu shortcuts - // - Add explorer context menus + // Remove any --squirrel-xxxx arguments + argv.shift() +} - // Always quit when done +if (!shouldQuit) { + // Prevent multiple instances of app from running at same time. New instances signal + // this instance and quit. + shouldQuit = app.makeSingleInstance(onAppOpen) + if (shouldQuit) { app.quit() } - if (squirrelCmd === '--squirrel-uninstall') { - // Undo anything we did in the --squirrel-install and --squirrel-updated handlers - - // TODO: implement this - - // Always quit when done - app.quit() - } - if (squirrelCmd === '--squirrel-obsolete') { - // This is called on the outgoing version of your app before we update to the new - // version - it's the opposite of --squirrel-updated - - // Always quit when done - app.quit() - } - if (squirrelCmd === '--squirrel-firstrun') { - argv.shift() - } } -// Prevent multiple instances of the app from running at the same time. New instances -// signal this instance and exit. -var shouldQuit = app.makeSingleInstance(function (newArgv) { +if (!shouldQuit) { + init() +} + +function init () { + app.ipcReady = false // main window has finished loading and IPC is ready + app.isQuitting = false + + // Open handlers must be added as early as possible + app.on('open-file', onOpen) + app.on('open-url', onOpen) + + ipc.init() + + app.on('will-finish-launching', function () { + autoUpdater.init() + setupCrashReporter() + }) + + app.on('ready', function () { + menu.init() + windows.createMainWindow() + shortcuts.init() + if (process.platform !== 'win32') handlers.init() + }) + + app.on('ipcReady', function () { + log('Command line args:', argv) + argv.forEach(function (torrentId) { + windows.main.send('dispatch', 'onOpen', torrentId) + }) + }) + + app.on('before-quit', function () { + app.isQuitting = true + }) + + app.on('activate', function () { + if (windows.main) { + windows.main.show() + } else { + windows.createMainWindow() + } + }) + + app.on('window-all-closed', function () { + if (process.platform !== 'darwin') { + app.quit() + } + }) +} + +function onOpen (e, torrentId) { + e.preventDefault() + + if (app.ipcReady) { + windows.main.send('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.focusMainWindow() + }, 100) + } else { + argv.push(torrentId) + } +} + +function onAppOpen (newArgv) { newArgv = sliceArgv(newArgv) if (app.ipcReady) { - log('Second app instance attempted to open but was prevented') + log('Second app instance opened, but was prevented:', newArgv) windows.focusMainWindow() newArgv.forEach(function (torrentId) { @@ -60,72 +112,6 @@ var shouldQuit = app.makeSingleInstance(function (newArgv) { } else { argv.push(...newArgv) } -}) - -if (shouldQuit) { - app.quit() -} - -app.on('open-file', onOpen) -app.on('open-url', onOpen) -app.on('will-finish-launching', function () { - autoUpdater.init() - setupCrashReporter() -}) - -app.ipcReady = false // main window has finished loading and IPC is ready -app.isQuitting = false - -app.on('ready', function () { - menu.init() - windows.createMainWindow() - shortcuts.init() - if (process.platform !== 'win32') handlers.init() -}) - -app.on('ipcReady', function () { - log('IS_PRODUCTION:', config.IS_PRODUCTION) - if (argv.length) { - log('command line args:', process.argv) - } - argv.forEach(function (torrentId) { - windows.main.send('dispatch', 'onOpen', torrentId) - }) -}) - -app.on('before-quit', function () { - app.isQuitting = true -}) - -app.on('activate', function () { - if (windows.main) { - windows.main.show() - } else { - windows.createMainWindow(menu) - } -}) - -app.on('window-all-closed', function () { - if (process.platform !== 'darwin') { - app.quit() - } -}) - -ipc.init() - -function onOpen (e, torrentId) { - e.preventDefault() - if (app.ipcReady) { - windows.main.send('dispatch', 'onOpen', torrentId) - setTimeout(function () { - // Required for magnet links opened from Chrome otherwise the confirmation dialog - // that Chrome shows causes Chrome to steal back the focus. - // Electron issue: https://github.com/atom/electron/issues/4338 - windows.focusMainWindow() - }, 100) - } else { - argv.push(torrentId) - } } function sliceArgv (argv) { diff --git a/main/squirrel-win32.js b/main/squirrel-win32.js new file mode 100644 index 00000000..f16bd22d --- /dev/null +++ b/main/squirrel-win32.js @@ -0,0 +1,51 @@ +module.exports = { + handleArgv +} + +var electron = require('electron') + +var app = electron.app + +var handlers = require('./handlers') + +function handleArgv (cmd) { + if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') { + handlers.init() + + // TODO: + // - Install desktop and start menu shortcuts + // - Add explorer context menus + + // Always quit when done + app.quit() + return true + } + + if (cmd === '--squirrel-uninstall') { + // Undo anything we did in the --squirrel-install and --squirrel-updated handlers + + // TODO: implement this + + // Always quit when done + app.quit() + return true + } + + if (cmd === '--squirrel-obsolete') { + // This is called on the outgoing version of your app before we update to the new + // version - it's the opposite of --squirrel-updated + + // Always quit when done + app.quit() + return true + } + + if (cmd === '--squirrel-firstrun') { + // This is called on the first run of the app. + + // Do not quit the app + return false + } + + return false +} From 6f9121ac12c4ffaa21e3ba00b750e7ecbfd16ae9 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Fri, 25 Mar 2016 00:55:19 -0700 Subject: [PATCH 09/14] delay install splash screen so user sees it --- main/squirrel-win32.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/main/squirrel-win32.js b/main/squirrel-win32.js index f16bd22d..cf6401cb 100644 --- a/main/squirrel-win32.js +++ b/main/squirrel-win32.js @@ -9,41 +9,46 @@ var app = electron.app var handlers = require('./handlers') function handleArgv (cmd) { - if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') { + if (cmd === '--squirrel-install') { + // App was just installed. handlers.init() // TODO: // - Install desktop and start menu shortcuts // - Add explorer context menus - // Always quit when done + // Ensure user sees install splash screen so they realize that Setup.exe actually + // installed an application and isn't the application itself. + setTimeout(function () { + app.quit() + }, 5000) + return true + } + + if (cmd === '--squirrel-updated') { + // App was just updated. (Called on new version of app.) + handlers.init() app.quit() return true } if (cmd === '--squirrel-uninstall') { - // Undo anything we did in the --squirrel-install and --squirrel-updated handlers + // App was just uninstalled. Undo anything we did in the --squirrel-install and + // --squirrel-updated handlers // TODO: implement this - - // Always quit when done app.quit() return true } if (cmd === '--squirrel-obsolete') { - // This is called on the outgoing version of your app before we update to the new - // version - it's the opposite of --squirrel-updated - - // Always quit when done + // App will be updated. (Called on outgoing version of app.) app.quit() return true } if (cmd === '--squirrel-firstrun') { - // This is called on the first run of the app. - - // Do not quit the app + // This is called on the app's first run. Do not quit, allow startup to continue. return false } From aa9310eb1568dfaca7a0764e57066c43dff8e032 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Fri, 25 Mar 2016 01:39:44 -0700 Subject: [PATCH 10/14] Windows: create desktop/start menu shortcuts on install/update --- main/index.js | 7 +++---- main/squirrel-win32.js | 43 +++++++++++++++++++++++++----------------- package.json | 2 +- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/main/index.js b/main/index.js index b0a1e88c..b0cd2027 100644 --- a/main/index.js +++ b/main/index.js @@ -16,10 +16,9 @@ var shouldQuit = false var argv = sliceArgv(process.argv) if (process.platform === 'win32') { - shouldQuit = squirrelWin32.handleArgv(argv[0]) - - // Remove any --squirrel-xxxx arguments - argv.shift() + shouldQuit = squirrelWin32.handleEvent(argv[0]) + argv.shift() // Remove any --squirrel-xxxx arguments + // app.setAppUserModelId('com.squirrel.WebTorrent.WebTorrent') } if (!shouldQuit) { diff --git a/main/squirrel-win32.js b/main/squirrel-win32.js index cf6401cb..14fa171d 100644 --- a/main/squirrel-win32.js +++ b/main/squirrel-win32.js @@ -1,34 +1,33 @@ module.exports = { - handleArgv + handleEvent } +var cp = require('child_process') var electron = require('electron') +var path = require('path') var app = electron.app +var config = require('../config') var handlers = require('./handlers') -function handleArgv (cmd) { - if (cmd === '--squirrel-install') { - // App was just installed. - handlers.init() +function handleEvent (cmd) { + if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') { + // App was installed/updated. (Called on new version of app.) - // TODO: - // - Install desktop and start menu shortcuts - // - Add explorer context menus + // Install protocol/file handlers, desktop/start menu shortcuts. + handlers.init() + createShortcuts() // Ensure user sees install splash screen so they realize that Setup.exe actually // installed an application and isn't the application itself. - setTimeout(function () { + if (cmd === '--squirrel-install') { + setTimeout(function () { + app.quit() + }, 5000) + } else { app.quit() - }, 5000) - return true - } - - if (cmd === '--squirrel-updated') { - // App was just updated. (Called on new version of app.) - handlers.init() - app.quit() + } return true } @@ -54,3 +53,13 @@ function handleArgv (cmd) { return false } + +function createShortcuts () { + var updateExe = path.join(process.execPath, '..', 'Update.exe') + var args = [ + '--createShortcut="' + config.APP_NAME + '.exe"', + '--shortcut-locations="Desktop,StartMenu,Startup"', + '--process-start-args="--autostart"' + ] + cp.execSync(updateExe + args.join(' ')) +} diff --git a/package.json b/package.json index 0a548050..22f36fa2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "webtorrent-app", + "name": "WebTorrent", "description": "WebTorrent, the streaming torrent client. For OS X, Windows, and Linux.", "version": "0.0.1", "author": { From f0a37b032ed36a97bcfc7019e76a5cbcff18f947 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Fri, 25 Mar 2016 01:44:46 -0700 Subject: [PATCH 11/14] Make install.gif not blink --- static/loading.gif | Bin 34401 -> 20110 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/static/loading.gif b/static/loading.gif index 355cfc83d593a9acfbbe552a09e3945dc58424e3..f938e69f2b313f59665fdf8ef277c4d935189b7c 100644 GIT binary patch delta 19489 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 delta 33942 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 XqAu Date: Fri, 25 Mar 2016 02:24:08 -0700 Subject: [PATCH 12/14] Windows: base Squirrel shortcut code on Nylas N1 --- main/squirrel-win32.js | 111 +++++++++++++++++++++++++++++++++-------- package.json | 1 + 2 files changed, 91 insertions(+), 21 deletions(-) diff --git a/main/squirrel-win32.js b/main/squirrel-win32.js index 14fa171d..b5e9550a 100644 --- a/main/squirrel-win32.js +++ b/main/squirrel-win32.js @@ -4,44 +4,54 @@ module.exports = { var cp = require('child_process') var electron = require('electron') +var fs = require('fs') +var os = require('os') var path = require('path') +var pathExists = require('path-exists') var app = electron.app -var config = require('../config') var handlers = require('./handlers') +var exeName = path.basename(process.execPath) +var updateDotExe = path.join(process.execPath, '..', '..', 'Update.exe') + function handleEvent (cmd) { - if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') { - // App was installed/updated. (Called on new version of app.) + if (cmd === '--squirrel-install') { + // App was installed. // Install protocol/file handlers, desktop/start menu shortcuts. handlers.init() - createShortcuts() - // Ensure user sees install splash screen so they realize that Setup.exe actually - // installed an application and isn't the application itself. - if (cmd === '--squirrel-install') { + createShortcuts(function () { + // Ensure user sees install splash screen so they realize that Setup.exe actually + // installed an application and isn't the application itself. setTimeout(function () { app.quit() }, 5000) - } else { + }) + return true + } + + if (cmd === '--squirrel-updated') { + // App was updated. (Called on new version of app) + updateShortcuts(function () { app.quit() - } + }) return true } if (cmd === '--squirrel-uninstall') { // App was just uninstalled. Undo anything we did in the --squirrel-install and // --squirrel-updated handlers - - // TODO: implement this - app.quit() + removeShortcuts(function () { + app.quit() + }) return true } if (cmd === '--squirrel-obsolete') { - // App will be updated. (Called on outgoing version of app.) + // App will be updated. (Called on outgoing version of app) app.quit() return true } @@ -54,12 +64,71 @@ function handleEvent (cmd) { return false } -function createShortcuts () { - var updateExe = path.join(process.execPath, '..', 'Update.exe') - var args = [ - '--createShortcut="' + config.APP_NAME + '.exe"', - '--shortcut-locations="Desktop,StartMenu,Startup"', - '--process-start-args="--autostart"' - ] - cp.execSync(updateExe + args.join(' ')) +// Spawn a command and invoke the callback when it completes with an error and the output +// from standard out. +function spawn (command, args, cb) { + var stdout = '' + + var child + try { + child = cp.spawn(command, args) + } catch (err) { + // Spawn can throw an error + process.nextTick(function () { + cb(error, stdout) + }) + return + } + + child.stdout.on('data', function (data) { + stdout += data + }) + + var error = null + child.on('error', function (processError) { + error = processError + }) + child.on('close', function (code, signal) { + if (code !== 0 && !error) error = new Error('Command failed: #{signal || code}') + if (error) error.stdout = stdout + cb(error, stdout) + }) +} + +// Spawn Squirrel's Update.exe with the given arguments and invoke the callback when the +// command completes. +function spawnUpdate (args, cb) { + spawn(updateDotExe, args, cb) +} + +// Create desktop/start menu shortcuts using the Squirrel Update.exe command line API +function createShortcuts (cb) { + spawnUpdate(['--createShortcut', exeName], cb) +} + +// Update desktop/start menu shortcuts using the Squirrel Update.exe command line API +function updateShortcuts (cb) { + var homeDir = os.homedir() + if (homeDir) { + var desktopShortcutPath = path.join(homeDir, 'Desktop', 'WebTorrent.lnk') + // Check if the desktop shortcut has been previously deleted and and keep it deleted + // if it was + pathExists(desktopShortcutPath).then(function (desktopShortcutExists) { + createShortcuts(function () { + if (desktopShortcutExists) { + cb() + } else { + // Remove the unwanted desktop shortcut that was recreated + fs.unlink(desktopShortcutPath, cb) + } + }) + }) + } else { + createShortcuts(cb) + } +} + +// Remove desktop/start menu shortcuts using the Squirrel Update.exe command line API +function removeShortcuts (cb) { + spawnUpdate(['--removeShortcut', exeName], cb) } diff --git a/package.json b/package.json index 22f36fa2..86af265a 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "mkdirp": "^0.5.1", "musicmetadata": "^2.0.2", "network-address": "^1.1.0", + "path-exists": "^2.1.0", "prettier-bytes": "^1.0.1", "upload-element": "^1.0.1", "virtual-dom": "^2.1.1", From f0d0afc36fdda463b347603abdac339cb1350dc7 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Fri, 25 Mar 2016 02:25:53 -0700 Subject: [PATCH 13/14] npm install before packaging --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 86af265a..aee14943 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "scripts": { "clean": "node ./bin/clean.js", "debug": "DEBUG=* electron .", - "package": "npm prune && npm dedupe && node ./bin/package.js", + "package": "npm install && npm prune && npm dedupe && node ./bin/package.js", "size": "npm run package -- --darwin && du -ch dist/WebTorrent-darwin-x64 | grep total", "start": "electron .", "test": "standard", From c273aafad3d7dab7903f3c376cd4668ceabc0429 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Fri, 25 Mar 2016 02:40:27 -0700 Subject: [PATCH 14/14] Windows: fix magnet link handling --- main/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/index.js b/main/index.js index b0cd2027..335b8b68 100644 --- a/main/index.js +++ b/main/index.js @@ -17,7 +17,7 @@ var argv = sliceArgv(process.argv) if (process.platform === 'win32') { shouldQuit = squirrelWin32.handleEvent(argv[0]) - argv.shift() // Remove any --squirrel-xxxx arguments + argv = argv.filter((arg) => arg.indexOf('--squirrel') === -1) // app.setAppUserModelId('com.squirrel.WebTorrent.WebTorrent') }