diff --git a/package.json b/package.json
index c274c57c..70548b0d 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"dependencies": {
"airplayer": "^2.0.0",
"application-config": "^1.0.0",
+ "auto-launch": "^4.0.0",
"bitfield": "^1.0.2",
"chromecasts": "^1.8.0",
"create-torrent": "^3.24.5",
diff --git a/src/main/index.js b/src/main/index.js
index d10a3b56..5eac4567 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -20,6 +20,7 @@ const windows = require('./windows')
let shouldQuit = false
let argv = sliceArgv(process.argv)
+const hidden = argv.includes('--hidden')
if (config.IS_PRODUCTION) {
// When Electron is running in production mode (packaged app), then run React
@@ -67,7 +68,7 @@ function init () {
app.on('ready', function () {
isReady = true
- windows.main.init()
+ windows.main.init({hidden: hidden})
windows.webtorrent.init()
menu.init()
@@ -155,6 +156,8 @@ function processArgv (argv) {
dialog.openTorrentFile()
} else if (arg === '-u') {
dialog.openTorrentAddress()
+ } else if (arg === '--hidden') {
+ // Igonre hidden argument, already being handled
} else if (arg.startsWith('-psn')) {
// Ignore Mac launchd "process serial number" argument
// Issue: https://github.com/feross/webtorrent-desktop/issues/214
diff --git a/src/main/ipc.js b/src/main/ipc.js
index 056232d2..11484e3e 100644
--- a/src/main/ipc.js
+++ b/src/main/ipc.js
@@ -17,6 +17,7 @@ const shortcuts = require('./shortcuts')
const externalPlayer = require('./external-player')
const windows = require('./windows')
const thumbar = require('./thumbar')
+const startup = require('./startup')
// Messages from the main process, to be sent once the WebTorrent process starts
const messageQueueMainToWebTorrent = []
@@ -102,6 +103,14 @@ function init () {
else handlers.uninstall()
})
+ /**
+ * Startup
+ */
+ ipc.on('setStartup', (e, flag) => {
+ if (flag) startup.install()
+ else startup.uninstall()
+ })
+
/**
* Windows: Main
*/
diff --git a/src/main/startup.js b/src/main/startup.js
new file mode 100644
index 00000000..135dc9f6
--- /dev/null
+++ b/src/main/startup.js
@@ -0,0 +1,27 @@
+module.exports = {
+ install,
+ uninstall
+}
+
+const config = require('../config')
+const AutoLaunch = require('auto-launch')
+
+const appLauncher = new AutoLaunch({
+ name: config.APP_NAME,
+ isHidden: true
+})
+
+function install () {
+ return appLauncher.isEnabled()
+ .then(enabled => {
+ if (enabled) return
+ return appLauncher.enable()
+ })
+}
+
+function uninstall () {
+ return appLauncher.isEnabled()
+ .then(enabled => {
+ if (enabled) return appLauncher.disable()
+ })
+}
diff --git a/src/main/windows/main.js b/src/main/windows/main.js
index 263ff38e..9e652ff9 100644
--- a/src/main/windows/main.js
+++ b/src/main/windows/main.js
@@ -26,7 +26,7 @@ const tray = require('../tray')
const HEADER_HEIGHT = 38
const TORRENT_HEIGHT = 100
-function init () {
+function init (options) {
if (main.win) {
return main.win.show()
}
@@ -40,7 +40,8 @@ function init () {
titleBarStyle: 'hidden-inset', // Hide title bar (Mac)
useContentSize: true, // Specify web page size without OS chrome
width: 500,
- height: HEADER_HEIGHT + (TORRENT_HEIGHT * 6) // header height + 5 torrents
+ height: HEADER_HEIGHT + (TORRENT_HEIGHT * 6), // header height + 5 torrents
+ show: !options.hidden
})
win.loadURL(config.WINDOW_MAIN)
diff --git a/src/renderer/controllers/prefs-controller.js b/src/renderer/controllers/prefs-controller.js
index cf93dc21..b85578f4 100644
--- a/src/renderer/controllers/prefs-controller.js
+++ b/src/renderer/controllers/prefs-controller.js
@@ -17,7 +17,9 @@ module.exports = class PrefsController {
setup: function (cb) {
// initialize preferences
state.window.title = 'Preferences'
- state.unsaved = Object.assign(state.unsaved || {}, {prefs: state.saved.prefs || {}})
+ state.unsaved = Object.assign(state.unsaved || {}, {
+ prefs: Object.assign({}, state.saved.prefs)
+ })
ipcRenderer.send('setAllowNav', false)
cb()
},
@@ -50,6 +52,9 @@ module.exports = class PrefsController {
if (state.unsaved.prefs.isFileHandler !== state.saved.prefs.isFileHandler) {
ipcRenderer.send('setDefaultFileHandler', state.unsaved.prefs.isFileHandler)
}
+ if (state.unsaved.prefs.startup !== state.saved.prefs.startup) {
+ ipcRenderer.send('setStartup', state.unsaved.prefs.startup)
+ }
state.saved.prefs = Object.assign(state.saved.prefs || {}, state.unsaved.prefs)
State.save(state)
dispatch('checkDownloadPath')
diff --git a/src/renderer/lib/state.js b/src/renderer/lib/state.js
index f2734c4d..2ea67df1 100644
--- a/src/renderer/lib/state.js
+++ b/src/renderer/lib/state.js
@@ -108,7 +108,8 @@ function setupSavedState (cb) {
downloadPath: config.DEFAULT_DOWNLOAD_PATH,
isFileHandler: false,
openExternalPlayer: false,
- externalPlayerPath: null
+ externalPlayerPath: null,
+ startup: false
},
torrents: config.DEFAULT_TORRENTS.map(createTorrentObject),
version: config.APP_VERSION /* make sure we can upgrade gracefully later */
diff --git a/src/renderer/main.js b/src/renderer/main.js
index 6b8a217b..aa99deec 100644
--- a/src/renderer/main.js
+++ b/src/renderer/main.js
@@ -123,7 +123,9 @@ function onState (err, _state) {
document.addEventListener('webkitvisibilitychange', onVisibilityChange)
// Done! Ideally we want to get here < 500ms after the user clicks the app
- sound.play('STARTUP')
+ if (electron.remote.getCurrentWindow().isVisible()) {
+ sound.play('STARTUP')
+ }
console.timeEnd('init')
}
diff --git a/src/renderer/pages/preferences-page.js b/src/renderer/pages/preferences-page.js
index 018aa08f..d6e0035a 100644
--- a/src/renderer/pages/preferences-page.js
+++ b/src/renderer/pages/preferences-page.js
@@ -8,6 +8,7 @@ const Heading = require('../components/heading')
const PathSelector = require('../components/path-selector')
const {dispatch} = require('../lib/dispatcher')
+const config = require('../../config')
class PreferencesPage extends React.Component {
constructor (props) {
@@ -21,6 +22,9 @@ class PreferencesPage extends React.Component {
this.handleExternalPlayerPathChange =
this.handleExternalPlayerPathChange.bind(this)
+
+ this.handleStartupChange =
+ this.handleStartupChange.bind(this)
}
downloadPathSelector () {
@@ -107,6 +111,29 @@ class PreferencesPage extends React.Component {
)
}
+ handleStartupChange (e, isChecked) {
+ dispatch('updatePreferences', 'startup', isChecked)
+ }
+
+ setStartupSection () {
+ if (config.IS_PORTABLE) {
+ return
+ }
+
+ return (
+
+
+
+
+
+ )
+ }
+
handleSetDefaultApp () {
dispatch('updatePreferences', 'isFileHandler', true)
}
@@ -129,6 +156,7 @@ class PreferencesPage extends React.Component {
{this.setDefaultAppButton()}
+ {this.setStartupSection()}
)
}