diff --git a/src/main/windows/main.js b/src/main/windows/main.js
index 3c8d26f4..0cd82636 100644
--- a/src/main/windows/main.js
+++ b/src/main/windows/main.js
@@ -45,18 +45,26 @@ function init (state, options) {
y: initialBounds.y
})
- win.once('ready-to-show', function () {
+ win.loadURL(config.WINDOW_MAIN)
+
+ win.once('ready-to-show', () => {
if (!options.hidden) win.show()
})
- win.loadURL(config.WINDOW_MAIN)
-
- if (win.setSheetOffset) win.setSheetOffset(config.UI_HEADER_HEIGHT)
+ if (win.setSheetOffset) {
+ win.setSheetOffset(config.UI_HEADER_HEIGHT)
+ }
win.webContents.on('dom-ready', function () {
menu.onToggleFullScreen(main.win.isFullScreen())
})
+ win.webContents.on('will-navigate', (e, url) => {
+ // Prevent drag-and-drop from navigating the Electron window, which can happen
+ // before our drag-and-drop handlers have been initialized.
+ e.preventDefault()
+ })
+
win.on('blur', onWindowBlur)
win.on('focus', onWindowFocus)
diff --git a/src/renderer/lib/state.js b/src/renderer/lib/state.js
index 14f38a7e..af506482 100644
--- a/src/renderer/lib/state.js
+++ b/src/renderer/lib/state.js
@@ -6,6 +6,8 @@ const config = require('../../config')
const SAVE_DEBOUNCE_INTERVAL = 1000
+appConfig.filePath = path.join(config.CONFIG_PATH, 'config.json')
+
const State = module.exports = Object.assign(new EventEmitter(), {
getDefaultPlayState,
load,
@@ -16,13 +18,11 @@ const State = module.exports = Object.assign(new EventEmitter(), {
// After first State.save() invokation, future calls go straight to the
// debounced function
State.save = debounce(saveImmediate, SAVE_DEBOUNCE_INTERVAL)
- State.save()
+ State.save(...arguments)
},
saveImmediate
})
-appConfig.filePath = path.join(config.CONFIG_PATH, 'config.json')
-
function getDefaultState () {
const LocationHistory = require('location-history')
diff --git a/src/renderer/lib/telemetry.js b/src/renderer/lib/telemetry.js
index 758b55a4..386161c6 100644
--- a/src/renderer/lib/telemetry.js
+++ b/src/renderer/lib/telemetry.js
@@ -2,6 +2,7 @@
// Reports back so that we can improve WebTorrent Desktop
module.exports = {
init,
+ send,
logUncaughtError,
logPlayAttempt
}
@@ -22,7 +23,9 @@ function init (state) {
telemetry = state.saved.telemetry = createSummary()
reset()
}
+}
+function send (state) {
const now = new Date()
telemetry.version = config.APP_VERSION
telemetry.timestamp = now.toISOString()
@@ -223,7 +226,7 @@ function getElemString (elem) {
let ret = elem.tagName
try {
ret += '.' + Array.from(elem.classList).join('.')
- } catch (e) {}
+ } catch (err) {}
return ret
}
diff --git a/src/renderer/main.js b/src/renderer/main.js
index 2dc56f9c..783562f4 100644
--- a/src/renderer/main.js
+++ b/src/renderer/main.js
@@ -3,6 +3,12 @@ console.time('init')
const crashReporter = require('../crash-reporter')
crashReporter.init()
+// Perf optimization: Start asynchronously read on config file before all the
+// blocking require() calls below.
+
+const State = require('./lib/state')
+State.load(onState)
+
const dragDrop = require('drag-drop')
const electron = require('electron')
const fs = require('fs')
@@ -12,7 +18,6 @@ const ReactDOM = require('react-dom')
const config = require('../config')
const telemetry = require('./lib/telemetry')
const sound = require('./lib/sound')
-const State = require('./lib/state')
const TorrentPlayer = require('./lib/torrent-player')
// Required by Material UI -- adds `onTouchTap` event
@@ -50,22 +55,22 @@ let state
// Root React component
let app
-State.load(onState)
-
// Called once when the application loads. (Not once per window.)
// Connects to the torrent networks, sets up the UI and OS integrations like
// the dock icon and drag+drop.
function onState (err, _state) {
if (err) return onError(err)
- state = window.state = _state // Make available for easier debugging
+
+ // Make available for easier debugging
+ state = window.state = _state
window.dispatch = dispatch
telemetry.init(state)
// Log uncaught JS errors
- window.addEventListener('error',
- (e) => telemetry.logUncaughtError('window', e),
- true /* capture */)
+ window.addEventListener(
+ 'error', (e) => telemetry.logUncaughtError('window', e), true /* capture */
+ )
// Create controllers
controllers = {
@@ -90,23 +95,18 @@ function onState (err, _state) {
// Restart everything we were torrenting last time the app ran
resumeTorrents()
+ // Initialize ReactDOM
+ app = ReactDOM.render(, document.querySelector('#body'))
+
// 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
setInterval(update, 1000)
- app = ReactDOM.render(, document.querySelector('#body'))
-
- // Lazy-load other stuff, like the AppleTV module, later to keep startup fast
- window.setTimeout(delayedInit, config.DELAYED_INIT)
// Listen for messages from the main process
setupIpc()
- // Warn if the download dir is gone, eg b/c an external drive is unplugged
- checkDownloadPath()
-
- // OS integrations:
- // ...drag and drop files/text to start torrenting or seeding
+ // Drag and drop files/text to start torrenting or seeding
dragDrop('body', {
onDrop: onOpen,
onDropText: onOpen
@@ -119,18 +119,28 @@ function onState (err, _state) {
window.addEventListener('focus', onFocus)
window.addEventListener('blur', onBlur)
- // ...window visibility state.
- document.addEventListener('webkitvisibilitychange', onVisibilityChange)
-
- // Done! Ideally we want to get here < 500ms after the user clicks the app
if (electron.remote.getCurrentWindow().isVisible()) {
sound.play('STARTUP')
}
+
+ // To keep app startup fast, some code is delayed.
+ window.setTimeout(delayedInit, config.DELAYED_INIT)
+
+ // Done! Ideally we want to get here < 500ms after the user clicks the app
console.timeEnd('init')
}
// Runs a few seconds after the app loads, to avoid slowing down startup time
function delayedInit () {
+ telemetry.send(state)
+
+ // Warn if the download dir is gone, eg b/c an external drive is unplugged
+ checkDownloadPath()
+
+ // ...window visibility state.
+ document.addEventListener('webkitvisibilitychange', onVisibilityChange)
+ onVisibilityChange()
+
lazyLoadCast()
}