transmission/web/javascript/torrent-renderer.js

371 lines
9.6 KiB
JavaScript

/*
* Copyright © Jordan Lee
* This code is licensed under the GPL version 2.
* <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
*/
/****
*****
*****
****/
function TorrentRendererHelper()
{
}
TorrentRendererHelper.getProgressInfo = function( controller, t )
{
var seed_ratio_limit = t.seedRatioLimit( controller );
var pct = 0;
if( t.needsMetaData( ) )
pct = t._metadataPercentComplete * 100;
else if( !t.isDone( ) )
pct = Math.round( t.getPercentDone() * 100 );
else if( seed_ratio_limit > 0 )
pct = Math.round( t._upload_ratio * 100 / seed_ratio_limit );
else
pct = 100;
var extra;
if( t.isStopped( ) )
extra = 'paused';
else if( t.isSeeding( ) )
extra = 'seeding';
else if( t.needsMetaData( ) )
extra = 'magnet';
else
extra = 'leeching';
return {
percent: pct,
complete: [ 'torrent_progress_bar', 'complete', extra ].join(' '),
incomplete: [ 'torrent_progress_bar', 'incomplete', extra ].join(' ')
};
}
TorrentRendererHelper.renderProgressbar = function( controller, t, complete, incomplete )
{
var info = TorrentRendererHelper.getProgressInfo( controller, t );
var e;
e = complete;
e.style.width = '' + info.percent + "%";
e.className = info.complete;
e.style.display = info.percent<=0 ? 'none' : 'block';
e = incomplete;
e.className = info.incomplete;
e.style.display = info.percent>=100 ? 'none' : 'block';
}
TorrentRendererHelper.formatUL = function( t )
{
return 'UL: ' + Transmission.fmt.speedBps( t.uploadSpeed( ) );
}
TorrentRendererHelper.formatDL = function( t )
{
return 'DL: ' + Transmission.fmt.speedBps( t.downloadSpeed( ) );
}
/****
*****
*****
****/
function TorrentRendererFull()
{
}
TorrentRendererFull.prototype =
{
createRow: function( )
{
var root = document.createElement( 'li' );
root.className = 'torrent';
var name = document.createElement( 'div' );
name.className = 'torrent_name';
var peers = document.createElement( 'div' );
peers.className = 'torrent_peer_details';
var complete = document.createElement( 'div' );
complete.className = 'torrent_progress_bar complete';
var incomplete = document.createElement( 'div' );
incomplete.className = 'torrent_progress_bar incomplete';
var progressbar = document.createElement( 'div' );
progressbar.className = 'torrent_progress_bar_container full';
progressbar.appendChild( complete );
progressbar.appendChild( incomplete );
var details = document.createElement( 'div' );
details.className = 'torrent_progress_details';
var image = document.createElement( 'div' );
var button = document.createElement( 'a' );
button.appendChild( image );
root.appendChild( name );
root.appendChild( peers );
root.appendChild( button );
root.appendChild( progressbar );
root.appendChild( details );
root._name_container = name;
root._peer_details_container = peers;
root._progress_details_container = details;
root._progress_complete_container = complete;
root._progress_incomplete_container = incomplete;
root._pause_resume_button_image = image;
root._toggle_running_button = button;
return root;
},
getPeerDetails: function( t )
{
var err;
if(( err = t.getErrorMessage()))
return err;
if( t.isDownloading( ) )
return [ 'Downloading from',
t.peersSendingToUs(),
'of',
t._peers_connected,
'peers',
'-',
TorrentRendererHelper.formatDL(t),
TorrentRendererHelper.formatUL(t) ].join(' ');
if( t.isSeeding( ) )
return [ 'Seeding to',
t.peersGettingFromUs(),
'of',
t._peers_connected,
'peers',
'-',
TorrentRendererHelper.formatUL(t) ].join(' ');
if( t.state() === Torrent._StatusCheck )
return [ 'Verifying local data (',
Transmission.fmt.percentString( 100.0 * t._recheckProgress ),
'% tested)' ].join('');
return t.stateStr( );
},
getProgressDetails: function( controller, t )
{
if( t.needsMetaData() ) {
var percent = 100 * t._metadataPercentComplete;
return [ "Magnetized transfer - retrieving metadata (",
Transmission.fmt.percentString( percent ),
"%)" ].join('');
}
var c;
var is_done = ( t.isDone( ) )
|| ( t.state() === Torrent._StatusSeeding );
if( is_done ) {
if( t._size == t._sizeWhenDone ) // seed: '698.05 MiB'
c = [ Transmission.fmt.size( t._size ) ];
else // partial seed: '127.21 MiB of 698.05 MiB (18.2%)'
c = [ Transmission.fmt.size( t._sizeWhenDone ),
' of ',
Transmission.fmt.size( t._size ),
' (', t.getPercentDoneStr, '%)' ];
// append UL stats: ', uploaded 8.59 GiB (Ratio: 12.3)'
c.push( ', uploaded ',
Transmission.fmt.size( t._upload_total ),
' (Ratio ',
Transmission.fmt.ratioString( t._upload_ratio ),
')' );
} else { // not done yet
c = [ Transmission.fmt.size( t._sizeWhenDone - t._leftUntilDone ),
' of ', Transmission.fmt.size( t._sizeWhenDone ),
' (', t.getPercentDoneStr(), '%)' ];
}
// maybe append eta
if( t.isActive() && ( !is_done || t.seedRatioLimit(controller)>0 ) ) {
c.push(' - ');
if (t._eta < 0 || this._eta >= Torrent._InfiniteTimeRemaining )
c.push( 'remaining time unknown' );
else
c.push( Transmission.fmt.timeInterval(t._eta),
' remaining' );
}
return c.join('');
},
render: function( controller, t, root )
{
// name
setInnerHTML( root._name_container, t.name() );
// progressbar
TorrentRendererHelper.renderProgressbar(
controller, t,
root._progress_complete_container,
root._progress_incomplete_container );
// peer details
var has_error = t._error !== Torrent._ErrNone;
var e = root._peer_details_container;
$(e).toggleClass('error',has_error);
setInnerHTML( e, this.getPeerDetails( t ) );
// progress details
e = root._progress_details_container;
setInnerHTML( e, this.getProgressDetails( controller, t ) );
// pause/resume button
var is_stopped = t.state() === Torrent._StatusStopped;
e = root._pause_resume_button_image;
e.alt = is_stopped ? 'Resume' : 'Pause';
e.className = is_stopped ? 'torrent_resume' : 'torrent_pause';
}
};
/****
*****
*****
****/
function TorrentRendererCompact()
{
}
TorrentRendererCompact.prototype =
{
createRow: function( )
{
var complete = document.createElement( 'div' );
complete.className = 'torrent_progress_bar complete';
var incomplete = document.createElement( 'div' );
incomplete.className = 'torrent_progress_bar incomplete';
var progressbar = document.createElement( 'div' );
progressbar.className = 'torrent_progress_bar_container compact';
progressbar.appendChild( complete );
progressbar.appendChild( incomplete );
var details = document.createElement( 'div' );
details.className = 'torrent_peer_details compact';
var name = document.createElement( 'div' );
name.className = 'torrent_name';
var root = document.createElement( 'li' );
root.appendChild( progressbar );
root.appendChild( details );
root.appendChild( name );
root.className = 'torrent compact';
root._progress_complete_container = complete;
root._progress_incomplete_container = incomplete;
root._details_container = details;
root._name_container = name;
return root;
},
getPeerDetails: function( t )
{
var c;
if(( c = t.getErrorMessage()))
return c;
if( t.isDownloading( ) )
return [ TorrentRendererHelper.formatDL(t),
TorrentRendererHelper.formatUL(t) ].join(' ');
if( t.isSeeding( ) )
return TorrentRendererHelper.formatUL(t);
return t.stateStr( );
},
render: function( controller, t, root )
{
// name
var is_stopped = t.state() === Torrent._StatusStopped;
var e = root._name_container;
$(e).toggleClass( 'paused', is_stopped );
setInnerHTML( e, t.name() );
// peer details
var has_error = t._error !== Torrent._ErrNone;
e = root._details_container;
$(e).toggleClass('error', has_error );
setInnerHTML( e, this.getPeerDetails( t ) );
// progressbar
TorrentRendererHelper.renderProgressbar(
controller, t,
root._progress_complete_container,
root._progress_incomplete_container );
}
};
/****
*****
*****
****/
function TorrentRow( controller, generator )
{
this.initialize( controller, generator );
}
TorrentRow.prototype =
{
initialize: function( controller, generator ) {
this._generator = generator;
var root = generator.createRow( );
this._element = root;
$(root).bind('dblclick', function(e) { controller.toggleInspector(); });
},
getElement: function( ) {
return this._element;
},
render: function( controller ) {
var tor = this.getTorrent( );
if( tor !== null )
this._generator.render( controller, tor, this.getElement( ) );
},
isSelected: function( ) {
return this.getElement().className.indexOf('selected') != -1;
},
setSelected: function( flag ) {
$(this.getElement()).toggleClass( 'selected', flag );
},
getToggleRunningButton: function( ) {
return this.getElement()._toggle_running_button;
},
setVisible: function( visible ) {
this.getElement().style.display = visible ? 'block' : 'none';
if( !visible )
this.setSelected( false );
},
isVisible: function( visible ) {
return this.getElement().style.display === 'block';
},
setTorrent: function( controller, t ) {
if( this._torrent !== t ) {
if( this._torrent )
$(this).unbind('dataChanged.renderer');
if(( this._torrent = t ))
$(this).bind('dataChanged.renderer',this.render(controller));
}
},
getTorrent: function() {
return this._torrent;
},
isEven: function() {
return this.getElement().className.indexOf('even') != -1;
},
setEven: function( even ) {
if( this.isEven() != even )
$(this.getElement()).toggleClass('even', even);
}
};