Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Commit

Permalink
link to individual files in a torrent
Browse files Browse the repository at this point in the history
  • Loading branch information
dcposch committed Nov 8, 2016
1 parent a633999 commit a501321
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 43 deletions.
152 changes: 109 additions & 43 deletions js/webtorrent/entry.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const ReactDOM = require('react-dom')
const magnetURI = require('magnet-uri')
const Button = require('../components/button')

/**
* TODO: Once WebTorrent is running in it's own process, replace the window
Expand All @@ -19,76 +21,140 @@ window.WEBTORRENT_ANNOUNCE = [

var state = {
torrentId: window.location.hash.substring(1),
torrent: null,
progress: 0,
files: [],
errorMessage: ''
dn: '',
errorMessage: '',
isFileLoaded: false
}

require('../../less/webtorrent.less')

// Start downloading the torrent
var client = window.client = new WebTorrent()
state.torrent = client.add(state.torrentId)
client.on('error', onError)

// Show a friendly window title
updateTitle()
state.torrent.on('metadata', updateTitle)

// Show download progress
setInterval(update, 1000)
setInterval(render, 1000)
render()

function start () {
state.torrent = client.add(state.torrentId)
}

function update () {
function render () {
var torrent = state.torrent
var id = state.torrentId

// TODO: right now, we only support magnet links as the torrentId
// Eventually, we need to support .torrent files as well, prob using parse-torrent
if (!state.magnetInfo && id.startsWith('magnet:?')) {
state.magnetInfo = magnetURI(id)
}
var magnetName = state.magnetInfo && state.magnetInfo.dn

var title
if (!torrent) {
title = magnetName || 'New torrent'
} else if (!torrent.name) {
title = magnetName || 'Loading torrent information...'
} else {
title = torrent.name
}
document.title = title

var status
if (!torrent.infoHash) {
status = 'Loading torrent information...'
if (!state.torrent) {
status = (
<Button l10nId='startTorrent' className='primaryButton' onClick={start}>Start</Button>
)
} else if (torrent.progress < 1) {
status = 'Downloading ' + (torrent.name || '...')
status = (
<span>Downloading: {(torrent.progress * 100).toFixed(1)}%</span>
)
} else {
status = 'Done!'
status = (
<span>Complete: 100%</span>
)
}
status = (
<span className='status'>
{status}
</span>
)

var content
if (!state.torrent) {
content = (
<div className='content'>
<strong>Warning: </strong>
please ensure that you have legal rights to download and share this content before
clicking Start.
</div>
)
} else if (state.magnetInfo && state.magnetInfo.ix != null) {
content = (
<div className='content'>
<div id='fileContainer' />
</div>
)

var ix = Number(state.magnetInfo.ix)
if (torrent && torrent.files && torrent.files[ix] && !state.isFileLoaded) {
var file = state.torrent.files[ix]
file.appendTo(document.querySelector('#fileContainer'))
state.isFileLoaded = true
}
} else {
var fileElems = torrent.files.map((file, i) => {
return (
<li>
<a href={id + '&ix=' + i}>{file.name}</a>
</li>
)
})

var fileList
if (fileElems.length === 0) {
fileList = (<div>Loading...</div>)
} else {
fileList = (
<ul className='files'>
{fileElems}
</ul>
)
}

content = (
<div className='content'>
<h3>Files</h3>
{fileList}
</div>
)
}

var elem = (
<div>
<h1>{status}</h1>
<h3>Progress: {(torrent.progress * 100).toFixed(1)}%</h3>
<h3>Files</h3>
<ul className='files'>
{torrent.files.map((file, i) => {
var className = i === state.selectedFileIndex ? 'selected' : ''
return (
<li data-ix={i} className={className} onClick={onClickFile}>
{file.name}
</li>
)
})}
</ul>
<div id='fileContainer' />
<h1>{title}</h1>
<div className='status-bar'>
{status}
<span className='button'>
<span className='fa fa-magnet' />
<span>Copy magnet link</span>
</span>
<span className='button'>
<span className='fa fa-file-o' />
<span>Save torrent file</span>
</span>
</div>
{content}
<div className='error'>{state.errorMessage}</div>
</div>
)
ReactDOM.render(elem, document.querySelector('#appContainer'))
}

function updateTitle () {
document.title = state.torrent.name || 'Downloading torrent...'
}

function onClickFile (e) {
var clickedIndex = Number(e.target.dataset.ix)
if (state.selectedFileIndex === clickedIndex) return
state.selectedFileIndex = clickedIndex

update()

var fileContainer = document.querySelector('#fileContainer')
fileContainer.innerHTML = ''
var file = state.torrent.files[state.selectedFileIndex]
file.appendTo(fileContainer)
}

function onError (err) {
state.errorMessage = err.message
}
27 changes: 27 additions & 0 deletions less/webtorrent.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */

@import "./variables.less";
@import "./button.less";
@import "../node_modules/font-awesome/css/font-awesome.css";

.files {
padding: 0;
Expand All @@ -20,3 +22,28 @@
.error {
color: @errorTextColor;
}

.status-bar {
margin-bottom: 20px;
}

.status {
display: inline-block;
width: 160px;
font-size: 1.17em;
font-weight: bold;
}

.button:not(:last-child) {
display: inline-block;
padding-right: 20px;
}

.fa {
display: inline-block;
width: 20px;
}

.content {
margin-top: 20px;
}

0 comments on commit a501321

Please sign in to comment.