Files
transmission/web/javascript/torrent-renderer.js
Jordan Lee b36c648b31 (trunk web) Torrent class cleanup:
1. remove some of its unnecessary coupling to other classes
2. make more of its method names consistent with each other
3. make its field names consistent with the RPC spec
4. better grouping of methods by relevance
5. syntactical cleanup
2011-08-20 21:17:12 +00:00

364 lines
9.2 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.getMetadataPercentComplete() * 100;
else if( !t.isDone( ) )
pct = Math.round( t.getPercentDone() * 100 );
else if( seed_ratio_limit > 0 )
pct = Math.round( t.getUploadRatio() * 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.createProgressbar = function( classes )
{
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 ' + classes;
progressbar.appendChild( complete );
progressbar.appendChild( incomplete );
return { 'element': progressbar, 'complete': complete, 'incomplete': incomplete }
}
TorrentRendererHelper.renderProgressbar = function( controller, t, progressbar )
{
var info = TorrentRendererHelper.getProgressInfo( controller, t );
var e;
e = progressbar.complete;
e.style.width = '' + info.percent + "%";
e.className = info.complete;
e.style.display = info.percent<=0 ? 'none' : 'block';
e = progressbar.incomplete;
e.className = info.incomplete;
e.style.display = info.percent>=100 ? 'none' : 'block';
}
TorrentRendererHelper.formatUL = function( t )
{
return 'UL: ' + Transmission.fmt.speedBps( t.getUploadSpeed( ) );
}
TorrentRendererHelper.formatDL = function( t )
{
return 'DL: ' + Transmission.fmt.speedBps( t.getDownloadSpeed( ) );
}
/****
*****
*****
****/
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 progressbar = TorrentRendererHelper.createProgressbar( 'full' );
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.element );
root.appendChild( details );
root._name_container = name;
root._peer_details_container = peers;
root._progress_details_container = details;
root._progressbar = progressbar;
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.getPeersSendingToUs(),
'of',
t.getPeersConnected(),
'peers',
'-',
TorrentRendererHelper.formatDL(t),
TorrentRendererHelper.formatUL(t) ].join(' ');
if( t.isSeeding( ) )
return [ 'Seeding to',
t.getPeersGettingFromUs(),
'of',
t.getPeersConnected(),
'peers',
'-',
TorrentRendererHelper.formatUL(t) ].join(' ');
if( t.isChecking( ) )
return [ 'Verifying local data (',
Transmission.fmt.percentString( 100.0 * t.getRecheckProgress() ),
'% tested)' ].join('');
return t.getStateString( );
},
getProgressDetails: function( controller, t )
{
if( t.needsMetaData() ) {
var percent = 100 * t.getMetadataPercentComplete();
return [ "Magnetized transfer - retrieving metadata (",
Transmission.fmt.percentString( percent ),
"%)" ].join('');
}
var c;
var sizeWhenDone = t.getSizeWhenDone()
var totalSize = t.getTotalSize()
var is_done = ( t.isDone( ) ) || ( t.isSeeding() )
if( is_done ) {
if( totalSize == sizeWhenDone ) // seed: '698.05 MiB'
c = [ Transmission.fmt.size( totalSize ) ];
else // partial seed: '127.21 MiB of 698.05 MiB (18.2%)'
c = [ Transmission.fmt.size( sizeWhenDone ),
' of ',
Transmission.fmt.size( t.getTotalSize() ),
' (', t.getPercentDoneStr, '%)' ];
// append UL stats: ', uploaded 8.59 GiB (Ratio: 12.3)'
c.push( ', uploaded ',
Transmission.fmt.size( t.getUploadedEver() ),
' (Ratio ',
Transmission.fmt.ratioString( t.getUploadRatio() ),
')' );
} else { // not done yet
c = [ Transmission.fmt.size( sizeWhenDone - t.getLeftUntilDone() ),
' of ', Transmission.fmt.size( sizeWhenDone ),
' (', t.getPercentDoneStr(), '%)' ];
}
// maybe append eta
if( !t.isStopped() && ( !is_done || t.seedRatioLimit(controller)>0 ) ) {
c.push(' - ');
var eta = t.getETA()
if (eta < 0 || eta >= (999*60*60) /* arbitrary */ )
c.push( 'remaining time unknown' );
else
c.push( Transmission.fmt.timeInterval(t.getETA()),
' remaining' );
}
return c.join('');
},
render: function( controller, t, root )
{
// name
setInnerHTML( root._name_container, t.getName() );
// progressbar
TorrentRendererHelper.renderProgressbar( controller, t, root._progressbar );
// peer details
var has_error = t.getError() !== 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.isStopped()
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 progressbar = TorrentRendererHelper.createProgressbar( 'compact' );
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.element );
root.appendChild( details );
root.appendChild( name );
root.className = 'torrent compact';
root._progressbar = progressbar;
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.getStateString( );
},
render: function( controller, t, root )
{
// name
var is_stopped = t.isStopped()
var e = root._name_container;
$(e).toggleClass( 'paused', is_stopped );
setInnerHTML( e, t.getName() );
// peer details
var has_error = t.getError() !== Torrent._ErrNone;
e = root._details_container;
$(e).toggleClass('error', has_error );
setInnerHTML( e, this.getPeerDetails( t ) );
// progressbar
TorrentRendererHelper.renderProgressbar( controller, t, root._progressbar );
}
};
/****
*****
*****
****/
function TorrentRow( view )
{
this.initialize( view );
}
TorrentRow.prototype =
{
initialize: function( view ) {
this._view = view;
this._element = view.createRow( );
},
getElement: function( ) {
return this._element;
},
render: function( controller ) {
var tor = this.getTorrent( );
if( tor !== null )
this._view.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 ) {
var key = 'dataChanged.renderer';
if( this._torrent )
$(this).unbind(key);
if(( this._torrent = t ))
$(this).bind(key,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);
}
};