No more harp, some ES6
This commit is contained in:
parent
6570d9fc93
commit
f61fb5ac71
14 changed files with 672 additions and 23245 deletions
48
200.jade
48
200.jade
|
@ -1,48 +0,0 @@
|
|||
doctype html
|
||||
html(ng-app="BTorrent" lang="en")
|
||||
head
|
||||
base(href="")
|
||||
meta(charset="UTF-8")
|
||||
title βTorrent: Browser WebTorrent Client
|
||||
meta(name="description" content="βTorrent is the first fully-featured Browser WebTorrent Client")
|
||||
meta(name="keywords" content="βTorrent, btorrent, client, webtorrent, browser, torrent, stream, bittorrent, torrenting, sharing, filesharing")
|
||||
meta(name="author" content="Diego Rodríguez Baquero - DiegoRBaquero")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||
script(src="https://cdn.jsdelivr.net/g/webtorrent@0.90,momentjs@2,angularjs@1.4(angular.min.js+angular-route.min.js+angular-sanitize.min.js),angular.ui-grid@3.1,angular.ng-notify@0.7,angular.file-upload@12")
|
||||
link(rel="stylesheet" href="https://cdn.jsdelivr.net/g/normalize@3.0,skeleton@2.0,angular.ng-notify@0.7(ng-notify.min.css)")
|
||||
link(rel="stylesheet" href="https://cdn.jsdelivr.net/fontawesome/4.5/css/font-awesome.min.css")
|
||||
link(rel="stylesheet" href="https://cdn.jsdelivr.net/angular.ui-grid/3.1/ui-grid.min.css")
|
||||
link(rel="stylesheet" href="style.css")
|
||||
body(ng-controller="BTorrentCtrl" ng-cloak="")
|
||||
header
|
||||
h1
|
||||
| βTorrent
|
||||
span.version v{{$root.version}}
|
||||
div.views(ng-show="$root.client.torrents.length == 0")
|
||||
a(ng-href="/#") Full
|
||||
| |
|
||||
a(ng-href="/download") Single Download
|
||||
| |
|
||||
a(ng-href="/view") Stream / View
|
||||
#viewer(ng-style="$root.viewerStyle")
|
||||
#view(ng-view)
|
||||
footer
|
||||
a.button(href="https://github.com/DiegoRBaquero/BTorrent/issues" target="_blank")
|
||||
i.fa.fa-github
|
||||
| Suggest a feature / Report a bug
|
||||
i.fa.fa-comment
|
||||
br
|
||||
b βTorrent is an Open-Source project by
|
||||
a(href="https://diegorbaquero.com" target="_blank") DiegoRBaquero
|
||||
br
|
||||
b
|
||||
a(href="https://tracker.btorrent.xyz/stats" target="_blank") βTorrent's Tracker Stats
|
||||
br
|
||||
| Powered by
|
||||
a(href="https://github.com/feross/webtorrent" target="_blank") WebTorrent
|
||||
br
|
||||
small Hosted by
|
||||
a(href="https://m.do.co/c/0b25a910e6e4" target="_blank") Digital Ocean
|
||||
.spinner(ng-show="client.processing")
|
||||
i.fa.fa-spinner.fa-spin.spinner-icon
|
||||
script(src="app.js")
|
18
README.md
18
README.md
|
@ -1,6 +1,6 @@
|
|||
βTorrent
|
||||
========
|
||||
**[βTorrent]** is a fully-featured **[WebTorrent]** browser client written in [Jade], [CoffeeScript] and [Sass]
|
||||
**[βTorrent]** is a fully-featured **[WebTorrent]** browser client written in HTML, JS and CSS
|
||||
|
||||
[![Join the chat at https://gitter.im/DiegoRBaquero/BTorrent](https://badges.gitter.im/DiegoRBaquero/BTorrent.svg)](https://gitter.im/DiegoRBaquero/BTorrent?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
|
@ -33,18 +33,14 @@ Website powered by [jsDelivr] and [CloudFlare]. I use [nginx] in my server.
|
|||
|
||||
Don't like CloudFlare? No problem! Check [Direct-βTorrent].
|
||||
|
||||
### Easily built, tested and served
|
||||
**I use [Harp] to rapidly test and compile the project**
|
||||
### HTML5 serving
|
||||
**You must serve index.html as the default**
|
||||
|
||||
Build the project into HTML, JS and CSS easily. Just use:
|
||||
```bash
|
||||
harp compile
|
||||
For nginx, use this conf:
|
||||
```
|
||||
This will create a www folder with the compiled files
|
||||
|
||||
If you need to serve the files and view the compiled version instantly just use:
|
||||
```bash
|
||||
harp server
|
||||
location / {
|
||||
try_files $uri$args $uri$args/ /index.html;
|
||||
}
|
||||
```
|
||||
|
||||
### Enable Debugging
|
||||
|
|
309
app.coffee
309
app.coffee
|
@ -1,309 +0,0 @@
|
|||
VERSION = "0.15"
|
||||
BUILD = "2"
|
||||
|
||||
trackers = [
|
||||
'wss://tracker.btorrent.xyz'
|
||||
'wss://tracker.webtorrent.io'
|
||||
'wss://tracker.openwebtorrent.com'
|
||||
'wss://tracker.fastcast.nz'
|
||||
]
|
||||
|
||||
opts = {
|
||||
announce: trackers
|
||||
}
|
||||
|
||||
rtcConfig = {
|
||||
"iceServers": [
|
||||
{
|
||||
"url": "stun:23.21.150.121"
|
||||
"urls": "stun:23.21.150.121"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
debug = window.localStorage.getItem('debug')?
|
||||
|
||||
dbg = (string, item, color) ->
|
||||
color = if color? then color else '#333333'
|
||||
if debug
|
||||
if item? && item.name
|
||||
console.debug '%cβTorrent:' + (if item.infoHash? then 'torrent ' else 'torrent ' + item._torrent.name + ':file ') + item.name + (if item.infoHash? then ' (' + item.infoHash + ')' else '') + ' %c' + string, 'color: #33C3F0', 'color: ' + color
|
||||
else
|
||||
console.debug '%cβTorrent:client %c' + string, 'color: #33C3F0', 'color: ' + color
|
||||
|
||||
er = (err, item) ->
|
||||
dbg err, item, '#FF0000'
|
||||
|
||||
dbg "Starting... v#{VERSION}b#{BUILD}"
|
||||
|
||||
client = new WebTorrent rtcConfig: rtcConfig
|
||||
scope = null
|
||||
|
||||
app = angular.module 'BTorrent', ['ngRoute', 'ui.grid', 'ui.grid.resizeColumns', 'ui.grid.selection', 'ngFileUpload', 'ngNotify'], ['$compileProvider','$locationProvider', '$routeProvider', ($compileProvider, $locationProvider, $routeProvider) ->
|
||||
$compileProvider.aHrefSanitizationWhitelist /^\s*(https?|magnet|blob|javascript):/
|
||||
$locationProvider.html5Mode(
|
||||
enabled: true
|
||||
requireBase: false
|
||||
).hashPrefix '#'
|
||||
|
||||
$routeProvider.when '/view',
|
||||
templateUrl: 'views/view.html'
|
||||
controller: 'ViewCtrl'
|
||||
.when '/download',
|
||||
templateUrl: 'views/download.html'
|
||||
controller: 'DownloadCtrl'
|
||||
.otherwise
|
||||
templateUrl: 'views/full.html'
|
||||
controller: 'FullCtrl'
|
||||
]
|
||||
|
||||
app.controller 'BTorrentCtrl', ['$scope','$rootScope','$http','$log','$location', 'ngNotify', ($scope, $rootScope, $http, $log, $location, ngNotify) ->
|
||||
$rootScope.version = VERSION
|
||||
|
||||
ngNotify.config
|
||||
duration: 5000
|
||||
html: true
|
||||
|
||||
if !WebTorrent.WEBRTC_SUPPORT?
|
||||
$rootScope.disabled = true
|
||||
ngNotify.set 'Please use latest Chrome, Firefox or Opera', {type: 'error', sticky: true, button: false}
|
||||
|
||||
$rootScope.client = client
|
||||
scope = $rootScope
|
||||
|
||||
updateAll = ->
|
||||
if $rootScope.client.processing
|
||||
return
|
||||
$rootScope.$apply()
|
||||
|
||||
setInterval updateAll, 500
|
||||
|
||||
$rootScope.seedFiles = (files) ->
|
||||
if files? && files.length > 0
|
||||
if files.length == 1
|
||||
dbg 'Seeding file ' + files[0].name
|
||||
else
|
||||
dbg 'Seeding ' + files.length + ' files'
|
||||
name = prompt('Please name your torrent', 'My Awesome Torrent') || 'My Awesome Torrent'
|
||||
opts.name = name
|
||||
$rootScope.client.processing = true
|
||||
$rootScope.client.seed files, opts, $rootScope.onSeed
|
||||
delete opts.name
|
||||
|
||||
$rootScope.openTorrentFile = (file) ->
|
||||
if file?
|
||||
dbg 'Adding torrent file ' + file.name
|
||||
$rootScope.client.processing = true
|
||||
$rootScope.client.add file, opts, $rootScope.onTorrent
|
||||
|
||||
$rootScope.client.on 'error', (err, torrent) ->
|
||||
$rootScope.client.processing = false
|
||||
ngNotify.set err, 'error'
|
||||
er err, torrent
|
||||
|
||||
$rootScope.addMagnet = (magnet, onTorrent) ->
|
||||
if magnet? && magnet.length > 0
|
||||
dbg 'Adding magnet/hash ' + magnet
|
||||
$rootScope.client.processing = true
|
||||
$rootScope.client.add magnet, opts, onTorrent || $rootScope.onTorrent
|
||||
|
||||
$rootScope.destroyedTorrent = (err) ->
|
||||
if err
|
||||
throw err
|
||||
dbg 'Destroyed torrent', $rootScope.selectedTorrent
|
||||
$rootScope.selectedTorrent = null
|
||||
$rootScope.client.processing = false
|
||||
|
||||
$rootScope.changePriority = (file) ->
|
||||
if file.priority == '-1'
|
||||
dbg 'Deselected', file
|
||||
file.deselect()
|
||||
else
|
||||
dbg 'Selected with priority ' + file.priority, file
|
||||
file.select(file.priority)
|
||||
|
||||
$rootScope.onTorrent = (torrent, isSeed) ->
|
||||
dbg torrent.magnetURI
|
||||
torrent.safeTorrentFileURL = torrent.torrentFileBlobURL
|
||||
torrent.fileName = torrent.name + '.torrent'
|
||||
if !isSeed
|
||||
dbg 'Received metadata', torrent
|
||||
ngNotify.set 'Received ' + torrent.name + ' metadata'
|
||||
if !($rootScope.selectedTorrent?)
|
||||
$rootScope.selectedTorrent = torrent
|
||||
$rootScope.client.processing = false
|
||||
torrent.files.forEach (file) ->
|
||||
file.getBlobURL (err, url) ->
|
||||
if err
|
||||
throw err
|
||||
if isSeed
|
||||
dbg 'Started seeding', torrent
|
||||
if !($rootScope.selectedTorrent?)
|
||||
$rootScope.selectedTorrent = torrent
|
||||
$rootScope.client.processing = false
|
||||
file.url = url
|
||||
if !isSeed
|
||||
dbg 'Done ', file
|
||||
ngNotify.set '<b>' + file.name + '</b> ready for download', 'success'
|
||||
torrent.on 'download', (chunkSize) ->
|
||||
#if !isSeed
|
||||
# dbg 'Downloaded chunk', torrent
|
||||
torrent.on 'upload', (chunkSize) ->
|
||||
#dbg 'Uploaded chunk', torrent
|
||||
torrent.on 'done', ->
|
||||
if !isSeed
|
||||
dbg 'Done', torrent
|
||||
ngNotify.set '<b>' + torrent.name + '</b> has finished downloading', 'success'
|
||||
torrent.on 'wire', (wire, addr) ->
|
||||
dbg 'Wire ' + addr, torrent
|
||||
torrent.on 'error', (err) ->
|
||||
er err
|
||||
|
||||
$rootScope.onSeed = (torrent) ->
|
||||
$rootScope.onTorrent torrent, true
|
||||
|
||||
dbg "Ready"
|
||||
]
|
||||
|
||||
app.controller 'FullCtrl', ['$scope','$rootScope','$http','$log','$location', 'ngNotify', ($scope, $rootScope, $http, $log, $location, ngNotify) ->
|
||||
ngNotify.config
|
||||
duration: 5000
|
||||
html: true
|
||||
|
||||
$scope.addMagnet = ->
|
||||
$rootScope.addMagnet $scope.torrentInput
|
||||
$scope.torrentInput = ''
|
||||
|
||||
$scope.columns = [
|
||||
{field: 'name', cellTooltip: true, minWidth: '200'}
|
||||
{field: 'length', name: 'Size', cellFilter: 'pbytes', width: '80'}
|
||||
{field: 'received', displayName: 'Downloaded', cellFilter: 'pbytes', width: '135'}
|
||||
{field: 'downloadSpeed', displayName: '↓ Speed', cellFilter: 'pbytes:1', width: '100'}
|
||||
{field: 'progress', displayName: 'Progress', cellFilter: 'progress', width: '100'}
|
||||
{field: 'timeRemaining', displayName: 'ETA', cellFilter: 'humanTime', width: '140'}
|
||||
{field: 'uploaded', displayName: 'Uploaded', cellFilter: 'pbytes', width: '125'}
|
||||
{field: 'uploadSpeed', displayName: '↑ Speed', cellFilter: 'pbytes:1', width: '100'}
|
||||
{field: 'numPeers', displayName: 'Peers', width: '80'}
|
||||
{field: 'ratio', cellFilter: 'number:2', width: '80'}
|
||||
]
|
||||
|
||||
$scope.gridOptions =
|
||||
columnDefs: $scope.columns
|
||||
data: $rootScope.client.torrents
|
||||
enableColumnResizing: true
|
||||
enableColumnMenus: false
|
||||
enableRowSelection: true
|
||||
enableRowHeaderSelection: false
|
||||
multiSelect: false
|
||||
|
||||
$scope.gridOptions.onRegisterApi = (gridApi) ->
|
||||
$scope.gridApi = gridApi
|
||||
gridApi.selection.on.rowSelectionChanged $scope, (row) ->
|
||||
if !row.isSelected && $rootScope.selectedTorrent? && $rootScope.selectedTorrent.infoHash = row.entity.infoHash
|
||||
$rootScope.selectedTorrent = null
|
||||
else
|
||||
$rootScope.selectedTorrent = row.entity
|
||||
|
||||
if $location.hash() != ''
|
||||
$rootScope.client.processing = true
|
||||
setTimeout ->
|
||||
dbg 'Adding ' + $location.hash()
|
||||
$rootScope.addMagnet $location.hash()
|
||||
, 0
|
||||
]
|
||||
|
||||
app.controller 'DownloadCtrl', ['$scope','$rootScope','$http','$log','$location', 'ngNotify', ($scope, $rootScope, $http, $log, $location, ngNotify) ->
|
||||
ngNotify.config
|
||||
duration: 5000
|
||||
html: true
|
||||
|
||||
$scope.addMagnet = ->
|
||||
$rootScope.addMagnet($scope.torrentInput)
|
||||
$scope.torrentInput = ''
|
||||
|
||||
if $location.hash() != ''
|
||||
$rootScope.client.processing = true
|
||||
setTimeout ->
|
||||
dbg 'Adding ' + $location.hash()
|
||||
$rootScope.addMagnet $location.hash()
|
||||
, 0
|
||||
]
|
||||
|
||||
app.controller 'ViewCtrl', ['$scope','$rootScope','$http','$log','$location', 'ngNotify', ($scope, $rootScope, $http, $log, $location, ngNotify) ->
|
||||
ngNotify.config
|
||||
duration: 2000
|
||||
html: true
|
||||
|
||||
onTorrent = (torrent) ->
|
||||
$rootScope.viewerStyle = {'margin-top': '-20px', 'text-align': 'center'}
|
||||
dbg torrent.magnetURI
|
||||
torrent.safeTorrentFileURL = torrent.torrentFileBlobURL
|
||||
torrent.fileName = torrent.name + '.torrent'
|
||||
$rootScope.selectedTorrent = torrent
|
||||
$rootScope.client.processing = false
|
||||
dbg 'Received metadata', torrent
|
||||
ngNotify.set 'Received ' + torrent.name + ' metadata'
|
||||
torrent.files.forEach (file) ->
|
||||
file.appendTo '#viewer'
|
||||
file.getBlobURL (err, url) ->
|
||||
if err
|
||||
throw err
|
||||
file.url = url
|
||||
dbg 'Done ', file
|
||||
torrent.on 'download', (chunkSize) ->
|
||||
# dbg 'Downloaded chunk', torrent
|
||||
torrent.on 'upload', (chunkSize) ->
|
||||
#dbg 'Uploaded chunk', torrent
|
||||
torrent.on 'done', ->
|
||||
dbg 'Done', torrent
|
||||
torrent.on 'wire', (wire, addr) ->
|
||||
dbg 'Wire ' + addr, torrent
|
||||
torrent.on 'error', (err) ->
|
||||
er err
|
||||
|
||||
$scope.addMagnet = ->
|
||||
$rootScope.addMagnet $scope.torrentInput, onTorrent
|
||||
$scope.torrentInput = ''
|
||||
|
||||
if $location.hash() != ''
|
||||
$rootScope.client.processing = true
|
||||
setTimeout ->
|
||||
dbg 'Adding ' + $location.hash()
|
||||
$rootScope.addMagnet $location.hash(), onTorrent
|
||||
, 0
|
||||
]
|
||||
|
||||
app.filter 'html', ['$sce', ($sce) ->
|
||||
(input) ->
|
||||
$sce.trustAsHtml input
|
||||
return
|
||||
]
|
||||
|
||||
app.filter 'pbytes', ->
|
||||
(num, speed) ->
|
||||
if isNaN(num)
|
||||
return ''
|
||||
units = [
|
||||
'B'
|
||||
'kB'
|
||||
'MB'
|
||||
'GB'
|
||||
'TB'
|
||||
]
|
||||
if num < 1
|
||||
return (if speed then '' else '0 B')
|
||||
exponent = Math.min(Math.floor(Math.log(num) / 6.907755278982137), 8)
|
||||
num = (num / 1000 ** exponent).toFixed(1) * 1
|
||||
unit = units[exponent]
|
||||
num + ' ' + unit + (if speed then '/s' else '')
|
||||
|
||||
app.filter 'humanTime', ->
|
||||
(millis) ->
|
||||
if millis < 1000
|
||||
return ''
|
||||
remaining = moment.duration(millis).humanize()
|
||||
remaining[0].toUpperCase() + remaining.substr(1)
|
||||
|
||||
app.filter 'progress', ->
|
||||
(num) ->
|
||||
(100 * num).toFixed(1) + '%'
|
376
app.js
Normal file
376
app.js
Normal file
|
@ -0,0 +1,376 @@
|
|||
let BUILD, VERSION, app, client, dbg, debug, er, opts, rtcConfig, trackers
|
||||
|
||||
VERSION = '0.15'
|
||||
|
||||
BUILD = '2'
|
||||
|
||||
trackers = ['wss://tracker.btorrent.xyz', 'wss://tracker.webtorrent.io', 'wss://tracker.openwebtorrent.com', 'wss://tracker.fastcast.nz']
|
||||
|
||||
opts = {
|
||||
announce: trackers
|
||||
}
|
||||
|
||||
rtcConfig = {
|
||||
'iceServers': [
|
||||
{
|
||||
'url': 'stun:23.21.150.121',
|
||||
'urls': 'stun:23.21.150.121'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
debug = window.localStorage.getItem('debug') != null
|
||||
|
||||
dbg = function (string, item, color) {
|
||||
color = color != null ? color : '#333333'
|
||||
if (debug) {
|
||||
if ((item != null) && item.name) {
|
||||
return console.debug(`%cβTorrent:${item.infoHash != null ? 'torrent ' : 'torrent ' + item._torrent.name + ':file '}${item.name}${item.infoHash != null ? ' (' + item.infoHash + ')' : ''} %c${string}`, 'color: #33C3F0', `color: ${color}`)
|
||||
} else {
|
||||
return console.debug(`%cβTorrent:client %c${string}`, 'color: #33C3F0', `color: ${color}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
er = function (err, item) { dbg(err, item, '#FF0000') }
|
||||
|
||||
dbg(`Starting... v${VERSION}b${BUILD}`)
|
||||
|
||||
client = new WebTorrent({
|
||||
tracker: {
|
||||
rtcConfig: rtcConfig,
|
||||
announce: trackers
|
||||
}
|
||||
})
|
||||
|
||||
app = angular.module('BTorrent',
|
||||
['ngRoute', 'ui.grid', 'ui.grid.resizeColumns', 'ui.grid.selection', 'ngFileUpload', 'ngNotify'],
|
||||
['$compileProvider', '$locationProvider', '$routeProvider', function ($compileProvider, $locationProvider, $routeProvider) {
|
||||
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|magnet|blob|javascript):/)
|
||||
$locationProvider.html5Mode({
|
||||
enabled: true,
|
||||
requireBase: false
|
||||
}).hashPrefix('#')
|
||||
$routeProvider.when('/view', {
|
||||
templateUrl: 'views/view.html',
|
||||
controller: 'ViewCtrl'
|
||||
}).when('/download', {
|
||||
templateUrl: 'views/download.html',
|
||||
controller: 'DownloadCtrl'
|
||||
}).otherwise({
|
||||
templateUrl: 'views/full.html',
|
||||
controller: 'FullCtrl'
|
||||
})
|
||||
}]
|
||||
)
|
||||
|
||||
app.controller('BTorrentCtrl', ['$scope', '$rootScope', '$http', '$log', '$location', 'ngNotify', function ($scope, $rootScope, $http, $log, $location, ngNotify) {
|
||||
let updateAll
|
||||
$rootScope.version = VERSION
|
||||
ngNotify.config({
|
||||
duration: 5000,
|
||||
html: true
|
||||
})
|
||||
if (WebTorrent.WEBRTC_SUPPORT == null) {
|
||||
$rootScope.disabled = true
|
||||
ngNotify.set('Please use latest Chrome, Firefox or Opera', {
|
||||
type: 'error',
|
||||
sticky: true,
|
||||
button: false
|
||||
})
|
||||
}
|
||||
$rootScope.client = client
|
||||
scope = $rootScope
|
||||
updateAll = function () {
|
||||
if ($rootScope.client.processing) {
|
||||
return
|
||||
}
|
||||
$rootScope.$apply()
|
||||
}
|
||||
setInterval(updateAll, 500)
|
||||
$rootScope.seedFiles = function (files) {
|
||||
let name
|
||||
if ((files != null) && files.length > 0) {
|
||||
if (files.length === 1) {
|
||||
dbg(`Seeding file ${files[0].name}`)
|
||||
} else {
|
||||
dbg(`Seeding ${files.length} files`)
|
||||
name = prompt('Please name your torrent', 'My Awesome Torrent') || 'My Awesome Torrent'
|
||||
opts.name = name
|
||||
}
|
||||
$rootScope.client.processing = true
|
||||
$rootScope.client.seed(files, opts, $rootScope.onSeed)
|
||||
delete opts.name
|
||||
}
|
||||
}
|
||||
$rootScope.openTorrentFile = function (file) {
|
||||
if (file != null) {
|
||||
dbg(`Adding torrent file ${file.name}`)
|
||||
$rootScope.client.processing = true
|
||||
$rootScope.client.add(file, opts, $rootScope.onTorrent)
|
||||
}
|
||||
}
|
||||
$rootScope.client.on('error', function (err, torrent) {
|
||||
$rootScope.client.processing = false
|
||||
ngNotify.set(err, 'error')
|
||||
er(err, torrent)
|
||||
})
|
||||
$rootScope.addMagnet = function (magnet, onTorrent) {
|
||||
if ((magnet != null) && magnet.length > 0) {
|
||||
dbg(`Adding magnet/hash ${magnet}`)
|
||||
$rootScope.client.processing = true
|
||||
$rootScope.client.add(magnet, opts, onTorrent || $rootScope.onTorrent)
|
||||
}
|
||||
}
|
||||
$rootScope.destroyedTorrent = function (err) {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
dbg('Destroyed torrent', $rootScope.selectedTorrent)
|
||||
$rootScope.selectedTorrent = null
|
||||
$rootScope.client.processing = false
|
||||
}
|
||||
$rootScope.changePriority = function (file) {
|
||||
if (file.priority === '-1') {
|
||||
dbg('Deselected', file)
|
||||
file.deselect()
|
||||
} else {
|
||||
dbg(`Selected with priority ${file.priority}`, file)
|
||||
file.select(file.priority)
|
||||
}
|
||||
}
|
||||
$rootScope.onTorrent = function (torrent, isSeed) {
|
||||
dbg(torrent.magnetURI)
|
||||
torrent.safeTorrentFileURL = torrent.torrentFileBlobURL
|
||||
torrent.fileName = `${torrent.name}.torrent`
|
||||
if (!isSeed) {
|
||||
dbg('Received metadata', torrent)
|
||||
ngNotify.set(`Received ${torrent.name} metadata`)
|
||||
if (!($rootScope.selectedTorrent != null)) {
|
||||
$rootScope.selectedTorrent = torrent
|
||||
}
|
||||
$rootScope.client.processing = false
|
||||
}
|
||||
torrent.files.forEach(function (file) {
|
||||
file.getBlobURL(function (err, url) {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
if (isSeed) {
|
||||
dbg('Started seeding', torrent)
|
||||
if (!($rootScope.selectedTorrent != null)) {
|
||||
$rootScope.selectedTorrent = torrent
|
||||
}
|
||||
$rootScope.client.processing = false
|
||||
}
|
||||
file.url = url
|
||||
if (!isSeed) {
|
||||
dbg('Done ', file)
|
||||
ngNotify.set(`<b>${file.name}</b> ready for download`, 'success')
|
||||
}
|
||||
})
|
||||
})
|
||||
torrent.on('done', function () {
|
||||
if (!isSeed) {
|
||||
dbg('Done', torrent)
|
||||
}
|
||||
ngNotify.set(`<b>${torrent.name}</b> has finished downloading`, 'success')
|
||||
})
|
||||
torrent.on('wire', function (wire, addr) { dbg(`Wire ${addr}`, torrent) })
|
||||
torrent.on('error', er)
|
||||
}
|
||||
$rootScope.onSeed = function (torrent) { $rootScope.onTorrent(torrent, true) }
|
||||
dbg('Ready')
|
||||
}
|
||||
])
|
||||
|
||||
app.controller('FullCtrl', ['$scope', '$rootScope', '$http', '$log', '$location', 'ngNotify', function ($scope, $rootScope, $http, $log, $location, ngNotify) {
|
||||
ngNotify.config({
|
||||
duration: 5000,
|
||||
html: true
|
||||
})
|
||||
$scope.addMagnet = function () {
|
||||
$rootScope.addMagnet($scope.torrentInput)
|
||||
$scope.torrentInput = ''
|
||||
}
|
||||
$scope.columns = [
|
||||
{
|
||||
field: 'name',
|
||||
cellTooltip: true,
|
||||
minWidth: '200'
|
||||
}, {
|
||||
field: 'length',
|
||||
name: 'Size',
|
||||
cellFilter: 'pbytes',
|
||||
width: '80'
|
||||
}, {
|
||||
field: 'received',
|
||||
displayName: 'Downloaded',
|
||||
cellFilter: 'pbytes',
|
||||
width: '135'
|
||||
}, {
|
||||
field: 'downloadSpeed',
|
||||
displayName: '↓ Speed',
|
||||
cellFilter: 'pbytes:1',
|
||||
width: '100'
|
||||
}, {
|
||||
field: 'progress',
|
||||
displayName: 'Progress',
|
||||
cellFilter: 'progress',
|
||||
width: '100'
|
||||
}, {
|
||||
field: 'timeRemaining',
|
||||
displayName: 'ETA',
|
||||
cellFilter: 'humanTime',
|
||||
width: '140'
|
||||
}, {
|
||||
field: 'uploaded',
|
||||
displayName: 'Uploaded',
|
||||
cellFilter: 'pbytes',
|
||||
width: '125'
|
||||
}, {
|
||||
field: 'uploadSpeed',
|
||||
displayName: '↑ Speed',
|
||||
cellFilter: 'pbytes:1',
|
||||
width: '100'
|
||||
}, {
|
||||
field: 'numPeers',
|
||||
displayName: 'Peers',
|
||||
width: '80'
|
||||
}, {
|
||||
field: 'ratio',
|
||||
cellFilter: 'number:2',
|
||||
width: '80'
|
||||
}
|
||||
]
|
||||
$scope.gridOptions = {
|
||||
columnDefs: $scope.columns,
|
||||
data: $rootScope.client.torrents,
|
||||
enableColumnResizing: true,
|
||||
enableColumnMenus: false,
|
||||
enableRowSelection: true,
|
||||
enableRowHeaderSelection: false,
|
||||
multiSelect: false
|
||||
}
|
||||
$scope.gridOptions.onRegisterApi = function (gridApi) {
|
||||
$scope.gridApi = gridApi
|
||||
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
|
||||
if (!row.isSelected && ($rootScope.selectedTorrent != null) && ($rootScope.selectedTorrent.infoHash = row.entity.infoHash)) {
|
||||
$rootScope.selectedTorrent = null
|
||||
} else {
|
||||
$rootScope.selectedTorrent = row.entity
|
||||
}
|
||||
})
|
||||
}
|
||||
if ($location.hash() !== '') {
|
||||
$rootScope.client.processing = true
|
||||
setTimeout(function () {
|
||||
dbg(`Adding ${$location.hash()}`)
|
||||
$rootScope.addMagnet($location.hash())
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
app.controller('DownloadCtrl', ['$scope', '$rootScope', '$http', '$log', '$location', 'ngNotify', function ($scope, $rootScope, $http, $log, $location, ngNotify) {
|
||||
ngNotify.config({
|
||||
duration: 5000,
|
||||
html: true
|
||||
})
|
||||
$scope.addMagnet = function() {
|
||||
$rootScope.addMagnet($scope.torrentInput)
|
||||
$scope.torrentInput = ''
|
||||
}
|
||||
if ($location.hash() !== '') {
|
||||
$rootScope.client.processing = true
|
||||
setTimeout(function () {
|
||||
dbg(`Adding ${$location.hash()}`)
|
||||
$rootScope.addMagnet($location.hash())
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
app.controller('ViewCtrl', ['$scope', '$rootScope', '$http', '$log', '$location', 'ngNotify', function ($scope, $rootScope, $http, $log, $location, ngNotify) {
|
||||
let onTorrent
|
||||
ngNotify.config({
|
||||
duration: 2000,
|
||||
html: true
|
||||
})
|
||||
onTorrent = function (torrent) {
|
||||
$rootScope.viewerStyle = {
|
||||
'margin-top': '-20px',
|
||||
'text-align': 'center'
|
||||
}
|
||||
dbg(torrent.magnetURI)
|
||||
torrent.safeTorrentFileURL = torrent.torrentFileBlobURL
|
||||
torrent.fileName = `${torrent.name}.torrent`
|
||||
$rootScope.selectedTorrent = torrent
|
||||
$rootScope.client.processing = false
|
||||
dbg('Received metadata', torrent)
|
||||
ngNotify.set(`Received ${torrent.name} metadata`)
|
||||
torrent.files.forEach(function (file) {
|
||||
file.appendTo('#viewer')
|
||||
file.getBlobURL(function (err, url) {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
file.url = url
|
||||
dbg('Done ', file)
|
||||
})
|
||||
})
|
||||
torrent.on('done', dbg('Done', torrent))
|
||||
torrent.on('wire', function (wire, addr) { dbg(`Wire ${addr}`, torrent) })
|
||||
torrent.on('error', er)
|
||||
}
|
||||
$scope.addMagnet = function () {
|
||||
$rootScope.addMagnet($scope.torrentInput, onTorrent)
|
||||
$scope.torrentInput = ''
|
||||
}
|
||||
if ($location.hash() !== '') {
|
||||
$rootScope.client.processing = true
|
||||
setTimeout(function () {
|
||||
dbg(`Adding ${$location.hash()}`)
|
||||
$rootScope.addMagnet($location.hash(), onTorrent)
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
app.filter('html', [
|
||||
'$sce', function ($sce) {
|
||||
return function (input) {
|
||||
$sce.trustAsHtml(input)
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
app.filter('pbytes', function () {
|
||||
return function (num, speed) {
|
||||
let exponent, unit, units
|
||||
if (isNaN(num)) {
|
||||
return ''
|
||||
}
|
||||
units = ['B', 'kB', 'MB', 'GB', 'TB']
|
||||
if (num < 1) {
|
||||
return (speed ? '' : '0 B')
|
||||
}
|
||||
exponent = Math.min(Math.floor(Math.log(num) / 6.907755278982137), 8)
|
||||
num = (num / Math.pow(1000, exponent)).toFixed(1) * 1
|
||||
unit = units[exponent]
|
||||
return `${num} ${unit}${speed ? '/s' : ''}`
|
||||
}
|
||||
})
|
||||
|
||||
app.filter('humanTime', function () {
|
||||
return function (millis) {
|
||||
let remaining
|
||||
if (millis < 1000) {
|
||||
return ''
|
||||
}
|
||||
remaining = moment.duration(millis).humanize()
|
||||
return remaining[0].toUpperCase() + remaining.substr(1)
|
||||
}
|
||||
})
|
||||
|
||||
app.filter('progress', function () { return function (num) { `${(100 * num).toFixed(1)}%` } })
|
34
index.html
Normal file
34
index.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html ng-app="BTorrent" lang="en">
|
||||
<head>
|
||||
<base href="">
|
||||
<meta charset="UTF-8">
|
||||
<title>βTorrent: Browser WebTorrent Client</title>
|
||||
<meta name="description" content="βTorrent is the first fully-featured Browser WebTorrent Client">
|
||||
<meta name="keywords" content="βTorrent, btorrent, client, webtorrent, browser, torrent, stream, bittorrent, torrenting, sharing, filesharing">
|
||||
<meta name="author" content="Diego Rodríguez Baquero - DiegoRBaquero">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://cdn.jsdelivr.net/g/webtorrent@0,momentjs@2,angularjs@1.5(angular.min.js+angular-route.min.js+angular-sanitize.min.js),angular.ui-grid@3.1,angular.ng-notify@0.8,angular.file-upload@12"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/g/normalize@3.0,skeleton@2.0,angular.ng-notify@0.8(ng-notify.min.css)">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/fontawesome/4.6/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/angular.ui-grid/3.1/ui-grid.min.css">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body ng-controller="BTorrentCtrl" ng-cloak="">
|
||||
<header>
|
||||
<h1>βTorrent<span class="version"> v{{$root.version}}</span></h1>
|
||||
<div class="views" ng-show="$root.client.torrents.length == 0"><a ng-href="/#">Full</a> | <a ng-href="/download">Single Download</a> | <a ng-href="/view">Stream / View</a></div>
|
||||
</header>
|
||||
<div id="viewer" ng-style="$root.viewerStyle"></div>
|
||||
<div id="view" ng-view></div>
|
||||
<footer>
|
||||
<a class="button" href="https://github.com/DiegoRBaquero/BTorrent/issues" target="_blank"><i class="fa fa-github"></i> Suggest a feature / Report a bug <i class="fa fa-comment"></i></a><br>
|
||||
<b>βTorrent is an Open-Source project by <a href="https://diegorbaquero.com" target="_blank">DiegoRBaquero</a></b><br>
|
||||
<b> <a href="https://tracker.btorrent.xyz/stats" target="_blank">βTorrent's Tracker Stats</a></b><br>
|
||||
Powered by <a href="https://github.com/feross/webtorrent" target="_blank">WebTorrent</a><br>
|
||||
<small>Hosted by <a href="https://m.do.co/c/0b25a910e6e4" target="_blank">Digital Ocean</a></small>
|
||||
</footer>
|
||||
<div class="spinner" ng-show="client.processing"><i class="fa fa-spinner fa-spin spinner-icon"></i></div>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
83
style.css
Normal file
83
style.css
Normal file
|
@ -0,0 +1,83 @@
|
|||
body {
|
||||
height: 100%;
|
||||
width: 100%; }
|
||||
|
||||
header, footer, .center {
|
||||
text-align: center; }
|
||||
|
||||
th, td {
|
||||
padding: 2px 15px;
|
||||
max-width: 200px;
|
||||
overflow: auto;
|
||||
white-space: nowrap; }
|
||||
|
||||
h2, h3, h4, h5, h6, ul, li {
|
||||
margin-bottom: 0; }
|
||||
|
||||
footer {
|
||||
margin-top: 10px; }
|
||||
|
||||
.container {
|
||||
width: 95%;
|
||||
max-width: 95%; }
|
||||
|
||||
.grid {
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
height: 200px; }
|
||||
|
||||
.version {
|
||||
color: #ccc;
|
||||
font-size: 0.3em; }
|
||||
|
||||
.views {
|
||||
margin-top: -20px;
|
||||
margin-bottom: 10px; }
|
||||
|
||||
.download-button {
|
||||
margin-left: 10px; }
|
||||
|
||||
.no-margin {
|
||||
margin: 0px; }
|
||||
|
||||
.spinner {
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
left: 30%;
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
z-index: 1000;
|
||||
background-color: grey;
|
||||
border-radius: 25px;
|
||||
opacity: .8;
|
||||
text-align: center; }
|
||||
|
||||
.spinner-icon {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
margin-top: -100px;
|
||||
font-size: 200px;
|
||||
transform: translateY(-50%); }
|
||||
|
||||
.button.button-danger,
|
||||
button.button-danger,
|
||||
input[type="submit"].button-danger,
|
||||
input[type="reset"].button-danger,
|
||||
input[type="button"].button-danger {
|
||||
color: #FFF;
|
||||
background-color: #D9534F;
|
||||
border-color: #D9534F; }
|
||||
|
||||
.button.button-danger:hover,
|
||||
button.button-danger:hover,
|
||||
input[type="submit"].button-danger:hover,
|
||||
input[type="reset"].button-danger:hover,
|
||||
input[type="button"].button-danger:hover,
|
||||
.button.button-danger:focus,
|
||||
button.button-danger:focus,
|
||||
input[type="submit"].button-danger:focus,
|
||||
input[type="reset"].button-danger:focus,
|
||||
input[type="button"].button-danger:focus {
|
||||
color: #FFF;
|
||||
background-color: #C43E3A;
|
||||
border-color: #C43E3A; }
|
82
style.sass
82
style.sass
|
@ -1,82 +0,0 @@
|
|||
body
|
||||
height: 100%
|
||||
width: 100%
|
||||
|
||||
header, footer, .center
|
||||
text-align: center
|
||||
|
||||
th, td
|
||||
padding: 2px 15px
|
||||
max-width: 200px
|
||||
overflow: auto
|
||||
white-space: nowrap
|
||||
|
||||
h2, h3, h4, h5, h6, ul, li
|
||||
margin-bottom: 0
|
||||
|
||||
footer
|
||||
margin-top: 10px
|
||||
|
||||
.container
|
||||
width: 95%
|
||||
max-width: 95%
|
||||
|
||||
.grid
|
||||
margin-bottom: 20px
|
||||
width: 100%
|
||||
height: 200px
|
||||
|
||||
.version
|
||||
color: #ccc
|
||||
font-size: 0.3em
|
||||
|
||||
.views
|
||||
margin-top: -20px
|
||||
margin-bottom: 10px
|
||||
|
||||
.download-button
|
||||
margin-left: 10px
|
||||
|
||||
.no-margin
|
||||
margin: 0px
|
||||
|
||||
.spinner
|
||||
position: absolute
|
||||
top: 30%
|
||||
left: 30%
|
||||
width: 40%
|
||||
height: 40%
|
||||
z-index: 1000
|
||||
background-color: grey
|
||||
border-radius: 25px
|
||||
opacity: .8
|
||||
text-align: center
|
||||
|
||||
.spinner-icon
|
||||
position: relative
|
||||
top: 50%
|
||||
margin-top: -100px
|
||||
font-size: 200px
|
||||
transform: translateY(-50%)
|
||||
|
||||
.button.button-danger,
|
||||
button.button-danger,
|
||||
input[type="submit"].button-danger,
|
||||
input[type="reset"].button-danger,
|
||||
input[type="button"].button-danger
|
||||
color: #FFF
|
||||
background-color: #D9534F
|
||||
border-color: #D9534F
|
||||
.button.button-danger:hover,
|
||||
button.button-danger:hover,
|
||||
input[type="submit"].button-danger:hover,
|
||||
input[type="reset"].button-danger:hover,
|
||||
input[type="button"].button-danger:hover,
|
||||
.button.button-danger:focus,
|
||||
button.button-danger:focus,
|
||||
input[type="submit"].button-danger:focus,
|
||||
input[type="reset"].button-danger:focus,
|
||||
input[type="button"].button-danger:focus
|
||||
color: #FFF
|
||||
background-color: #C43E3A
|
||||
border-color: #C43E3A
|
88
views/download.html
Normal file
88
views/download.html
Normal file
|
@ -0,0 +1,88 @@
|
|||
|
||||
<div class="container">
|
||||
<div ng-hide="$root.client.torrents.length != 0" style="vertical-align: middle; text-align: center">
|
||||
<div class="row">
|
||||
<form class="no-margin" ng-submit="addMagnet()">
|
||||
<label>Enter magnet, hash or http(s) .torrent</label>
|
||||
<input type="text" placeholder="magnet, hash or http(s) .torrent" ng-model="torrentInput" ng-disabled="$root.disabled" style="width: 50%"/>
|
||||
</form>
|
||||
<!--button(ng-click="addMagnet()" ng-disabled="!torrentInput.length || $root.disabled" ng-class="{"button-primary": torrentInput.length}")
|
||||
i.fa.fa-download
|
||||
| Download
|
||||
-->
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>or...</label>
|
||||
<button type="file" ngf-select="$root.openTorrentFile($file)" ng-disabled="$root.disabled" ng-class="{'button-primary': !$root.disabled}"><i class="fa fa-folder-open"></i> Open torrent file</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div" ng-if="selectedTorrent" style="text-align: center">
|
||||
<div class="four columns" style="overflow: auto">
|
||||
<h4>Information</h4>
|
||||
<table class="u-full-width">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{$root.selectedTorrent.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Size</td>
|
||||
<td>{{$root.selectedTorrent.length | pbytes}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Completed</td>
|
||||
<td>{{$root.selectedTorrent.progress | progress}} ({{$root.selectedTorrent.downloaded | pbytes}})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Peers</td>
|
||||
<td>{{$root.selectedTorrent.numPeers}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>↓ Speed</td>
|
||||
<td>{{$root.selectedTorrent.downloadSpeed | pbytes:1}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ETA</td>
|
||||
<td>{{$root.selectedTorrent.timeRemaining | humanTime}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="four columns">
|
||||
<h4>Files</h4>
|
||||
<table class="u-full-width" style="margin: auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Priority</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="files" ng-repeat="file in $root.selectedTorrent.files">
|
||||
<td ng-hide="file.done">{{file.name}}</td>
|
||||
<td ng-show="file.done"><a ng-href="{{file.url}}" download="{{file.name}}" target="_self" ng-show="file.done">{{file.name}}</a></td>
|
||||
<td>{{file.length | pbytes}}</td>
|
||||
<td>
|
||||
<select class="no-margin" name="{{file.name}}Priority" ng-model="file.priority" ng-init="file.priority = '0'" ng-change="$root.changePriority(file)">
|
||||
<option value="1">High Priority</option>
|
||||
<option value="0" selected="">Low Priority</option>
|
||||
<option value="-1">Don't download</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h5>↑ Click a file to download it</h5>
|
||||
</div>
|
||||
<div class="four columns">
|
||||
<h4>Share</h4>
|
||||
<ul style="text-align: justify">
|
||||
<li><a ng-href="#{{$root.selectedTorrent.infoHash}}" target="_blank">βTorrent</a></li>
|
||||
<li><a ng-href="{{$root.selectedTorrent.magnetURI}}" target="_blank">Magnet URI</a></li>
|
||||
<li><a ng-href="{{$root.selectedTorrent.safeTorrentFileURL}}" target="_self" download="{{$root.selectedTorrent.fileName}}">.torrent</a></li>
|
||||
<li><strong>Hash: </strong>{{$root.selectedTorrent.infoHash}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,69 +0,0 @@
|
|||
.container
|
||||
div(ng-hide="$root.client.torrents.length != 0" style="vertical-align: middle; text-align: center")
|
||||
.row
|
||||
form.no-margin(ng-submit="addMagnet()")
|
||||
label Enter magnet, hash or http(s) .torrent
|
||||
input(type="text" placeholder="magnet, hash or http(s) .torrent" ng-model="torrentInput" ng-disabled="$root.disabled" style="width: 50%")
|
||||
//button(ng-click="addMagnet()" ng-disabled="!torrentInput.length || $root.disabled" ng-class="{"button-primary": torrentInput.length}")
|
||||
i.fa.fa-download
|
||||
| Download
|
||||
.row
|
||||
label or...
|
||||
button(type="file" ngf-select="$root.openTorrentFile($file)" ng-disabled="$root.disabled" ng-class="{'button-primary': !$root.disabled}")
|
||||
i.fa.fa-folder-open
|
||||
| Open torrent file
|
||||
.div(ng-if="selectedTorrent" style="text-align: center")
|
||||
.four.columns(style="overflow: auto")
|
||||
h4 Information
|
||||
table.u-full-width
|
||||
tbody
|
||||
tr
|
||||
td Name
|
||||
td {{$root.selectedTorrent.name}}
|
||||
tr
|
||||
td Size
|
||||
td {{$root.selectedTorrent.length | pbytes}}
|
||||
tr
|
||||
td Completed
|
||||
td {{$root.selectedTorrent.progress | progress}} ({{$root.selectedTorrent.downloaded | pbytes}})
|
||||
tr
|
||||
td Peers
|
||||
td {{$root.selectedTorrent.numPeers}}
|
||||
tr
|
||||
td ↓ Speed
|
||||
td {{$root.selectedTorrent.downloadSpeed | pbytes:1}}
|
||||
tr
|
||||
td ETA
|
||||
td {{$root.selectedTorrent.timeRemaining | humanTime}}
|
||||
.four.columns
|
||||
h4 Files
|
||||
table.u-full-width(style="margin: auto")
|
||||
thead
|
||||
tr
|
||||
th Name
|
||||
th Size
|
||||
th Priority
|
||||
tbody
|
||||
tr.files(ng-repeat="file in $root.selectedTorrent.files")
|
||||
td(ng-hide="file.done") {{file.name}}
|
||||
td(ng-show="file.done")
|
||||
a(ng-href="{{file.url}}" download="{{file.name}}" target="_self" ng-show="file.done") {{file.name}}
|
||||
td {{file.length | pbytes}}
|
||||
td
|
||||
select.no-margin(name="{{file.name}}Priority" ng-model="file.priority" ng-init="file.priority = '0'" ng-change="$root.changePriority(file)")
|
||||
option(value="1") High Priority
|
||||
option(value="0" selected="") Low Priority
|
||||
option(value="-1") Don't download
|
||||
h5 ↑ Click a file to download it
|
||||
.four.columns
|
||||
h4 Share
|
||||
ul(style="text-align: justify")
|
||||
li
|
||||
a(ng-href="#{{$root.selectedTorrent.infoHash}}" target="_blank") βTorrent
|
||||
li
|
||||
a(ng-href="{{$root.selectedTorrent.magnetURI}}" target="_blank") Magnet URI
|
||||
li
|
||||
a(ng-href="{{$root.selectedTorrent.safeTorrentFileURL}}" target="_self" download="{{$root.selectedTorrent.fileName}}") .torrent
|
||||
li
|
||||
strong Hash:
|
||||
| {{$root.selectedTorrent.infoHash}}
|
64
views/full.html
Normal file
64
views/full.html
Normal file
|
@ -0,0 +1,64 @@
|
|||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="four columns">
|
||||
<input class="u-full-width" type="text" placeholder="magnet, hash or http(s) .torrent" ng-model="torrentInput" ng-disabled="$root.disabled"/>
|
||||
</div>
|
||||
<div class="two columns download-button">
|
||||
<button ng-click="addMagnet()" ng-disabled="!torrentInput.length || $root.disabled" ng-class="{'button-primary': torrentInput.length}"><i class="fa fa-download"></i> Download</button>
|
||||
</div>
|
||||
<div class="three columns">
|
||||
<button type="file" ngf-select="$root.openTorrentFile($file)" ng-disabled="$root.disabled" ng-class="{'button-primary': !$root.disabled}"><i class="fa fa-folder-open"></i> Open torrent file</button>
|
||||
</div>
|
||||
<div class="three columns u-pull-right">
|
||||
<button class="u-pull-right" ngf-select="$root.seedFiles($files)" multiple="" ng-disabled="$root.disabled" ng-class="{'button-primary': !$root.disabled}"><i class="fa fa-upload"></i> Seed files</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row grid" ui-grid="gridOptions" ui-grid-resize-columns="ui-grid-resize-columns" ui-grid-selection="ui-grid-selection"></div>
|
||||
<div class="row" ng-if="selectedTorrent">
|
||||
<div class="six columns" style="overflow: auto">
|
||||
<h5>{{$root.selectedTorrent.name}}
|
||||
<button ng-if="!$root.selectedTorrent.swarm.paused" ng-click="$root.selectedTorrent.pause()"><i class="fa fa-pause"></i> Pause</button>
|
||||
<button ng-if="$root.selectedTorrent.swarm.paused" ng-click="$root.selectedTorrent.resume()"><i class="fa fa-play"></i> Resume</button>
|
||||
<button class="button-danger" ng-click="$root.selectedTorrent.destroy($root.destroyedTorrent)"><i class="fa fa-times"></i> Remove</button>
|
||||
</h5>
|
||||
<h6>Share</h6>
|
||||
<ul>
|
||||
<li><a ng-href="#{{$root.selectedTorrent.infoHash}}" target="_blank">βTorrent</a></li>
|
||||
<li><a ng-href="{{$root.selectedTorrent.magnetURI}}" target="_blank">Magnet URI</a></li>
|
||||
<li><a ng-href="{{$root.selectedTorrent.safeTorrentFileURL}}" target="_self" download="{{$root.selectedTorrent.fileName}}">.torrent</a></li>
|
||||
<li><strong>Hash: </strong>{{$root.selectedTorrent.infoHash}} </li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="six columns">
|
||||
<h5>Files</h5>
|
||||
<table class="u-full-width">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Priority</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="files" ng-repeat="file in $root.selectedTorrent.files">
|
||||
<td ng-hide="file.done">{{file.name}}</td>
|
||||
<td ng-show="file.done"><a ng-href="{{file.url}}" download="{{file.name}}" target="_self" ng-show="file.done">{{file.name}}</a></td>
|
||||
<td>{{file.length | pbytes}}</td>
|
||||
<td>
|
||||
<select class="no-margin" name="{{file.name}}Priority" ng-model="file.priority" ng-init="file.priority = '0'" ng-change="$root.changePriority(file)">
|
||||
<option value="1">High Priority</option>
|
||||
<option value="0" selected="">Low Priority</option>
|
||||
<option value="-1">Don't download</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center"><strong>Client Stats:
|
||||
↓ {{$root.client.downloadSpeed | pbytes}}/s ·
|
||||
↑ {{$root.client.uploadSpeed | pbytes}}/s ·
|
||||
Ratio: {{$root.client.ratio | number:2}}</strong></div>
|
||||
</div>
|
|
@ -1,66 +0,0 @@
|
|||
.container
|
||||
.row
|
||||
.four.columns
|
||||
input.u-full-width(type="text" placeholder="magnet, hash or http(s) .torrent" ng-model="torrentInput" ng-disabled="$root.disabled")
|
||||
.two.columns.download-button
|
||||
button(ng-click="addMagnet()" ng-disabled="!torrentInput.length || $root.disabled" ng-class="{'button-primary': torrentInput.length}")
|
||||
i.fa.fa-download
|
||||
| Download
|
||||
.three.columns
|
||||
button(type="file" ngf-select="$root.openTorrentFile($file)" ng-disabled="$root.disabled" ng-class="{'button-primary': !$root.disabled}")
|
||||
i.fa.fa-folder-open
|
||||
| Open torrent file
|
||||
.three.columns.u-pull-right
|
||||
button.u-pull-right(ngf-select="$root.seedFiles($files)" multiple="" ng-disabled="$root.disabled" ng-class="{'button-primary': !$root.disabled}")
|
||||
i.fa.fa-upload
|
||||
| Seed files
|
||||
.row.grid(ui-grid="gridOptions" ui-grid-resize-columns, ui-grid-selection)
|
||||
.row(ng-if="selectedTorrent")
|
||||
.six.columns(style="overflow: auto")
|
||||
h5 {{$root.selectedTorrent.name}}
|
||||
button(ng-if="!$root.selectedTorrent.swarm.paused" ng-click="$root.selectedTorrent.pause()")
|
||||
i.fa.fa-pause
|
||||
| Pause
|
||||
|
|
||||
button(ng-if="$root.selectedTorrent.swarm.paused" ng-click="$root.selectedTorrent.resume()")
|
||||
i.fa.fa-play
|
||||
| Resume
|
||||
|
|
||||
button.button-danger(ng-click="$root.selectedTorrent.destroy($root.destroyedTorrent)")
|
||||
i.fa.fa-times
|
||||
| Remove
|
||||
h6 Share
|
||||
ul
|
||||
li
|
||||
a(ng-href="#{{$root.selectedTorrent.infoHash}}" target="_blank") βTorrent
|
||||
li
|
||||
a(ng-href="{{$root.selectedTorrent.magnetURI}}" target="_blank") Magnet URI
|
||||
li
|
||||
a(ng-href="{{$root.selectedTorrent.safeTorrentFileURL}}" target="_self" download="{{$root.selectedTorrent.fileName}}") .torrent
|
||||
li
|
||||
strong Hash:
|
||||
| {{$root.selectedTorrent.infoHash}}
|
||||
.six.columns
|
||||
h5 Files
|
||||
table.u-full-width
|
||||
thead
|
||||
tr
|
||||
th Name
|
||||
th Size
|
||||
th Priority
|
||||
tbody
|
||||
tr.files(ng-repeat="file in $root.selectedTorrent.files")
|
||||
td(ng-hide="file.done") {{file.name}}
|
||||
td(ng-show="file.done")
|
||||
a(ng-href="{{file.url}}" download="{{file.name}}" target="_self" ng-show="file.done") {{file.name}}
|
||||
td {{file.length | pbytes}}
|
||||
td
|
||||
select.no-margin(name="{{file.name}}Priority" ng-model="file.priority" ng-init="file.priority = '0'" ng-change="$root.changePriority(file)")
|
||||
option(value="1") High Priority
|
||||
option(value="0" selected="") Low Priority
|
||||
option(value="-1") Don't download
|
||||
.center
|
||||
strong Client Stats:
|
||||
| ↓ {{$root.client.downloadSpeed | pbytes}}/s ·
|
||||
| ↑ {{$root.client.uploadSpeed | pbytes}}/s ·
|
||||
| Ratio: {{$root.client.ratio | number:2}}
|
20
views/view.html
Normal file
20
views/view.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
<div class="container">
|
||||
<div ng-hide="$root.client.torrents.length != 0" style="vertical-align: middle; text-align: center">
|
||||
<div class="row">
|
||||
<form class="no-margin" ng-submit="addMagnet()">
|
||||
<label>Enter magnet, hash or http(s) .torrent</label>
|
||||
<input type="text" placeholder="magnet, hash or http(s) .torrent" ng-model="torrentInput" ng-disabled="$root.disabled" style="width: 50%"/>
|
||||
</form>
|
||||
<!--button(ng-click="addMagnet()" ng-disabled="!torrentInput.length || $root.disabled" ng-class="{"button-primary": torrentInput.length}")
|
||||
i.fa.fa-download
|
||||
| Download
|
||||
-->
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>or...</label>
|
||||
<button type="file" ngf-select="$root.openTorrentFile($file)" ng-disabled="$root.disabled" ng-class="{'button-primary': !$root.disabled}"><i class="fa fa-folder-open"></i> Open torrent file</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div" ng-if="selectedTorrent" style="text-align: center">Downloaded {{$root.selectedTorrent.downloaded | pbytes}}/{{$root.selectedTorrent.length | pbytes}} ({{$root.selectedTorrent.progress | progress}}) at {{$root.selectedTorrent.downloadSpeed | pbytes:1}} from {{$root.selectedTorrent.numPeers}} peers. ETA: {{$root.selectedTorrent.timeRemaining | humanTime}}</div>
|
||||
</div>
|
|
@ -1,16 +0,0 @@
|
|||
.container
|
||||
div(ng-hide="$root.client.torrents.length != 0" style="vertical-align: middle; text-align: center")
|
||||
.row
|
||||
form.no-margin(ng-submit="addMagnet()")
|
||||
label Enter magnet, hash or http(s) .torrent
|
||||
input(type="text" placeholder="magnet, hash or http(s) .torrent" ng-model="torrentInput" ng-disabled="$root.disabled" style="width: 50%")
|
||||
//button(ng-click="addMagnet()" ng-disabled="!torrentInput.length || $root.disabled" ng-class="{"button-primary": torrentInput.length}")
|
||||
i.fa.fa-download
|
||||
| Download
|
||||
.row
|
||||
label or...
|
||||
button(type="file" ngf-select="$root.openTorrentFile($file)" ng-disabled="$root.disabled" ng-class="{'button-primary': !$root.disabled}")
|
||||
i.fa.fa-folder-open
|
||||
| Open torrent file
|
||||
.div(ng-if="selectedTorrent" style="text-align: center")
|
||||
| Downloaded {{$root.selectedTorrent.downloaded | pbytes}}/{{$root.selectedTorrent.length | pbytes}} ({{$root.selectedTorrent.progress | progress}}) at {{$root.selectedTorrent.downloadSpeed | pbytes:1}} from {{$root.selectedTorrent.numPeers}} peers. ETA: {{$root.selectedTorrent.timeRemaining | humanTime}}
|
22644
webtorrent.debug.js
22644
webtorrent.debug.js
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue