From 83929f8396551e68fc49b8decdc2f7be01593078 Mon Sep 17 00:00:00 2001 From: Mitchell Livingston Date: Sat, 14 Mar 2009 21:33:08 +0000 Subject: [PATCH] #1435 selective downloading and file prioritization for web ui --- web/images/buttons/file_priority_buttons.png | Bin 0 -> 5376 bytes web/images/buttons/file_wanted_buttons.png | Bin 0 -> 1764 bytes web/images/buttons/info_files.png | Bin 0 -> 917 bytes web/index.html | 7 + web/javascript/common.js | 7 +- web/javascript/torrent.js | 192 +++++++++++++++++-- web/javascript/transmission.js | 111 ++++++++--- web/javascript/transmission.remote.js | 118 +++++++----- web/stylesheets/common.css | 110 ++++++++++- 9 files changed, 453 insertions(+), 92 deletions(-) create mode 100644 web/images/buttons/file_priority_buttons.png create mode 100644 web/images/buttons/file_wanted_buttons.png create mode 100644 web/images/buttons/info_files.png diff --git a/web/images/buttons/file_priority_buttons.png b/web/images/buttons/file_priority_buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..855b178b21cd567b16984f4af1755393f76b753b GIT binary patch literal 5376 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 e3sD}N3;hiuptBA^gc|(-0000<_ literal 0 HcmV?d00001 diff --git a/web/images/buttons/file_wanted_buttons.png b/web/images/buttons/file_wanted_buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..482730ebda5821fe60aba86e7af5c2b629b63cec GIT binary patch literal 1764 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 literal 0 HcmV?d00001 diff --git a/web/index.html b/web/index.html index ba6675b64..1b1a842a8 100755 --- a/web/index.html +++ b/web/index.html @@ -14,6 +14,7 @@ + @@ -61,6 +62,7 @@
Information
Activity
+
Files
@@ -168,6 +170,11 @@
+ + +
diff --git a/web/javascript/common.js b/web/javascript/common.js index 1eab824bc..8ddf6a6e3 100644 --- a/web/javascript/common.js +++ b/web/javascript/common.js @@ -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 ) { diff --git a/web/javascript/torrent.js b/web/javascript/torrent.js index 3d200ce7f..280175682 100644 --- a/web/javascript/torrent.js +++ b/web/javascript/torrent.js @@ -23,8 +23,7 @@ Torrent.prototype = /* * Constructor */ - initialize: function(controller,data) - { + initialize: function(controller, data) { // Create a new
  • element var element = $('
  • '); 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 = $('
      ').addClass('inspector_torrent_file_list').addClass('inspector_group').hide(). + append($('
    • ').addClass('inspector_group_label').append( + $('
      ').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 = $('
    • ').append( + $('
      ').addClass('file_wanted_control'). + bind('click', { file: this }, this.fileWantedControlClicked) + + ).append( + this._priority_control = $('
      ').addClass('file_priority_control'). + bind('click', { file: this }, this.filePriorityControlClicked) + + ).append( + $('
      ').addClass('inspector_torrent_file_list_entry_name'). + append(this.name) + + ).append( + this._progress = $('
      ').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'); } + } + +}; diff --git a/web/javascript/transmission.js b/web/javascript/transmission.js index 6237190c7..71ae2c784 100644 --- a/web/javascript/transmission.js +++ b/web/javascript/transmission.js @@ -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 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 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.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 -- 2.40.0