Add Torrent Link modal

This commit is contained in:
DC
2016-03-09 02:43:50 -08:00
parent ab939e185d
commit c176e3897a
7 changed files with 208 additions and 48 deletions

View File

@@ -9,6 +9,10 @@ var menu = require('./menu')
var windows = require('./windows')
function init () {
ipcMain.on('showOpenTorrentFile', function (e) {
menu.showOpenTorrentFile()
})
ipcMain.on('setBounds', function (e, bounds) {
setBounds(bounds)
})

View File

@@ -71,6 +71,35 @@ function getMenuItem (label) {
}
}
// Prompts the user for a file or folder, then makes a torrent out of the data
function showCreateTorrent () {
electron.dialog.showOpenDialog({
title: 'Select a file or folder for the torrent file.',
properties: [ 'openFile', 'openDirectory', 'multiSelections' ]
}, function (filenames) {
if (!Array.isArray(filenames)) return
windows.main.send('dispatch', 'seed', filenames)
})
}
// 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.',
properties: [ 'openFile', 'multiSelections' ]
}, function (filenames) {
if (!Array.isArray(filenames)) return
filenames.forEach(function (filename) {
windows.main.send('dispatch', 'addTorrent', filename)
})
})
}
// Prompts the user for the URL of a torrent file, then downloads and adds it
function showOpenTorrentAddress () {
windows.main.send('showOpenTorrentAddress')
}
function getMenuTemplate () {
var template = [
{
@@ -79,44 +108,25 @@ function getMenuTemplate () {
{
label: 'Create New Torrent...',
accelerator: 'CmdOrCtrl+N',
click: function () {
electron.dialog.showOpenDialog({
title: 'Select a file or folder for the torrent file.',
properties: [ 'openFile', 'openDirectory', 'multiSelections' ]
}, function (filenames) {
if (!Array.isArray(filenames)) return
windows.main.send('dispatch', 'seed', filenames)
})
}
click: showCreateTorrent
},
{
label: 'Open Torrent File...',
accelerator: 'CmdOrCtrl+O',
click: function () {
electron.dialog.showOpenDialog(windows.main, {
title: 'Select a .torrent file to open.',
properties: [ 'openFile', 'multiSelections' ]
}, function (filenames) {
if (!Array.isArray(filenames)) return
filenames.forEach(function (filename) {
windows.main.send('dispatch', 'addTorrent', filename)
})
})
}
click: showOpenTorrentFile
},
{
label: 'Open Torrent Address...',
accelerator: 'CmdOrCtrl+U',
click: function () { electron.dialog.showMessageBox({ message: 'TODO', buttons: ['OK'] }) }
click: showOpenTorrentAddress
},
{
type: 'separator'
},
{
label: (function () {
if (process.platform === 'darwin') return 'Close Window'
else return 'Close'
})(),
label: process.platform === 'darwin'
? 'Close Window'
: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
}
@@ -153,10 +163,9 @@ function getMenuTemplate () {
{
label: 'Full Screen',
type: 'checkbox',
accelerator: (function () {
if (process.platform === 'darwin') return 'Ctrl+Command+F'
else return 'F11'
})(),
accelerator: process.platform === 'darwin'
? 'Ctrl+Command+F'
: 'F11',
click: toggleFullScreen
},
{
@@ -177,10 +186,9 @@ function getMenuTemplate () {
},
{
label: 'Developer Tools',
accelerator: (function () {
if (process.platform === 'darwin') return 'Alt+Command+I'
else return 'Ctrl+Shift+I'
})(),
accelerator: process.platform === 'darwin'
? 'Alt+Command+I'
: 'Ctrl+Shift+I',
click: toggleDevTools
},
{
@@ -215,18 +223,18 @@ function getMenuTemplate () {
submenu: [
{
label: 'Learn more about ' + config.APP_NAME,
click: function () { electron.shell.openExternal('https://webtorrent.io') }
click: () => electron.shell.openExternal('https://webtorrent.io')
},
{
label: 'Contribute on GitHub',
click: function () { electron.shell.openExternal('https://github.com/feross/webtorrent-app') }
click: () => electron.shell.openExternal('https://github.com/feross/webtorrent-app')
},
{
type: 'separator'
},
{
label: 'Report an Issue...',
click: function () { electron.shell.openExternal('https://github.com/feross/webtorrent-app/issues') }
click: () => electron.shell.openExternal('https://github.com/feross/webtorrent-app/issues')
}
]
}
@@ -299,5 +307,6 @@ module.exports = {
onToggleFullScreen: onToggleFullScreen,
onWindowHide: onWindowHide,
onWindowShow: onWindowShow,
toggleFullScreen: toggleFullScreen
toggleFullScreen: toggleFullScreen,
showOpenTorrentFile: showOpenTorrentFile
}

View File

@@ -254,6 +254,81 @@ a:not(.disabled):hover, i:not(.disabled):hover {
margin-top: 0;
}
/*
* MODAL POPOVERS
*/
.modal .modal-background {
content: ' ';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
opacity: 0.5;
}
.modal .modal-content {
position: fixed;
top: 45px;
left: 0;
right: 0;
margin: 0 auto;
width: calc(100% - 20px);
max-width: 600px;
box-shadow: 2px 2px 10px 0px rgba(0,0,0,0.4);
background-color: white;
color: #222;
padding: 20px;
}
.open-torrent-address-modal input {
width: calc(100% - 100px)
}
/*
* BUTTONS
*/
button {
background: transparent;
margin-left: 10px;
padding: 0;
border: none;
font-size: 14px;
font-weight: bold;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
cursor: pointer;
color: #aaa;
}
button.primary {
color: #0cf;
}
button:hover {
-webkit-filter: brightness(1.1);
}
button:active {
-webkit-filter: brightness(1.1);
text-shadow: none;
}
/*
* OTHER FORM ELEMENT DEFAULTS
*/
input {
background: transparent;
width: 300px;
padding: 6px;
border: 1px solid #bbb;
border-radius: 3px;
box-shadow: 1px 1px 1px 0px rgba(0,0,0,0.1);
}
/*
* PLAYER
*/
@@ -384,6 +459,10 @@ body.drag .torrent-placeholder span {
background-color: #F44336;
}
.torrent.timeout .play {
padding-top: 8px;
}
.torrent.requested .play {
border-top: 6px solid rgba(255, 255, 255, 0.2);
border-right: 6px solid rgba(255, 255, 255, 0.2);

View File

@@ -4,7 +4,6 @@ var airplay = require('airplay-js')
var cfg = require('application-config')('WebTorrent')
var cfgDirectory = require('application-config-path')('WebTorrent')
var chromecasts = require('chromecasts')()
var config = require('../config')
var createTorrent = require('create-torrent')
var dragDrop = require('drag-drop')
var electron = require('electron')
@@ -13,16 +12,21 @@ var fs = require('fs')
var mainLoop = require('main-loop')
var networkAddress = require('network-address')
var path = require('path')
var torrentPoster = require('./lib/torrent-poster')
var WebTorrent = require('webtorrent')
var App = require('./views/app')
var createElement = require('virtual-dom/create-element')
var diff = require('virtual-dom/diff')
var patch = require('virtual-dom/patch')
var clipboard = electron.clipboard
var App = require('./views/app')
var config = require('../config')
var torrentPoster = require('./lib/torrent-poster')
// Electron apps have two processes: a main process (node) runs first and starts
// a renderer process (essentially a Chrome window). We're in the renderer process,
// and this IPC channel receives from and sends messages to the main process
var ipcRenderer = electron.ipcRenderer
var clipboard = electron.clipboard
// For easy debugging in Developer Tools
var state = global.state = require('./state')
@@ -94,7 +98,9 @@ function init () {
// ...keyboard shortcuts
document.addEventListener('keydown', function (e) {
if (e.which === 27) { /* ESC means either exit fullscreen or go back */
if (state.window.isFullScreen) {
if (state.modal) {
dispatch('exitModal')
} else if (state.window.isFullScreen) {
dispatch('toggleFullScreen')
} else {
dispatch('back')
@@ -157,6 +163,9 @@ function dispatch (action, ...args) {
if (action === 'addTorrent') {
addTorrent(args[0] /* torrent */)
}
if (action === 'showOpenTorrentFile') {
ipcRenderer.send('showOpenTorrentFile')
}
if (action === 'seed') {
seed(args[0] /* files */)
}
@@ -207,6 +216,10 @@ function dispatch (action, ...args) {
state.video.mouseStationarySince = new Date().getTime()
update()
}
if (action === 'exitModal') {
state.modal = null
update()
}
}
function setupIpc () {
@@ -214,6 +227,11 @@ function setupIpc () {
dispatch(action, ...args)
})
ipcRenderer.on('showOpenTorrentAddress', function (e) {
state.modal = 'open-torrent-address-modal'
update()
})
ipcRenderer.on('fullscreenChanged', function (e, isFullScreen) {
state.window.isFullScreen = isFullScreen
update()
@@ -288,7 +306,9 @@ function onFiles (files) {
dispatch('seed', files.filter(isNotTorrentFile))
}
function onPaste () {
function onPaste (e) {
if (e.target.tagName.toLowerCase() === 'input') return
var torrentIds = clipboard.readText().split('\n')
torrentIds.forEach(function (torrentId) {
torrentId = torrentId.trim()
@@ -460,6 +480,7 @@ function startServerFromReadyTorrent (torrent, cb) {
}
function stopServer () {
if (!state.server) return
state.server.server.destroy()
state.server = null
}
@@ -520,7 +541,7 @@ function toggleTorrent (torrentSummary) {
function deleteTorrent (torrentSummary) {
var infoHash = torrentSummary.infoHash
var torrent = getTorrent(infoHash)
torrent.destroy()
if (torrent) torrent.destroy()
var index = state.saved.torrents.findIndex((x) => x.infoHash === infoHash)
if (index > -1) state.saved.torrents.splice(index, 1)

View File

@@ -7,8 +7,9 @@ var hx = hyperx(h)
var Header = require('./header')
var Player = require('./player')
var TorrentList = require('./torrent-list')
var isOSX = process.platform === 'darwin'
var Modals = {
'open-torrent-address-modal': require('./open-torrent-address-modal')
}
function App (state, dispatch) {
// Hide player controls while playing video, if the mouse stays still for a while
@@ -28,21 +29,36 @@ function App (state, dispatch) {
if (state.window.isFullScreen) cls.push('is-fullscreen')
if (state.window.isFocused) cls.push('is-focused')
if (hideControls) cls.push('hide-video-controls')
return hx`
<div class='app ${cls.join(' ')}'>
${getHeader()}
<div class='content'>${getView()}</div>
${getModal()}
</div>
`
function getHeader () {
var isOSX = process.platform === 'darwin'
// Hide the header on Windows/Linux when in the player
if (isOSX || state.url !== 'player') {
return Header(state, dispatch)
}
}
function getModal () {
if (state.modal) {
var contents = Modals[state.modal](state, dispatch)
return hx`
<div class='modal'>
<div class='modal-background'></div>
<div class='modal-content add-file-modal'>
${contents}
</div>
</div>
`
}
}
function getView () {
if (state.url === 'home') {
return TorrentList(state, dispatch)

View File

@@ -40,7 +40,7 @@ function Header (state, dispatch) {
<i
class='icon add'
title='add torrent'
onclick=${() => dispatch('addTorrent')}>
onclick=${() => dispatch('showOpenTorrentFile')}>
add
</i>
`

View File

@@ -0,0 +1,31 @@
module.exports = OpenTorrentAddressModal
var h = require('virtual-dom/h')
var hyperx = require('hyperx')
var hx = hyperx(h)
function OpenTorrentAddressModal (state, dispatch) {
return hx`
<div class='open-torrent-address-modal'>
<p><strong>Enter torrent address or magnet link</strong></p>
<p>
<input id='add-torrent-url' type='text' autofocus onkeypress=${handleKeyPress} />
<button class='primary' onclick=${handleOK}>OK</button>
<button class='cancel' onclick=${handleCancel}>Cancel</button>
</p>
</div>
`
function handleKeyPress (e) {
if (e.which === 13) handleOK() /* hit Enter to submit */
}
function handleOK () {
dispatch('exitModal')
dispatch('addTorrent', document.querySelector('#add-torrent-url').value)
}
function handleCancel () {
dispatch('exitModal')
}
}