Merge pull request #218 from feross/windows-installer
Create Windows .exe installer
This commit is contained in:
@@ -58,7 +58,7 @@ To build for one platform:
|
|||||||
$ npm run package -- [platform]
|
$ npm run package -- [platform]
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `[platform]` is `--darwin`, `--linux`, or `--win32`.
|
Where `[platform]` is `darwin`, `linux`, or `win32`.
|
||||||
|
|
||||||
#### Windows build notes
|
#### Windows build notes
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ var BUILD_NAME = config.APP_NAME + '-v' + config.APP_VERSION
|
|||||||
|
|
||||||
function build () {
|
function build () {
|
||||||
var platform = process.argv[2]
|
var platform = process.argv[2]
|
||||||
if (platform === '--darwin') {
|
if (platform === 'darwin') {
|
||||||
buildDarwin(printDone)
|
buildDarwin(printDone)
|
||||||
} else if (platform === '--win32') {
|
} else if (platform === 'win32') {
|
||||||
buildWin32(printDone)
|
buildWin32(printDone)
|
||||||
} else if (platform === '--linux') {
|
} else if (platform === 'linux') {
|
||||||
buildLinux(printDone)
|
buildLinux(printDone)
|
||||||
} else {
|
} else {
|
||||||
buildDarwin(function (err, buildPath) {
|
buildDarwin(function (err, buildPath) {
|
||||||
@@ -137,9 +137,7 @@ var linux = {
|
|||||||
build()
|
build()
|
||||||
|
|
||||||
function buildDarwin (cb) {
|
function buildDarwin (cb) {
|
||||||
var appDmg = require('appdmg')
|
|
||||||
var plist = require('plist')
|
var plist = require('plist')
|
||||||
var sign = require('electron-osx-sign')
|
|
||||||
|
|
||||||
electronPackager(Object.assign({}, all, darwin), function (err, buildPath) {
|
electronPackager(Object.assign({}, all, darwin), function (err, buildPath) {
|
||||||
if (err) return cb(err)
|
if (err) return cb(err)
|
||||||
@@ -185,6 +183,9 @@ function buildDarwin (cb) {
|
|||||||
cp.execSync(`cp ${config.APP_FILE_ICON + '.icns'} ${resourcesPath}`)
|
cp.execSync(`cp ${config.APP_FILE_ICON + '.icns'} ${resourcesPath}`)
|
||||||
|
|
||||||
if (process.platform === 'darwin') {
|
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:
|
* 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
|
* - So the auto-updater (Squirrrel.Mac) can check that app updates are signed by
|
||||||
@@ -208,13 +209,14 @@ function buildDarwin (cb) {
|
|||||||
if (err) return cb(err)
|
if (err) return cb(err)
|
||||||
|
|
||||||
// Create .zip file (used by the auto-updater)
|
// 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`)
|
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.
|
// Create a .dmg (OS X disk image) file, for easy user installation.
|
||||||
var dmgOpts = {
|
var dmgOpts = {
|
||||||
basepath: config.ROOT_PATH,
|
basepath: config.ROOT_PATH,
|
||||||
target: path.join(buildPath[0], BUILD_NAME + '.dmg'),
|
target: path.join(config.ROOT_PATH, 'dist', BUILD_NAME + '.dmg'),
|
||||||
specification: {
|
specification: {
|
||||||
title: config.APP_NAME,
|
title: config.APP_NAME,
|
||||||
icon: config.APP_ICON + '.icns',
|
icon: config.APP_ICON + '.icns',
|
||||||
@@ -239,6 +241,7 @@ function buildDarwin (cb) {
|
|||||||
if (info.type === 'step-begin') console.log(info.title + '...')
|
if (info.type === 'step-begin') console.log(info.title + '...')
|
||||||
})
|
})
|
||||||
dmg.on('finish', function (info) {
|
dmg.on('finish', function (info) {
|
||||||
|
console.log('Created OS X disk image (.dmg) file.')
|
||||||
cb(null, buildPath)
|
cb(null, buildPath)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -247,7 +250,33 @@ function buildDarwin (cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildWin32 (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)
|
||||||
|
|
||||||
|
console.log('Creating Windows installer...')
|
||||||
|
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: '', // TODO
|
||||||
|
// usePackageJson: false
|
||||||
|
loadingGif: path.join(config.STATIC_PATH, 'loading.gif')
|
||||||
|
}).then(function () {
|
||||||
|
console.log('Created Windows installer.')
|
||||||
|
cb(null, buildPath)
|
||||||
|
}).catch(cb)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildLinux (cb) {
|
function buildLinux (cb) {
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ var applicationConfigPath = require('application-config-path')
|
|||||||
var path = require('path')
|
var path = require('path')
|
||||||
|
|
||||||
var APP_NAME = 'WebTorrent'
|
var APP_NAME = 'WebTorrent'
|
||||||
|
var APP_TEAM = 'The WebTorrent Project'
|
||||||
var APP_VERSION = require('./package.json').version
|
var APP_VERSION = require('./package.json').version
|
||||||
|
|
||||||
module.exports = {
|
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_FILE_ICON: path.join(__dirname, 'static', 'WebTorrentFile'),
|
||||||
APP_ICON: path.join(__dirname, 'static', 'WebTorrent'),
|
APP_ICON: path.join(__dirname, 'static', 'WebTorrent'),
|
||||||
APP_NAME: APP_NAME,
|
APP_NAME: APP_NAME,
|
||||||
|
APP_TEAM: APP_TEAM,
|
||||||
APP_VERSION: APP_VERSION,
|
APP_VERSION: APP_VERSION,
|
||||||
|
|
||||||
AUTO_UPDATE_URL: 'https://webtorrent.io/app/update?version=' + APP_VERSION,
|
AUTO_UPDATE_URL: 'https://webtorrent.io/app/update?version=' + APP_VERSION,
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
init
|
||||||
|
}
|
||||||
|
|
||||||
var log = require('./log')
|
var log = require('./log')
|
||||||
|
|
||||||
module.exports = function () {
|
function init () {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
var path = require('path')
|
var path = require('path')
|
||||||
var iconPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'static', 'WebTorrentFile.ico')
|
var iconPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'static', 'WebTorrentFile.ico')
|
||||||
163
main/index.js
163
main/index.js
@@ -4,20 +4,105 @@ var app = electron.app
|
|||||||
|
|
||||||
var autoUpdater = require('./auto-updater')
|
var autoUpdater = require('./auto-updater')
|
||||||
var config = require('../config')
|
var config = require('../config')
|
||||||
|
var handlers = require('./handlers')
|
||||||
var ipc = require('./ipc')
|
var ipc = require('./ipc')
|
||||||
var log = require('./log')
|
var log = require('./log')
|
||||||
var menu = require('./menu')
|
var menu = require('./menu')
|
||||||
var registerProtocolHandler = require('./register-handlers')
|
|
||||||
var shortcuts = require('./shortcuts')
|
var shortcuts = require('./shortcuts')
|
||||||
|
var squirrelWin32 = require('./squirrel-win32')
|
||||||
var windows = require('./windows')
|
var windows = require('./windows')
|
||||||
|
|
||||||
// Prevent multiple instances of the app from running at the same time. New instances
|
var shouldQuit = false
|
||||||
// signal this instance and exit.
|
var argv = sliceArgv(process.argv)
|
||||||
var shouldQuit = app.makeSingleInstance(function (newArgv) {
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
shouldQuit = squirrelWin32.handleEvent(argv[0])
|
||||||
|
argv = argv.filter((arg) => arg.indexOf('--squirrel') === -1)
|
||||||
|
// app.setAppUserModelId('com.squirrel.WebTorrent.WebTorrent')
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (!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)
|
newArgv = sliceArgv(newArgv)
|
||||||
|
|
||||||
if (app.ipcReady) {
|
if (app.ipcReady) {
|
||||||
log('Second app instance attempted to open but was prevented')
|
log('Second app instance opened, but was prevented:', newArgv)
|
||||||
windows.focusMainWindow()
|
windows.focusMainWindow()
|
||||||
|
|
||||||
newArgv.forEach(function (torrentId) {
|
newArgv.forEach(function (torrentId) {
|
||||||
@@ -26,74 +111,6 @@ var shouldQuit = app.makeSingleInstance(function (newArgv) {
|
|||||||
} else {
|
} else {
|
||||||
argv.push(...newArgv)
|
argv.push(...newArgv)
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
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 () {
|
|
||||||
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()
|
|
||||||
registerProtocolHandler()
|
|
||||||
})
|
|
||||||
|
|
||||||
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) {
|
function sliceArgv (argv) {
|
||||||
|
|||||||
134
main/squirrel-win32.js
Normal file
134
main/squirrel-win32.js
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
module.exports = {
|
||||||
|
handleEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
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 handlers = require('./handlers')
|
||||||
|
|
||||||
|
var exeName = path.basename(process.execPath)
|
||||||
|
var updateDotExe = path.join(process.execPath, '..', '..', 'Update.exe')
|
||||||
|
|
||||||
|
function handleEvent (cmd) {
|
||||||
|
if (cmd === '--squirrel-install') {
|
||||||
|
// App was installed.
|
||||||
|
|
||||||
|
// Install protocol/file handlers, desktop/start menu shortcuts.
|
||||||
|
handlers.init()
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
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
|
||||||
|
removeShortcuts(function () {
|
||||||
|
app.quit()
|
||||||
|
})
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd === '--squirrel-obsolete') {
|
||||||
|
// App will be updated. (Called on outgoing version of app)
|
||||||
|
app.quit()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd === '--squirrel-firstrun') {
|
||||||
|
// This is called on the app's first run. Do not quit, allow startup to continue.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
@@ -13,7 +13,6 @@ var menu = require('./menu')
|
|||||||
|
|
||||||
function createMainWindow () {
|
function createMainWindow () {
|
||||||
var win = windows.main = new electron.BrowserWindow({
|
var win = windows.main = new electron.BrowserWindow({
|
||||||
autoHideMenuBar: true, // Hide top menu bar unless Alt key is pressed (Windows, Linux)
|
|
||||||
backgroundColor: '#282828',
|
backgroundColor: '#282828',
|
||||||
darkTheme: true, // Forces dark theme (GTK+3)
|
darkTheme: true, // Forces dark theme (GTK+3)
|
||||||
icon: config.APP_ICON + '.png',
|
icon: config.APP_ICON + '.png',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "webtorrent-app",
|
"name": "WebTorrent",
|
||||||
"description": "WebTorrent, the streaming torrent client. For OS X, Windows, and Linux.",
|
"description": "WebTorrent, the streaming torrent client. For OS X, Windows, and Linux.",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"author": {
|
"author": {
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"musicmetadata": "^2.0.2",
|
"musicmetadata": "^2.0.2",
|
||||||
"network-address": "^1.1.0",
|
"network-address": "^1.1.0",
|
||||||
|
"path-exists": "^2.1.0",
|
||||||
"prettier-bytes": "^1.0.1",
|
"prettier-bytes": "^1.0.1",
|
||||||
"upload-element": "^1.0.1",
|
"upload-element": "^1.0.1",
|
||||||
"virtual-dom": "^2.1.1",
|
"virtual-dom": "^2.1.1",
|
||||||
@@ -34,6 +35,7 @@
|
|||||||
"electron-osx-sign": "^0.3.0",
|
"electron-osx-sign": "^0.3.0",
|
||||||
"electron-packager": "^5.0.0",
|
"electron-packager": "^5.0.0",
|
||||||
"electron-prebuilt": "0.37.2",
|
"electron-prebuilt": "0.37.2",
|
||||||
|
"electron-winstaller": "^2.0.5",
|
||||||
"gh-release": "^2.0.2",
|
"gh-release": "^2.0.2",
|
||||||
"path-exists": "^2.1.0",
|
"path-exists": "^2.1.0",
|
||||||
"plist": "^1.2.0",
|
"plist": "^1.2.0",
|
||||||
@@ -58,7 +60,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "node ./bin/clean.js",
|
"clean": "node ./bin/clean.js",
|
||||||
"debug": "DEBUG=* electron .",
|
"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",
|
"size": "npm run package -- --darwin && du -ch dist/WebTorrent-darwin-x64 | grep total",
|
||||||
"start": "electron .",
|
"start": "electron .",
|
||||||
"test": "standard",
|
"test": "standard",
|
||||||
|
|||||||
BIN
static/loading.gif
Normal file
BIN
static/loading.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Reference in New Issue
Block a user