Fix screen stacking bug
You can no longer open a whole stack of Prefs windows, or Create Torrent windows Simplifies and fixes behavior when dropping files onto the app or the dock icon. Before, you could use drag-drop to create stacks of Create Torrent windows. Now, you can only create torrents from the home screen. Fixes #665
This commit is contained in:
@@ -61,14 +61,14 @@ function init () {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ipc.on('onPlayerOpen', function () {
|
ipc.on('onPlayerOpen', function () {
|
||||||
menu.onPlayerOpen()
|
menu.setPlayerOpen(true)
|
||||||
powerSaveBlocker.enable()
|
powerSaveBlocker.enable()
|
||||||
shortcuts.enable()
|
shortcuts.enable()
|
||||||
thumbar.enable()
|
thumbar.enable()
|
||||||
})
|
})
|
||||||
|
|
||||||
ipc.on('onPlayerClose', function () {
|
ipc.on('onPlayerClose', function () {
|
||||||
menu.onPlayerClose()
|
menu.setPlayerOpen(false)
|
||||||
powerSaveBlocker.disable()
|
powerSaveBlocker.disable()
|
||||||
shortcuts.disable()
|
shortcuts.disable()
|
||||||
thumbar.disable()
|
thumbar.disable()
|
||||||
@@ -112,6 +112,7 @@ function init () {
|
|||||||
ipc.on('setTitle', (e, ...args) => main.setTitle(...args))
|
ipc.on('setTitle', (e, ...args) => main.setTitle(...args))
|
||||||
ipc.on('show', () => main.show())
|
ipc.on('show', () => main.show())
|
||||||
ipc.on('toggleFullScreen', (e, ...args) => main.toggleFullScreen(...args))
|
ipc.on('toggleFullScreen', (e, ...args) => main.toggleFullScreen(...args))
|
||||||
|
ipc.on('setAllowNav', (e, ...args) => menu.setAllowNav(...args))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VLC
|
* VLC
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
init,
|
init,
|
||||||
onPlayerClose,
|
setPlayerOpen,
|
||||||
onPlayerOpen,
|
setWindowFocus,
|
||||||
|
setAllowNav,
|
||||||
onToggleAlwaysOnTop,
|
onToggleAlwaysOnTop,
|
||||||
onToggleFullScreen,
|
onToggleFullScreen
|
||||||
onWindowBlur,
|
|
||||||
onWindowFocus
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var electron = require('electron')
|
var electron = require('electron')
|
||||||
@@ -24,26 +23,28 @@ function init () {
|
|||||||
electron.Menu.setApplicationMenu(menu)
|
electron.Menu.setApplicationMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPlayerClose () {
|
function setPlayerOpen (flag) {
|
||||||
getMenuItem('Play/Pause').enabled = false
|
getMenuItem('Play/Pause').enabled = flag
|
||||||
getMenuItem('Increase Volume').enabled = false
|
getMenuItem('Increase Volume').enabled = flag
|
||||||
getMenuItem('Decrease Volume').enabled = false
|
getMenuItem('Decrease Volume').enabled = flag
|
||||||
getMenuItem('Step Forward').enabled = false
|
getMenuItem('Step Forward').enabled = flag
|
||||||
getMenuItem('Step Backward').enabled = false
|
getMenuItem('Step Backward').enabled = flag
|
||||||
getMenuItem('Increase Speed').enabled = false
|
getMenuItem('Increase Speed').enabled = flag
|
||||||
getMenuItem('Decrease Speed').enabled = false
|
getMenuItem('Decrease Speed').enabled = flag
|
||||||
getMenuItem('Add Subtitles File...').enabled = false
|
getMenuItem('Add Subtitles File...').enabled = flag
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPlayerOpen () {
|
function setWindowFocus (flag) {
|
||||||
getMenuItem('Play/Pause').enabled = true
|
getMenuItem('Full Screen').enabled = flag
|
||||||
getMenuItem('Increase Volume').enabled = true
|
getMenuItem('Float on Top').enabled = flag
|
||||||
getMenuItem('Decrease Volume').enabled = true
|
}
|
||||||
getMenuItem('Step Forward').enabled = true
|
|
||||||
getMenuItem('Step Backward').enabled = true
|
// Disallow opening more screens on top of the current one.
|
||||||
getMenuItem('Increase Speed').enabled = true
|
function setAllowNav (flag) {
|
||||||
getMenuItem('Decrease Speed').enabled = true
|
getMenuItem('Preferences').enabled = flag
|
||||||
getMenuItem('Add Subtitles File...').enabled = true
|
getMenuItem('Create New Torrent...').enabled = flag
|
||||||
|
var item = getMenuItem('Create New Torrent from File...')
|
||||||
|
if (item) item.enabled = flag
|
||||||
}
|
}
|
||||||
|
|
||||||
function onToggleAlwaysOnTop (flag) {
|
function onToggleAlwaysOnTop (flag) {
|
||||||
@@ -54,16 +55,6 @@ function onToggleFullScreen (flag) {
|
|||||||
getMenuItem('Full Screen').checked = flag
|
getMenuItem('Full Screen').checked = flag
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWindowBlur () {
|
|
||||||
getMenuItem('Full Screen').enabled = false
|
|
||||||
getMenuItem('Float on Top').enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWindowFocus () {
|
|
||||||
getMenuItem('Full Screen').enabled = true
|
|
||||||
getMenuItem('Float on Top').enabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMenuItem (label) {
|
function getMenuItem (label) {
|
||||||
for (var i = 0; i < menu.items.length; i++) {
|
for (var i = 0; i < menu.items.length; i++) {
|
||||||
var menuItem = menu.items[i].submenu.items.find(function (item) {
|
var menuItem = menu.items[i].submenu.items.find(function (item) {
|
||||||
@@ -130,14 +121,6 @@ function getMenuTemplate () {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'selectall'
|
role: 'selectall'
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'separator'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Preferences',
|
|
||||||
accelerator: 'CmdOrCtrl+,',
|
|
||||||
click: () => windows.main.dispatch('preferences')
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -350,6 +333,17 @@ function getMenuTemplate () {
|
|||||||
click: () => dialog.openSeedFile()
|
click: () => dialog.openSeedFile()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Edit menu (Windows, Linux)
|
||||||
|
template[1].submenu.push(
|
||||||
|
{
|
||||||
|
type: 'separator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Preferences',
|
||||||
|
accelerator: 'CmdOrCtrl+,',
|
||||||
|
click: () => windows.main.dispatch('preferences')
|
||||||
|
})
|
||||||
|
|
||||||
// Help menu (Windows, Linux)
|
// Help menu (Windows, Linux)
|
||||||
template[4].submenu.push(
|
template[4].submenu.push(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
hasTray,
|
hasTray,
|
||||||
init,
|
init,
|
||||||
onWindowBlur,
|
setWindowFocus
|
||||||
onWindowFocus
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var electron = require('electron')
|
var electron = require('electron')
|
||||||
@@ -31,12 +30,7 @@ function hasTray () {
|
|||||||
return !!tray
|
return !!tray
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWindowBlur () {
|
function setWindowFocus (flag) {
|
||||||
if (!tray) return
|
|
||||||
updateTrayMenu()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWindowFocus () {
|
|
||||||
if (!tray) return
|
if (!tray) return
|
||||||
updateTrayMenu()
|
updateTrayMenu()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,13 +206,13 @@ function toggleFullScreen (flag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onWindowBlur () {
|
function onWindowBlur () {
|
||||||
menu.onWindowBlur()
|
menu.setWindowFocus(false)
|
||||||
tray.onWindowBlur()
|
tray.setWindowFocus(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWindowFocus () {
|
function onWindowFocus () {
|
||||||
menu.onWindowFocus()
|
menu.setWindowFocus(true)
|
||||||
tray.onWindowFocus()
|
tray.setWindowFocus(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIconPath () {
|
function getIconPath () {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
const {dispatch} = require('../lib/dispatcher')
|
|
||||||
const State = require('../lib/state')
|
const State = require('../lib/state')
|
||||||
const ipcRenderer = require('electron').ipcRenderer
|
const ipcRenderer = require('electron').ipcRenderer
|
||||||
|
|
||||||
@@ -16,11 +15,15 @@ module.exports = class PrefsController {
|
|||||||
url: 'preferences',
|
url: 'preferences',
|
||||||
setup: function (cb) {
|
setup: function (cb) {
|
||||||
// initialize preferences
|
// initialize preferences
|
||||||
dispatch('setTitle', 'Preferences')
|
state.window.title = 'Preferences'
|
||||||
state.unsaved = Object.assign(state.unsaved || {}, {prefs: state.saved.prefs || {}})
|
state.unsaved = Object.assign(state.unsaved || {}, {prefs: state.saved.prefs || {}})
|
||||||
|
ipcRenderer.send('setAllowNav', false)
|
||||||
cb()
|
cb()
|
||||||
},
|
},
|
||||||
destroy: () => this.save()
|
destroy: () => {
|
||||||
|
ipcRenderer.send('setAllowNav', true)
|
||||||
|
this.save()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ module.exports = class TorrentListController {
|
|||||||
|
|
||||||
// Shows the Create Torrent page with options to seed a given file or folder
|
// Shows the Create Torrent page with options to seed a given file or folder
|
||||||
showCreateTorrent (files) {
|
showCreateTorrent (files) {
|
||||||
|
// You can only create torrents from the home screen.
|
||||||
|
if (this.state.location.url() !== 'home') {
|
||||||
|
return dispatch('error', 'Please go back to the torrent list before creating a new torrent.')
|
||||||
|
}
|
||||||
|
|
||||||
// Files will either be an array of file objects, which we can send directly
|
// Files will either be an array of file objects, which we can send directly
|
||||||
// to the create-torrent screen
|
// to the create-torrent screen
|
||||||
if (files.length === 0 || typeof files[0] !== 'string') {
|
if (files.length === 0 || typeof files[0] !== 'string') {
|
||||||
@@ -67,9 +72,7 @@ module.exports = class TorrentListController {
|
|||||||
var state = this.state
|
var state = this.state
|
||||||
var torrentKey = state.nextTorrentKey++
|
var torrentKey = state.nextTorrentKey++
|
||||||
ipcRenderer.send('wt-create-torrent', torrentKey, options)
|
ipcRenderer.send('wt-create-torrent', torrentKey, options)
|
||||||
state.location.backToFirst(function () {
|
state.location.cancel()
|
||||||
state.location.clearForward('create-torrent')
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts downloading and/or seeding a given torrentSummary.
|
// Starts downloading and/or seeding a given torrentSummary.
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ const dispatchHandlers = {
|
|||||||
'escapeBack': escapeBack,
|
'escapeBack': escapeBack,
|
||||||
'back': () => state.location.back(),
|
'back': () => state.location.back(),
|
||||||
'forward': () => state.location.forward(),
|
'forward': () => state.location.forward(),
|
||||||
|
'cancel': () => state.location.cancel(),
|
||||||
|
|
||||||
// Controlling the window
|
// Controlling the window
|
||||||
'setDimensions': setDimensions,
|
'setDimensions': setDimensions,
|
||||||
@@ -360,25 +361,25 @@ function setDimensions (dimensions) {
|
|||||||
function onOpen (files) {
|
function onOpen (files) {
|
||||||
if (!Array.isArray(files)) files = [ files ]
|
if (!Array.isArray(files)) files = [ files ]
|
||||||
|
|
||||||
if (state.modal) {
|
var url = state.location.url()
|
||||||
|
var allTorrents = files.every(TorrentPlayer.isTorrent)
|
||||||
|
var allSubtitles = files.every(controllers.subtitles.isSubtitle)
|
||||||
|
|
||||||
|
if (allTorrents) {
|
||||||
|
// Drop torrents onto the app: go to home screen, add torrents, no matter what
|
||||||
|
dispatch('backToList')
|
||||||
|
// All .torrent files? Add them.
|
||||||
|
files.forEach((file) => controllers.torrentList.addTorrent(file))
|
||||||
|
} else if (url === 'player' && allSubtitles) {
|
||||||
|
// Drop subtitles onto a playing video: add subtitles
|
||||||
|
controllers.subtitles.addSubtitles(files, true)
|
||||||
|
} else if (url === 'home') {
|
||||||
|
// Drop files onto home screen: show Create Torrent
|
||||||
state.modal = null
|
state.modal = null
|
||||||
}
|
controllers.torrentList.showCreateTorrent(files)
|
||||||
|
} else {
|
||||||
var subtitles = files.filter(controllers.subtitles.isSubtitle)
|
// Drop files onto any other screen: show error
|
||||||
|
return onError('Please go back to the torrent list before creating a new torrent.')
|
||||||
if (state.location.url() === 'home' || subtitles.length === 0) {
|
|
||||||
if (files.every(TorrentPlayer.isTorrent)) {
|
|
||||||
if (state.location.url() !== 'home') {
|
|
||||||
dispatch('backToList')
|
|
||||||
}
|
|
||||||
// All .torrent files? Add them.
|
|
||||||
files.forEach((file) => controllers.torrentList.addTorrent(file))
|
|
||||||
} else {
|
|
||||||
// Show the Create Torrent screen. Let's seed those files.
|
|
||||||
controllers.torrentList.showCreateTorrent(files)
|
|
||||||
}
|
|
||||||
} else if (state.location.url() === 'player') {
|
|
||||||
controllers.subtitles.addSubtitles(subtitles, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update()
|
update()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ module.exports = class CreateTorrentErrorPage extends React.Component {
|
|||||||
</p>
|
</p>
|
||||||
</p>
|
</p>
|
||||||
<p className='float-right'>
|
<p className='float-right'>
|
||||||
<button className='button-flat light' onClick={dispatcher('back')}>
|
<button className='button-flat light' onClick={dispatcher('cancel')}>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ module.exports = class CreateTorrentPage extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div key='buttons' className='float-right'>
|
<div key='buttons' className='float-right'>
|
||||||
<button key='cancel' className='button-flat light' onClick={dispatcher('back')}>Cancel</button>
|
<button key='cancel' className='button-flat light' onClick={dispatcher('cancel')}>Cancel</button>
|
||||||
<button key='create' className='button-raised' onClick={handleOK}>Create Torrent</button>
|
<button key='create' className='button-raised' onClick={handleOK}>Create Torrent</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ function renderDownloadDirSelector (state) {
|
|||||||
},
|
},
|
||||||
state.unsaved.prefs.downloadPath,
|
state.unsaved.prefs.downloadPath,
|
||||||
function (filePath) {
|
function (filePath) {
|
||||||
setStateValue('downloadPath', filePath)
|
dispatch('updatePreferences', 'downloadPath', filePath)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,12 +98,18 @@ function renderSection (definition, controls) {
|
|||||||
// - callback takes a new file or folder path
|
// - callback takes a new file or folder path
|
||||||
function renderFileSelector (definition, value, callback) {
|
function renderFileSelector (definition, value, callback) {
|
||||||
var controls = [(
|
var controls = [(
|
||||||
<input type='text' className='file-picker-text'
|
<input
|
||||||
|
type='text'
|
||||||
|
className='file-picker-text'
|
||||||
|
key={definition.property}
|
||||||
id={definition.property}
|
id={definition.property}
|
||||||
disabled='disabled'
|
disabled='disabled'
|
||||||
value={value} />
|
value={value} />
|
||||||
), (
|
), (
|
||||||
<button className='btn' onClick={handleClick}>
|
<button
|
||||||
|
key={definition.property + '-btn'}
|
||||||
|
className='btn'
|
||||||
|
onClick={handleClick}>
|
||||||
<i className='icon'>folder_open</i>
|
<i className='icon'>folder_open</i>
|
||||||
</button>
|
</button>
|
||||||
)]
|
)]
|
||||||
@@ -132,7 +138,3 @@ function renderControlGroup (definition, controls) {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStateValue (property, value) {
|
|
||||||
dispatch('updatePreferences', property, value)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ module.exports = class TorrentList extends React.Component {
|
|||||||
if (torrentSummary.playStatus) classes.push(torrentSummary.playStatus)
|
if (torrentSummary.playStatus) classes.push(torrentSummary.playStatus)
|
||||||
if (isSelected) classes.push('selected')
|
if (isSelected) classes.push('selected')
|
||||||
if (!infoHash) classes.push('disabled')
|
if (!infoHash) classes.push('disabled')
|
||||||
|
if (torrentSummary.torrrentKey) console.error('Missing torrentKey', torrentSummary)
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={torrentSummary.torrentKey}
|
key={torrentSummary.torrentKey}
|
||||||
|
|||||||
@@ -11,18 +11,18 @@ module.exports = class UpdateAvailableModal extends React.Component {
|
|||||||
<p><strong>A new version of WebTorrent is available: v{state.modal.version}</strong></p>
|
<p><strong>A new version of WebTorrent is available: v{state.modal.version}</strong></p>
|
||||||
<p>We have an auto-updater for Windows and Mac. We don't have one for Linux yet, so you'll have to download the new version manually.</p>
|
<p>We have an auto-updater for Windows and Mac. We don't have one for Linux yet, so you'll have to download the new version manually.</p>
|
||||||
<p className='float-right'>
|
<p className='float-right'>
|
||||||
<button className='button button-flat' onClick={handleCancel}>Skip This Release</button>
|
<button className='button button-flat' onClick={handleSkip}>Skip This Release</button>
|
||||||
<button className='button button-raised' onClick={handleOK}>Show Download Page</button>
|
<button className='button button-raised' onClick={handleShow}>Show Download Page</button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
function handleOK () {
|
function handleShow () {
|
||||||
electron.shell.openExternal('https://github.com/feross/webtorrent-desktop/releases')
|
electron.shell.openExternal('https://github.com/feross/webtorrent-desktop/releases')
|
||||||
dispatch('exitModal')
|
dispatch('exitModal')
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCancel () {
|
function handleSkip () {
|
||||||
dispatch('skipVersion', state.modal.version)
|
dispatch('skipVersion', state.modal.version)
|
||||||
dispatch('exitModal')
|
dispatch('exitModal')
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user