WebTorrent process

* Separate hidden window, with its own renderer process, for WebTorrent
  (Must be a window. You cannot run WebRTC at all in a Web Worker, and you can't
   run it well in a node process like the electron main process.)

* Disabled the create-torrent-modal for now. That gives us a consistent UX
  regardless of whether the user dragged files or folders onto the app or opened
  the Create New Torrent menu item.

* Main process routes all messages between the main and webtorrent windows.

* The renderer index.js is smaller now (but still too big), with the WebTorrent
  interface moved to webtorrent.js / it's own process.

* The UI should be faster now, and should not lag under load.
This commit is contained in:
DC
2016-04-04 08:43:27 -07:00
committed by Feross Aboukhadijeh
parent 38ce25592f
commit db9e3e90c5
12 changed files with 726 additions and 427 deletions

View File

@@ -27,9 +27,6 @@ function TorrentList (state) {
function renderTorrent (torrentSummary) {
// Get ephemeral data (like progress %) directly from the WebTorrent handle
var infoHash = torrentSummary.infoHash
var torrent = state.client
? state.client.torrents.find((x) => x.infoHash === infoHash)
: null
var isSelected = infoHash && state.selectedInfoHash === infoHash
// Background image: show some nice visuals, like a frame from the movie, if possible
@@ -57,34 +54,34 @@ function TorrentList (state) {
<div style=${style} class=${classes}
oncontextmenu=${infoHash && dispatcher('openTorrentContextMenu', infoHash)}
onclick=${infoHash && dispatcher('toggleSelectTorrent', infoHash)}>
${renderTorrentMetadata(torrent, torrentSummary)}
${renderTorrentMetadata(torrentSummary)}
${infoHash ? renderTorrentButtons(torrentSummary) : ''}
${isSelected ? renderTorrentDetails(torrent, torrentSummary) : ''}
${isSelected ? renderTorrentDetails(torrentSummary) : ''}
</div>
`
}
// Show name, download status, % complete
function renderTorrentMetadata (torrent, torrentSummary) {
function renderTorrentMetadata (torrentSummary) {
var name = torrentSummary.name || 'Loading torrent...'
var elements = [hx`
<div class='name ellipsis'>${name}</div>
`]
// If a torrent is paused and we only get the torrentSummary
// If it's downloading/seeding then we have more information
if (torrent) {
var progress = Math.floor(100 * torrent.progress)
var downloaded = prettyBytes(torrent.downloaded)
var total = prettyBytes(torrent.length || 0)
// If it's downloading/seeding then show progress info
var prog = torrentSummary.progress
if (torrentSummary.state !== 'paused' && prog) {
var progress = Math.floor(100 * prog.progress)
var downloaded = prettyBytes(prog.downloaded)
var total = prettyBytes(prog.length || 0)
if (downloaded !== total) downloaded += ` / ${total}`
elements.push(hx`
<div class='status ellipsis'>
${getFilesLength()}
<span>${getPeers()}</span>
<span>↓ ${prettyBytes(torrent.downloadSpeed || 0)}/s</span>
<span>↑ ${prettyBytes(torrent.uploadSpeed || 0)}/s</span>
<span>↓ ${prettyBytes(prog.downloadSpeed || 0)}/s</span>
<span>↑ ${prettyBytes(prog.uploadSpeed || 0)}/s</span>
</div>
`)
elements.push(hx`
@@ -98,13 +95,13 @@ function TorrentList (state) {
return hx`<div class='metadata'>${elements}</div>`
function getPeers () {
var count = torrent.numPeers === 1 ? 'peer' : 'peers'
return `${torrent.numPeers} ${count}`
var count = prog.numPeers === 1 ? 'peer' : 'peers'
return `${prog.numPeers} ${count}`
}
function getFilesLength () {
if (torrent.ready && torrent.files.length > 1) {
return hx`<span class='files'>${torrent.files.length} files</span>`
if (torrentSummary.files && torrentSummary.files.length > 1) {
return hx`<span class='files'>${torrentSummary.files.length} files</span>`
}
}
}
@@ -165,19 +162,19 @@ function TorrentList (state) {
}
// Show files, per-file download status and play buttons, and so on
function renderTorrentDetails (torrent, torrentSummary) {
function renderTorrentDetails (torrentSummary) {
var infoHash = torrentSummary.infoHash
var filesElement
if (!torrentSummary.files) {
// We don't know what files this torrent contains
var message = torrent
? 'Downloading torrent info...'
: 'Failed to load torrent info. Click the download button to try again...'
var message = torrentSummary.status === 'paused'
? 'Failed to load torrent info. Click the download button to try again...'
: 'Downloading torrent info...'
filesElement = hx`<div class='files warning'>${message}</div>`
} else {
// We do know the files. List them and show download stats for each one
var fileRows = torrentSummary.files.map(
(file, index) => renderFileRow(torrent, torrentSummary, file, index))
(file, index) => renderFileRow(torrentSummary, file, index))
filesElement = hx`
<div class='files'>
<strong>Files</strong>
@@ -200,10 +197,14 @@ function TorrentList (state) {
}
// Show a single torrentSummary file in the details view for a single torrent
function renderFileRow (torrent, torrentSummary, file, index) {
function renderFileRow (torrentSummary, file, index) {
// First, find out how much of the file we've downloaded
var isDone = file.numPiecesPresent === file.numPieces
var progress = Math.round(100 * file.numPiecesPresent / (file.numPieces || 0)) + '%'
var progress = ''
if (torrentSummary.progress) {
var fileProg = torrentSummary.progress.files[index]
progress = Math.round(100 * fileProg.numPiecesPresent / fileProg.numPieces) + '%'
}
// Second, render the file as a table row
var infoHash = torrentSummary.infoHash