Major refactor -- split windows into separate files
This commit is contained in:
@@ -3,7 +3,6 @@ module.exports = {
|
||||
}
|
||||
|
||||
var electron = require('electron')
|
||||
var get = require('simple-get')
|
||||
|
||||
var config = require('../config')
|
||||
var log = require('./log')
|
||||
@@ -13,6 +12,7 @@ var ANNOUNCEMENT_URL = config.ANNOUNCEMENT_URL +
|
||||
'&platform=' + process.platform
|
||||
|
||||
function init () {
|
||||
var get = require('simple-get')
|
||||
get.concat(ANNOUNCEMENT_URL, onResponse)
|
||||
}
|
||||
|
||||
|
||||
53
main/dialog.js
Normal file
53
main/dialog.js
Normal file
@@ -0,0 +1,53 @@
|
||||
module.exports = {
|
||||
openSeedFile,
|
||||
openSeedDirectory,
|
||||
openTorrentFile,
|
||||
openTorrentAddress
|
||||
}
|
||||
|
||||
var electron = require('electron')
|
||||
var windows = require('./windows')
|
||||
|
||||
// Prompts the user for a file, then creates a torrent. Only allows a single file
|
||||
// selection.
|
||||
function openSeedFile () {
|
||||
electron.dialog.showOpenDialog({
|
||||
title: 'Select a file for the torrent file.',
|
||||
properties: [ 'openFile' ]
|
||||
}, function (selectedPaths) {
|
||||
if (!Array.isArray(selectedPaths)) return
|
||||
windows.main.send('dispatch', 'showCreateTorrent', selectedPaths)
|
||||
})
|
||||
}
|
||||
|
||||
// Prompts the user for a file or directory, then creates a torrent. Only allows a
|
||||
// single selection. To create a multi-file torrent, the user must select a
|
||||
// directory.
|
||||
function openSeedDirectory () {
|
||||
electron.dialog.showOpenDialog({
|
||||
title: 'Select a file or folder for the torrent file.',
|
||||
properties: [ 'openFile', 'openDirectory' ]
|
||||
}, function (selectedPaths) {
|
||||
if (!Array.isArray(selectedPaths)) return
|
||||
windows.main.send('dispatch', 'showCreateTorrent', selectedPaths)
|
||||
})
|
||||
}
|
||||
|
||||
// Prompts the user to choose a torrent file, then adds it.
|
||||
function openTorrentFile () {
|
||||
electron.dialog.showOpenDialog(windows.main.win, {
|
||||
title: 'Select a .torrent file to open.',
|
||||
filters: [{ name: 'Torrent Files', extensions: ['torrent'] }],
|
||||
properties: [ 'openFile', 'multiSelections' ]
|
||||
}, function (selectedPaths) {
|
||||
if (!Array.isArray(selectedPaths)) return
|
||||
selectedPaths.forEach(function (selectedPath) {
|
||||
windows.main.send('dispatch', 'addTorrent', selectedPath)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Prompts the user for the URL of a torrent file, then downloads and adds it
|
||||
function openTorrentAddress () {
|
||||
windows.main.send('showOpenTorrentAddress')
|
||||
}
|
||||
@@ -8,6 +8,7 @@ var ipcMain = electron.ipcMain
|
||||
var announcement = require('./announcement')
|
||||
var config = require('../config')
|
||||
var crashReporter = require('../crash-reporter')
|
||||
var dialog = require('./dialog')
|
||||
var handlers = require('./handlers')
|
||||
var ipc = require('./ipc')
|
||||
var log = require('./log')
|
||||
@@ -60,8 +61,8 @@ function init () {
|
||||
app.on('ready', function () {
|
||||
isReady = true
|
||||
|
||||
windows.createMainWindow()
|
||||
windows.createWebTorrentHiddenWindow()
|
||||
windows.main.create()
|
||||
windows.webtorrent.create()
|
||||
menu.init()
|
||||
|
||||
// To keep app startup fast, some code is delayed.
|
||||
@@ -79,13 +80,13 @@ function init () {
|
||||
|
||||
app.isQuitting = true
|
||||
e.preventDefault()
|
||||
windows.main.send('dispatch', 'saveState') /* try to save state on exit */
|
||||
windows.main.send('dispatch', 'saveState') // try to save state on exit
|
||||
ipcMain.once('savedState', () => app.quit())
|
||||
setTimeout(() => app.quit(), 2000) /* quit after 2 secs, at most */
|
||||
setTimeout(() => app.quit(), 2000) // quit after 2 secs, at most
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
if (isReady) windows.createMainWindow()
|
||||
if (isReady) windows.main.create()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -101,11 +102,11 @@ function onOpen (e, torrentId) {
|
||||
|
||||
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.
|
||||
// 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.focusWindow(windows.main)
|
||||
windows.main.focus()
|
||||
}, 100)
|
||||
} else {
|
||||
argv.push(torrentId)
|
||||
@@ -114,10 +115,11 @@ 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)
|
||||
windows.focusWindow(windows.main)
|
||||
windows.main.focus()
|
||||
|
||||
processArgv(newArgv)
|
||||
} else {
|
||||
@@ -130,27 +132,22 @@ function sliceArgv (argv) {
|
||||
}
|
||||
|
||||
function processArgv (argv) {
|
||||
var pathsToOpen = []
|
||||
var paths = []
|
||||
argv.forEach(function (arg) {
|
||||
if (arg === '-n') {
|
||||
menu.showOpenSeedFiles()
|
||||
dialog.openSeedDirectory()
|
||||
} else if (arg === '-o') {
|
||||
menu.showOpenTorrentFile()
|
||||
dialog.openTorrentFile()
|
||||
} else if (arg === '-u') {
|
||||
menu.showOpenTorrentAddress()
|
||||
dialog.openTorrentAddress()
|
||||
} else if (arg.startsWith('-psn')) {
|
||||
// Ignore OS X launchd "process serial number" argument
|
||||
// More: https://github.com/feross/webtorrent-desktop/issues/214
|
||||
// Issue: https://github.com/feross/webtorrent-desktop/issues/214
|
||||
} else {
|
||||
pathsToOpen.push(arg)
|
||||
paths.push(arg)
|
||||
}
|
||||
})
|
||||
if (pathsToOpen.length > 0) openFilePaths(pathsToOpen)
|
||||
}
|
||||
|
||||
// Send files to the renderer process
|
||||
// Opening files means either adding torrents, creating and seeding a torrent
|
||||
// from files, or adding subtitles
|
||||
function openFilePaths (paths) {
|
||||
windows.main.send('dispatch', 'onOpen', paths)
|
||||
if (paths.length > 0) {
|
||||
windows.main.send('dispatch', 'onOpen', paths)
|
||||
}
|
||||
}
|
||||
|
||||
60
main/ipc.js
60
main/ipc.js
@@ -5,24 +5,23 @@ module.exports = {
|
||||
var electron = require('electron')
|
||||
|
||||
var app = electron.app
|
||||
var ipcMain = electron.ipcMain
|
||||
|
||||
var log = require('./log')
|
||||
var menu = require('./menu')
|
||||
var windows = require('./windows')
|
||||
var powerSaveBlocker = require('./power-save-blocker')
|
||||
var shortcuts = require('./shortcuts')
|
||||
var vlc = require('./vlc')
|
||||
var windows = require('./windows')
|
||||
|
||||
// has to be a number, not a boolean, and undefined throws an error
|
||||
var powerSaveBlockerId = 0
|
||||
|
||||
// messages from the main process, to be sent once the WebTorrent process starts
|
||||
// Messages from the main process, to be sent once the WebTorrent process starts
|
||||
var messageQueueMainToWebTorrent = []
|
||||
|
||||
// holds a ChildProcess while we're playing a video in VLC, null otherwise
|
||||
var vlcProcess
|
||||
|
||||
function init () {
|
||||
var ipcMain = electron.ipcMain
|
||||
|
||||
ipcMain.on('ipcReady', function (e) {
|
||||
windows.main.show()
|
||||
app.ipcReady = true
|
||||
@@ -39,7 +38,7 @@ function init () {
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('showOpenTorrentFile', menu.showOpenTorrentFile)
|
||||
ipcMain.on('showOpenTorrentFile', () => menu.showOpenTorrentFile())
|
||||
|
||||
ipcMain.on('setBounds', function (e, bounds, maximize) {
|
||||
setBounds(bounds, maximize)
|
||||
@@ -58,11 +57,11 @@ function init () {
|
||||
})
|
||||
|
||||
ipcMain.on('toggleFullScreen', function (e, flag) {
|
||||
menu.toggleFullScreen(flag)
|
||||
windows.main.toggleFullScreen(flag)
|
||||
})
|
||||
|
||||
ipcMain.on('setTitle', function (e, title) {
|
||||
windows.main.setTitle(title)
|
||||
windows.main.win.setTitle(title)
|
||||
})
|
||||
|
||||
ipcMain.on('openItem', function (e, path) {
|
||||
@@ -75,9 +74,8 @@ function init () {
|
||||
electron.shell.showItemInFolder(path)
|
||||
})
|
||||
|
||||
ipcMain.on('blockPowerSave', blockPowerSave)
|
||||
|
||||
ipcMain.on('unblockPowerSave', unblockPowerSave)
|
||||
ipcMain.on('blockPowerSave', () => powerSaveBlocker.start())
|
||||
ipcMain.on('unblockPowerSave', () => powerSaveBlocker.stop())
|
||||
|
||||
ipcMain.on('onPlayerOpen', function () {
|
||||
menu.onPlayerOpen()
|
||||
@@ -174,7 +172,7 @@ function init () {
|
||||
|
||||
function setBounds (bounds, maximize) {
|
||||
// Do nothing in fullscreen
|
||||
if (!windows.main || windows.main.isFullScreen()) {
|
||||
if (!windows.main.win || windows.main.win.isFullScreen()) {
|
||||
log('setBounds: not setting bounds because we\'re in full screen')
|
||||
return
|
||||
}
|
||||
@@ -182,19 +180,19 @@ function setBounds (bounds, maximize) {
|
||||
// Maximize or minimize, if the second argument is present
|
||||
var willBeMaximized
|
||||
if (maximize === true) {
|
||||
if (!windows.main.isMaximized()) {
|
||||
if (!windows.main.win.isMaximized()) {
|
||||
log('setBounds: maximizing')
|
||||
windows.main.maximize()
|
||||
windows.main.win.maximize()
|
||||
}
|
||||
willBeMaximized = true
|
||||
} else if (maximize === false) {
|
||||
if (windows.main.isMaximized()) {
|
||||
if (windows.main.win.isMaximized()) {
|
||||
log('setBounds: unmaximizing')
|
||||
windows.main.unmaximize()
|
||||
windows.main.win.unmaximize()
|
||||
}
|
||||
willBeMaximized = false
|
||||
} else {
|
||||
willBeMaximized = windows.main.isMaximized()
|
||||
willBeMaximized = windows.main.win.isMaximized()
|
||||
}
|
||||
|
||||
// Assuming we're not maximized or maximizing, set the window size
|
||||
@@ -202,12 +200,12 @@ function setBounds (bounds, maximize) {
|
||||
log('setBounds: setting bounds to ' + JSON.stringify(bounds))
|
||||
if (bounds.x === null && bounds.y === null) {
|
||||
// X and Y not specified? By default, center on current screen
|
||||
var scr = electron.screen.getDisplayMatching(windows.main.getBounds())
|
||||
var scr = electron.screen.getDisplayMatching(windows.main.win.getBounds())
|
||||
bounds.x = Math.round(scr.bounds.x + scr.bounds.width / 2 - bounds.width / 2)
|
||||
bounds.y = Math.round(scr.bounds.y + scr.bounds.height / 2 - bounds.height / 2)
|
||||
log('setBounds: centered to ' + JSON.stringify(bounds))
|
||||
}
|
||||
windows.main.setBounds(bounds, true)
|
||||
windows.main.win.setBounds(bounds, true)
|
||||
} else {
|
||||
log('setBounds: not setting bounds because of window maximization')
|
||||
}
|
||||
@@ -215,9 +213,8 @@ function setBounds (bounds, maximize) {
|
||||
|
||||
function setAspectRatio (aspectRatio) {
|
||||
log('setAspectRatio %o', aspectRatio)
|
||||
if (windows.main) {
|
||||
windows.main.setAspectRatio(aspectRatio)
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.win.setAspectRatio(aspectRatio)
|
||||
}
|
||||
|
||||
// Display string in dock badging area (OS X)
|
||||
@@ -231,19 +228,6 @@ function setBadge (text) {
|
||||
// Show progress bar. Valid range is [0, 1]. Remove when < 0; indeterminate when > 1.
|
||||
function setProgress (progress) {
|
||||
log('setProgress %s', progress)
|
||||
if (windows.main) {
|
||||
windows.main.setProgressBar(progress)
|
||||
}
|
||||
}
|
||||
|
||||
function blockPowerSave () {
|
||||
powerSaveBlockerId = electron.powerSaveBlocker.start('prevent-display-sleep')
|
||||
log('blockPowerSave %d', powerSaveBlockerId)
|
||||
}
|
||||
|
||||
function unblockPowerSave () {
|
||||
if (electron.powerSaveBlocker.isStarted(powerSaveBlockerId)) {
|
||||
electron.powerSaveBlocker.stop(powerSaveBlockerId)
|
||||
log('unblockPowerSave %d', powerSaveBlockerId)
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.win.setProgressBar(progress)
|
||||
}
|
||||
|
||||
@@ -10,11 +10,16 @@ module.exports.error = error
|
||||
|
||||
var electron = require('electron')
|
||||
|
||||
var config = require('../config')
|
||||
var windows = require('./windows')
|
||||
|
||||
var app = electron.app
|
||||
|
||||
function log (...args) {
|
||||
if (!config.IS_PRODUCTION) {
|
||||
// In development, also log to the console
|
||||
console.log(...args)
|
||||
}
|
||||
if (app.ipcReady) {
|
||||
windows.main.send('log', ...args)
|
||||
} else {
|
||||
|
||||
154
main/menu.js
154
main/menu.js
@@ -4,13 +4,7 @@ module.exports = {
|
||||
onPlayerOpen,
|
||||
onToggleFullScreen,
|
||||
onWindowHide,
|
||||
onWindowShow,
|
||||
|
||||
// TODO: move these out of menu.js -- they don't belong here
|
||||
showOpenSeedFiles,
|
||||
showOpenTorrentAddress,
|
||||
showOpenTorrentFile,
|
||||
toggleFullScreen
|
||||
onWindowShow
|
||||
}
|
||||
|
||||
var electron = require('electron')
|
||||
@@ -18,6 +12,7 @@ var electron = require('electron')
|
||||
var app = electron.app
|
||||
|
||||
var config = require('../config')
|
||||
var dialog = require('./dialog')
|
||||
var log = require('./log')
|
||||
var windows = require('./windows')
|
||||
|
||||
@@ -33,100 +28,76 @@ function init () {
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFullScreen (flag) {
|
||||
log('toggleFullScreen %s', flag)
|
||||
if (windows.main && windows.main.isVisible()) {
|
||||
flag = flag != null ? flag : !windows.main.isFullScreen()
|
||||
if (flag) {
|
||||
// Allows the window to use the full screen in fullscreen mode (OS X).
|
||||
windows.main.setAspectRatio(0)
|
||||
}
|
||||
windows.main.setFullScreen(flag)
|
||||
}
|
||||
}
|
||||
|
||||
// Sets whether the window should always show on top of other windows
|
||||
function toggleFloatOnTop (flag) {
|
||||
if (!windows.main.win) return
|
||||
log('toggleFloatOnTop %s', flag)
|
||||
if (windows.main) {
|
||||
flag = flag != null ? flag : !windows.main.isAlwaysOnTop()
|
||||
windows.main.setAlwaysOnTop(flag)
|
||||
getMenuItem('Float on Top').checked = flag
|
||||
}
|
||||
flag = flag != null ? flag : !windows.main.isAlwaysOnTop()
|
||||
windows.main.setAlwaysOnTop(flag)
|
||||
getMenuItem('Float on Top').checked = flag
|
||||
}
|
||||
|
||||
function toggleDevTools () {
|
||||
if (!windows.main.win) return
|
||||
log('toggleDevTools')
|
||||
if (windows.main) {
|
||||
windows.main.toggleDevTools()
|
||||
}
|
||||
windows.main.toggleDevTools()
|
||||
}
|
||||
|
||||
function showWebTorrentWindow () {
|
||||
log('showWebTorrentWindow')
|
||||
windows.webtorrent.show()
|
||||
windows.webtorrent.webContents.openDevTools({ detach: true })
|
||||
windows.webtorrent.win.webContents.openDevTools({ detach: true })
|
||||
}
|
||||
|
||||
function playPause () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'playPause')
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'playPause')
|
||||
}
|
||||
|
||||
function increaseVolume () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'changeVolume', 0.1)
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'changeVolume', 0.1)
|
||||
}
|
||||
|
||||
function decreaseVolume () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'changeVolume', -0.1)
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'changeVolume', -0.1)
|
||||
}
|
||||
|
||||
function openSubtitles () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'openSubtitles')
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'openSubtitles')
|
||||
}
|
||||
|
||||
function skipForward () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'skip', 1)
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'skip', 1)
|
||||
}
|
||||
|
||||
function skipBack () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'skip', -1)
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'skip', -1)
|
||||
}
|
||||
|
||||
function increasePlaybackRate () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'changePlaybackRate', 1)
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'changePlaybackRate', 1)
|
||||
}
|
||||
|
||||
function decreasePlaybackRate () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'changePlaybackRate', -1)
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'changePlaybackRate', -1)
|
||||
}
|
||||
|
||||
// Open the preferences window
|
||||
function showPreferences () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'preferences')
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'preferences')
|
||||
}
|
||||
|
||||
function escapeBack () {
|
||||
if (windows.main) {
|
||||
windows.main.send('dispatch', 'escapeBack')
|
||||
}
|
||||
if (!windows.main.win) return
|
||||
windows.main.send('dispatch', 'escapeBack')
|
||||
}
|
||||
|
||||
function onWindowShow () {
|
||||
@@ -166,8 +137,10 @@ function onPlayerClose () {
|
||||
}
|
||||
|
||||
function onToggleFullScreen (isFullScreen) {
|
||||
isFullScreen = isFullScreen != null ? isFullScreen : windows.main.isFullScreen()
|
||||
windows.main.setMenuBarVisibility(!isFullScreen)
|
||||
if (isFullScreen == null) {
|
||||
isFullScreen = windows.main.win.isFullScreen()
|
||||
}
|
||||
windows.main.win.setMenuBarVisibility(!isFullScreen)
|
||||
getMenuItem('Full Screen').checked = isFullScreen
|
||||
windows.main.send('fullscreenChanged', isFullScreen)
|
||||
}
|
||||
@@ -181,49 +154,6 @@ function getMenuItem (label) {
|
||||
}
|
||||
}
|
||||
|
||||
// Prompts the user for a file, then creates a torrent. Only allows a single file
|
||||
// selection.
|
||||
function showOpenSeedFile () {
|
||||
electron.dialog.showOpenDialog({
|
||||
title: 'Select a file for the torrent file.',
|
||||
properties: [ 'openFile' ]
|
||||
}, function (selectedPaths) {
|
||||
if (!Array.isArray(selectedPaths)) return
|
||||
windows.main.send('dispatch', 'showCreateTorrent', selectedPaths)
|
||||
})
|
||||
}
|
||||
|
||||
// Prompts the user for a file or directory, then creates a torrent. Only allows a single
|
||||
// selection. To create a multi-file torrent, the user must select a directory.
|
||||
function showOpenSeedFiles () {
|
||||
electron.dialog.showOpenDialog({
|
||||
title: 'Select a file or folder for the torrent file.',
|
||||
properties: [ 'openFile', 'openDirectory' ]
|
||||
}, function (selectedPaths) {
|
||||
if (!Array.isArray(selectedPaths)) return
|
||||
windows.main.send('dispatch', 'showCreateTorrent', selectedPaths)
|
||||
})
|
||||
}
|
||||
|
||||
// Prompts the user to choose a torrent file, then adds it to the app
|
||||
function showOpenTorrentFile () {
|
||||
electron.dialog.showOpenDialog(windows.main, {
|
||||
title: 'Select a .torrent file to open.',
|
||||
filters: [{ name: 'Torrent Files', extensions: ['torrent'] }],
|
||||
properties: [ 'openFile', 'multiSelections' ]
|
||||
}, function (selectedPaths) {
|
||||
if (!Array.isArray(selectedPaths)) return
|
||||
selectedPaths.forEach(function (selectedPath) {
|
||||
windows.main.send('dispatch', 'addTorrent', selectedPath)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Prompts the user for the URL of a torrent file, then downloads and adds it
|
||||
function showOpenTorrentAddress () {
|
||||
windows.main.send('showOpenTorrentAddress')
|
||||
}
|
||||
|
||||
function getAppMenuTemplate () {
|
||||
var template = [
|
||||
{
|
||||
@@ -234,17 +164,17 @@ function getAppMenuTemplate () {
|
||||
? 'Create New Torrent...'
|
||||
: 'Create New Torrent from Folder...',
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
click: showOpenSeedFiles
|
||||
click: () => dialog.openSeedDirectory()
|
||||
},
|
||||
{
|
||||
label: 'Open Torrent File...',
|
||||
accelerator: 'CmdOrCtrl+O',
|
||||
click: showOpenTorrentFile
|
||||
click: () => dialog.openTorrentFile()
|
||||
},
|
||||
{
|
||||
label: 'Open Torrent Address...',
|
||||
accelerator: 'CmdOrCtrl+U',
|
||||
click: showOpenTorrentAddress
|
||||
click: () => dialog.openTorrentAddress()
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
@@ -300,7 +230,7 @@ function getAppMenuTemplate () {
|
||||
accelerator: process.platform === 'darwin'
|
||||
? 'Ctrl+Command+F'
|
||||
: 'F11',
|
||||
click: () => toggleFullScreen()
|
||||
click: () => windows.toggleFullScreen()
|
||||
},
|
||||
{
|
||||
label: 'Float on Top',
|
||||
@@ -505,7 +435,7 @@ function getAppMenuTemplate () {
|
||||
// File menu (Windows, Linux)
|
||||
template[0].submenu.unshift({
|
||||
label: 'Create New Torrent from File...',
|
||||
click: showOpenSeedFile
|
||||
click: () => dialog.openSeedFile()
|
||||
})
|
||||
|
||||
// Help menu (Windows, Linux)
|
||||
@@ -515,7 +445,7 @@ function getAppMenuTemplate () {
|
||||
},
|
||||
{
|
||||
label: 'About ' + config.APP_NAME,
|
||||
click: windows.createAboutWindow
|
||||
click: () => windows.about.create()
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -537,17 +467,17 @@ function getDockMenuTemplate () {
|
||||
{
|
||||
label: 'Create New Torrent...',
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
click: showOpenSeedFiles
|
||||
click: () => dialog.openSeedDirectory()
|
||||
},
|
||||
{
|
||||
label: 'Open Torrent File...',
|
||||
accelerator: 'CmdOrCtrl+O',
|
||||
click: showOpenTorrentFile
|
||||
click: () => dialog.openTorrentFile()
|
||||
},
|
||||
{
|
||||
label: 'Open Torrent Address...',
|
||||
accelerator: 'CmdOrCtrl+U',
|
||||
click: showOpenTorrentAddress
|
||||
click: () => dialog.openTorrentAddress()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
25
main/power-save-blocker.js
Normal file
25
main/power-save-blocker.js
Normal file
@@ -0,0 +1,25 @@
|
||||
module.exports = {
|
||||
start,
|
||||
stop
|
||||
}
|
||||
|
||||
var electron = require('electron')
|
||||
var log = require('./log')
|
||||
|
||||
var powerSaveBlockerId = 0
|
||||
|
||||
function start () {
|
||||
// Stop the previous power saver block, if one exists.
|
||||
stop()
|
||||
|
||||
powerSaveBlockerId = electron.powerSaveBlocker.start('prevent-display-sleep')
|
||||
log('powerSaveBlocker.start %d', powerSaveBlockerId)
|
||||
}
|
||||
|
||||
function stop () {
|
||||
if (!electron.powerSaveBlocker.isStarted(powerSaveBlockerId)) {
|
||||
return
|
||||
}
|
||||
electron.powerSaveBlocker.stop(powerSaveBlockerId)
|
||||
log('powerSaveBlocker.stop %d', powerSaveBlockerId)
|
||||
}
|
||||
98
main/tray.js
98
main/tray.js
@@ -1,9 +1,10 @@
|
||||
module.exports = {
|
||||
hasTray,
|
||||
init,
|
||||
hasTray
|
||||
onWindowHide,
|
||||
onWindowShow
|
||||
}
|
||||
|
||||
var cp = require('child_process')
|
||||
var electron = require('electron')
|
||||
|
||||
var app = electron.app
|
||||
@@ -11,41 +12,32 @@ var app = electron.app
|
||||
var config = require('../config')
|
||||
var windows = require('./windows')
|
||||
|
||||
var trayIcon
|
||||
var tray
|
||||
|
||||
function init () {
|
||||
// OS X has no tray icon
|
||||
if (process.platform === 'darwin') return
|
||||
|
||||
// On Linux, asynchronously check for libappindicator1
|
||||
if (process.platform === 'linux') {
|
||||
checkLinuxTraySupport(function (supportsTray) {
|
||||
if (supportsTray) createTrayIcon()
|
||||
})
|
||||
initLinux()
|
||||
}
|
||||
|
||||
// Windows always supports minimize-to-tray
|
||||
if (process.platform === 'win32') createTrayIcon()
|
||||
if (process.platform === 'win32') {
|
||||
initWin32()
|
||||
}
|
||||
// OS X apps generally do not have menu bar icons
|
||||
}
|
||||
|
||||
function hasTray () {
|
||||
return !!trayIcon
|
||||
function initLinux () {
|
||||
// Check for libappindicator1 support before creating tray icon
|
||||
checkLinuxTraySupport(function (supportsTray) {
|
||||
if (supportsTray) createTray()
|
||||
})
|
||||
}
|
||||
|
||||
function createTrayIcon () {
|
||||
trayIcon = new electron.Tray(getIconPath())
|
||||
|
||||
// On Windows, left click to open the app, right click for context menu
|
||||
// On Linux, any click (right or left) opens the context menu
|
||||
trayIcon.on('click', showApp)
|
||||
|
||||
// Show the tray context menu, and keep the available commands up to date
|
||||
updateTrayMenu()
|
||||
windows.main.on('show', updateTrayMenu)
|
||||
windows.main.on('hide', updateTrayMenu)
|
||||
function initWin32 () {
|
||||
createTray()
|
||||
}
|
||||
|
||||
function checkLinuxTraySupport (cb) {
|
||||
var cp = require('child_process')
|
||||
|
||||
// Check that we're on Ubuntu (or another debian system) and that we have
|
||||
// libappindicator1. If WebTorrent was installed from the deb file, we should
|
||||
// always have it. If it was installed from the zip file, we might not.
|
||||
@@ -57,18 +49,54 @@ function checkLinuxTraySupport (cb) {
|
||||
})
|
||||
}
|
||||
|
||||
function hasTray () {
|
||||
return !!tray
|
||||
}
|
||||
|
||||
function createTray () {
|
||||
tray = new electron.Tray(getIconPath())
|
||||
|
||||
// On Windows, left click opens the app, right click opens the context menu.
|
||||
// On Linux, any click (left or right) opens the context menu.
|
||||
tray.on('click', showApp)
|
||||
|
||||
// Show the tray context menu, and keep the available commands up to date
|
||||
updateTrayMenu()
|
||||
}
|
||||
|
||||
function onWindowHide () {
|
||||
updateTrayMenu()
|
||||
}
|
||||
|
||||
function onWindowShow () {
|
||||
updateTrayMenu()
|
||||
}
|
||||
|
||||
function updateTrayMenu () {
|
||||
var showHideMenuItem
|
||||
if (windows.main.isVisible()) {
|
||||
showHideMenuItem = { label: 'Hide to tray', click: hideApp }
|
||||
} else {
|
||||
showHideMenuItem = { label: 'Show', click: showApp }
|
||||
}
|
||||
if (!tray) return
|
||||
|
||||
var contextMenu = electron.Menu.buildFromTemplate([
|
||||
showHideMenuItem,
|
||||
{ label: 'Quit', click: () => app.quit() }
|
||||
getToggleItem(),
|
||||
{
|
||||
label: 'Quit',
|
||||
click: () => app.quit()
|
||||
}
|
||||
])
|
||||
trayIcon.setContextMenu(contextMenu)
|
||||
tray.setContextMenu(contextMenu)
|
||||
|
||||
function getToggleItem () {
|
||||
if (windows.main.win.isVisible()) {
|
||||
return {
|
||||
label: 'Hide to tray',
|
||||
click: hideApp
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
label: 'Show WebTorrent',
|
||||
click: showApp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showApp () {
|
||||
|
||||
145
main/windows.js
145
main/windows.js
@@ -1,145 +0,0 @@
|
||||
var windows = module.exports = {
|
||||
about: null,
|
||||
main: null,
|
||||
createAboutWindow,
|
||||
createWebTorrentHiddenWindow,
|
||||
createMainWindow,
|
||||
focusWindow
|
||||
}
|
||||
|
||||
var electron = require('electron')
|
||||
|
||||
var app = electron.app
|
||||
|
||||
var config = require('../config')
|
||||
var menu = require('./menu')
|
||||
var tray = require('./tray')
|
||||
|
||||
function createAboutWindow () {
|
||||
if (windows.about) {
|
||||
return focusWindow(windows.about)
|
||||
}
|
||||
var win = windows.about = new electron.BrowserWindow({
|
||||
backgroundColor: '#ECECEC',
|
||||
show: false,
|
||||
center: true,
|
||||
resizable: false,
|
||||
icon: getIconPath(),
|
||||
title: process.platform !== 'darwin'
|
||||
? 'About ' + config.APP_WINDOW_TITLE
|
||||
: '',
|
||||
useContentSize: true, // Specify web page size without OS chrome
|
||||
width: 300,
|
||||
height: 170,
|
||||
minimizable: false,
|
||||
maximizable: false,
|
||||
fullscreen: false,
|
||||
skipTaskbar: true
|
||||
})
|
||||
win.loadURL(config.WINDOW_ABOUT)
|
||||
|
||||
// No window menu
|
||||
win.setMenu(null)
|
||||
|
||||
win.webContents.on('did-finish-load', function () {
|
||||
win.show()
|
||||
})
|
||||
|
||||
win.once('closed', function () {
|
||||
windows.about = null
|
||||
})
|
||||
}
|
||||
|
||||
function createWebTorrentHiddenWindow () {
|
||||
var win = windows.webtorrent = new electron.BrowserWindow({
|
||||
backgroundColor: '#1E1E1E',
|
||||
show: false,
|
||||
center: true,
|
||||
title: 'webtorrent-hidden-window',
|
||||
useContentSize: true,
|
||||
width: 150,
|
||||
height: 150,
|
||||
minimizable: false,
|
||||
maximizable: false,
|
||||
resizable: false,
|
||||
fullscreenable: false,
|
||||
fullscreen: false,
|
||||
skipTaskbar: true
|
||||
})
|
||||
win.loadURL(config.WINDOW_WEBTORRENT)
|
||||
|
||||
// Prevent killing the WebTorrent process
|
||||
win.on('close', function (e) {
|
||||
if (!app.isQuitting) {
|
||||
e.preventDefault()
|
||||
win.hide()
|
||||
}
|
||||
})
|
||||
|
||||
win.once('closed', function () {
|
||||
windows.webtorrent = null
|
||||
})
|
||||
}
|
||||
|
||||
var HEADER_HEIGHT = 37
|
||||
var TORRENT_HEIGHT = 100
|
||||
|
||||
function createMainWindow () {
|
||||
if (windows.main) {
|
||||
return focusWindow(windows.main)
|
||||
}
|
||||
var win = windows.main = new electron.BrowserWindow({
|
||||
backgroundColor: '#1E1E1E',
|
||||
darkTheme: true, // Forces dark theme (GTK+3)
|
||||
icon: getIconPath(), // Window icon (Windows, Linux)
|
||||
minWidth: config.WINDOW_MIN_WIDTH,
|
||||
minHeight: config.WINDOW_MIN_HEIGHT,
|
||||
show: false, // Hide window until renderer sends 'ipcReady' event
|
||||
title: config.APP_WINDOW_TITLE,
|
||||
titleBarStyle: 'hidden-inset', // Hide OS chrome, except traffic light buttons (OS X)
|
||||
useContentSize: true, // Specify web page size without OS chrome
|
||||
width: 500,
|
||||
height: HEADER_HEIGHT + (TORRENT_HEIGHT * 6) // header height + 5 torrents
|
||||
})
|
||||
win.loadURL(config.WINDOW_MAIN)
|
||||
if (process.platform === 'darwin') {
|
||||
win.setSheetOffset(HEADER_HEIGHT)
|
||||
}
|
||||
|
||||
win.webContents.on('dom-ready', function () {
|
||||
menu.onToggleFullScreen()
|
||||
})
|
||||
|
||||
win.on('blur', menu.onWindowHide)
|
||||
win.on('focus', menu.onWindowShow)
|
||||
|
||||
win.on('enter-full-screen', () => menu.onToggleFullScreen(true))
|
||||
win.on('leave-full-screen', () => menu.onToggleFullScreen(false))
|
||||
|
||||
win.on('close', function (e) {
|
||||
if (process.platform !== 'darwin' && !tray.hasTray()) {
|
||||
app.quit()
|
||||
} else if (!app.isQuitting) {
|
||||
e.preventDefault()
|
||||
win.hide()
|
||||
win.send('dispatch', 'backToList')
|
||||
}
|
||||
})
|
||||
|
||||
win.once('closed', function () {
|
||||
windows.main = null
|
||||
})
|
||||
}
|
||||
|
||||
function focusWindow (win) {
|
||||
if (win.isMinimized()) {
|
||||
win.restore()
|
||||
}
|
||||
win.show() // shows and gives focus
|
||||
}
|
||||
|
||||
function getIconPath () {
|
||||
return process.platform === 'win32'
|
||||
? config.APP_ICON + '.ico'
|
||||
: config.APP_ICON + '.png'
|
||||
}
|
||||
50
main/windows/about.js
Normal file
50
main/windows/about.js
Normal file
@@ -0,0 +1,50 @@
|
||||
var about = module.exports = {
|
||||
create,
|
||||
win: null
|
||||
}
|
||||
|
||||
var electron = require('electron')
|
||||
|
||||
var config = require('../../config')
|
||||
var util = require('./util')
|
||||
|
||||
function create () {
|
||||
if (about.win) {
|
||||
return util.focusWindow(about.win)
|
||||
}
|
||||
|
||||
var win = about.win = new electron.BrowserWindow({
|
||||
backgroundColor: '#ECECEC',
|
||||
center: true,
|
||||
fullscreen: false,
|
||||
height: 170,
|
||||
icon: getIconPath(),
|
||||
maximizable: false,
|
||||
minimizable: false,
|
||||
resizable: false,
|
||||
show: false,
|
||||
skipTaskbar: true,
|
||||
useContentSize: true,
|
||||
width: 300
|
||||
})
|
||||
|
||||
win.loadURL(config.WINDOW_ABOUT)
|
||||
|
||||
// No menu on the About window
|
||||
win.setMenu(null)
|
||||
|
||||
// TODO: can this be removed?
|
||||
win.webContents.on('did-finish-load', function () {
|
||||
win.show()
|
||||
})
|
||||
|
||||
win.once('closed', function () {
|
||||
about.win = null
|
||||
})
|
||||
}
|
||||
|
||||
function getIconPath () {
|
||||
return process.platform === 'win32'
|
||||
? config.APP_ICON + '.ico'
|
||||
: config.APP_ICON + '.png'
|
||||
}
|
||||
3
main/windows/index.js
Normal file
3
main/windows/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
exports.about = require('./about')
|
||||
exports.main = require('./main')
|
||||
exports.webtorrent = require('./webtorrent')
|
||||
115
main/windows/main.js
Normal file
115
main/windows/main.js
Normal file
@@ -0,0 +1,115 @@
|
||||
var main = module.exports = {
|
||||
create,
|
||||
focus,
|
||||
hide,
|
||||
send,
|
||||
show,
|
||||
toggleFullScreen,
|
||||
win: null
|
||||
}
|
||||
|
||||
var electron = require('electron')
|
||||
|
||||
var app = electron.app
|
||||
|
||||
var config = require('../../config')
|
||||
var log = require('../log')
|
||||
var menu = require('../menu')
|
||||
var tray = require('../tray')
|
||||
var util = require('./util')
|
||||
|
||||
var HEADER_HEIGHT = 37
|
||||
var TORRENT_HEIGHT = 100
|
||||
|
||||
function create () {
|
||||
if (main.win) {
|
||||
return util.focusWindow(main.win)
|
||||
}
|
||||
var win = main.win = new electron.BrowserWindow({
|
||||
backgroundColor: '#1E1E1E',
|
||||
darkTheme: true, // Forces dark theme (GTK+3)
|
||||
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
|
||||
width: 500,
|
||||
height: HEADER_HEIGHT + (TORRENT_HEIGHT * 6) // header height + 5 torrents
|
||||
})
|
||||
|
||||
win.loadURL(config.WINDOW_MAIN)
|
||||
|
||||
if (win.setSheetOffset) win.setSheetOffset(HEADER_HEIGHT)
|
||||
|
||||
win.webContents.on('dom-ready', function () {
|
||||
menu.onToggleFullScreen()
|
||||
})
|
||||
|
||||
win.on('blur', function () {
|
||||
menu.onWindowHide()
|
||||
tray.onWindowHide()
|
||||
})
|
||||
|
||||
win.on('focus', function () {
|
||||
menu.onWindowShow()
|
||||
tray.onWindowShow()
|
||||
})
|
||||
|
||||
win.on('enter-full-screen', () => menu.onToggleFullScreen(true))
|
||||
win.on('leave-full-screen', () => menu.onToggleFullScreen(false))
|
||||
|
||||
win.on('close', function (e) {
|
||||
if (process.platform !== 'darwin' && !tray.hasTray()) {
|
||||
app.quit()
|
||||
} else if (!app.isQuitting) {
|
||||
e.preventDefault()
|
||||
win.hide()
|
||||
win.send('dispatch', 'backToList')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getIconPath () {
|
||||
return process.platform === 'win32'
|
||||
? config.APP_ICON + '.ico'
|
||||
: config.APP_ICON + '.png'
|
||||
}
|
||||
|
||||
function toggleFullScreen (flag) {
|
||||
if (!main.win || !main.win.isVisible()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (flag == null) flag = !main.win.isFullScreen()
|
||||
|
||||
log('toggleFullScreen %s', flag)
|
||||
|
||||
if (flag) {
|
||||
// Fullscreen behaves oddly unless the aspect ratio is disabled. (OS X)
|
||||
main.win.setAspectRatio(0)
|
||||
}
|
||||
|
||||
main.win.setFullScreen(flag)
|
||||
}
|
||||
|
||||
function send (...args) {
|
||||
if (!main.win) return
|
||||
main.win.send(...args)
|
||||
}
|
||||
|
||||
function show () {
|
||||
if (!main.win) return
|
||||
main.win.show()
|
||||
}
|
||||
|
||||
function hide () {
|
||||
if (!main.win) return
|
||||
main.win.hide()
|
||||
}
|
||||
|
||||
function focus () {
|
||||
if (!main.win) return
|
||||
util.focusWindow(main.win)
|
||||
}
|
||||
11
main/windows/util.js
Normal file
11
main/windows/util.js
Normal file
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
focusWindow
|
||||
}
|
||||
|
||||
function focusWindow (win) {
|
||||
if (win.isMinimized()) {
|
||||
// TODO: can this be removed?
|
||||
win.restore()
|
||||
}
|
||||
win.show() // shows and gives focus
|
||||
}
|
||||
48
main/windows/webtorrent.js
Normal file
48
main/windows/webtorrent.js
Normal file
@@ -0,0 +1,48 @@
|
||||
var webtorrent = module.exports = {
|
||||
create,
|
||||
send,
|
||||
show,
|
||||
win: null
|
||||
}
|
||||
|
||||
var config = require('../../config')
|
||||
var electron = require('electron')
|
||||
|
||||
function create () {
|
||||
var win = webtorrent.win = new electron.BrowserWindow({
|
||||
backgroundColor: '#1E1E1E',
|
||||
center: true,
|
||||
fullscreen: false,
|
||||
fullscreenable: false,
|
||||
height: 150,
|
||||
maximizable: false,
|
||||
minimizable: false,
|
||||
resizable: false,
|
||||
show: false,
|
||||
skipTaskbar: true,
|
||||
title: 'webtorrent-hidden-window',
|
||||
useContentSize: true,
|
||||
width: 150
|
||||
})
|
||||
|
||||
win.loadURL(config.WINDOW_WEBTORRENT)
|
||||
|
||||
// Prevent killing the WebTorrent process
|
||||
win.on('close', function (e) {
|
||||
if (electron.app.isQuitting) {
|
||||
return
|
||||
}
|
||||
e.preventDefault()
|
||||
win.hide()
|
||||
})
|
||||
}
|
||||
|
||||
function show () {
|
||||
if (!webtorrent.win) return
|
||||
webtorrent.win.show()
|
||||
}
|
||||
|
||||
function send (...args) {
|
||||
if (!webtorrent.win) return
|
||||
webtorrent.win.send(...args)
|
||||
}
|
||||
Reference in New Issue
Block a user