Changeset 389
- Timestamp:
- 06/27/08 06:29:30 (2 months ago)
- Files:
-
- branches/rpc/README.txt (added)
- branches/rpc/web/images/favicon.ico (modified) (previous)
- branches/rpc/web/index.html (added)
- branches/rpc/web/javascript/common.js (modified) (2 diffs)
- branches/rpc/web/javascript/hash.js (deleted)
- branches/rpc/web/javascript/torrent.js (modified) (17 diffs)
- branches/rpc/web/javascript/transmission.js (modified) (15 diffs)
- branches/rpc/web/javascript/transmission.remote.js (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/rpc/web/javascript/common.js
r388 r389 115 115 */ 116 116 Array.prototype.inArray = function (obj) { 117 var i; 118 for (i=0; i < this.length; i++) { 119 if (this[i] === obj) { 120 return true; 121 } 122 } 123 return false; 117 return this.indexOf( obj ) != -1; 124 118 }; 125 119 … … 293 287 } 294 288 289 290 /* 291 * Given a numerator and denominator, return a ratio string 292 */ 293 Math.ratio = function( numerator, denominator ) 294 { 295 var result = Math.roundWithPrecision((numerator / denominator), 2); 296 297 // check for special cases 298 if (isNaN(result)) result = 0; 299 if (result=="Infinity") result = "∞"; 300 301 // Add the decimals if this is an integer 302 if ((result % 1) == 0) 303 result = result + '.00'; 304 305 return result; 306 } 307 295 308 /* 296 309 * Trim whitespace from a string 297 310 */ 298 311 String.prototype.trim = function () { 299 return this.replace(/^\s*/, "").replace(/\s*$/, ""); 300 } 301 312 return this.replace(/^\s*/, "").replace(/\s*$/, ""); 313 } 314 315 316 317 /*** 318 **** Preferences 319 ***/ 320 321 function Prefs() { } 322 Prefs.prototype = { } 323 324 Prefs._RefreshRate = 'refresh_rate'; 325 326 Prefs._ShowFilter = 'show_filter'; 327 328 Prefs._ShowInspector = 'show_inspector'; 329 330 Prefs._FilterMode = 'filter'; 331 Prefs._FilterAll = 'all'; 332 Prefs._FilterSeeding = 'seeding'; 333 Prefs._FilterDownloading = 'downloading'; 334 Prefs._FilterPaused = 'paused'; 335 336 Prefs._SortDirection = 'sort_direction'; 337 Prefs._SortAscending = 'ascending'; 338 Prefs._SortDescending = 'descending'; 339 340 Prefs._SortMethod = 'sort_method'; 341 Prefs._SortByAge = 'age'; 342 Prefs._SortByActivity = 'activity'; 343 Prefs._SortByQueue = 'queue_order'; 344 Prefs._SortByName = 'name'; 345 Prefs._SortByProgress = 'percent_completed'; 346 Prefs._SortByState = 'state'; 347 Prefs._SortByTracker = 'tracker'; 348 349 350 Prefs._Defaults = 351 { 352 'filter': 'all', 353 'refresh_rate' : 5, 354 'show_filter': true, 355 'show_inspector': false, 356 'sort_direction': 'ascending', 357 'sort_method': 'name' 358 }; 359 360 /* 361 * Set a preference option 362 */ 363 Prefs.setValue = function( key, val ) 364 { 365 if( Prefs._Defaults[key] == undefined ) 366 console.warn( "unrecognized preference key '%s'", key ); 367 368 var days = 30; 369 var date = new Date(); 370 date.setTime(date.getTime()+(days*24*60*60*1000)); 371 document.cookie = key+"="+val+"; expires="+date.toGMTString()+"; path=/"; 372 } 373 374 /** 375 * Get a preference option 376 * 377 * @param key the preference's key 378 * @param fallback if the option isn't set, return this instead 379 */ 380 Prefs.getValue = function( key, fallback ) 381 { 382 var val; 383 384 if( Prefs._Defaults[key] == undefined ) 385 console.warn( "unrecognized preference key '%s'", key ); 386 387 var lines = document.cookie.split( ';' ); 388 for( var i=0, len=lines.length; !val && i<len; ++i ) { 389 var line = lines[i].trim( ); 390 var delim = line.indexOf( '=' ); 391 if( ( delim == key.length ) && line.indexOf( key ) == 0 ) 392 val = line.substring( delim + 1 ); 393 } 394 395 // FIXME: we support strings and booleans... add number support too? 396 if( !val ) val = fallback; 397 else if( val == 'true' ) val = true; 398 else if( val == 'false' ) val = false; 399 return val; 400 } 401 402 /** 403 * Get an object with all the Clutch preferences set 404 * 405 * @pararm o object to be populated (optional) 406 */ 407 Prefs.getClutchPrefs = function( o ) 408 { 409 if( o == null ) 410 o = new Object( ); 411 for( var key in Prefs._Defaults ) 412 o[key] = Prefs.getValue( key, Prefs._Defaults[key] ); 413 return o; 414 } branches/rpc/web/javascript/torrent.js
r385 r389 2 2 * Copyright © Dave Perrett and Malcolm Jarvis 3 3 * This code is licensed under the GPL version 2. 4 * For moredetails, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html4 * For details, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 5 5 * 6 * Class Torrent6 * Class Torrent 7 7 */ 8 8 9 function Torrent(data) { 10 // Constants 11 this._StatusDownloading = 'downloading'; 12 this._StatusSeeding = 'seeding'; 13 this._StatusStopping = 'stopping'; 14 this._StatusPaused = 'paused'; 15 this._StatusChecking = 'checking'; 16 this._StatusWaitingToCheck = 'waiting to checking'; 17 this._InfiniteTimeRemaining = 215784000; // 999 Hours - may as well be infinite 18 this._MaxProgressBarWidth = 100; // reduce this to make the progress bar shorter (%) 19 20 this.initialize(data); 9 function Torrent(controller,data) { 10 this.initialize(controller,data); 21 11 } 22 12 23 Torrent.prototype = { 24 25 /* 26 * Constructor 27 */ 28 initialize: function(data) { 29 13 // Constants 14 Torrent._StatusSeeding = 'seeding'; 15 Torrent._StatusDownloading = 'downloading'; 16 Torrent._StatusPaused = 'paused'; 17 Torrent._StatusChecking = 'verifying local data'; 18 Torrent._StatusWaitingToCheck = 'waiting to verify'; 19 Torrent._InfiniteTimeRemaining = 215784000; // 999 Hours - may as well be infinite 20 Torrent._MaxProgressBarWidth = 100; // reduce this to make the progress bar shorter (%) 21 22 Torrent.prototype = 23 { 24 /* 25 * Constructor 26 */ 27 initialize: function(controller,data) 28 { 30 29 // Create a new <li> element 31 30 var element = $('<li/>'); 32 31 element.addClass('torrent'); 33 32 element[0].id = 'torrent_' + data.id; 33 element._torrent = this; 34 34 this._element = element; 35 this._controller = controller; 36 controller._rows.push( element ); 35 37 36 38 // Create the 'name' <div> 37 this._name_container= $('<div/>');38 this._name_container.addClass('torrent_name');39 this._name_container[0].innerHTML= data.name;40 this._element.append(this._name_container);39 var e = $('<div/>'); 40 e.addClass('torrent_name'); 41 element.append( e ); 42 element._name_container = e; 41 43 42 44 // Create the 'progress details' <div> 43 this._progress_details_container = $('<div/>'); 44 this._progress_details_container.addClass('torrent_progress_details'); 45 this._element.append(this._progress_details_container); 46 45 e = $('<div/>'); 46 e.addClass('torrent_progress_details'); 47 element.append(e); 48 element._progress_details_container = e; 49 47 50 // Create the 'in progress' bar 48 this._progress_complete_container= $('<div/>');49 this._progress_complete_container.addClass('torrent_progress_bar');50 this._progress_complete_container.addClass('incomplete');51 this._progress_complete_container.css('width', '0%');52 this._element.append(this._progress_complete_container);51 e = $('<div/>'); 52 e.addClass('torrent_progress_bar incomplete'); 53 e.css('width', '0%'); 54 element.append( e ); 55 element._progress_complete_container = e; 53 56 54 57 // Create the 'incomplete' bar (initially hidden) 55 this._progress_incomplete_container = $('<div/>'); 56 this._progress_incomplete_container.addClass('torrent_progress_bar'); 57 this._progress_incomplete_container.addClass('incomplete'); 58 this._progress_incomplete_container.hide(); 59 this._element.append(this._progress_incomplete_container); 60 61 // Add the pause/resume button - don't specify the image or alt text until 62 // the 'refresh()' function (depends on torrent state) 63 this._pause_resume_button = $('<a/>'); 64 this._pause_resume_button_image = $('<div/>'); 65 this._pause_resume_button_image.addClass('torrent_pause'); 66 this._pause_resume_button.append(this._pause_resume_button_image); 67 this._element.append(this._pause_resume_button); 68 69 // Set the pause button click observer (not shown on iPhone) 70 if (!iPhone) this._pause_resume_button.bind('click', {torrent: this}, this.clickPauseResumeButton); 58 e = $('<div/>'); 59 e.addClass('torrent_progress_bar incomplete'); 60 e.hide(); 61 element.append( e ); 62 element._progress_incomplete_container = e; 63 64 // Add the pause/resume button - don't specify the 65 // image or alt text until the 'refresh()' function 66 // (depends on torrent state) 67 var image = $('<div/>'); 68 image.addClass('torrent_pause'); 69 e = $('<a/>'); 70 e.append( image ); 71 element.append( e ); 72 element._pause_resume_button_image = image; 73 element._pause_resume_button = e; 74 if (!iPhone) e.bind('click', {element: element}, this.clickPauseResumeButton); 71 75 72 76 // Create the 'peer details' <div> 73 this._peer_details_container = $('<div/>'); 74 this._peer_details_container.addClass('torrent_peer_details'); 75 this._element.append(this._peer_details_container); 77 e = $('<div/>'); 78 e.addClass('torrent_peer_details'); 79 element.append( e ); 80 element._peer_details_container = e; 76 81 77 82 // Set the torrent click observer 78 this._element.bind('click', {torrent: this}, this.clickTorrent);79 if (!iPhone) this._element.bind('contextmenu', {torrent: this}, this.rightClickTorrent);83 element.bind('click', {element: element}, this.clickTorrent); 84 if (!iPhone) element.bind('contextmenu', {element: element}, this.rightClickTorrent); 80 85 81 86 // Safari hack - first torrent needs to be moved down for some reason. Seems to be ok when 82 87 // using <li>'s in straight html, but adding through the DOM gets a bit odd. 83 if ($.browser.safari) {88 if ($.browser.safari) 84 89 this._element.css('margin-top', '7px'); 85 }86 90 87 91 // insert the element … … 91 95 this.refresh(data); 92 96 }, 93 94 97 95 98 … … 99 102 * 100 103 *--------------------------------------------*/ 101 102 104 103 /* 104 * Set the main transmission controller 105 */ 106 setController: function(controller) { 107 this._controller = controller; 108 }, 109 110 /* 111 * Return the id of this torrent 112 */ 113 id: function() { 114 return parseInt(this._id); 115 }, 116 117 /* 118 * Return the DOM element for this torrent (a <LI> element) 119 */ 105 /* Return the DOM element for this torrent (a <LI> element) */ 120 106 element: function() { 121 107 return this._element; 122 108 }, 123 124 /* 125 * Return the torrent before this in the list 126 */ 127 previousTorrent: function() { 128 return this._previous_torrent; 129 }, 130 131 /* 132 * Set the torrent before this in the list 133 */ 134 setPreviousTorrent: function(torrent) { 135 this._previous_torrent = torrent; 136 }, 137 138 /* 139 * Return the torrent after this in the list 140 */ 141 nextTorrent: function() { 142 return this._next_torrent; 143 }, 144 145 /* 146 * Set the torrent after this in the list 147 */ 148 setNextTorrent: function(torrent) { 149 this._next_torrent = torrent; 150 }, 151 152 /* 153 * Return the position of this torrent in the list 154 */ 155 position: function() { 156 return this._position; 157 }, 158 159 /* 160 * Set the position of this torrent in the list 161 */ 162 setPosition: function(position) { 163 return this._position = position; 164 }, 165 166 /* 167 * Return the state of this torrent 168 */ 169 isActive: function() { 170 return this._state == this._StatusSeeding || !(this._state == this._StatusStopping || this._state == this._StatusPaused); 171 }, 172 173 /* 174 * Return the name of this torrent 175 */ 176 name: function() { 177 return this._name; 178 }, 179 180 /* 181 * Return the error message for this torrent 182 */ 183 errorMessage: function() { 184 return this._error_message; 185 }, 186 187 /* 188 * Return the creator of this torrent 189 */ 190 creator: function() { 191 return this._creator; 192 }, 193 194 /* 195 * Return the comment for this torrent 196 */ 197 comment: function() { 198 return this._comment; 199 }, 200 201 /* 202 * Return the swarm speed of this torrent 203 */ 204 swarmSpeed: function() { 205 return this._swarm_speed; 206 }, 207 208 /* 209 * Return the size of this torrent 210 */ 211 size: function() { 212 return this._size; 213 }, 214 215 /* 216 * Return the hash of this torrent 217 */ 218 hash: function() { 219 return this._hash; 220 }, 221 222 /* 223 * Return the state of this torrent 224 */ 225 state: function() { 226 return this._state; 227 }, 228 229 /* 230 * Return the download speed of this torrent 231 */ 232 downloadSpeed: function() { 233 return this._download_speed; 234 }, 235 236 /* 237 * Return the upload speed of this torrent 238 */ 239 uploadSpeed: function() { 240 return this._upload_speed; 241 }, 242 243 /* 244 * Return the download total of this torrent 245 */ 246 downloadTotal: function() { 247 return this._download_total; 248 }, 249 250 /* 251 * Return the bytes completed of this torrent 252 */ 253 completed: function() { 254 return this._completed; 255 }, 256 257 /* 258 * Return the percent completed of this torrent 259 */ 260 percentCompleted: function() { 261 return this._percent_completed; 262 }, 263 264 /* 265 * Return the upload total of this torrent 266 */ 267 uploadTotal: function() { 268 return this._upload_total; 269 }, 270 271 /* 272 * Return the total number of seeders for this torrent 273 */ 274 totalSeeders: function() { 275 return ((this._total_seeders == '') ? 0 : this._total_seeders); 276 }, 277 278 /* 279 * Return the total number of leechers for this torrent 280 */ 281 totalLeechers: function() { 282 return ((this._total_leechers == '') ? 0 : this._total_leechers); 283 }, 284 285 /* 286 * Return the total number of peers downloading for this torrent 287 */ 288 peersDownloading: function() { 289 return ((this._peers_downloading == '') ? 0 : this._peers_downloading); 290 }, 291 292 /* 293 * Return the total number of peers uploading for this torrent 294 */ 295 peersUploading: function() { 296 return ((this._peers_uploading == '') ? 0 : this._peers_uploading); 297 }, 298 299 /* 300 * Return the ratio for this torrent 301 */ 302 ratio: function() { 303 var result = Math.roundWithPrecision((this._upload_total / this._download_total), 2); 304 305 // check for special cases 306 if (isNaN(result)) result = 0; 307 if (result=="Infinity") result = "∞"; 308 309 // Add the decimals if this is an integer 310 if ((result % 1) == 0) { 311 result = result + '.00'; 312 } 313 314 return result; 315 }, 316 317 109 110 setElement: function( element ) { 111 if( this._element != element ) { 112 this._element = element; 113 element._torrent = this; 114 this.refreshHTML( ); 115 } 116 }, 117 118 activity: function() { return this._download_speed + this._upload_speed; }, 119 comment: function() { return this._comment; }, 120 completed: function() { return this._completed; }, 121 creator: function() { return this._creator; }, 122 dateAdded: function() { return this._date; }, 123 downloadSpeed: function() { return this._download_speed; }, 124 downloadTotal: function() { return this._download_total; }, 125 errorMessage: function() { return this._error_message; }, 126 hash: function() { return this._hashString; }, 127 id: function() { return this._id; }, 128 isActive: function() { return this.state() != Torrent._StatusPaused; }, 129 isDownloading: function() { return this.state() == Torrent._StatusDownloading; }, 130 isSeeding: function() { return this.state() == Torrent._StatusSeeding; }, 131 name: function() { return this._name; }, 132 peersDownloading: function() { return this._peers_downloading; }, 133 peersUploading: function() { return this._peers_uploading; }, 134 percentCompleted: function() { return this._percent_completed; }, 135 size: function() { return this._size; }, 136 state: function() { return this._state; }, 137 swarmSpeed: function() { return this._swarm_speed; }, 138 totalLeechers: function() { return this._total_leechers; }, 139 totalSeeders: function() { return this._total_seeders; }, 140 uploadSpeed: function() { return this._upload_speed; }, 141 uploadTotal: function() { return this._upload_total; }, 318 142 319 143 /*-------------------------------------------- … … 321 145 * E V E N T F U N C T I O N S 322 146 * 323 *--------------------------------------------*/ 147 *--------------------------------------------*/ 324 148 325 149 /* … … 328 152 rightClickTorrent: function(event) { 329 153 330 var torrent = event.data. torrent;154 var torrent = event.data.element._torrent; 331 155 332 156 // Don't stop the event! need it for the right-click menu … … 344 168 // which deselects all on click 345 169 event.stopPropagation(); 346 var torrent = event.data. torrent;347 170 var torrent = event.data.element._torrent; 171 348 172 // 'Apple' button emulation on PC : 349 173 // Need settable meta-key and ctrl-key variables for mac emulation … … 355 179 } 356 180 181 var selectionChanged = false; 182 357 183 // Shift-Click - Highlight a range between this torrent and the last-clicked torrent 358 184 if (iPhone) { 359 185 torrent._controller.deselectAll(); 360 torrent.select(); 186 torrent.select( ); 187 selectionChanged = true; 188 361 189 } else if (event.shiftKey) { 362 torrent._controller.selectRange(torrent );190 torrent._controller.selectRange(torrent, true ); 363 191 // Need to deselect any selected text 364 192 window.focus(); … … 366 194 // Apple-Click, not selected 367 195 } else if (!torrent.isSelected() && meta_key) { 368 torrent.select(); 196 torrent.select( ); 197 selectionChanged = true; 369 198 370 199 // Regular Click, not selected 371 200 } else if (!torrent.isSelected()) { 372 201 torrent._controller.deselectAll(); 373 torrent.select(); 202 torrent.select( ); 203 selectionChanged = true; 374 204 375 205 // Apple-Click, selected 376 206 } else if (torrent.isSelected() && meta_key) { 377 torrent.deselect(); 207 torrent.deselect( ); 208 selectionChanged = true; 378 209 379 210 // Regular Click, selected 380 211 } else if (torrent.isSelected()) { 381 212 torrent._controller.deselectAll(); 382 torrent.select(); 213 torrent.select( ); 214 selectionChanged = true; 383 215 } 384 216 385 217 torrent._controller.setLastTorrentClicked(torrent); 386 }, 387 218 219 if( selectionChanged ) 220 torrent._controller.selectionChanged( ); 221 }, 388 222 389 223 /* … … 393 227 // Prevents click event resulting in selection of torrent 394 228 event.stopPropagation(); 395 var torrent = event.data.torrent; 396 397 var action; 398 if (torrent._state == torrent._StatusPaused) { 229 var torrent = event.data.element._torrent; 230 231 var action; 232 var name; 233 if( torrent.isActive( ) ) { 234 name = "torrent_pause"; 235 action = 'pauseTorrents'; 236 } else { 237 name = "torrent_resume"; 399 238 action = 'resumeTorrents'; 400 torrent._pause_resume_button_image[0].style.className = "torrent_resume"; 401 } else { 402 action = 'pauseTorrents'; 403 torrent._pause_resume_button_image[0].style.className = "torrent_pause"; 404 } 405 239 } 240 241 torrent._element._pause_resume_button_image[0].style.className = name; 406 242 // Send an ajax request to perform the action 407 243 torrent._controller.remote.request(action, $.toJSON([torrent._id])); 408 244 }, 409 410 411 245 412 246 /*-------------------------------------------- … … 416 250 *--------------------------------------------*/ 417 251 252 refresh: function(data) { 253 this.refreshData( data ); 254 this.refreshHTML( ); 255 }, 256 418 257 /* 419 258 * Refresh display 420 259 */ 421 refresh: function(data) { 260 refreshData: function(data) 261 { 262 // These variables never change after the inital load 263 if (data.name) this._name = data.name; 264 if (data.isPrivate) this._is_private = data.isPrivate; 265 if (data.hashString) this._hashString = data.hashString; 266 if (data.addedDate) this._date = data.addedDate; 267 if (data.totalSize) this._size = data.totalSize; 268 if (data.announceURL) this._tracker = data.announceURL; 269 if (data.comment) this._comment = data.comment; 270 if (data.creator) this._creator = data.creator; 271 if (data.dateCreated) this._creator_date = data.dateCreated; 272 if (data.path) this._torrent_file = data.path;//FIXME 273 274 // Set the regularly-changing torrent variables 275 this._id = data.id; 276 this._completed = data.haveUnchecked + data.haveValid; 277 this._verified = data.haveValid; 278 this._percent_completed = 100 * this._completed / this._size; 279 this._download_total = data.downloadedEver; 280 this._upload_total = data.uploadedEver; 281 this._download_speed = data.rateDownload; 282 this._upload_speed = data.rateUpload; 283 this._peers_downloading = data.peersGettingFromUs; 284 this._peers_uploading = data.peersSendingToUs; 285 this._peers_total = data.peersKnown; 286 this._error = data.error; 287 this._error_message = data.errorString; 288 this._eta = data.eta; 289 this._swarm_speed = data.swarm_speed; 290 this._total_leechers = data.leechers; 291 this._total_seeders = data.seeders; 292 293 switch( data.status ) { 294 case 1: this._state = Torrent._StatusWaitingToCheck; break; 295 case 2: this._state = Torrent._StatusChecking; break; 296 case 4: this._state = Torrent._StatusDownloading; break; 297 case 8: this._state = Torrent._StatusSeeding; break; 298 case 16: this._state = Torrent._StatusPaused; break; 299 } 300 301 this._is_running = this._state != Torrent._StatusPaused; 302 303 // Get -1 returned sometimes (maybe torrents with errors?) 304 if( this._total_leechers < 0 ) 305 this._total_leechers = 0; 306 if( this._total_seeders < 0 ) 307 this._total_seeders = 0; 308 }, 309 310 refreshHTML: function() 311 { 422 312 var progress_details; 423 313 var peer_details; 424 425 // These variables never change after the inital load 426 if (data.name) this._name = data.name; 427 if (data.hash) this._hash = data.hash; 428 if (data.date) this._date = data.date; 429 if (data.size) this._size = data.size; 430 if (data.position) this._position = data.position; 431 if (data.tracker) this._tracker = data.tracker; 432 if (data.comment) this._comment = data.comment; 433 if (data.creator) this._creator = data.creator; 434 if (data.date) this._creator_date = data.date; 435 if (data.path) this._torrent_file = data.path; 436 437 // Set the regularly-changing torrent variables 438 this._id = data.id; 439 this._completed = data.completed; 440 this._percent_completed = data.percent_completed; 441 this._download_total = data.download_total; 442 this._upload_total = data.upload_total; 443 this._download_speed = data.download_speed; 444 this._upload_speed = data.upload_speed; 445 this._peers_downloading = data.peers_downloading; 446 this._peers_uploading = data.peers_uploading; 447 // Don't *think* we need this anywhere 448 this._peers_from = data.peers_from; 449 this._peers_total = data.peers_total; 450 this._error = data.error; 451 this._error_message = data.error_message; 452 this._state = data.state; 453 this._eta = data.eta; 454 this._running = data.running; 455 this._swarm_speed = data.swarm_speed; 456 this._total_leechers = data.scrape_leechers; 457 this._total_seeders = data.scrape_seeders; 458 459 // Get -1 returned sometimes (maybe torrents with errors?) 460 if (this._total_leechers < 0) { 461 this._total_leechers = 0; 462 } 463 if (this._total_seeders < 0) { 464 this._total_seeders = 0; 465 } 314 var root = this._element; 315 316 root._name_container[0].innerHTML = this._name; 466 317 467 318 // Figure out the percent completed 468 var css_percent_completed = Math.floor(this._percent_completed * this._MaxProgressBarWidth / 100);319 var css_percent_completed = Math.floor(this._percent_completed * Torrent._MaxProgressBarWidth / 100); 469 320 var int_percent_completed = Math.floor(this._percent_completed); 470 321 471 322 // Sometimes get figures greater that the max 472 if (css_percent_completed > this._MaxProgressBarWidth) {473 css_percent_completed = this._MaxProgressBarWidth;323 if (css_percent_completed > Torrent._MaxProgressBarWidth) { 324 css_percent_completed = Torrent._MaxProgressBarWidth; 474 325 } 475 326 476 327 // Add the progress bar 477 if (int_percent_completed < 100 && this.state() != "seeding") {478 479 // Add the decimals if the percentage is an integer480 if ((this._percent_completed % 1) == 0) {481 this._percent_completed = this._percent_completed + '.00';482 }328 if (int_percent_completed < 100 && this.state() != "seeding") 329 { 330 // Add the decimals if the percentage is an integer 331 if ((this._percent_completed % 1) == 0) { 332 this._percent_completed = this._percent_completed + '.00'; 333 } 483 334 // Create the 'progress details' label 484 335 // Eg: '101 MB of 631 MB (16.02%) - 2 hr 30 min remaining' … … 486 337 progress_details += Math.formatBytes(this._size) + ' ('; 487 338 progress_details += this._percent_completed + '%)'; 488 if ((this._eta < 0 || this._eta >= this._InfiniteTimeRemaining) && this.isActive()) {339 if ((this._eta < 0 || this._eta >= Torrent._InfiniteTimeRemaining) && this.isActive()) { 489 340 progress_details += ' - remaining time unknown'; 490 341 } else if (this.isActive()) { … … 494 345 // Update the 'in progress' bar 495 346 var class_name = (this.isActive()) ? 'in_progress' : 'incomplete_stopped'; 496 this._progress_complete_container.removeClass();497 this._progress_complete_container.addClass('torrent_progress_bar');498 this._progress_complete_container.addClass(class_name);499 this._progress_complete_container.css('width', css_percent_completed + '%');347 root._progress_complete_container.removeClass(); 348 root._progress_complete_container.addClass('torrent_progress_bar'); 349 root._progress_complete_container.addClass(class_name); 350 root._progress_complete_container.css('width', css_percent_completed + '%'); 500 351 501 352 // Update the 'incomplete' bar 502 if (! this._progress_incomplete_container.is('.incomplete')) { 503 this._progress_incomplete_container.removeClass(); 504 this._progress_incomplete_container.addClass('torrent_progress_bar'); 505 this._progress_incomplete_container.addClass('in_progress'); 353 if (! root._progress_incomplete_container.is('.incomplete')) { 354 root._progress_incomplete_container.removeClass(); 355 root._progress_incomplete_container.addClass('torrent_progress_bar in_progress'); 506 356 } 507 this._progress_incomplete_container.css('width', (this._MaxProgressBarWidth - css_percent_completed) + '%');508 this._progress_incomplete_container.show();357 root._progress_incomplete_container.css('width', (Torrent._MaxProgressBarWidth - css_percent_completed) + '%'); 358 root._progress_incomplete_container.show(); 509 359 510 360 // Create the 'peer details' label 511 361 // Eg: 'Downloading from 36 of 40 peers - DL: 60.2 KB/s UL: 4.3 KB/s' 512 &nbs
