Changeset 401
- Timestamp:
- 07/02/08 08:17:50 (2 months ago)
- Files:
-
- branches/rpc/web/javascript/common.js (modified) (1 diff)
- branches/rpc/web/javascript/torrent.js (modified) (15 diffs)
- branches/rpc/web/javascript/transmission.js (modified) (4 diffs)
- branches/rpc/web/javascript/transmission.remote.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/rpc/web/javascript/common.js
r400 r401 254 254 } 255 255 256 /** 257 * @brief strcmp()-style compare useful for sorting 258 */ 259 String.prototype.compareTo = function( that ) { 260 // FIXME: how to fold these two comparisons together? 261 if( this < that ) return -1; 262 if( this > that ) return 1; 263 return 0; 264 } 265 266 256 267 /*** 257 268 **** Preferences branches/rpc/web/javascript/torrent.js
r400 r401 12 12 13 13 // Constants 14 Torrent._Status Seeding = 'seeding';15 Torrent._Status Downloading = 'downloading';16 Torrent._Status Paused = 'paused';17 Torrent._Status Checking = 'verifying local data';18 Torrent._Status WaitingToCheck = 'waiting to verify';14 Torrent._StatusWaitingToCheck = 1; 15 Torrent._StatusChecking = 2; 16 Torrent._StatusDownloading = 4; 17 Torrent._StatusSeeding = 8; 18 Torrent._StatusPaused = 16; 19 19 Torrent._InfiniteTimeRemaining = 215784000; // 999 Hours - may as well be infinite 20 20 Torrent._MaxProgressBarWidth = 100; // reduce this to make the progress bar shorter (%) … … 132 132 size: function() { return this._size; }, 133 133 state: function() { return this._state; }, 134 stateStr: function() { 135 switch( this.state() ) { 136 case Torrent._StatusSeeding: return 'Seeding'; 137 case Torrent._StatusDownloading: return 'Downloading'; 138 case Torrent._StatusPaused: return 'Paused'; 139 case Torrent._StatusChecking: return 'Verifying local data'; 140 case Torrent._StatusWaitingToCheck: return 'Waiting to verify'; 141 default: return 'error'; 142 } 143 }, 134 144 swarmSpeed: function() { return this._swarm_speed; }, 135 145 totalLeechers: function() { return this._total_leechers; }, … … 207 217 * Process a click event on the pause/resume button 208 218 */ 209 clickPauseResumeButton: function(event) { 210 // Prevents click event resulting in selection of torrent 219 clickPauseResumeButton: function( event ) 220 { 221 // prevent click event resulting in selection of torrent 211 222 event.stopPropagation(); 223 224 // either stop or start the torrent 212 225 var torrent = event.data.element._torrent; 213 214 var action; 215 var name; 216 if( torrent.isActive( ) ) { 217 name = "torrent_pause"; 218 action = 'pauseTorrents'; 219 } else { 220 name = "torrent_resume"; 221 action = 'resumeTorrents'; 222 } 223 224 torrent._element._pause_resume_button_image[0].style.className = name; 225 // Send an ajax request to perform the action 226 torrent._controller.remote.request(action, $.toJSON([torrent._id])); 226 if( torrent.isActive( ) ) 227 torrent._controller.stopTorrent( torrent ); 228 else 229 torrent._controller.startTorrent( torrent ); 227 230 }, 228 231 … … 244 247 { 245 248 // These variables never change after the inital load 246 if (data.name) this._name = data.name;247 249 if (data.isPrivate) this._is_private = data.isPrivate; 248 250 if (data.hashString) this._hashString = data.hashString; … … 254 256 if (data.dateCreated) this._creator_date = data.dateCreated; 255 257 if (data.path) this._torrent_file = data.path;//FIXME 258 if (data.name) { 259 this._name = data.name; 260 this._name_lc = this._name.toLowerCase( ); 261 } 256 262 257 263 // Set the regularly-changing torrent variables … … 272 278 this._total_leechers = data.leechers; 273 279 this._total_seeders = data.seeders; 274 275 switch( data.status ) { 276 case 1: this._state = Torrent._StatusWaitingToCheck; break; 277 case 2: this._state = Torrent._StatusChecking; break; 278 case 4: this._state = Torrent._StatusDownloading; break; 279 case 8: this._state = Torrent._StatusSeeding; break; 280 case 16: this._state = Torrent._StatusPaused; break; 281 } 282 283 this._is_running = this._state != Torrent._StatusPaused; 280 this._state = data.status; 284 281 285 282 // Get -1 returned sometimes (maybe torrents with errors?) … … 299 296 300 297 // Figure out the percent completed 301 var percent _completed= Math.min( 1.0, ( this._completed / this._size ) );302 var css_completed_width = Math.floor( percent _completed* Torrent._MaxProgressBarWidth );298 var percent = Math.min( 1.0, ( this._completed / this._size ) ); 299 var css_completed_width = Math.floor( percent * Torrent._MaxProgressBarWidth ); 303 300 304 301 // Add the progress bar … … 306 303 if( notDone ) 307 304 { 305 var eta = ''; 306 307 if( this.isActive( ) ) 308 { 309 eta = '-'; 310 if (this._eta < 0 || this._eta >= Torrent._InfiniteTimeRemaining ) 311 eta += 'remaining time unknown'; 312 else 313 eta += Math.formatSeconds(this._eta) + ' remaining'; 314 } 315 308 316 // Create the 'progress details' label 309 // Eg: '101 MB of 631 MB (16.02%) - 2 hr 30 min remaining' 310 progress_details = Math.formatBytes(this._completed) + ' of '; 311 progress_details += Math.formatBytes(this._size) + ' ('; 312 progress_details += Math.ratio( this._completed, this._size ) + '%)'; 313 if ((this._eta < 0 || this._eta >= Torrent._InfiniteTimeRemaining) && this.isActive()) { 314 progress_details += ' - remaining time unknown'; 315 } else if (this.isActive()) { 316 progress_details += ' - ' + Math.formatSeconds(this._eta) + ' remaining'; 317 } 317 // Eg: '101 MB of 631 MB (16.02%) - 2 hr remaining' 318 progress_details = Math.formatBytes( this._completed ) 319 + ' of ' 320 + Math.formatBytes( this._size ) 321 + ' (' 322 + Math.ratio( this._completed, this._size ) 323 + '%)' 324 + eta; 318 325 319 326 // Update the 'in progress' bar 320 327 var class_name = (this.isActive()) ? 'in_progress' : 'incomplete_stopped'; 321 root._progress_complete_container.removeClass(); 322 root._progress_complete_container.addClass('torrent_progress_bar'); 323 root._progress_complete_container.addClass(class_name); 324 root._progress_complete_container.css('width', css_completed_width + '%'); 328 var e = root._progress_complete_container; 329 e.removeClass(); 330 e.addClass('torrent_progress_bar'); 331 e.addClass(class_name); 332 e.css('width', css_completed_width + '%'); 325 333 326 334 // Update the 'incomplete' bar 327 if (! root._progress_incomplete_container.is('.incomplete')) { 328 root._progress_incomplete_container.removeClass(); 329 root._progress_incomplete_container.addClass('torrent_progress_bar in_progress'); 335 e = root._progress_incomplete_container; 336 if( !e.is('.incomplete')) { 337 e.removeClass(); 338 e.addClass('torrent_progress_bar in_progress'); 330 339 } 331 root._progress_incomplete_container.css('width', (Torrent._MaxProgressBarWidth - css_completed_width) + '%');332 root._progress_incomplete_container.show();340 e.css('width', (Torrent._MaxProgressBarWidth - css_completed_width) + '%'); 341 e.show(); 333 342 334 343 // Create the 'peer details' label 335 344 // Eg: 'Downloading from 36 of 40 peers - DL: 60.2 KB/s UL: 4.3 KB/s' 336 if (this._state == Torrent._StatusChecking) { 337 peer_details = 'Checking existing files'; 338 339 } else if (this._state == Torrent._StatusWaitingToCheck) { 340 peer_details = 'Waiting to check existing files'; 341 342 } else { 343 peer_details = 'Downloading from ' + this._peers_downloading + ' of '; 344 peer_details += this._peers_total + ' peers - DL: '; 345 peer_details += Math.formatBytes(this._download_speed) + '/s UL: '; 346 peer_details += Math.formatBytes(this._upload_speed) + '/s'; 345 if( !this.isDownloading( ) ) 346 peer_details = this.stateStr( ); 347 else { 348 peer_details = 'Downloading from ' 349 + this._peers_downloading 350 + ' of ' 351 + this._peers_total 352 + ' peers - DL: ' 353 + Math.formatBytes(this._download_speed) 354 + '/s UL: ' 355 + Math.formatBytes(this._upload_speed) 356 + '/s'; 347 357 } 348 358 349 } else { 350 359 } 360 else 361 { 351 362 // Update the 'in progress' bar 352 363 var class_name = (this.isActive()) ? 'complete' : 'complete_stopped'; 353 root._progress_complete_container.removeClass(); 354 root._progress_complete_container.addClass('torrent_progress_bar ' + class_name ); 364 var e = root._progress_complete_container; 365 e.removeClass(); 366 e.addClass('torrent_progress_bar ' + class_name ); 355 367 356 368 // Create the 'progress details' label 357 369 // Eg: '698.05 MB, uploaded 8.59 GB (Ratio: 12.3)' 358 progress_details = Math.formatBytes(this._size) + ', uploaded '; 359 progress_details += Math.formatBytes(this._upload_total) + ' (Ratio '; 360 progress_details += Math.ratio(this._completed, this._size) + ')'; 370 progress_details = Math.formatBytes( this._size ) 371 + ', uploaded '; 372 + Math.formatBytes( this._upload_total ) 373 + ' (Ratio ' 374 + Math.ratio( this._upload_total, this._download_total ) 375 + ')'; 361 376 362 377 // Hide the 'incomplete' bar … … 368 383 // Create the 'peer details' label 369 384 // Eg: 'Seeding to 13 of 22 peers - UL: 36.2 KB/s' 370 peer_details = 'Seeding to ' + this._peers_uploading + ' of '; 371 peer_details += this._peers_total + ' peers - UL: '; 372 peer_details += Math.formatBytes(this._upload_speed) + '/s'; 385 if( !this.isSeeding( ) ) 386 peer_details = this.stateStr( ); 387 else 388 peer_details = 'Seeding to ' 389 + this._peers_uploading 390 + ' of ' 391 + this._peers_total 392 + ' peers - UL: ' 393 + Math.formatBytes(this._upload_speed) 394 + '/s'; 373 395 } 374 396 … … 377 399 378 400 // Update the peer details and pause/resume button 379 if (this._state == Torrent._StatusPaused ) {380 peer_details = 'Paused';381 root._pause_resume_button_image[0].alt = 'Resume';382 root._pause_resume_button_image[0].className = "torrent_resume";401 e = root._pause_resume_button_image[0]; 402 if ( this.state() == Torrent._StatusPaused ) { 403 e.alt = 'Resume'; 404 e.className = "torrent_resume"; 383 405 } else { 384 root._pause_resume_button_image[0].alt = 'Pause'; 385 root._pause_resume_button_image[0].className = "torrent_pause"; 386 } 387 388 if (this._error_message && this._error_message != '' && this._error_message != 'other' ) { 406 e.alt = 'Pause'; 407 e.className = "torrent_pause"; 408 } 409 410 if( this._error_message && 411 this._error_message != '' && 412 this._error_message != 'other' ) { 389 413 peer_details = this._error_message; 390 414 } … … 432 456 return pass; 433 457 434 var pos = this. name().toLowerCase().indexOf( search.toLowerCase() );458 var pos = this._name_lc.indexOf( search.toLowerCase() ); 435 459 pass = pos != -1; 436 460 return pass; … … 450 474 /** Helper function for sortTorrents(). */ 451 475 Torrent.compareByName = function( a, b ) { 452 // FIXME: how to fold these two comparisons together? 453 if( a.name() < b.name() ) return -1; 454 if( a.name() > b.name() ) return 1; 455 return 0; 476 return a._name_lc.compareTo( b._name_lc ); 477 }; 478 479 /** Helper function for sortTorrents(). */ 480 Torrent.compareByTracker = function( a, b ) { 481 return a._tracker.compareTo( b._tracker ); 482 }; 483 484 /** Helper function for sortTorrents(). */ 485 Torrent.compareByState = function( a, b ) { 486 return a.state() - b.state(); 456 487 }; 457 488 … … 461 492 }; 462 493 494 /** Helper function for sortTorrents(). */ 495 Torrent.compareByProgress = function( a, b ) { 496 var a_prog = Math.ratio( a._completed, a._size ); 497 var b_prog = Math.ratio( b._completed, b._size ); 498 if( a_prog !== b_prog ) 499 return a_prog - b_prog; 500 var a_ratio = Math.ratio( a._upload_total, a._download_total ); 501 var b_ratio = Math.ratio( b._upload_total, b._download_total ); 502 return a_ratio - b_ratio; 503 } 463 504 464 505 /** … … 472 513 { 473 514 case Prefs._SortByActivity: 474 torrents.sort( this.compareByAge);515 torrents.sort( this.compareByActivity ); 475 516 break; 476 517 case Prefs._SortByAge: 477 torrents.sort( this.compareByAge);518 torrents.sort( this.compareByAge ); 478 519 break; 479 520 case Prefs._SortByQueue: 480 torrents.sort( this.compareById);521 torrents.sort( this.compareById ); 481 522 break; 482 523 case Prefs._SortByProgress: 483 // FIXME 524 torrents.sort( this.compareByProgress ); 525 break; 484 526 case Prefs._SortByState: 485 // FIXME 527 torrents.sort( this.compareByState ); 528 break; 486 529 case Prefs._SortByTracker: 487 // FIXME 530 torrents.sort( this.compareByTracker ); 531 break; 488 532 case Prefs._SortByName: 489 torrents.sort( this.compareByName);533 torrents.sort( this.compareByName ); 490 534 break; 491 535 default: … … 501 545 502 546 /** 547 * @brief fast binary search to find a torrent 503 548 * @param torrents an array of torrents sorted by Id 504 549 * @param id the id to search for branches/rpc/web/javascript/transmission.js
r400 r401 853 853 total_swarm_speed += t.swarmSpeed(); 854 854 if( total_state == null ) 855 total_state = t.state ();856 else if ( total_state.search ( t.state () ) == -1 )857 total_state += '/' + t.state ();855 total_state = t.stateStr(); 856 else if ( total_state.search ( t.stateStr() ) == -1 ) 857 total_state += '/' + t.stateStr(); 858 858 var tracker = t._tracker; 859 859 if ( total_tracker.search ( tracker ) == -1 ) … … 1119 1119 var torrent = torrents[0]; 1120 1120 var header = 'Remove ' + torrent.name() + '?'; 1121 var message = 'The torrent \"' + torrent.name() + '\" is ' + torrent.state ();1121 var message = 'The torrent \"' + torrent.name() + '\" is ' + torrent.stateStr(); 1122 1122 if( torrent._error_message && torrent._error_message != '' ) message += ', but reporting an error'; 1123 1123 message += '. Remove this torrent? '; … … 1144 1144 tr.startTorrents( tr.getAllTorrents( ) ); 1145 1145 }, 1146 startTorrent: function( torrent ) { 1147 this.startTorrents( [ torrent ] ); 1148 }, 1146 1149 startTorrents: function( torrents ) { 1147 1150 this.remote.startTorrents( torrents ); … … 1155 1158 var tr = transmission; 1156 1159 tr.stopTorrents( tr.getAllTorrents( ) ); 1160 }, 1161 stopTorrent: function( torrent ) { 1162 this.stopTorrents( [ torrent ] ); 1157 1163 }, 1158 1164 stopTorrents: function( torrents ) { branches/rpc/web/javascript/transmission.remote.js
r400 r401 39 39 40 40 /* 41 * Perform a generic remote request42 */43 request: function(action, param ) {44 if (param == null) {45 param = '0';46 }47 48 $.ajax({49 type: 'GET',50 url: 'remote/index.php?action=' + action +51 '¶m=' + param,52 dataType: "script",53 error: this.ajaxError54 });55 },56 57 /*58 41 * Display an error if an ajax request fails, and stop sending requests 59 42 */ 60 43 ajaxError: function(request, error_string, exception) { 61 this._error = request.responseText ? request.responseText.trim().replace(/(<([^>]+)>)/ig,"") : ""; 62 if( this._error.length == 0 ) 44 this._error = request.responseText 45 ? request.responseText.trim().replace(/(<([^>]+)>)/ig,"") 46 : ""; 47 if( !this._error.length ) 63 48 this._error = 'Server not responding'; 64 49 … … 122 107 o.method = 'session-set'; 123 108 o.arguments = args; 124 $.post( RPC._Root, $.toJSON(o), function(){remote.loadDaemonPrefs();}, "json" ); 109 $.post( RPC._Root, $.toJSON(o), function(){ 110 remote.loadDaemonPrefs(); 111 }, "json" ); 125 112 }, 126 113 127 114 /* 128 115 * Upload Torrent by URL 129 */130 116 addTorrentByURL: function() { 131 117 $('#torrent_upload_form')[0].action = 'remote/index.php?action=addTorrentByURL¶m=[]'; 132 118 $('#torrent_upload_form').ajaxSubmit({dataType: 'script', type: 'POST'}); 133 119 }, 120 */ 134 121 };
