Create Torrent dialog

This commit is contained in:
DC
2016-04-20 22:25:56 -07:00
committed by DC
parent 6b70554e63
commit 31ef283e7b
5 changed files with 60 additions and 76 deletions

View File

@@ -120,7 +120,7 @@ function sliceArgv (argv) {
function processArgv (argv) { function processArgv (argv) {
argv.forEach(function (arg) { argv.forEach(function (arg) {
if (arg === '-n') { if (arg === '-n') {
windows.main.send('dispatch', 'showCreateTorrent') windows.main.send('dispatch', 'showOpenSeedFiles')
} else if (arg === '-o') { } else if (arg === '-o') {
windows.main.send('dispatch', 'showOpenTorrentFile') windows.main.send('dispatch', 'showOpenTorrentFile')
} else if (arg === '-u') { } else if (arg === '-u') {

View File

@@ -36,7 +36,7 @@ function init () {
}) })
ipcMain.on('showOpenTorrentFile', menu.showOpenTorrentFile) ipcMain.on('showOpenTorrentFile', menu.showOpenTorrentFile)
ipcMain.on('showCreateTorrent', menu.showCreateTorrent) ipcMain.on('showOpenSeedFiles', menu.showOpenSeedFiles)
ipcMain.on('setBounds', function (e, bounds, maximize) { ipcMain.on('setBounds', function (e, bounds, maximize) {
setBounds(bounds, maximize) setBounds(bounds, maximize)

View File

@@ -5,7 +5,7 @@ module.exports = {
onWindowShow, onWindowShow,
onPlayerOpen, onPlayerOpen,
onPlayerClose, onPlayerClose,
showCreateTorrent, showOpenSeedFiles,
showOpenTorrentFile, showOpenTorrentFile,
toggleFullScreen toggleFullScreen
} }
@@ -109,7 +109,7 @@ function getMenuItem (label) {
} }
// Prompts the user for a file or folder, then makes a torrent out of the data // Prompts the user for a file or folder, then makes a torrent out of the data
function showCreateTorrent () { function showOpenSeedFiles () {
// Allow only a single selection // Allow only a single selection
// To create a multi-file torrent, the user must select a folder // To create a multi-file torrent, the user must select a folder
electron.dialog.showOpenDialog({ electron.dialog.showOpenDialog({
@@ -117,10 +117,8 @@ function showCreateTorrent () {
properties: [ 'openFile', 'openDirectory' ] properties: [ 'openFile', 'openDirectory' ]
}, function (filenames) { }, function (filenames) {
if (!Array.isArray(filenames)) return if (!Array.isArray(filenames)) return
var options = { var fileOrFolder = filenames[0]
files: filenames[0] windows.main.send('dispatch', 'showCreateTorrent', fileOrFolder)
}
windows.main.send('dispatch', 'createTorrent', options)
}) })
} }
@@ -148,7 +146,7 @@ function getAppMenuTemplate () {
{ {
label: 'Create New Torrent...', label: 'Create New Torrent...',
accelerator: 'CmdOrCtrl+N', accelerator: 'CmdOrCtrl+N',
click: showCreateTorrent click: showOpenSeedFiles
}, },
{ {
label: 'Open Torrent File...', label: 'Open Torrent File...',
@@ -373,7 +371,7 @@ function getDockMenuTemplate () {
{ {
label: 'Create New Torrent...', label: 'Create New Torrent...',
accelerator: 'CmdOrCtrl+N', accelerator: 'CmdOrCtrl+N',
click: showCreateTorrent click: showOpenSeedFiles
}, },
{ {
label: 'Open Torrent File...', label: 'Open Torrent File...',

View File

@@ -211,12 +211,15 @@ function dispatch (action, ...args) {
if (action === 'addTorrent') { if (action === 'addTorrent') {
addTorrent(args[0] /* torrent */) addTorrent(args[0] /* torrent */)
} }
if (action === 'showCreateTorrent') { if (action === 'showOpenSeedFiles') {
ipcRenderer.send('showCreateTorrent') /* open file or folder to seed */ ipcRenderer.send('showOpenSeedFiles') /* open file or folder to seed */
} }
if (action === 'showOpenTorrentFile') { if (action === 'showOpenTorrentFile') {
ipcRenderer.send('showOpenTorrentFile') /* open torrent file */ ipcRenderer.send('showOpenTorrentFile') /* open torrent file */
} }
if (action === 'showCreateTorrent') {
showCreateTorrent(args[0] /* fileOrFolder */)
}
if (action === 'createTorrent') { if (action === 'createTorrent') {
createTorrent(args[0] /* options */) createTorrent(args[0] /* options */)
} }
@@ -521,7 +524,10 @@ function onOpen (files) {
// everything else = seed these files // everything else = seed these files
var rest = files.filter(not(isTorrent)).filter(not(isSubtitle)) var rest = files.filter(not(isTorrent)).filter(not(isSubtitle))
if (rest.length > 0) { if (rest.length > 0) {
createTorrentFromFileObjects(rest) state.modal = {
id: 'create-torrent-modal',
files: rest
}
} }
} }
@@ -626,62 +632,43 @@ function startTorrentingSummary (torrentSummary) {
ipcRenderer.send('wt-start-torrenting', s.torrentKey, torrentID, path, s.fileModtimes) ipcRenderer.send('wt-start-torrenting', s.torrentKey, torrentID, path, s.fileModtimes)
} }
// TODO: maybe have a "create torrent" modal in the future, with options like
// custom trackers, private flag, and so on?
//
// Right now create-torrent-modal is v basic, only user input is OK / Cancel
//
// Also, if you uncomment below below, creating a torrent thru
// File > Create New Torrent will still create a new torrent directly, while
// dragging files or folders onto the app opens the create-torrent-modal
//
// That's because the former gets a single string and the latter gets a list
// of W3C File objects. We should fix this inconsistency, ideally without
// duping this code in the drag-drop module:
// https://github.com/feross/drag-drop/blob/master/index.js
//
// function showCreateTorrentModal (files) {
// if (files.length === 0) return
// state.modal = {
// id: 'create-torrent-modal',
// files: files
// }
// }
// //
// TORRENT MANAGEMENT // TORRENT MANAGEMENT
// Send commands to the WebTorrent process, handle events // Send commands to the WebTorrent process, handle events
// //
// Creates a new torrent from a drag-dropped file or folder // Shows the Create Torrent page with options to seed a given file or folder
function createTorrentFromFileObjects (files) { function showCreateTorrent (files) {
var filePaths = files.map((x) => x.path) if (Array.isArray(files)) {
state.modal = {
// Single-file torrents are easy. Multi-file torrents require special handling id: 'create-torrent-modal',
// make sure WebTorrent seeds all files in place, without copying to /tmp files: files
if (filePaths.length === 1) { }
return createTorrent({files: filePaths[0]}) return
} }
// First, extract the base folder that the files are all in var fileOrFolder = files
var pathPrefix = files.map((x) => x.path).reduce(findCommonPrefix) fs.stat(fileOrFolder, function (err, stat) {
if (files.length > 0 && !pathPrefix.endsWith('/') && !pathPrefix.endsWith('\\')) { if (err) return onError(err)
pathPrefix = path.dirname(pathPrefix) if (stat.isDirectory()) {
fs.readdir(fileOrFolder, function (err, fileNames) {
if (err) return onError(err)
// TODO: support nested folders
var fileObjs = fileNames.map(function (fileName) {
return {
name: fileName,
path: path.join(fileOrFolder, fileName)
} }
})
// Then, use the name of the base folder (or sole file, for a single file torrent) showCreateTorrent(fileObjs)
// as the default name. Show all files relative to the base folder. })
var defaultName = path.basename(pathPrefix) } else {
var basePath = path.dirname(pathPrefix) showCreateTorrent([{
var options = { name: path.basename(fileOrFolder),
// TODO: we can't let the user choose their own name if we want WebTorrent path: fileOrFolder
// to use the files in place rather than creating a new folder. }])
name: defaultName,
path: basePath,
files: filePaths
} }
})
createTorrent(options)
} }
// Creates a new torrent and start seeeding // Creates a new torrent and start seeeding
@@ -1078,16 +1065,6 @@ function showDoneNotification (torrent) {
sound.play('DONE') sound.play('DONE')
} }
// Finds the longest common prefix
function findCommonPrefix (a, b) {
for (var i = 0; i < a.length && i < b.length; i++) {
if (a.charCodeAt(i) !== b.charCodeAt(i)) break
}
if (i === a.length) return a
if (i === b.length) return b
return a.substring(0, i)
}
// Hide player controls while playing video, if the mouse stays still for a while // Hide player controls while playing video, if the mouse stays still for a while
// Never hide the controls when: // Never hide the controls when:
// * The mouse is over the controls or we're scrubbing (see CSS) // * The mouse is over the controls or we're scrubbing (see CSS)

View File

@@ -9,12 +9,21 @@ var path = require('path')
var {dispatch} = require('../lib/dispatcher') var {dispatch} = require('../lib/dispatcher')
function UpdateAvailableModal (state) { function UpdateAvailableModal (state) {
var info = state.modal
// First, extract the base folder that the files are all in // First, extract the base folder that the files are all in
var files = state.modal.files var files = info.files
var pathPrefix = files.map((x) => x.path).reduce(findCommonPrefix) var pathPrefix = info.folderPath
if (files.length > 0 && !pathPrefix.endsWith('/') && !pathPrefix.endsWith('\\')) { if (!pathPrefix) {
if (files.length > 0) {
pathPrefix = files.map((x) => x.path).reduce(findCommonPrefix)
if (!pathPrefix.endsWith('/') && !pathPrefix.endsWith('\\')) {
pathPrefix = path.dirname(pathPrefix) pathPrefix = path.dirname(pathPrefix)
} }
} else {
pathPrefix = files[0]
}
}
// Then, use the name of the base folder (or sole file, for a single file torrent) // Then, use the name of the base folder (or sole file, for a single file torrent)
// as the default name. Show all files relative to the base folder. // as the default name. Show all files relative to the base folder.