#1435 selective downloading and file prioritization for web ui
This commit is contained in:
parent
f8b1326101
commit
83929f8396
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 917 B |
|
@ -14,6 +14,7 @@
|
|||
<link media="screen and (min-device-width: 481px)" href="./stylesheets/common.css" type="text/css" rel="stylesheet" />
|
||||
<script type="text/javascript" src="./javascript/jquery/jquery.transmenu.min.js"></script>
|
||||
<script type="text/javascript" src="./javascript/jquery/jquery.contextmenu.min.js"></script>
|
||||
<script type="text/javascript" src="./javascript/jquery/jquery.tinysort.min.js"></script>
|
||||
<script type="text/javascript" src="./javascript/menu.js"></script>
|
||||
<script type="text/javascript" src="./javascript/jquery/jquery.form.min.js"></script>
|
||||
<script type="text/javascript" src="./javascript/jquery/json.min.js"></script>
|
||||
|
@ -61,6 +62,7 @@
|
|||
<div id="inspector_tabs">
|
||||
<div class="inspector_tab selected" id="inspector_tab_info"><a href="#info"><img src="images/buttons/info_general.png" alt="Information"/></a></div>
|
||||
<div class="inspector_tab" id="inspector_tab_activity"><a href="#activity"><img src="images/buttons/info_activity.png" alt="Activity"/></a></div>
|
||||
<div class="inspector_tab" id="inspector_tab_files"><a href="#files"><img src="images/buttons/info_files.png" alt="Files"/></a></div>
|
||||
</div>
|
||||
|
||||
<div id="inspector_header">
|
||||
|
@ -168,6 +170,11 @@
|
|||
</div>
|
||||
</div><!-- class="inspector_group"-->
|
||||
</div><!-- id="inspector_tab_activity_container" -->
|
||||
|
||||
<div style="display:none;" class="inspector_container" id="inspector_tab_files_container">
|
||||
<span id="inspector_file_list"></span>
|
||||
</div><!-- id="inspector_tab_files_container" -->
|
||||
|
||||
</div>
|
||||
|
||||
<div id="torrent_container">
|
||||
|
|
|
@ -42,11 +42,6 @@ $(document).ready( function() {
|
|||
transmission = new Transmission();
|
||||
|
||||
if ($.browser.safari) {
|
||||
|
||||
// Fix div height problem - causes scrollbar flash in
|
||||
// firefox so have to be safari-specific
|
||||
$('#torrent_inspector').css('height', '100%');
|
||||
|
||||
// Move search field's margin down for the styled input
|
||||
$('#torrent_search').css('margin-top', 3);
|
||||
}
|
||||
|
@ -88,7 +83,7 @@ Array.prototype.clone = function () {
|
|||
/**
|
||||
* "innerHTML = html" is pretty slow in FF. Happily a lot of our innerHTML
|
||||
* changes are triggered by periodic refreshes on torrents whose state hasn't
|
||||
* changed sine the last update, so even this simple test helps a lot.
|
||||
* changed since the last update, so even this simple test helps a lot.
|
||||
*/
|
||||
function setInnerHTML( e, html )
|
||||
{
|
||||
|
|
|
@ -23,8 +23,7 @@ Torrent.prototype =
|
|||
/*
|
||||
* Constructor
|
||||
*/
|
||||
initialize: function(controller,data)
|
||||
{
|
||||
initialize: function(controller, data) {
|
||||
// Create a new <li> element
|
||||
var element = $('<li/>');
|
||||
element.addClass('torrent');
|
||||
|
@ -77,7 +76,7 @@ Torrent.prototype =
|
|||
e.addClass('torrent_peer_details');
|
||||
element.append( e );
|
||||
element._peer_details_container = e;
|
||||
|
||||
|
||||
// Set the torrent click observer
|
||||
element.bind('click', {element: element}, this.clickTorrent);
|
||||
if (!iPhone) element.bind('contextmenu', {element: element}, this.rightClickTorrent);
|
||||
|
@ -89,12 +88,39 @@ Torrent.prototype =
|
|||
|
||||
// insert the element
|
||||
$('#torrent_list').append(this._element);
|
||||
this.initializeTorrentFilesInspectorGroup();
|
||||
|
||||
for (var i = 0; i < data.files.length; i++) {
|
||||
var file = data.files[i];
|
||||
file.index = i;
|
||||
file.torrent = this;
|
||||
file.priority = data.priorities[i];
|
||||
file.wanted = data.wanted[i];
|
||||
var torrentFile = new TorrentFile(file);
|
||||
this._files.push(torrentFile);
|
||||
this._fileList.append(
|
||||
torrentFile.element().addClass(i % 2 ? 'even' : 'odd').addClass('inspector_torrent_file_list_entry')
|
||||
);
|
||||
}
|
||||
|
||||
// Update all the labels etc
|
||||
this.refresh(data);
|
||||
},
|
||||
|
||||
|
||||
|
||||
initializeTorrentFilesInspectorGroup: function() {
|
||||
this._files = [];
|
||||
this._fileList = $('<ul/>').addClass('inspector_torrent_file_list').addClass('inspector_group').hide().
|
||||
append($('<li/>').addClass('inspector_group_label').append(
|
||||
$('<div/>').append(this.name())
|
||||
)
|
||||
);
|
||||
$('#inspector_file_list').append(this._fileList);
|
||||
},
|
||||
|
||||
fileList: function() {
|
||||
return this._fileList;
|
||||
},
|
||||
|
||||
/*--------------------------------------------
|
||||
*
|
||||
* S E T T E R S / G E T T E R S
|
||||
|
@ -131,8 +157,7 @@ Torrent.prototype =
|
|||
getPercentDone: function() {
|
||||
if( !this._sizeWhenDone ) return 1.0;
|
||||
if( !this._leftUntilDone ) return 1.0;
|
||||
return ( this._sizeWhenDone - this._leftUntilDone )
|
||||
/ this._sizeWhenDone;
|
||||
return ( this._sizeWhenDone - this._leftUntilDone ) / this._sizeWhenDone;
|
||||
},
|
||||
getPercentDoneStr: function() {
|
||||
return Math.ratio( 100 * ( this._sizeWhenDone - this._leftUntilDone ),
|
||||
|
@ -155,7 +180,9 @@ Torrent.prototype =
|
|||
totalSeeders: function() { return this._total_seeders; },
|
||||
uploadSpeed: function() { return this._upload_speed; },
|
||||
uploadTotal: function() { return this._upload_total; },
|
||||
|
||||
showFileList: function() { if (this.fileList()) return this.fileList().show(); },
|
||||
hideFileList: function() { if (this.fileList()) return this.fileList().hide(); },
|
||||
|
||||
/*--------------------------------------------
|
||||
*
|
||||
* E V E N T F U N C T I O N S
|
||||
|
@ -252,8 +279,7 @@ Torrent.prototype =
|
|||
/*
|
||||
* Refresh display
|
||||
*/
|
||||
refreshData: function(data)
|
||||
{
|
||||
refreshData: function(data) {
|
||||
// These variables never change after the inital load
|
||||
if (data.isPrivate) this._is_private = data.isPrivate;
|
||||
if (data.hashString) this._hashString = data.hashString;
|
||||
|
@ -263,8 +289,8 @@ Torrent.prototype =
|
|||
if (data.comment) this._comment = data.comment;
|
||||
if (data.creator) this._creator = data.creator;
|
||||
if (data.dateCreated) this._creator_date = data.dateCreated;
|
||||
if (data.leftUntilDone) this._leftUntilDone = data.leftUntilDone;
|
||||
if (data.sizeWhenDone) this._sizeWhenDone = data.sizeWhenDone;
|
||||
if (data.leftUntilDone) this._leftUntilDone = data.leftUntilDone;
|
||||
if (data.sizeWhenDone) this._sizeWhenDone = data.sizeWhenDone;
|
||||
if (data.path) this._torrent_file = data.path;//FIXME
|
||||
if (data.name) {
|
||||
this._name = data.name;
|
||||
|
@ -289,10 +315,18 @@ Torrent.prototype =
|
|||
this._total_leechers = Math.max( 0, data.leechers );
|
||||
this._total_seeders = Math.max( 0, data.seeders );
|
||||
this._state = data.status;
|
||||
|
||||
if (data.files) {
|
||||
for (var i = 0; i < data.files.length; i++) {
|
||||
var file_data = data.files[i];
|
||||
if (data.priorities) { file_data.priority = data.priorities[i]; }
|
||||
if (data.wanted) { file_data.wanted = data.wanted[i]; }
|
||||
this._files[i].readAttributes(file_data);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
refreshHTML: function()
|
||||
{
|
||||
refreshHTML: function() {
|
||||
var progress_details;
|
||||
var peer_details;
|
||||
var root = this._element;
|
||||
|
@ -426,6 +460,12 @@ Torrent.prototype =
|
|||
}
|
||||
|
||||
setInnerHTML( root._peer_details_container[0], peer_details );
|
||||
|
||||
// Update individual files within a torrent
|
||||
jQuery.each(this._files, function () {
|
||||
this.refreshHTML();
|
||||
} );
|
||||
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -587,3 +627,127 @@ Torrent.lookup = function( torrents, id )
|
|||
var pos = Torrent.indexOf( torrents, id );
|
||||
return pos >= 0 ? torrents[pos] : null;
|
||||
};
|
||||
|
||||
function TorrentFile(file_data) {
|
||||
this.initialize(file_data);
|
||||
}
|
||||
|
||||
TorrentFile.prototype = {
|
||||
initialize: function(file_data) {
|
||||
this._torrent = file_data.torrent;
|
||||
var pos = file_data.name.indexOf('/');
|
||||
if (pos >= 0)
|
||||
this.name = file_data.name.substring(pos + 1);
|
||||
else
|
||||
this.name = file_data.name;
|
||||
this.readAttributes(file_data);
|
||||
|
||||
this._element = $('<li/>').append(
|
||||
$('<div/>').addClass('file_wanted_control').
|
||||
bind('click', { file: this }, this.fileWantedControlClicked)
|
||||
|
||||
).append(
|
||||
this._priority_control = $('<div/>').addClass('file_priority_control').
|
||||
bind('click', { file: this }, this.filePriorityControlClicked)
|
||||
|
||||
).append(
|
||||
$('<div/>').addClass('inspector_torrent_file_list_entry_name').
|
||||
append(this.name)
|
||||
|
||||
).append(
|
||||
this._progress = $('<div/>').addClass('inspector_torrent_file_list_entry_progress')
|
||||
)
|
||||
},
|
||||
|
||||
readAttributes: function(file_data) {
|
||||
if (undefined != file_data.index) this._index = file_data.index;
|
||||
if (undefined != file_data.bytesCompleted) this._done = file_data.bytesCompleted;
|
||||
if (undefined != file_data.length) this._size = file_data.length;
|
||||
if (undefined != file_data.priority) this._prio = file_data.priority;
|
||||
if (undefined != file_data.wanted) this._wanted = file_data.wanted;
|
||||
},
|
||||
|
||||
element: function() {
|
||||
return this._element;
|
||||
},
|
||||
|
||||
setPriority: function(priority) {
|
||||
var priority_level = { high: 1, normal: 0, low: -1 }[priority];
|
||||
if (this._prio == priority_level) { return; }
|
||||
this._prio = priority_level;
|
||||
this._torrent._controller.changeFileCommand("priority-" + priority, this._torrent, this);
|
||||
this.refreshPriorityHTML();
|
||||
},
|
||||
|
||||
setWanted: function(wanted) {
|
||||
this._wanted = wanted;
|
||||
var command;
|
||||
|
||||
if (wanted) {
|
||||
this.element().removeClass('skip');
|
||||
command = 'files-wanted'
|
||||
} else {
|
||||
this.element().addClass('skip');
|
||||
command = 'files-unwanted';
|
||||
}
|
||||
this._torrent._controller.changeFileCommand(command, this._torrent, this);
|
||||
},
|
||||
|
||||
toggleWanted: function() {
|
||||
this.setWanted(!this._wanted);
|
||||
},
|
||||
|
||||
refreshHTML: function() {
|
||||
this.refreshProgressHTML();
|
||||
this.refreshWantedHTML();
|
||||
this.refreshPriorityHTML();
|
||||
},
|
||||
|
||||
refreshProgressHTML: function() {
|
||||
progress_details = Math.formatBytes(this._done) + ' of ' +
|
||||
Math.formatBytes(this._size) + ' (' +
|
||||
Math.ratio(100 * this._done, this._size) + '%)';
|
||||
setInnerHTML(this._progress[0], progress_details);
|
||||
},
|
||||
|
||||
refreshWantedHTML: function() {
|
||||
var element = this.element();
|
||||
if (this._wanted && element.hasClass('skip'))
|
||||
this.element().removeClass('skip');
|
||||
else if (!this._wanted && !element.hasClass('skip'))
|
||||
this.element().addClass('skip');
|
||||
|
||||
if (this._done < this._size && this.element().hasClass('complete'))
|
||||
this.element().removeClass('complete');
|
||||
else if (!this.element().hasClass('complete'))
|
||||
this.element().addClass('complete');
|
||||
},
|
||||
|
||||
refreshPriorityHTML: function() {
|
||||
if (this['_last_refreshed_prio'] == this._prio) { return; }
|
||||
var priority = { '1': 'high', '0': 'normal', '-1': 'low' }[new String(this._prio)];
|
||||
var off_priorities = [ 'high', 'normal', 'low' ].sort(function(a,b) { return (a == priority) ? 1 : -1; } );
|
||||
this._priority_control.addClass(priority).
|
||||
removeClass(off_priorities[0]).
|
||||
removeClass(off_priorities[1]);
|
||||
this._last_refreshed_prio = this._prio;
|
||||
},
|
||||
|
||||
fileWantedControlClicked: function(event) {
|
||||
event.data.file.toggleWanted();
|
||||
},
|
||||
|
||||
filePriorityControlClicked: function(event) {
|
||||
var x = event.pageX;
|
||||
var target = this;
|
||||
while (target != null) {
|
||||
x = x - target.offsetLeft;
|
||||
target = target.offsetParent;
|
||||
}
|
||||
var file = event.data.file;
|
||||
if (x < 8) { file.setPriority('low'); }
|
||||
else if (x < 16) { file.setPriority('normal'); }
|
||||
else { file.setPriority('high'); }
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -58,6 +58,7 @@ Transmission.prototype =
|
|||
$('#prefs_cancel_button').bind('click', this.cancelPrefsClicked);
|
||||
$('#inspector_tab_info').bind('click', this.inspectorTabClicked);
|
||||
$('#inspector_tab_activity').bind('click', this.inspectorTabClicked);
|
||||
$('#inspector_tab_files').bind('click', this.inspectorTabClicked);
|
||||
if (iPhone) {
|
||||
$('#torrent_inspector').bind('click', this.hideInspector);
|
||||
$('#preferences_link').bind('click', this.releaseClutchPreferencesButton);
|
||||
|
@ -83,28 +84,31 @@ Transmission.prototype =
|
|||
|
||||
// Get preferences & torrents from the daemon
|
||||
this.remote.loadDaemonPrefs( );
|
||||
this.remote.loadTorrents( );
|
||||
this.remote.loadTorrents( true );
|
||||
this.togglePeriodicRefresh( true );
|
||||
},
|
||||
|
||||
preloadImages: function() {
|
||||
if (iPhone) {
|
||||
this.loadImages(
|
||||
'images/buttons/info_activity.png',
|
||||
'images/buttons/info_general.png',
|
||||
'images/buttons/info_activity.png',
|
||||
'images/buttons/info_files.png',
|
||||
'images/buttons/toolbar_buttons.png',
|
||||
'images/graphics/filter_bar.png',
|
||||
'images/graphics/iphone_chrome.png',
|
||||
'images/graphics/logo.png',
|
||||
'images/progress/progress.png'
|
||||
'images/graphics/logo.png'
|
||||
);
|
||||
} else {
|
||||
this.loadImages(
|
||||
'images/buttons/info_activity.png',
|
||||
'images/buttons/info_general.png',
|
||||
'images/buttons/info_activity.png',
|
||||
'images/buttons/info_files.png',
|
||||
'images/buttons/tab_backgrounds.png',
|
||||
'images/buttons/toolbar_buttons.png',
|
||||
'images/buttons/torrent_buttons.png',
|
||||
'images/buttons/file_wanted_buttons.png',
|
||||
'images/buttons/file_priority_buttons.png',
|
||||
'images/graphics/chrome.png',
|
||||
'images/graphics/filter_bar.png',
|
||||
'images/graphics/logo.png',
|
||||
|
@ -292,7 +296,18 @@ Transmission.prototype =
|
|||
s.push( v[i] );
|
||||
return s;
|
||||
},
|
||||
|
||||
|
||||
getDeselectedTorrents: function() {
|
||||
var visible_torrent_ids = jQuery.map(this.getVisibleTorrents(), function(t) { return t.id(); } );
|
||||
var s = [ ];
|
||||
jQuery.each( this.getAllTorrents( ), function() {
|
||||
var visible = (-1 != jQuery.inArray(this.id(), visible_torrent_ids));
|
||||
if (!this.isSelected() || !visible)
|
||||
s.push( this );
|
||||
} );
|
||||
return s;
|
||||
},
|
||||
|
||||
getVisibleRows: function()
|
||||
{
|
||||
var rows = [ ];
|
||||
|
@ -409,7 +424,7 @@ Transmission.prototype =
|
|||
if( doUpdate )
|
||||
this.selectionChanged( );
|
||||
},
|
||||
|
||||
|
||||
selectionChanged: function()
|
||||
{
|
||||
this.updateButtonStates();
|
||||
|
@ -579,7 +594,9 @@ Transmission.prototype =
|
|||
|
||||
// Select the clicked tab, unselect the others,
|
||||
// and display the appropriate info
|
||||
var tab_ids = ['inspector_tab_info', 'inspector_tab_activity'];
|
||||
var tab_ids = $(this).parent('#inspector_tabs').find('.inspector_tab').map(
|
||||
function() { return $(this).attr('id'); }
|
||||
);
|
||||
for( var i=0; i<tab_ids.length; ++i ) {
|
||||
if (this.id == tab_ids[i]) {
|
||||
$('#' + tab_ids[i]).addClass('selected');
|
||||
|
@ -643,12 +660,25 @@ Transmission.prototype =
|
|||
// sanity check
|
||||
if( !this[Prefs._RefreshRate] )
|
||||
this[Prefs._RefreshRate] = 5;
|
||||
this._periodic_refresh = setInterval('transmission.remote.loadTorrents()', this[Prefs._RefreshRate] * 1000 );
|
||||
remote = this.remote;
|
||||
this._periodic_refresh = setInterval(this.periodicRefresh, this[Prefs._RefreshRate] * 1000 );
|
||||
} else {
|
||||
clearInterval(this._periodic_refresh);
|
||||
this._periodic_refresh = null;
|
||||
}
|
||||
},
|
||||
|
||||
periodicRefresh: function() {
|
||||
// Note: 'this' != 'transmission instance' since it is being called by setInterval
|
||||
if (!transmission._periodicRefreshIterations)
|
||||
transmission._periodicRefreshIterations = 0;
|
||||
|
||||
remote.loadTorrents(transmission._periodicRefreshIterations++ % 10 == 0);
|
||||
},
|
||||
|
||||
scheduleFileRefresh: function() {
|
||||
this._periodicRefreshIterations = 0;
|
||||
},
|
||||
|
||||
/*--------------------------------------------
|
||||
*
|
||||
|
@ -656,8 +686,7 @@ Transmission.prototype =
|
|||
*
|
||||
*--------------------------------------------*/
|
||||
|
||||
showPrefsDialog: function( )
|
||||
{
|
||||
showPrefsDialog: function( ) {
|
||||
$('body').addClass('prefs_showing');
|
||||
$('#prefs_container').show();
|
||||
transmission.hideiPhoneAddressbar();
|
||||
|
@ -865,7 +894,7 @@ Transmission.prototype =
|
|||
var na = 'N/A';
|
||||
|
||||
$("#torrent_inspector_size, .inspector_row div").css('color', '#222');
|
||||
|
||||
|
||||
if( torrents.length == 0 )
|
||||
{
|
||||
var ti = '#torrent_inspector_';
|
||||
|
@ -890,7 +919,8 @@ Transmission.prototype =
|
|||
setInnerHTML( $(ti+'progress')[0], na );
|
||||
setInnerHTML( $(ti+'comment')[0], na );
|
||||
setInnerHTML( $(ti+'creator')[0], na );
|
||||
setInnerHTML( $(ti+'error')[0], na );
|
||||
setInnerHTML( $(ti+'error')[0], na );
|
||||
this.updateVisibleFileLists();
|
||||
$("#torrent_inspector_size, .inspector_row > div:contains('N/A')").css('color', '#666');
|
||||
return;
|
||||
}
|
||||
|
@ -918,7 +948,7 @@ Transmission.prototype =
|
|||
date_created = Math.formatTimestamp( t._creator_date );
|
||||
}
|
||||
|
||||
for( i=0; i<torrents.length; ++i ) {
|
||||
for(i = 0; i < torrents.length; ++i ) {
|
||||
var t = torrents[i];
|
||||
sizeWhenDone += t._sizeWhenDone;
|
||||
sizeDone += t._sizeWhenDone - t._leftUntilDone;
|
||||
|
@ -979,6 +1009,16 @@ Transmission.prototype =
|
|||
$(ti+'error')[0].innerHTML = error;
|
||||
|
||||
$(".inspector_row > div:contains('N/A')").css('color', '#666');
|
||||
this.updateVisibleFileLists();
|
||||
},
|
||||
|
||||
updateVisibleFileLists: function() {
|
||||
jQuery.each( this.getSelectedTorrents(), function() {
|
||||
this.showFileList();
|
||||
} );
|
||||
jQuery.each( this.getDeselectedTorrents(), function() {
|
||||
this.hideFileList();
|
||||
} );
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -990,7 +1030,7 @@ Transmission.prototype =
|
|||
else
|
||||
this.showInspector( );
|
||||
},
|
||||
|
||||
|
||||
showInspector: function() {
|
||||
$('#torrent_inspector').show();
|
||||
if (iPhone) {
|
||||
|
@ -1054,36 +1094,53 @@ Transmission.prototype =
|
|||
this.setFilter( Prefs._FilterAll );
|
||||
},
|
||||
|
||||
updateTorrentsData: function( torrent_list ) {
|
||||
var tr = this;
|
||||
jQuery.each( torrent_list, function() {
|
||||
var t = Torrent.lookup(tr._torrents, this.id);
|
||||
if (t) t.refresh(this);
|
||||
} );
|
||||
},
|
||||
|
||||
/*
|
||||
* Process got some new torrent data from the server
|
||||
*/
|
||||
updateTorrents: function( torrent_list )
|
||||
{
|
||||
updateAllTorrents: function( torrent_list ) {
|
||||
var torrent_data;
|
||||
var new_torrents = [];
|
||||
var torrent_ids = [];
|
||||
var handled = [];
|
||||
|
||||
// refresh existing torrents
|
||||
this.updateTorrentsData( torrent_list );
|
||||
|
||||
// partition existing and new torrents
|
||||
|
||||
for( var i=0, len=torrent_list.length; i<len; ++i ) {
|
||||
var data = torrent_list[i];
|
||||
var t = Torrent.lookup( this._torrents, data.id );
|
||||
if( !t )
|
||||
new_torrents.push( data );
|
||||
else {
|
||||
t.refresh( data );
|
||||
handled.push( t );
|
||||
}
|
||||
}
|
||||
|
||||
// Add any torrents that aren't already being displayed
|
||||
// if file data is available
|
||||
if( new_torrents.length ) {
|
||||
for( var i=0, len=new_torrents.length; i<len; ++i ) {
|
||||
var t = new Torrent( this, new_torrents[i] );
|
||||
this._torrents.push( t );
|
||||
handled.push( t );
|
||||
if (data.files) {
|
||||
for( var i=0, len=new_torrents.length; i<len; ++i ) {
|
||||
var t = new Torrent( this, new_torrents[i] );
|
||||
this._torrents.push( t );
|
||||
handled.push( t );
|
||||
}
|
||||
this._torrents.sort( Torrent.compareById );
|
||||
} else {
|
||||
// There are new torrents available
|
||||
// pick them up on the next refresh
|
||||
this.scheduleFileRefresh();
|
||||
}
|
||||
this._torrents.sort( Torrent.compareById );
|
||||
}
|
||||
|
||||
// Remove any torrents that weren't in the refresh list
|
||||
|
@ -1099,6 +1156,7 @@ Transmission.prototype =
|
|||
delete e._torrent;
|
||||
e.hide( );
|
||||
}
|
||||
t.hideFileList();
|
||||
this._torrents.splice( pos, 1 );
|
||||
removedAny = true;
|
||||
}
|
||||
|
@ -1192,10 +1250,10 @@ Transmission.prototype =
|
|||
args.dataType = 'xml';
|
||||
args.iframe = true;
|
||||
args.success = function( data ) {
|
||||
tr.remote.loadTorrents( );
|
||||
tr.remote.loadTorrents( true );
|
||||
tr.togglePeriodicRefresh( true );
|
||||
};
|
||||
this.togglePeriodicRefresh( false );
|
||||
tr.togglePeriodicRefresh( false );
|
||||
$('#torrent_upload_form').ajaxSubmit( args );
|
||||
}
|
||||
}
|
||||
|
@ -1290,6 +1348,9 @@ Transmission.prototype =
|
|||
stopTorrents: function( torrents ) {
|
||||
this.remote.stopTorrents( torrents );
|
||||
},
|
||||
changeFileCommand: function(command, torrent, file) {
|
||||
this.remote.changeFileCommand(command, torrent, file)
|
||||
},
|
||||
|
||||
hideiPhoneAddressbar: function(timeInSeconds) {
|
||||
if( iPhone ) {
|
||||
|
|
|
@ -55,63 +55,92 @@ TransmissionRemote.prototype =
|
|||
'Dismiss');
|
||||
transmission.togglePeriodicRefresh(false);
|
||||
},
|
||||
|
||||
sendRequest: function( url, data, success, contentType )
|
||||
{
|
||||
var o = { };
|
||||
o.cache = false;
|
||||
o.contentType = contentType;
|
||||
o.data = data;
|
||||
o.dataType = 'json';
|
||||
o.error = this.ajaxError;
|
||||
o.success = success;
|
||||
o.type = 'POST';
|
||||
o.url = url;
|
||||
$.ajax( o );
|
||||
|
||||
sendRequest: function( data, success ) {
|
||||
$.ajax( {
|
||||
url: RPC._Root,
|
||||
type: 'POST',
|
||||
contentType: 'json',
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
data: $.toJSON(data),
|
||||
error: this.ajaxError,
|
||||
success: success
|
||||
} );
|
||||
},
|
||||
|
||||
loadDaemonPrefs: function() {
|
||||
var tr = this._controller;
|
||||
var o = { };
|
||||
o.method = 'session-get';
|
||||
this.sendRequest( RPC._Root, $.toJSON(o), function(data) {
|
||||
var o = { method: 'session-get' };
|
||||
this.sendRequest( o, function(data) {
|
||||
var o = data.arguments;
|
||||
Prefs.getClutchPrefs( o );
|
||||
tr.updatePrefs( o );
|
||||
}, "json" );
|
||||
} );
|
||||
},
|
||||
|
||||
loadTorrents: function() {
|
||||
loadTorrents: function(update_files) {
|
||||
var tr = this._controller;
|
||||
var o = { };
|
||||
o.method = 'torrent-get'
|
||||
o.arguments = { };
|
||||
o.arguments.fields = [
|
||||
'addedDate', 'announceURL', 'comment', 'creator',
|
||||
'dateCreated', 'downloadedEver', 'error', 'errorString',
|
||||
'eta', 'hashString', 'haveUnchecked', 'haveValid', 'id',
|
||||
'isPrivate', 'leechers', 'leftUntilDone', 'name',
|
||||
'peersConnected', 'peersGettingFromUs', 'peersSendingToUs',
|
||||
'rateDownload', 'rateUpload', 'seeders', 'sizeWhenDone',
|
||||
'status', 'swarmSpeed', 'totalSize', 'uploadedEver' ];
|
||||
this.sendRequest( RPC._Root, $.toJSON(o), function(data) {
|
||||
tr.updateTorrents( data.arguments.torrents );
|
||||
}, "json" );
|
||||
var o = {
|
||||
method: 'torrent-get',
|
||||
arguments: { fields: [
|
||||
'addedDate', 'announceURL', 'comment', 'creator',
|
||||
'dateCreated', 'downloadedEver', 'error', 'errorString',
|
||||
'eta', 'hashString', 'haveUnchecked', 'haveValid', 'id',
|
||||
'isPrivate', 'leechers', 'leftUntilDone', 'name',
|
||||
'peersConnected', 'peersGettingFromUs', 'peersSendingToUs',
|
||||
'rateDownload', 'rateUpload', 'seeders', 'sizeWhenDone',
|
||||
'status', 'swarmSpeed', 'totalSize', 'uploadedEver' ]
|
||||
}
|
||||
};
|
||||
if (update_files) {
|
||||
o.arguments.fields.push('files');
|
||||
o.arguments.fields.push('wanted');
|
||||
o.arguments.fields.push('priorities');
|
||||
}
|
||||
this.sendRequest( o, function(data) {
|
||||
tr.updateAllTorrents( data.arguments.torrents );
|
||||
} );
|
||||
},
|
||||
|
||||
|
||||
loadTorrentFiles: function( torrent_ids ) {
|
||||
var tr = this._controller;
|
||||
this.sendRequest( {
|
||||
method: 'torrent-get',
|
||||
arguments: { fields: [ 'files', 'wanted', 'priorities'] },
|
||||
ids: torrent_ids
|
||||
}, function(data) {
|
||||
tr.updateTorrentsData( data.arguments.torrents );
|
||||
} );
|
||||
},
|
||||
|
||||
changeFileCommand: function( command, torrent, file ) {
|
||||
var remote = this;
|
||||
var torrent_ids = [ torrent.id() ];
|
||||
var o = {
|
||||
method: 'torrent-set',
|
||||
arguments: { ids: torrent_ids }
|
||||
};
|
||||
o.arguments[command] = [ file._index ];
|
||||
this.sendRequest( o, function( ) {
|
||||
remote.loadTorrentFiles( torrent_ids );
|
||||
} );
|
||||
},
|
||||
|
||||
sendTorrentCommand: function( method, torrents ) {
|
||||
var remote = this;
|
||||
var o = { };
|
||||
o.method = method;
|
||||
o.arguments = { };
|
||||
o.arguments.ids = [ ];
|
||||
var o = {
|
||||
method: method,
|
||||
arguments: { ids: [ ] }
|
||||
};
|
||||
if( torrents != null )
|
||||
for( var i=0, len=torrents.length; i<len; ++i )
|
||||
o.arguments.ids.push( torrents[i].id() );
|
||||
this.sendRequest( RPC._Root, $.toJSON(o), function( ) {
|
||||
this.sendRequest( o, function( ) {
|
||||
remote.loadTorrents();
|
||||
}, "json" );
|
||||
} );
|
||||
},
|
||||
|
||||
startTorrents: function( torrents ) {
|
||||
this.sendTorrentCommand( 'torrent-start', torrents );
|
||||
},
|
||||
|
@ -149,11 +178,12 @@ TransmissionRemote.prototype =
|
|||
},
|
||||
savePrefs: function( args ) {
|
||||
var remote = this;
|
||||
var o = { };
|
||||
o.method = 'session-set';
|
||||
o.arguments = args;
|
||||
this.sendRequest( RPC._Root, $.toJSON(o), function(){
|
||||
var o = {
|
||||
method: 'session-set',
|
||||
arguments: args
|
||||
};
|
||||
this.sendRequest( o, function() {
|
||||
remote.loadDaemonPrefs();
|
||||
}, "json" );
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -514,6 +514,7 @@ div#torrent_inspector {
|
|||
border-left: 1px solid #888;
|
||||
z-index: 2;
|
||||
text-align: left;
|
||||
overflow: auto;
|
||||
}
|
||||
div#torrent_inspector #torrent_inspector_name {
|
||||
margin: 0;
|
||||
|
@ -532,9 +533,9 @@ div#inspector_header {
|
|||
padding-right: 10px;
|
||||
}
|
||||
div#inspector_tabs {
|
||||
width: 189px;
|
||||
margin: 0 auto;
|
||||
padding-top: 10px;
|
||||
width: 140px;
|
||||
}
|
||||
.inspector_tab {
|
||||
float: left;
|
||||
|
@ -548,8 +549,8 @@ div#inspector_tabs {
|
|||
background-position: left -26px; /* the highlighted part of the image */
|
||||
}
|
||||
.inspector_container {
|
||||
margin: 10px;
|
||||
width: 330px; /* inspector_width==350 - ((margin==10)*2) */
|
||||
margin: 3%;
|
||||
width: 96%;
|
||||
}
|
||||
.inspector_group {
|
||||
display: table;
|
||||
|
@ -575,6 +576,109 @@ div#inspector_tabs {
|
|||
width: 230px; /* inspector_container_width==330 - inspector_label_width==100 */
|
||||
}
|
||||
|
||||
/* Files Inspector Tab */
|
||||
#inspector_file_list {
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
text-align: left;
|
||||
cursor: default;
|
||||
overflow: hidden;
|
||||
}
|
||||
ul.inspector_torrent_file_list {
|
||||
width: 100%;
|
||||
margin: 0 0 0 0;
|
||||
padding-bottom: 10px;
|
||||
text-align: left;
|
||||
display: block;
|
||||
cursor: default;
|
||||
list-style-type: none;
|
||||
list-style: none;
|
||||
list-style-image: none;
|
||||
}
|
||||
li.inspector_torrent_file_list_entry {
|
||||
padding: 3px 0 3px 2px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
li.inspector_torrent_file_list_entry.skip {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
li.inspector_torrent_file_list_entry.even {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
div.inspector_torrent_file_list_entry_name {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
margin-left: 20px;
|
||||
}
|
||||
li.inspector_torrent_file_list_entry.skip>.inspector_torrent_file_list_entry_name {
|
||||
color: #666;
|
||||
}
|
||||
li.inspector_torrent_file_list_entry.even {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
div.inspector_torrent_file_list_entry_progress {
|
||||
font-size: 1em;
|
||||
color: #666;
|
||||
margin-left: 20px;
|
||||
}
|
||||
div.file_wanted_control {
|
||||
background-position: left -16px;
|
||||
float: left;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
margin: 0 0 0 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-image: url('../images/buttons/file_wanted_buttons.png');
|
||||
background-repeat: no-repeat;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
li.inspector_torrent_file_list_entry.skip>.file_wanted_control {
|
||||
background-position: left 0px;
|
||||
}
|
||||
|
||||
li.inspector_torrent_file_list_entry.complete>.file_wanted_control {
|
||||
background-position: -16px -16px;
|
||||
}
|
||||
|
||||
li.inspector_torrent_file_list_entry.complete.skip>.file_wanted_control {
|
||||
background-position: -16px 0px;
|
||||
}
|
||||
|
||||
div.file_priority_control {
|
||||
float: right;
|
||||
margin: 0 0 0 0;
|
||||
width: 24px;
|
||||
height: 12px;
|
||||
background-image: url('../images/buttons/file_priority_buttons.png');
|
||||
background-repeat: no-repeat;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
div.file_priority_control.high {
|
||||
background-position: left -12px;
|
||||
}
|
||||
div.file_priority_control.high:hover {
|
||||
background-position: right -12px;
|
||||
}
|
||||
div.file_priority_control.normal {
|
||||
background-position: left -24px;
|
||||
}
|
||||
div.file_priority_control.normal:hover {
|
||||
background-position: right -24px;
|
||||
}
|
||||
div.file_priority_control.low {
|
||||
background-position: left 0px;
|
||||
}
|
||||
div.file_priority_control.low:hover {
|
||||
background-position: right 0px;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------
|
||||
*
|
||||
* T O R R E N T F O O T E R
|
||||
|
|
Loading…
Reference in New Issue