#6089: Beautified JavaScript (patch by skybon)
This commit is contained in:
parent
0fd932eaa5
commit
5569efc3d4
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"indent_size": 4,
|
||||
"indent_char": " ",
|
||||
"indent_level": 0,
|
||||
"indent_with_tabs": false,
|
||||
"preserve_newlines": true,
|
||||
"max_preserve_newlines": 2,
|
||||
"jslint_happy": true
|
||||
}
|
|
@ -10,91 +10,110 @@ var transmission,
|
|||
isMobileDevice = RegExp("(iPhone|iPod|Android)").test(navigator.userAgent),
|
||||
scroll_timeout;
|
||||
|
||||
if (!Array.indexOf){
|
||||
Array.prototype.indexOf = function(obj){
|
||||
var i, len;
|
||||
for (i=0, len=this.length; i<len; i++)
|
||||
if (this[i]==obj)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!Array.indexOf) {
|
||||
Array.prototype.indexOf = function (obj) {
|
||||
var i, len;
|
||||
for (i = 0, len = this.length; i < len; i++) {
|
||||
if (this[i] == obj) {
|
||||
return i;
|
||||
};
|
||||
};
|
||||
return -1;
|
||||
};
|
||||
};
|
||||
|
||||
// http://forum.jquery.com/topic/combining-ui-dialog-and-tabs
|
||||
$.fn.tabbedDialog = function (dialog_opts) {
|
||||
this.tabs({selected: 0});
|
||||
this.dialog(dialog_opts);
|
||||
this.find('.ui-tab-dialog-close').append(this.parent().find('.ui-dialog-titlebar-close'));
|
||||
this.find('.ui-tab-dialog-close').css({'position':'absolute','right':'0', 'top':'16px'});
|
||||
this.find('.ui-tab-dialog-close > a').css({'float':'none','padding':'0'});
|
||||
var tabul = this.find('ul:first');
|
||||
this.parent().addClass('ui-tabs').prepend(tabul).draggable('option','handle',tabul);
|
||||
this.siblings('.ui-dialog-titlebar').remove();
|
||||
tabul.addClass('ui-dialog-titlebar');
|
||||
this.tabs({
|
||||
selected: 0
|
||||
});
|
||||
this.dialog(dialog_opts);
|
||||
this.find('.ui-tab-dialog-close').append(this.parent().find('.ui-dialog-titlebar-close'));
|
||||
this.find('.ui-tab-dialog-close').css({
|
||||
'position': 'absolute',
|
||||
'right': '0',
|
||||
'top': '16px'
|
||||
});
|
||||
this.find('.ui-tab-dialog-close > a').css({
|
||||
'float': 'none',
|
||||
'padding': '0'
|
||||
});
|
||||
var tabul = this.find('ul:first');
|
||||
this.parent().addClass('ui-tabs').prepend(tabul).draggable('option', 'handle', tabul);
|
||||
this.siblings('.ui-dialog-titlebar').remove();
|
||||
tabul.addClass('ui-dialog-titlebar');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$(document).ready(function () {
|
||||
|
||||
// IE8 and below don’t support ES5 Date.now()
|
||||
if (!Date.now) {
|
||||
Date.now = function() {
|
||||
return +new Date();
|
||||
};
|
||||
}
|
||||
// IE8 and below don’t support ES5 Date.now()
|
||||
if (!Date.now) {
|
||||
Date.now = function () {
|
||||
return +new Date();
|
||||
};
|
||||
};
|
||||
|
||||
// IE specific fixes here
|
||||
if ($.browser.msie) {
|
||||
try {
|
||||
document.execCommand("BackgroundImageCache", false, true);
|
||||
} catch(err) {}
|
||||
$('.dialog_container').css('height',$(window).height()+'px');
|
||||
}
|
||||
// IE specific fixes here
|
||||
if ($.browser.msie) {
|
||||
try {
|
||||
document.execCommand("BackgroundImageCache", false, true);
|
||||
} catch (err) {};
|
||||
$('.dialog_container').css('height', $(window).height() + 'px');
|
||||
};
|
||||
|
||||
if ($.browser.safari) {
|
||||
// Move search field's margin down for the styled input
|
||||
$('#torrent_search').css('margin-top', 3);
|
||||
}
|
||||
if (isMobileDevice){
|
||||
window.onload = function(){ setTimeout(function() { window.scrollTo(0,1); },500); };
|
||||
window.onorientationchange = function(){ setTimeout(function() { window.scrollTo(0,1); },100); };
|
||||
if (window.navigator.standalone)
|
||||
// Fix min height for isMobileDevice when run in full screen mode from home screen
|
||||
// so the footer appears in the right place
|
||||
$('body div#torrent_container').css('min-height', '338px');
|
||||
$("label[for=torrent_upload_url]").text("URL: ");
|
||||
} else {
|
||||
// Fix for non-Safari-3 browsers: dark borders to replace shadows.
|
||||
$('div.dialog_container div.dialog_window').css('border', '1px solid #777');
|
||||
}
|
||||
if ($.browser.safari) {
|
||||
// Move search field's margin down for the styled input
|
||||
$('#torrent_search').css('margin-top', 3);
|
||||
};
|
||||
|
||||
// Initialise the dialog controller
|
||||
dialog = new Dialog();
|
||||
if (isMobileDevice) {
|
||||
window.onload = function () {
|
||||
setTimeout(function () {
|
||||
window.scrollTo(0, 1);
|
||||
}, 500);
|
||||
};
|
||||
window.onorientationchange = function () {
|
||||
setTimeout(function () {
|
||||
window.scrollTo(0, 1);
|
||||
}, 100);
|
||||
};
|
||||
if (window.navigator.standalone) {
|
||||
// Fix min height for isMobileDevice when run in full screen mode from home screen
|
||||
// so the footer appears in the right place
|
||||
$('body div#torrent_container').css('min-height', '338px');
|
||||
};
|
||||
$("label[for=torrent_upload_url]").text("URL: ");
|
||||
} else {
|
||||
// Fix for non-Safari-3 browsers: dark borders to replace shadows.
|
||||
$('div.dialog_container div.dialog_window').css('border', '1px solid #777');
|
||||
};
|
||||
|
||||
// Initialise the main Transmission controller
|
||||
transmission = new Transmission();
|
||||
// Initialise the dialog controller
|
||||
dialog = new Dialog();
|
||||
|
||||
// Initialise the main Transmission controller
|
||||
transmission = new Transmission();
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks to see if the content actually changed before poking the DOM.
|
||||
*/
|
||||
function setInnerHTML(e, html)
|
||||
{
|
||||
if (!e)
|
||||
return;
|
||||
function setInnerHTML(e, html) {
|
||||
if (!e) {
|
||||
return;
|
||||
};
|
||||
|
||||
/* innerHTML is listed as a string, but the browser seems to change it.
|
||||
* For example, "∞" gets changed to "∞" somewhere down the line.
|
||||
* So, let's use an arbitrary different field to test our state... */
|
||||
if (e.currentHTML != html)
|
||||
{
|
||||
e.currentHTML = html;
|
||||
e.innerHTML = html;
|
||||
}
|
||||
/* innerHTML is listed as a string, but the browser seems to change it.
|
||||
* For example, "∞" gets changed to "∞" somewhere down the line.
|
||||
* So, let's use an arbitrary different field to test our state... */
|
||||
if (e.currentHTML != html) {
|
||||
e.currentHTML = html;
|
||||
e.innerHTML = html;
|
||||
};
|
||||
};
|
||||
|
||||
function sanitizeText(text)
|
||||
{
|
||||
return text.replace(/</g, "<").replace(/>/g, ">");
|
||||
function sanitizeText(text) {
|
||||
return text.replace(/</g, "<").replace(/>/g, ">");
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -102,99 +121,100 @@ function sanitizeText(text)
|
|||
* on torrents whose state hasn't changed since the last update,
|
||||
* so see if the text actually changed before poking the DOM.
|
||||
*/
|
||||
function setTextContent(e, text)
|
||||
{
|
||||
if (e && (e.textContent != text))
|
||||
e.textContent = text;
|
||||
function setTextContent(e, text) {
|
||||
if (e && (e.textContent != text)) {
|
||||
e.textContent = text;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Given a numerator and denominator, return a ratio string
|
||||
*/
|
||||
Math.ratio = function(numerator, denominator) {
|
||||
var result = Math.floor(100 * numerator / denominator) / 100;
|
||||
Math.ratio = function (numerator, denominator) {
|
||||
var result = Math.floor(100 * numerator / denominator) / 100;
|
||||
|
||||
// check for special cases
|
||||
if (result==Number.POSITIVE_INFINITY || result==Number.NEGATIVE_INFINITY) result = -2;
|
||||
else if (isNaN(result)) result = -1;
|
||||
// check for special cases
|
||||
if (result == Number.POSITIVE_INFINITY || result == Number.NEGATIVE_INFINITY) {
|
||||
result = -2;
|
||||
} else if (isNaN(result)) {
|
||||
result = -1;
|
||||
};
|
||||
|
||||
return result;
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Round a string of a number to a specified number of decimal places
|
||||
*/
|
||||
Number.prototype.toTruncFixed = function(place) {
|
||||
var ret = Math.floor(this * Math.pow (10, place)) / Math.pow(10, place);
|
||||
return ret.toFixed(place);
|
||||
}
|
||||
Number.prototype.toTruncFixed = function (place) {
|
||||
var ret = Math.floor(this * Math.pow(10, place)) / Math.pow(10, place);
|
||||
return ret.toFixed(place);
|
||||
};
|
||||
|
||||
Number.prototype.toStringWithCommas = function() {
|
||||
Number.prototype.toStringWithCommas = function () {
|
||||
return this.toString().replace(/\B(?=(?:\d{3})+(?!\d))/g, ",");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Trim whitespace from a string
|
||||
*/
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s*/, "").replace(/\s*$/, "");
|
||||
}
|
||||
return this.replace(/^\s*/, "").replace(/\s*$/, "");
|
||||
};
|
||||
|
||||
/***
|
||||
**** Preferences
|
||||
***/
|
||||
**** Preferences
|
||||
***/
|
||||
|
||||
function Prefs() { }
|
||||
Prefs.prototype = { };
|
||||
function Prefs() {};
|
||||
Prefs.prototype = {};
|
||||
|
||||
Prefs._RefreshRate = 'refresh_rate';
|
||||
Prefs._RefreshRate = 'refresh_rate';
|
||||
|
||||
Prefs._FilterMode = 'filter';
|
||||
Prefs._FilterAll = 'all';
|
||||
Prefs._FilterActive = 'active';
|
||||
Prefs._FilterSeeding = 'seeding';
|
||||
Prefs._FilterDownloading = 'downloading';
|
||||
Prefs._FilterPaused = 'paused';
|
||||
Prefs._FilterFinished = 'finished';
|
||||
Prefs._FilterMode = 'filter';
|
||||
Prefs._FilterAll = 'all';
|
||||
Prefs._FilterActive = 'active';
|
||||
Prefs._FilterSeeding = 'seeding';
|
||||
Prefs._FilterDownloading = 'downloading';
|
||||
Prefs._FilterPaused = 'paused';
|
||||
Prefs._FilterFinished = 'finished';
|
||||
|
||||
Prefs._SortDirection = 'sort_direction';
|
||||
Prefs._SortAscending = 'ascending';
|
||||
Prefs._SortDescending = 'descending';
|
||||
Prefs._SortDirection = 'sort_direction';
|
||||
Prefs._SortAscending = 'ascending';
|
||||
Prefs._SortDescending = 'descending';
|
||||
|
||||
Prefs._SortMethod = 'sort_method';
|
||||
Prefs._SortByAge = 'age';
|
||||
Prefs._SortByActivity = 'activity';
|
||||
Prefs._SortByName = 'name';
|
||||
Prefs._SortByQueue = 'queue_order';
|
||||
Prefs._SortBySize = 'size';
|
||||
Prefs._SortByProgress = 'percent_completed';
|
||||
Prefs._SortByRatio = 'ratio';
|
||||
Prefs._SortByState = 'state';
|
||||
Prefs._SortMethod = 'sort_method';
|
||||
Prefs._SortByAge = 'age';
|
||||
Prefs._SortByActivity = 'activity';
|
||||
Prefs._SortByName = 'name';
|
||||
Prefs._SortByQueue = 'queue_order';
|
||||
Prefs._SortBySize = 'size';
|
||||
Prefs._SortByProgress = 'percent_completed';
|
||||
Prefs._SortByRatio = 'ratio';
|
||||
Prefs._SortByState = 'state';
|
||||
|
||||
Prefs._CompactDisplayState= 'compact_display_state';
|
||||
Prefs._CompactDisplayState = 'compact_display_state';
|
||||
|
||||
Prefs._Defaults =
|
||||
{
|
||||
'filter': 'all',
|
||||
'refresh_rate' : 5,
|
||||
'sort_direction': 'ascending',
|
||||
'sort_method': 'name',
|
||||
'turtle-state' : false,
|
||||
'compact_display_state' : false
|
||||
Prefs._Defaults = {
|
||||
'filter': 'all',
|
||||
'refresh_rate': 5,
|
||||
'sort_direction': 'ascending',
|
||||
'sort_method': 'name',
|
||||
'turtle-state': false,
|
||||
'compact_display_state': false
|
||||
};
|
||||
|
||||
/*
|
||||
* Set a preference option
|
||||
*/
|
||||
Prefs.setValue = function(key, val)
|
||||
{
|
||||
if (!(key in Prefs._Defaults))
|
||||
console.warn("unrecognized preference key '%s'", key);
|
||||
Prefs.setValue = function (key, val) {
|
||||
if (!(key in Prefs._Defaults)) {
|
||||
console.warn("unrecognized preference key '%s'", key);
|
||||
};
|
||||
|
||||
var date = new Date();
|
||||
date.setFullYear (date.getFullYear() + 1);
|
||||
document.cookie = key+"="+val+"; expires="+date.toGMTString()+"; path=/";
|
||||
var date = new Date();
|
||||
date.setFullYear(date.getFullYear() + 1);
|
||||
document.cookie = key + "=" + val + "; expires=" + date.toGMTString() + "; path=/";
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -203,26 +223,31 @@ Prefs.setValue = function(key, val)
|
|||
* @param key the preference's key
|
||||
* @param fallback if the option isn't set, return this instead
|
||||
*/
|
||||
Prefs.getValue = function(key, fallback)
|
||||
{
|
||||
var val;
|
||||
Prefs.getValue = function (key, fallback) {
|
||||
var val;
|
||||
|
||||
if (!(key in Prefs._Defaults))
|
||||
console.warn("unrecognized preference key '%s'", key);
|
||||
if (!(key in Prefs._Defaults)) {
|
||||
console.warn("unrecognized preference key '%s'", key);
|
||||
};
|
||||
|
||||
var lines = document.cookie.split(';');
|
||||
for (var i=0, len=lines.length; !val && i<len; ++i) {
|
||||
var line = lines[i].trim();
|
||||
var delim = line.indexOf('=');
|
||||
if ((delim === key.length) && line.indexOf(key) === 0)
|
||||
val = line.substring(delim + 1);
|
||||
}
|
||||
var lines = document.cookie.split(';');
|
||||
for (var i = 0, len = lines.length; !val && i < len; ++i) {
|
||||
var line = lines[i].trim();
|
||||
var delim = line.indexOf('=');
|
||||
if ((delim === key.length) && line.indexOf(key) === 0) {
|
||||
val = line.substring(delim + 1);
|
||||
};
|
||||
};
|
||||
|
||||
// FIXME: we support strings and booleans... add number support too?
|
||||
if (!val) val = fallback;
|
||||
else if (val === 'true') val = true;
|
||||
else if (val === 'false') val = false;
|
||||
return val;
|
||||
// FIXME: we support strings and booleans... add number support too?
|
||||
if (!val) {
|
||||
val = fallback;
|
||||
} else if (val === 'true') {
|
||||
val = true;
|
||||
} else if (val === 'false') {
|
||||
val = false;
|
||||
};
|
||||
return val;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -230,41 +255,40 @@ Prefs.getValue = function(key, fallback)
|
|||
*
|
||||
* @pararm o object to be populated (optional)
|
||||
*/
|
||||
Prefs.getClutchPrefs = function(o)
|
||||
{
|
||||
if (!o)
|
||||
o = { };
|
||||
for (var key in Prefs._Defaults)
|
||||
o[key] = Prefs.getValue(key, Prefs._Defaults[key]);
|
||||
return o;
|
||||
Prefs.getClutchPrefs = function (o) {
|
||||
if (!o) {
|
||||
o = {};
|
||||
};
|
||||
for (var key in Prefs._Defaults) {
|
||||
o[key] = Prefs.getValue(key, Prefs._Defaults[key]);
|
||||
};
|
||||
return o;
|
||||
};
|
||||
|
||||
|
||||
// forceNumeric() plug-in implementation
|
||||
jQuery.fn.forceNumeric = function () {
|
||||
return this.each(function () {
|
||||
$(this).keydown(function (e) {
|
||||
var key = e.which || e.keyCode;
|
||||
return !e.shiftKey && !e.altKey && !e.ctrlKey &&
|
||||
// numbers
|
||||
key >= 48 && key <= 57 ||
|
||||
// Numeric keypad
|
||||
key >= 96 && key <= 105 ||
|
||||
// comma, period and minus, . on keypad
|
||||
key === 190 || key === 188 || key === 109 || key === 110 ||
|
||||
// Backspace and Tab and Enter
|
||||
key === 8 || key === 9 || key === 13 ||
|
||||
// Home and End
|
||||
key === 35 || key === 36 ||
|
||||
// left and right arrows
|
||||
key === 37 || key === 39 ||
|
||||
// Del and Ins
|
||||
key === 46 || key === 45;
|
||||
});
|
||||
});
|
||||
return this.each(function () {
|
||||
$(this).keydown(function (e) {
|
||||
var key = e.which || e.keyCode;
|
||||
return !e.shiftKey && !e.altKey && !e.ctrlKey &&
|
||||
// numbers
|
||||
key >= 48 && key <= 57 ||
|
||||
// Numeric keypad
|
||||
key >= 96 && key <= 105 ||
|
||||
// comma, period and minus, . on keypad
|
||||
key === 190 || key === 188 || key === 109 || key === 110 ||
|
||||
// Backspace and Tab and Enter
|
||||
key === 8 || key === 9 || key === 13 ||
|
||||
// Home and End
|
||||
key === 35 || key === 36 ||
|
||||
// left and right arrows
|
||||
key === 37 || key === 39 ||
|
||||
// Del and Ins
|
||||
key === 46 || key === 45;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* http://blog.stevenlevithan.com/archives/parseuri
|
||||
*
|
||||
|
@ -272,31 +296,35 @@ jQuery.fn.forceNumeric = function () {
|
|||
* (c) Steven Levithan <stevenlevithan.com>
|
||||
* MIT License
|
||||
*/
|
||||
function parseUri (str) {
|
||||
var o = parseUri.options,
|
||||
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
|
||||
uri = {},
|
||||
i = 14;
|
||||
function parseUri(str) {
|
||||
var o = parseUri.options;
|
||||
var m = o.parser[o.strictMode ? "strict" : "loose"].exec(str);
|
||||
var uri = {};
|
||||
var i = 14;
|
||||
|
||||
while (i--) uri[o.key[i]] = m[i] || "";
|
||||
while (i--) {
|
||||
uri[o.key[i]] = m[i] || "";
|
||||
};
|
||||
|
||||
uri[o.q.name] = {};
|
||||
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
|
||||
if ($1) uri[o.q.name][$1] = $2;
|
||||
});
|
||||
uri[o.q.name] = {};
|
||||
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
|
||||
if ($1) {
|
||||
uri[o.q.name][$1] = $2;
|
||||
};
|
||||
});
|
||||
|
||||
return uri;
|
||||
return uri;
|
||||
};
|
||||
|
||||
parseUri.options = {
|
||||
strictMode: false,
|
||||
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
|
||||
q: {
|
||||
name: "queryKey",
|
||||
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
|
||||
},
|
||||
parser: {
|
||||
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
|
||||
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
|
||||
}
|
||||
strictMode: false,
|
||||
key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
|
||||
q: {
|
||||
name: "queryKey",
|
||||
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
|
||||
},
|
||||
parser: {
|
||||
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
|
||||
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,109 +5,107 @@
|
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
function Dialog(){
|
||||
this.initialize();
|
||||
}
|
||||
function Dialog() {
|
||||
this.initialize();
|
||||
};
|
||||
|
||||
Dialog.prototype = {
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
initialize: function() {
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
initialize: function () {
|
||||
|
||||
/*
|
||||
* Private Interface Variables
|
||||
*/
|
||||
this._container = $('#dialog_container');
|
||||
this._heading = $('#dialog_heading');
|
||||
this._message = $('#dialog_message');
|
||||
this._cancel_button = $('#dialog_cancel_button');
|
||||
this._confirm_button = $('#dialog_confirm_button');
|
||||
this._callback = null;
|
||||
/*
|
||||
* Private Interface Variables
|
||||
*/
|
||||
this._container = $('#dialog_container');
|
||||
this._heading = $('#dialog_heading');
|
||||
this._message = $('#dialog_message');
|
||||
this._cancel_button = $('#dialog_cancel_button');
|
||||
this._confirm_button = $('#dialog_confirm_button');
|
||||
this._callback = null;
|
||||
|
||||
// Observe the buttons
|
||||
this._cancel_button.bind('click', {dialog: this}, this.onCancelClicked);
|
||||
this._confirm_button.bind('click', {dialog: this}, this.onConfirmClicked);
|
||||
},
|
||||
// Observe the buttons
|
||||
this._cancel_button.bind('click', {
|
||||
dialog: this
|
||||
}, this.onCancelClicked);
|
||||
this._confirm_button.bind('click', {
|
||||
dialog: this
|
||||
}, this.onConfirmClicked);
|
||||
},
|
||||
|
||||
/*--------------------------------------------
|
||||
*
|
||||
* E V E N T F U N C T I O N S
|
||||
*
|
||||
*--------------------------------------------*/
|
||||
|
||||
hideDialog: function () {
|
||||
$('body.dialog_showing').removeClass('dialog_showing');
|
||||
this._container.hide();
|
||||
transmission.hideMobileAddressbar();
|
||||
transmission.updateButtonStates();
|
||||
},
|
||||
|
||||
onCancelClicked: function (event) {
|
||||
event.data.dialog.hideDialog();
|
||||
},
|
||||
|
||||
onConfirmClicked: function (event) {
|
||||
var dialog = event.data.dialog;
|
||||
dialog._callback();
|
||||
dialog.hideDialog();
|
||||
},
|
||||
|
||||
/*--------------------------------------------
|
||||
*
|
||||
* E V E N T F U N C T I O N S
|
||||
*
|
||||
*--------------------------------------------*/
|
||||
/*--------------------------------------------
|
||||
*
|
||||
* I N T E R F A C E F U N C T I O N S
|
||||
*
|
||||
*--------------------------------------------*/
|
||||
|
||||
hideDialog: function()
|
||||
{
|
||||
$('body.dialog_showing').removeClass('dialog_showing');
|
||||
this._container.hide();
|
||||
transmission.hideMobileAddressbar();
|
||||
transmission.updateButtonStates();
|
||||
},
|
||||
/*
|
||||
* Display a confirm dialog
|
||||
*/
|
||||
confirm: function (dialog_heading, dialog_message, confirm_button_label,
|
||||
callback, cancel_button_label) {
|
||||
if (!isMobileDevice) {
|
||||
$('.dialog_container').hide();
|
||||
};
|
||||
setTextContent(this._heading[0], dialog_heading);
|
||||
setTextContent(this._message[0], dialog_message);
|
||||
setTextContent(this._cancel_button[0], cancel_button_label || 'Cancel');
|
||||
setTextContent(this._confirm_button[0], confirm_button_label);
|
||||
this._confirm_button.show();
|
||||
this._callback = callback;
|
||||
$('body').addClass('dialog_showing');
|
||||
this._container.show();
|
||||
transmission.updateButtonStates();
|
||||
if (isMobileDevice) {
|
||||
transmission.hideMobileAddressbar();
|
||||
};
|
||||
},
|
||||
|
||||
onCancelClicked: function(event)
|
||||
{
|
||||
event.data.dialog.hideDialog();
|
||||
},
|
||||
|
||||
onConfirmClicked: function(event)
|
||||
{
|
||||
var dialog = event.data.dialog;
|
||||
dialog._callback();
|
||||
dialog.hideDialog();
|
||||
},
|
||||
|
||||
/*--------------------------------------------
|
||||
*
|
||||
* I N T E R F A C E F U N C T I O N S
|
||||
*
|
||||
*--------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Display a confirm dialog
|
||||
*/
|
||||
confirm: function(dialog_heading, dialog_message, confirm_button_label,
|
||||
callback, cancel_button_label)
|
||||
{
|
||||
if (!isMobileDevice)
|
||||
$('.dialog_container').hide();
|
||||
setTextContent(this._heading[0], dialog_heading);
|
||||
setTextContent(this._message[0], dialog_message);
|
||||
setTextContent(this._cancel_button[0], cancel_button_label || 'Cancel');
|
||||
setTextContent(this._confirm_button[0], confirm_button_label);
|
||||
this._confirm_button.show();
|
||||
this._callback = callback;
|
||||
$('body').addClass('dialog_showing');
|
||||
this._container.show();
|
||||
transmission.updateButtonStates();
|
||||
if (isMobileDevice)
|
||||
transmission.hideMobileAddressbar();
|
||||
},
|
||||
|
||||
/*
|
||||
* Display an alert dialog
|
||||
*/
|
||||
alert: function(dialog_heading, dialog_message, cancel_button_label) {
|
||||
if (!isMobileDevice)
|
||||
$('.dialog_container').hide();
|
||||
setTextContent(this._heading[0], dialog_heading);
|
||||
setTextContent(this._message[0], dialog_message);
|
||||
// jquery::hide() doesn't work here in Safari for some odd reason
|
||||
this._confirm_button.css('display', 'none');
|
||||
setTextContent(this._cancel_button[0], cancel_button_label);
|
||||
// Just in case
|
||||
$('#upload_container').hide();
|
||||
$('#move_container').hide();
|
||||
$('body').addClass('dialog_showing');
|
||||
transmission.updateButtonStates();
|
||||
if (isMobileDevice)
|
||||
transmission.hideMobileAddressbar();
|
||||
this._container.show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
* Display an alert dialog
|
||||
*/
|
||||
alert: function (dialog_heading, dialog_message, cancel_button_label) {
|
||||
if (!isMobileDevice) {
|
||||
$('.dialog_container').hide();
|
||||
};
|
||||
setTextContent(this._heading[0], dialog_heading);
|
||||
setTextContent(this._message[0], dialog_message);
|
||||
// jquery::hide() doesn't work here in Safari for some odd reason
|
||||
this._confirm_button.css('display', 'none');
|
||||
setTextContent(this._cancel_button[0], cancel_button_label);
|
||||
// Just in case
|
||||
$('#upload_container').hide();
|
||||
$('#move_container').hide();
|
||||
$('body').addClass('dialog_showing');
|
||||
transmission.updateButtonStates();
|
||||
if (isMobileDevice) {
|
||||
transmission.hideMobileAddressbar();
|
||||
};
|
||||
this._container.show();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,190 +5,205 @@
|
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
function FileRow(torrent, depth, name, indices, even)
|
||||
{
|
||||
var fields = {
|
||||
have: 0,
|
||||
indices: [],
|
||||
isWanted: true,
|
||||
priorityLow: false,
|
||||
priorityNormal: false,
|
||||
priorityHigh: false,
|
||||
me: this,
|
||||
size: 0,
|
||||
torrent: null
|
||||
},
|
||||
function FileRow(torrent, depth, name, indices, even) {
|
||||
var fields = {
|
||||
have: 0,
|
||||
indices: [],
|
||||
isWanted: true,
|
||||
priorityLow: false,
|
||||
priorityNormal: false,
|
||||
priorityHigh: false,
|
||||
me: this,
|
||||
size: 0,
|
||||
torrent: null
|
||||
};
|
||||
|
||||
elements = {
|
||||
priority_low_button: null,
|
||||
priority_normal_button: null,
|
||||
priority_high_button: null,
|
||||
progress: null,
|
||||
root: null
|
||||
},
|
||||
var elements = {
|
||||
priority_low_button: null,
|
||||
priority_normal_button: null,
|
||||
priority_high_button: null,
|
||||
progress: null,
|
||||
root: null
|
||||
};
|
||||
|
||||
initialize = function(torrent, depth, name, indices, even) {
|
||||
fields.torrent = torrent;
|
||||
fields.indices = indices;
|
||||
createRow(torrent, depth, name, even);
|
||||
},
|
||||
var initialize = function (torrent, depth, name, indices, even) {
|
||||
fields.torrent = torrent;
|
||||
fields.indices = indices;
|
||||
createRow(torrent, depth, name, even);
|
||||
};
|
||||
|
||||
refreshWantedHTML = function()
|
||||
{
|
||||
var e = $(elements.root);
|
||||
e.toggleClass('skip', !fields.isWanted);
|
||||
e.toggleClass('complete', isDone());
|
||||
$(e[0].checkbox).prop('disabled', !isEditable());
|
||||
$(e[0].checkbox).prop('checked', fields.isWanted);
|
||||
},
|
||||
refreshProgressHTML = function()
|
||||
{
|
||||
var pct = 100 * (fields.size ? (fields.have / fields.size) : 1.0),
|
||||
c = [ Transmission.fmt.size(fields.have),
|
||||
' of ',
|
||||
Transmission.fmt.size(fields.size),
|
||||
' (',
|
||||
Transmission.fmt.percentString(pct),
|
||||
'%)' ].join('');
|
||||
setTextContent(elements.progress, c);
|
||||
},
|
||||
refreshImpl = function() {
|
||||
var i,
|
||||
file,
|
||||
have = 0,
|
||||
size = 0,
|
||||
wanted = false,
|
||||
low = false,
|
||||
normal = false,
|
||||
high = false;
|
||||
var refreshWantedHTML = function () {
|
||||
var e = $(elements.root);
|
||||
e.toggleClass('skip', !fields.isWanted);
|
||||
e.toggleClass('complete', isDone());
|
||||
$(e[0].checkbox).prop('disabled', !isEditable());
|
||||
$(e[0].checkbox).prop('checked', fields.isWanted);
|
||||
};
|
||||
|
||||
// loop through the file_indices that affect this row
|
||||
for (i=0; i<fields.indices.length; ++i) {
|
||||
file = fields.torrent.getFile (fields.indices[i]);
|
||||
have += file.bytesCompleted;
|
||||
size += file.length;
|
||||
wanted |= file.wanted;
|
||||
switch (file.priority) {
|
||||
case -1: low = true; break;
|
||||
case 0: normal = true; break;
|
||||
case 1: high = true; break;
|
||||
}
|
||||
}
|
||||
var refreshProgressHTML = function () {
|
||||
var pct = 100 * (fields.size ? (fields.have / fields.size) : 1.0)
|
||||
var c = [Transmission.fmt.size(fields.have), ' of ', Transmission.fmt.size(fields.size), ' (', Transmission.fmt.percentString(pct), '%)'].join('');
|
||||
setTextContent(elements.progress, c);
|
||||
};
|
||||
|
||||
if ((fields.have != have) || (fields.size != size)) {
|
||||
fields.have = have;
|
||||
fields.size = size;
|
||||
refreshProgressHTML();
|
||||
}
|
||||
var refreshImpl = function () {
|
||||
var i,
|
||||
file,
|
||||
have = 0,
|
||||
size = 0,
|
||||
wanted = false,
|
||||
low = false,
|
||||
normal = false,
|
||||
high = false;
|
||||
|
||||
if (fields.isWanted !== wanted) {
|
||||
fields.isWanted = wanted;
|
||||
refreshWantedHTML();
|
||||
}
|
||||
// loop through the file_indices that affect this row
|
||||
for (i = 0; i < fields.indices.length; ++i) {
|
||||
file = fields.torrent.getFile(fields.indices[i]);
|
||||
have += file.bytesCompleted;
|
||||
size += file.length;
|
||||
wanted |= file.wanted;
|
||||
switch (file.priority) {
|
||||
case -1:
|
||||
low = true;
|
||||
break;
|
||||
case 0:
|
||||
normal = true;
|
||||
break;
|
||||
case 1:
|
||||
high = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fields.priorityLow !== low) {
|
||||
fields.priorityLow = low;
|
||||
$(elements.priority_low_button).toggleClass('selected', low);
|
||||
}
|
||||
if ((fields.have != have) || (fields.size != size)) {
|
||||
fields.have = have;
|
||||
fields.size = size;
|
||||
refreshProgressHTML();
|
||||
}
|
||||
|
||||
if (fields.priorityNormal !== normal) {
|
||||
fields.priorityNormal = normal;
|
||||
$(elements.priority_normal_button).toggleClass('selected', normal);
|
||||
}
|
||||
if (fields.isWanted !== wanted) {
|
||||
fields.isWanted = wanted;
|
||||
refreshWantedHTML();
|
||||
}
|
||||
|
||||
if (fields.priorityHigh !== high) {
|
||||
fields.priorityHigh = high;
|
||||
$(elements.priority_high_button).toggleClass('selected', high);
|
||||
}
|
||||
},
|
||||
if (fields.priorityLow !== low) {
|
||||
fields.priorityLow = low;
|
||||
$(elements.priority_low_button).toggleClass('selected', low);
|
||||
}
|
||||
|
||||
isDone = function () {
|
||||
return fields.have >= fields.size;
|
||||
},
|
||||
isEditable = function () {
|
||||
return (fields.torrent.getFileCount()>1) && !isDone();
|
||||
},
|
||||
if (fields.priorityNormal !== normal) {
|
||||
fields.priorityNormal = normal;
|
||||
$(elements.priority_normal_button).toggleClass('selected', normal);
|
||||
}
|
||||
|
||||
createRow = function(torrent, depth, name, even) {
|
||||
var e, root, box;
|
||||
if (fields.priorityHigh !== high) {
|
||||
fields.priorityHigh = high;
|
||||
$(elements.priority_high_button).toggleClass('selected', high);
|
||||
}
|
||||
};
|
||||
|
||||
root = document.createElement('li');
|
||||
root.className = 'inspector_torrent_file_list_entry' + (even?'even':'odd');
|
||||
elements.root = root;
|
||||
var isDone = function () {
|
||||
return fields.have >= fields.size;
|
||||
};
|
||||
|
||||
e = document.createElement('input');
|
||||
e.type = 'checkbox';
|
||||
e.className = "file_wanted_control";
|
||||
e.title = 'Download file';
|
||||
$(e).change(function(ev){ fireWantedChanged( $(ev.currentTarget).prop('checked')); });
|
||||
root.checkbox = e;
|
||||
root.appendChild(e);
|
||||
var isEditable = function () {
|
||||
return (fields.torrent.getFileCount() > 1) && !isDone();
|
||||
};
|
||||
|
||||
e = document.createElement('div');
|
||||
e.className = 'file-priority-radiobox';
|
||||
box = e;
|
||||
var createRow = function (torrent, depth, name, even) {
|
||||
var e, root, box;
|
||||
|
||||
e = document.createElement('div');
|
||||
e.className = 'low';
|
||||
e.title = 'Low Priority';
|
||||
$(e).click(function(){ firePriorityChanged(-1); });
|
||||
elements.priority_low_button = e;
|
||||
box.appendChild(e);
|
||||
root = document.createElement('li');
|
||||
root.className = 'inspector_torrent_file_list_entry' + (even ? 'even' : 'odd');
|
||||
elements.root = root;
|
||||
|
||||
e = document.createElement('div');
|
||||
e.className = 'normal';
|
||||
e.title = 'Normal Priority';
|
||||
$(e).click(function(){ firePriorityChanged(0); });
|
||||
elements.priority_normal_button = e;
|
||||
box.appendChild(e);
|
||||
e = document.createElement('input');
|
||||
e.type = 'checkbox';
|
||||
e.className = "file_wanted_control";
|
||||
e.title = 'Download file';
|
||||
$(e).change(function (ev) {
|
||||
fireWantedChanged($(ev.currentTarget).prop('checked'));
|
||||
});
|
||||
root.checkbox = e;
|
||||
root.appendChild(e);
|
||||
|
||||
e = document.createElement('div');
|
||||
e.title = 'High Priority';
|
||||
e.className = 'high';
|
||||
$(e).click(function(){ firePriorityChanged(1); });
|
||||
elements.priority_high_button = e;
|
||||
box.appendChild(e);
|
||||
e = document.createElement('div');
|
||||
e.className = 'file-priority-radiobox';
|
||||
box = e;
|
||||
|
||||
root.appendChild(box);
|
||||
e = document.createElement('div');
|
||||
e.className = 'low';
|
||||
e.title = 'Low Priority';
|
||||
$(e).click(function () {
|
||||
firePriorityChanged(-1);
|
||||
});
|
||||
elements.priority_low_button = e;
|
||||
box.appendChild(e);
|
||||
|
||||
e = document.createElement('div');
|
||||
e.className = "inspector_torrent_file_list_entry_name";
|
||||
setTextContent(e, name);
|
||||
$(e).click(function(){ fireNameClicked(-1); });
|
||||
root.appendChild(e);
|
||||
e = document.createElement('div');
|
||||
e.className = 'normal';
|
||||
e.title = 'Normal Priority';
|
||||
$(e).click(function () {
|
||||
firePriorityChanged(0);
|
||||
});
|
||||
elements.priority_normal_button = e;
|
||||
box.appendChild(e);
|
||||
|
||||
e = document.createElement('div');
|
||||
e.className = "inspector_torrent_file_list_entry_progress";
|
||||
root.appendChild(e);
|
||||
$(e).click(function(){ fireNameClicked(-1); });
|
||||
elements.progress = e;
|
||||
e = document.createElement('div');
|
||||
e.title = 'High Priority';
|
||||
e.className = 'high';
|
||||
$(e).click(function () {
|
||||
firePriorityChanged(1);
|
||||
});
|
||||
elements.priority_high_button = e;
|
||||
box.appendChild(e);
|
||||
|
||||
$(root).css('margin-left', '' + (depth*16) + 'px');
|
||||
root.appendChild(box);
|
||||
|
||||
refreshImpl();
|
||||
return root;
|
||||
},
|
||||
e = document.createElement('div');
|
||||
e.className = "inspector_torrent_file_list_entry_name";
|
||||
setTextContent(e, name);
|
||||
$(e).click(function () {
|
||||
fireNameClicked(-1);
|
||||
});
|
||||
root.appendChild(e);
|
||||
|
||||
fireWantedChanged = function(do_want) {
|
||||
$(fields.me).trigger('wantedToggled',[ fields.indices, do_want ]);
|
||||
},
|
||||
firePriorityChanged = function(priority) {
|
||||
$(fields.me).trigger('priorityToggled',[ fields.indices, priority ]);
|
||||
},
|
||||
fireNameClicked = function() {
|
||||
$(fields.me).trigger('nameClicked',[ fields.me, fields.indices ]);
|
||||
};
|
||||
e = document.createElement('div');
|
||||
e.className = "inspector_torrent_file_list_entry_progress";
|
||||
root.appendChild(e);
|
||||
$(e).click(function () {
|
||||
fireNameClicked(-1);
|
||||
});
|
||||
elements.progress = e;
|
||||
|
||||
/***
|
||||
**** PUBLIC
|
||||
***/
|
||||
$(root).css('margin-left', '' + (depth * 16) + 'px');
|
||||
|
||||
this.getElement = function() {
|
||||
return elements.root;
|
||||
};
|
||||
this.refresh = function() {
|
||||
refreshImpl();
|
||||
};
|
||||
refreshImpl();
|
||||
return root;
|
||||
};
|
||||
|
||||
initialize(torrent, depth, name, indices, even);
|
||||
var fireWantedChanged = function (do_want) {
|
||||
$(fields.me).trigger('wantedToggled', [fields.indices, do_want]);
|
||||
};
|
||||
|
||||
var firePriorityChanged = function (priority) {
|
||||
$(fields.me).trigger('priorityToggled', [fields.indices, priority]);
|
||||
};
|
||||
|
||||
var fireNameClicked = function () {
|
||||
$(fields.me).trigger('nameClicked', [fields.me, fields.indices]);
|
||||
};
|
||||
|
||||
/***
|
||||
**** PUBLIC
|
||||
***/
|
||||
|
||||
this.getElement = function () {
|
||||
return elements.root;
|
||||
};
|
||||
this.refresh = function () {
|
||||
refreshImpl();
|
||||
};
|
||||
|
||||
initialize(torrent, depth, name, indices, even);
|
||||
};
|
||||
|
|
|
@ -5,309 +5,290 @@
|
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
Transmission.fmt = (function()
|
||||
{
|
||||
var speed_K = 1000;
|
||||
var speed_B_str = 'B/s';
|
||||
var speed_K_str = 'kB/s';
|
||||
var speed_M_str = 'MB/s';
|
||||
var speed_G_str = 'GB/s';
|
||||
var speed_T_str = 'TB/s';
|
||||
Transmission.fmt = (function () {
|
||||
var speed_K = 1000;
|
||||
var speed_B_str = 'B/s';
|
||||
var speed_K_str = 'kB/s';
|
||||
var speed_M_str = 'MB/s';
|
||||
var speed_G_str = 'GB/s';
|
||||
var speed_T_str = 'TB/s';
|
||||
|
||||
var size_K = 1000;
|
||||
var size_B_str = 'B';
|
||||
var size_K_str = 'kB';
|
||||
var size_M_str = 'MB';
|
||||
var size_G_str = 'GB';
|
||||
var size_T_str = 'TB';
|
||||
var size_K = 1000;
|
||||
var size_B_str = 'B';
|
||||
var size_K_str = 'kB';
|
||||
var size_M_str = 'MB';
|
||||
var size_G_str = 'GB';
|
||||
var size_T_str = 'TB';
|
||||
|
||||
var mem_K = 1024;
|
||||
var mem_B_str = 'B';
|
||||
var mem_K_str = 'KiB';
|
||||
var mem_M_str = 'MiB';
|
||||
var mem_G_str = 'GiB';
|
||||
var mem_T_str = 'TiB';
|
||||
var mem_K = 1024;
|
||||
var mem_B_str = 'B';
|
||||
var mem_K_str = 'KiB';
|
||||
var mem_M_str = 'MiB';
|
||||
var mem_G_str = 'GiB';
|
||||
var mem_T_str = 'TiB';
|
||||
|
||||
return {
|
||||
return {
|
||||
|
||||
updateUnits: function(u)
|
||||
{
|
||||
/*
|
||||
speed_K = u['speed-bytes'];
|
||||
speed_K_str = u['speed-units'][0];
|
||||
speed_M_str = u['speed-units'][1];
|
||||
speed_G_str = u['speed-units'][2];
|
||||
speed_T_str = u['speed-units'][3];
|
||||
/*
|
||||
* Format a percentage to a string
|
||||
*/
|
||||
percentString: function (x) {
|
||||
if (x < 10.0) {
|
||||
return x.toTruncFixed(2);
|
||||
} else if (x < 100.0) {
|
||||
return x.toTruncFixed(1);
|
||||
} else {
|
||||
return x.toTruncFixed(0);
|
||||
}
|
||||
},
|
||||
|
||||
size_K = u['size-bytes'];
|
||||
size_K_str = u['size-units'][0];
|
||||
size_M_str = u['size-units'][1];
|
||||
size_G_str = u['size-units'][2];
|
||||
size_T_str = u['size-units'][3];
|
||||
/*
|
||||
* Format a ratio to a string
|
||||
*/
|
||||
ratioString: function (x) {
|
||||
if (x === -1) {
|
||||
return "None";
|
||||
}
|
||||
if (x === -2) {
|
||||
return '∞';
|
||||
}
|
||||
return this.percentString(x);
|
||||
},
|
||||
|
||||
mem_K = u['memory-bytes'];
|
||||
mem_K_str = u['memory-units'][0];
|
||||
mem_M_str = u['memory-units'][1];
|
||||
mem_G_str = u['memory-units'][2];
|
||||
mem_T_str = u['memory-units'][3];
|
||||
*/
|
||||
},
|
||||
/**
|
||||
* Formats the a memory size into a human-readable string
|
||||
* @param {Number} bytes the filesize in bytes
|
||||
* @return {String} human-readable string
|
||||
*/
|
||||
mem: function (bytes) {
|
||||
if (bytes < mem_K)
|
||||
return [bytes, mem_B_str].join(' ');
|
||||
|
||||
/*
|
||||
* Format a percentage to a string
|
||||
*/
|
||||
percentString: function(x) {
|
||||
if (x < 10.0)
|
||||
return x.toTruncFixed(2);
|
||||
else if (x < 100.0)
|
||||
return x.toTruncFixed(1);
|
||||
else
|
||||
return x.toTruncFixed(0);
|
||||
},
|
||||
var convertedSize;
|
||||
var unit;
|
||||
|
||||
/*
|
||||
* Format a ratio to a string
|
||||
*/
|
||||
ratioString: function(x) {
|
||||
if (x === -1)
|
||||
return "None";
|
||||
if (x === -2)
|
||||
return '∞';
|
||||
return this.percentString(x);
|
||||
},
|
||||
if (bytes < Math.pow(mem_K, 2)) {
|
||||
convertedSize = bytes / mem_K;
|
||||
unit = mem_K_str;
|
||||
} else if (bytes < Math.pow(mem_K, 3)) {
|
||||
convertedSize = bytes / Math.pow(mem_K, 2);
|
||||
unit = mem_M_str;
|
||||
} else if (bytes < Math.pow(mem_K, 4)) {
|
||||
convertedSize = bytes / Math.pow(mem_K, 3);
|
||||
unit = mem_G_str;
|
||||
} else {
|
||||
convertedSize = bytes / Math.pow(mem_K, 4);
|
||||
unit = mem_T_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the a memory size into a human-readable string
|
||||
* @param {Number} bytes the filesize in bytes
|
||||
* @return {String} human-readable string
|
||||
*/
|
||||
mem: function(bytes)
|
||||
{
|
||||
if (bytes < mem_K)
|
||||
return [ bytes, mem_B_str ].join(' ');
|
||||
// try to have at least 3 digits and at least 1 decimal
|
||||
return convertedSize <= 9.995 ? [convertedSize.toTruncFixed(2), unit].join(' ') : [convertedSize.toTruncFixed(1), unit].join(' ');
|
||||
},
|
||||
|
||||
var convertedSize;
|
||||
var unit;
|
||||
/**
|
||||
* Formats the a disk capacity or file size into a human-readable string
|
||||
* @param {Number} bytes the filesize in bytes
|
||||
* @return {String} human-readable string
|
||||
*/
|
||||
size: function (bytes) {
|
||||
if (bytes < size_K) {
|
||||
return [bytes, size_B_str].join(' ');
|
||||
}
|
||||
|
||||
if (bytes < Math.pow(mem_K, 2))
|
||||
{
|
||||
convertedSize = bytes / mem_K;
|
||||
unit = mem_K_str;
|
||||
}
|
||||
else if (bytes < Math.pow(mem_K, 3))
|
||||
{
|
||||
convertedSize = bytes / Math.pow(mem_K, 2);
|
||||
unit = mem_M_str;
|
||||
}
|
||||
else if (bytes < Math.pow(mem_K, 4))
|
||||
{
|
||||
convertedSize = bytes / Math.pow(mem_K, 3);
|
||||
unit = mem_G_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedSize = bytes / Math.pow(mem_K, 4);
|
||||
unit = mem_T_str;
|
||||
}
|
||||
var convertedSize;
|
||||
var unit;
|
||||
|
||||
// try to have at least 3 digits and at least 1 decimal
|
||||
return convertedSize <= 9.995 ? [ convertedSize.toTruncFixed(2), unit ].join(' ')
|
||||
: [ convertedSize.toTruncFixed(1), unit ].join(' ');
|
||||
},
|
||||
if (bytes < Math.pow(size_K, 2)) {
|
||||
convertedSize = bytes / size_K;
|
||||
unit = size_K_str;
|
||||
} else if (bytes < Math.pow(size_K, 3)) {
|
||||
convertedSize = bytes / Math.pow(size_K, 2);
|
||||
unit = size_M_str;
|
||||
} else if (bytes < Math.pow(size_K, 4)) {
|
||||
convertedSize = bytes / Math.pow(size_K, 3);
|
||||
unit = size_G_str;
|
||||
} else {
|
||||
convertedSize = bytes / Math.pow(size_K, 4);
|
||||
unit = size_T_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the a disk capacity or file size into a human-readable string
|
||||
* @param {Number} bytes the filesize in bytes
|
||||
* @return {String} human-readable string
|
||||
*/
|
||||
size: function(bytes)
|
||||
{
|
||||
if (bytes < size_K)
|
||||
return [ bytes, size_B_str ].join(' ');
|
||||
// try to have at least 3 digits and at least 1 decimal
|
||||
return convertedSize <= 9.995 ? [convertedSize.toTruncFixed(2), unit].join(' ') : [convertedSize.toTruncFixed(1), unit].join(' ');
|
||||
},
|
||||
|
||||
var convertedSize;
|
||||
var unit;
|
||||
speedBps: function (Bps) {
|
||||
return this.speed(this.toKBps(Bps));
|
||||
},
|
||||
|
||||
if (bytes < Math.pow(size_K, 2))
|
||||
{
|
||||
convertedSize = bytes / size_K;
|
||||
unit = size_K_str;
|
||||
}
|
||||
else if (bytes < Math.pow(size_K, 3))
|
||||
{
|
||||
convertedSize = bytes / Math.pow(size_K, 2);
|
||||
unit = size_M_str;
|
||||
}
|
||||
else if (bytes < Math.pow(size_K, 4))
|
||||
{
|
||||
convertedSize = bytes / Math.pow(size_K, 3);
|
||||
unit = size_G_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedSize = bytes / Math.pow(size_K, 4);
|
||||
unit = size_T_str;
|
||||
}
|
||||
toKBps: function (Bps) {
|
||||
return Math.floor(Bps / speed_K);
|
||||
},
|
||||
|
||||
// try to have at least 3 digits and at least 1 decimal
|
||||
return convertedSize <= 9.995 ? [ convertedSize.toTruncFixed(2), unit ].join(' ')
|
||||
: [ convertedSize.toTruncFixed(1), unit ].join(' ');
|
||||
},
|
||||
speed: function (KBps) {
|
||||
var speed = KBps;
|
||||
|
||||
speedBps: function(Bps)
|
||||
{
|
||||
return this.speed(this.toKBps(Bps));
|
||||
},
|
||||
if (speed <= 999.95) { // 0 KBps to 999 K
|
||||
return [speed.toTruncFixed(0), speed_K_str].join(' ');
|
||||
}
|
||||
|
||||
toKBps: function(Bps)
|
||||
{
|
||||
return Math.floor(Bps / speed_K);
|
||||
},
|
||||
speed /= speed_K;
|
||||
|
||||
speed: function(KBps)
|
||||
{
|
||||
var speed = KBps;
|
||||
if (speed <= 99.995) { // 1 M to 99.99 M
|
||||
return [speed.toTruncFixed(2), speed_M_str].join(' ');
|
||||
}
|
||||
if (speed <= 999.95) { // 100 M to 999.9 M
|
||||
return [speed.toTruncFixed(1), speed_M_str].join(' ');
|
||||
}
|
||||
|
||||
if (speed <= 999.95) // 0 KBps to 999 K
|
||||
return [ speed.toTruncFixed(0), speed_K_str ].join(' ');
|
||||
// insane speeds
|
||||
speed /= speed_K;
|
||||
return [speed.toTruncFixed(2), speed_G_str].join(' ');
|
||||
},
|
||||
|
||||
speed /= speed_K;
|
||||
timeInterval: function (seconds) {
|
||||
var days = Math.floor(seconds / 86400),
|
||||
hours = Math.floor((seconds % 86400) / 3600),
|
||||
minutes = Math.floor((seconds % 3600) / 60),
|
||||
seconds = Math.floor(seconds % 60),
|
||||
d = days + ' ' + (days > 1 ? 'days' : 'day'),
|
||||
h = hours + ' ' + (hours > 1 ? 'hours' : 'hour'),
|
||||
m = minutes + ' ' + (minutes > 1 ? 'minutes' : 'minute'),
|
||||
s = seconds + ' ' + (seconds > 1 ? 'seconds' : 'second');
|
||||
|
||||
if (speed <= 99.995) // 1 M to 99.99 M
|
||||
return [ speed.toTruncFixed(2), speed_M_str ].join(' ');
|
||||
if (speed <= 999.95) // 100 M to 999.9 M
|
||||
return [ speed.toTruncFixed(1), speed_M_str ].join(' ');
|
||||
if (days) {
|
||||
if (days >= 4 || !hours) {
|
||||
return d;
|
||||
}
|
||||
return d + ', ' + h;
|
||||
}
|
||||
if (hours) {
|
||||
if (hours >= 4 || !minutes) {
|
||||
return h;
|
||||
}
|
||||
return h + ', ' + m;
|
||||
}
|
||||
if (minutes) {
|
||||
if (minutes >= 4 || !seconds) {
|
||||
return m;
|
||||
}
|
||||
return m + ', ' + s;
|
||||
}
|
||||
return s;
|
||||
},
|
||||
|
||||
// insane speeds
|
||||
speed /= speed_K;
|
||||
return [ speed.toTruncFixed(2), speed_G_str ].join(' ');
|
||||
},
|
||||
timestamp: function (seconds) {
|
||||
if (!seconds) {
|
||||
return 'N/A';
|
||||
}
|
||||
|
||||
timeInterval: function(seconds)
|
||||
{
|
||||
var days = Math.floor (seconds / 86400),
|
||||
hours = Math.floor ((seconds % 86400) / 3600),
|
||||
minutes = Math.floor ((seconds % 3600) / 60),
|
||||
seconds = Math.floor (seconds % 60),
|
||||
d = days + ' ' + (days > 1 ? 'days' : 'day'),
|
||||
h = hours + ' ' + (hours > 1 ? 'hours' : 'hour'),
|
||||
m = minutes + ' ' + (minutes > 1 ? 'minutes' : 'minute'),
|
||||
s = seconds + ' ' + (seconds > 1 ? 'seconds' : 'second');
|
||||
var myDate = new Date(seconds * 1000);
|
||||
var now = new Date();
|
||||
|
||||
if (days) {
|
||||
if (days >= 4 || !hours)
|
||||
return d;
|
||||
return d + ', ' + h;
|
||||
}
|
||||
if (hours) {
|
||||
if (hours >= 4 || !minutes)
|
||||
return h;
|
||||
return h + ', ' + m;
|
||||
}
|
||||
if (minutes) {
|
||||
if (minutes >= 4 || !seconds)
|
||||
return m;
|
||||
return m + ', ' + s;
|
||||
}
|
||||
return s;
|
||||
},
|
||||
var date = "";
|
||||
var time = "";
|
||||
|
||||
timestamp: function(seconds)
|
||||
{
|
||||
if (!seconds)
|
||||
return 'N/A';
|
||||
var sameYear = now.getFullYear() === myDate.getFullYear();
|
||||
var sameMonth = now.getMonth() === myDate.getMonth();
|
||||
|
||||
var myDate = new Date(seconds*1000);
|
||||
var now = new Date();
|
||||
var dateDiff = now.getDate() - myDate.getDate();
|
||||
if (sameYear && sameMonth && Math.abs(dateDiff) <= 1) {
|
||||
if (dateDiff === 0) {
|
||||
date = "Today";
|
||||
} else if (dateDiff === 1) {
|
||||
date = "Yesterday";
|
||||
} else {
|
||||
date = "Tomorrow";
|
||||
}
|
||||
} else {
|
||||
date = myDate.toDateString();
|
||||
}
|
||||
|
||||
var date = "";
|
||||
var time = "";
|
||||
var hours = myDate.getHours();
|
||||
var period = "AM";
|
||||
if (hours > 12) {
|
||||
hours = hours - 12;
|
||||
period = "PM";
|
||||
}
|
||||
if (hours === 0) {
|
||||
hours = 12;
|
||||
}
|
||||
if (hours < 10) {
|
||||
hours = "0" + hours;
|
||||
}
|
||||
var minutes = myDate.getMinutes();
|
||||
if (minutes < 10) {
|
||||
minutes = "0" + minutes;
|
||||
}
|
||||
var seconds = myDate.getSeconds();
|
||||
if (seconds < 10) {
|
||||
seconds = "0" + seconds;
|
||||
}
|
||||
|
||||
var sameYear = now.getFullYear() === myDate.getFullYear();
|
||||
var sameMonth = now.getMonth() === myDate.getMonth();
|
||||
time = [hours, minutes, seconds].join(':');
|
||||
|
||||
var dateDiff = now.getDate() - myDate.getDate();
|
||||
if (sameYear && sameMonth && Math.abs(dateDiff) <= 1){
|
||||
if (dateDiff === 0){
|
||||
date = "Today";
|
||||
}
|
||||
else if (dateDiff === 1){
|
||||
date = "Yesterday";
|
||||
}
|
||||
else{
|
||||
date = "Tomorrow";
|
||||
}
|
||||
}
|
||||
else{
|
||||
date = myDate.toDateString();
|
||||
}
|
||||
return [date, time, period].join(' ');
|
||||
},
|
||||
|
||||
var hours = myDate.getHours();
|
||||
var period = "AM";
|
||||
if (hours > 12){
|
||||
hours = hours - 12;
|
||||
period = "PM";
|
||||
}
|
||||
if (hours === 0){
|
||||
hours = 12;
|
||||
}
|
||||
if (hours < 10){
|
||||
hours = "0" + hours;
|
||||
}
|
||||
var minutes = myDate.getMinutes();
|
||||
if (minutes < 10){
|
||||
minutes = "0" + minutes;
|
||||
}
|
||||
var seconds = myDate.getSeconds();
|
||||
if (seconds < 10){
|
||||
seconds = "0" + seconds;
|
||||
}
|
||||
ngettext: function (msgid, msgid_plural, n) {
|
||||
// TODO(i18n): http://doc.qt.digia.com/4.6/i18n-plural-rules.html
|
||||
return n === 1 ? msgid : msgid_plural;
|
||||
},
|
||||
|
||||
time = [hours, minutes, seconds].join(':');
|
||||
countString: function (msgid, msgid_plural, n) {
|
||||
return [n.toStringWithCommas(), this.ngettext(msgid, msgid_plural, n)].join(' ');
|
||||
},
|
||||
|
||||
return [date, time, period].join(' ');
|
||||
},
|
||||
peerStatus: function (flagStr) {
|
||||
var formattedFlags = [];
|
||||
for (var i = 0, flag; flag = flagStr[i]; ++i) {
|
||||
var explanation = null;
|
||||
switch (flag) {
|
||||
case "O":
|
||||
explanation = "Optimistic unchoke";
|
||||
break;
|
||||
case "D":
|
||||
explanation = "Downloading from this peer";
|
||||
break;
|
||||
case "d":
|
||||
explanation = "We would download from this peer if they'd let us";
|
||||
break;
|
||||
case "U":
|
||||
explanation = "Uploading to peer";
|
||||
break;
|
||||
case "u":
|
||||
explanation = "We would upload to this peer if they'd ask";
|
||||
break;
|
||||
case "K":
|
||||
explanation = "Peer has unchoked us, but we're not interested";
|
||||
break;
|
||||
case "?":
|
||||
explanation = "We unchoked this peer, but they're not interested";
|
||||
break;
|
||||
case "E":
|
||||
explanation = "Encrypted Connection";
|
||||
break;
|
||||
case "H":
|
||||
explanation = "Peer was discovered through Distributed Hash Table (DHT)";
|
||||
break;
|
||||
case "X":
|
||||
explanation = "Peer was discovered through Peer Exchange (PEX)";
|
||||
break;
|
||||
case "I":
|
||||
explanation = "Peer is an incoming connection";
|
||||
break;
|
||||
case "T":
|
||||
explanation = "Peer is connected via uTP";
|
||||
break;
|
||||
};
|
||||
|
||||
ngettext: function(msgid, msgid_plural, n)
|
||||
{
|
||||
// TODO(i18n): http://doc.qt.digia.com/4.6/i18n-plural-rules.html
|
||||
return n === 1 ? msgid : msgid_plural;
|
||||
},
|
||||
if (!explanation) {
|
||||
formattedFlags.push(flag);
|
||||
} else {
|
||||
formattedFlags.push("<span title=\"" + flag + ': ' + explanation + "\">" + flag + "</span>");
|
||||
};
|
||||
};
|
||||
|
||||
countString: function(msgid, msgid_plural, n)
|
||||
{
|
||||
return [ n.toStringWithCommas(), this.ngettext(msgid,msgid_plural,n) ].join(' ');
|
||||
},
|
||||
|
||||
peerStatus: function( flagStr )
|
||||
{
|
||||
var formattedFlags = [];
|
||||
for (var i=0, flag; flag=flagStr[i]; ++i)
|
||||
{
|
||||
var explanation = null;
|
||||
switch (flag)
|
||||
{
|
||||
case "O": explanation = "Optimistic unchoke"; break;
|
||||
case "D": explanation = "Downloading from this peer"; break;
|
||||
case "d": explanation = "We would download from this peer if they'd let us"; break;
|
||||
case "U": explanation = "Uploading to peer"; break;
|
||||
case "u": explanation = "We would upload to this peer if they'd ask"; break;
|
||||
case "K": explanation = "Peer has unchoked us, but we're not interested"; break;
|
||||
case "?": explanation = "We unchoked this peer, but they're not interested"; break;
|
||||
case "E": explanation = "Encrypted Connection"; break;
|
||||
case "H": explanation = "Peer was discovered through Distributed Hash Table (DHT)"; break;
|
||||
case "X": explanation = "Peer was discovered through Peer Exchange (PEX)"; break;
|
||||
case "I": explanation = "Peer is an incoming connection"; break;
|
||||
case "T": explanation = "Peer is connected via uTP"; break;
|
||||
}
|
||||
|
||||
if (!explanation) {
|
||||
formattedFlags.push(flag);
|
||||
} else {
|
||||
formattedFlags.push("<span title=\"" + flag + ': ' + explanation + "\">" + flag + "</span>");
|
||||
}
|
||||
}
|
||||
return formattedFlags.join('');
|
||||
}
|
||||
}
|
||||
return formattedFlags.join('');
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,42 +1,42 @@
|
|||
var Notifications = {};
|
||||
|
||||
$(document).ready(function () {
|
||||
if (!window.webkitNotifications) {
|
||||
return;
|
||||
}
|
||||
if (!window.webkitNotifications) {
|
||||
return;
|
||||
};
|
||||
|
||||
var notificationsEnabled = (window.webkitNotifications.checkPermission() === 0),
|
||||
toggle = $('#toggle_notifications');
|
||||
var notificationsEnabled = (window.webkitNotifications.checkPermission() === 0)
|
||||
var toggle = $('#toggle_notifications');
|
||||
|
||||
toggle.show();
|
||||
updateMenuTitle();
|
||||
$(transmission).bind('downloadComplete seedingComplete', function (event, torrent) {
|
||||
if (notificationsEnabled) {
|
||||
var title = (event.type == 'downloadComplete' ? 'Download' : 'Seeding') + ' complete',
|
||||
content = torrent.getName(),
|
||||
notification;
|
||||
toggle.show();
|
||||
updateMenuTitle();
|
||||
$(transmission).bind('downloadComplete seedingComplete', function (event, torrent) {
|
||||
if (notificationsEnabled) {
|
||||
var title = (event.type == 'downloadComplete' ? 'Download' : 'Seeding') + ' complete',
|
||||
content = torrent.getName(),
|
||||
notification;
|
||||
|
||||
notification = window.webkitNotifications.createNotification('style/transmission/images/logo.png', title, content);
|
||||
notification.show();
|
||||
setTimeout(function () {
|
||||
notification.cancel();
|
||||
}, 5000);
|
||||
};
|
||||
});
|
||||
notification = window.webkitNotifications.createNotification('style/transmission/images/logo.png', title, content);
|
||||
notification.show();
|
||||
setTimeout(function () {
|
||||
notification.cancel();
|
||||
}, 5000);
|
||||
};
|
||||
});
|
||||
|
||||
function updateMenuTitle() {
|
||||
toggle.html((notificationsEnabled ? 'Disable' : 'Enable') + ' Notifications');
|
||||
}
|
||||
function updateMenuTitle() {
|
||||
toggle.html((notificationsEnabled ? 'Disable' : 'Enable') + ' Notifications');
|
||||
};
|
||||
|
||||
Notifications.toggle = function () {
|
||||
if (window.webkitNotifications.checkPermission() !== 0) {
|
||||
window.webkitNotifications.requestPermission(function () {
|
||||
notificationsEnabled = (window.webkitNotifications.checkPermission() === 0);
|
||||
updateMenuTitle();
|
||||
});
|
||||
} else {
|
||||
notificationsEnabled = !notificationsEnabled;
|
||||
updateMenuTitle();
|
||||
}
|
||||
};
|
||||
Notifications.toggle = function () {
|
||||
if (window.webkitNotifications.checkPermission() !== 0) {
|
||||
window.webkitNotifications.requestPermission(function () {
|
||||
notificationsEnabled = (window.webkitNotifications.checkPermission() === 0);
|
||||
updateMenuTitle();
|
||||
});
|
||||
} else {
|
||||
notificationsEnabled = !notificationsEnabled;
|
||||
updateMenuTitle();
|
||||
};
|
||||
};
|
||||
});
|
||||
|
|
|
@ -7,312 +7,296 @@
|
|||
|
||||
function PrefsDialog(remote) {
|
||||
|
||||
var data = {
|
||||
dialog: null,
|
||||
remote: null,
|
||||
elements: { },
|
||||
var data = {
|
||||
dialog: null,
|
||||
remote: null,
|
||||
elements: {},
|
||||
|
||||
// all the RPC session keys that we have gui controls for
|
||||
keys: [
|
||||
'alt-speed-down',
|
||||
'alt-speed-time-begin',
|
||||
'alt-speed-time-day',
|
||||
'alt-speed-time-enabled',
|
||||
'alt-speed-time-end',
|
||||
'alt-speed-up',
|
||||
'blocklist-enabled',
|
||||
'blocklist-size',
|
||||
'blocklist-url',
|
||||
'dht-enabled',
|
||||
'download-dir',
|
||||
'encryption',
|
||||
'idle-seeding-limit',
|
||||
'idle-seeding-limit-enabled',
|
||||
'lpd-enabled',
|
||||
'peer-limit-global',
|
||||
'peer-limit-per-torrent',
|
||||
'peer-port',
|
||||
'peer-port-random-on-start',
|
||||
'pex-enabled',
|
||||
'port-forwarding-enabled',
|
||||
'rename-partial-files',
|
||||
'seedRatioLimit',
|
||||
'seedRatioLimited',
|
||||
'speed-limit-down',
|
||||
'speed-limit-down-enabled',
|
||||
'speed-limit-up',
|
||||
'speed-limit-up-enabled',
|
||||
'start-added-torrents',
|
||||
'utp-enabled'
|
||||
],
|
||||
// all the RPC session keys that we have gui controls for
|
||||
keys: [
|
||||
'alt-speed-down',
|
||||
'alt-speed-time-begin',
|
||||
'alt-speed-time-day',
|
||||
'alt-speed-time-enabled',
|
||||
'alt-speed-time-end',
|
||||
'alt-speed-up',
|
||||
'blocklist-enabled',
|
||||
'blocklist-size',
|
||||
'blocklist-url',
|
||||
'dht-enabled',
|
||||
'download-dir',
|
||||
'encryption',
|
||||
'idle-seeding-limit',
|
||||
'idle-seeding-limit-enabled',
|
||||
'lpd-enabled',
|
||||
'peer-limit-global',
|
||||
'peer-limit-per-torrent',
|
||||
'peer-port',
|
||||
'peer-port-random-on-start',
|
||||
'pex-enabled',
|
||||
'port-forwarding-enabled',
|
||||
'rename-partial-files',
|
||||
'seedRatioLimit',
|
||||
'seedRatioLimited',
|
||||
'speed-limit-down',
|
||||
'speed-limit-down-enabled',
|
||||
'speed-limit-up',
|
||||
'speed-limit-up-enabled',
|
||||
'start-added-torrents',
|
||||
'utp-enabled'
|
||||
],
|
||||
|
||||
// map of keys that are enabled only if a 'parent' key is enabled
|
||||
groups: {
|
||||
'alt-speed-time-enabled': ['alt-speed-time-begin',
|
||||
'alt-speed-time-day',
|
||||
'alt-speed-time-end' ],
|
||||
'blocklist-enabled': ['blocklist-url',
|
||||
'blocklist-update-button' ],
|
||||
'idle-seeding-limit-enabled': [ 'idle-seeding-limit' ],
|
||||
'seedRatioLimited': [ 'seedRatioLimit' ],
|
||||
'speed-limit-down-enabled': [ 'speed-limit-down' ],
|
||||
'speed-limit-up-enabled': [ 'speed-limit-up' ]
|
||||
}
|
||||
},
|
||||
// map of keys that are enabled only if a 'parent' key is enabled
|
||||
groups: {
|
||||
'alt-speed-time-enabled': ['alt-speed-time-begin',
|
||||
'alt-speed-time-day',
|
||||
'alt-speed-time-end'
|
||||
],
|
||||
'blocklist-enabled': ['blocklist-url',
|
||||
'blocklist-update-button'
|
||||
],
|
||||
'idle-seeding-limit-enabled': ['idle-seeding-limit'],
|
||||
'seedRatioLimited': ['seedRatioLimit'],
|
||||
'speed-limit-down-enabled': ['speed-limit-down'],
|
||||
'speed-limit-up-enabled': ['speed-limit-up']
|
||||
}
|
||||
};
|
||||
|
||||
initTimeDropDown = function(e)
|
||||
{
|
||||
var i, hour, mins, value, content;
|
||||
var initTimeDropDown = function (e) {
|
||||
var i, hour, mins, value, content;
|
||||
|
||||
for (i=0; i<24*4; ++i) {
|
||||
hour = parseInt(i/4, 10);
|
||||
mins = ((i%4) * 15);
|
||||
value = i * 15;
|
||||
content = hour + ':' + (mins || '00');
|
||||
e.options[i] = new Option(content, value);
|
||||
}
|
||||
},
|
||||
for (i = 0; i < 24 * 4; ++i) {
|
||||
hour = parseInt(i / 4, 10);
|
||||
mins = ((i % 4) * 15);
|
||||
value = i * 15;
|
||||
content = hour + ':' + (mins || '00');
|
||||
e.options[i] = new Option(content, value);
|
||||
}
|
||||
};
|
||||
|
||||
onPortChecked = function(response)
|
||||
{
|
||||
var is_open = response['arguments']['port-is-open'],
|
||||
text = 'Port is <b>' + (is_open ? 'Open' : 'Closed') + '</b>',
|
||||
e = data.elements.root.find('#port-label');
|
||||
setInnerHTML(e[0],text);
|
||||
},
|
||||
var onPortChecked = function (response) {
|
||||
var is_open = response['arguments']['port-is-open'];
|
||||
var text = 'Port is <b>' + (is_open ? 'Open' : 'Closed') + '</b>';
|
||||
var e = data.elements.root.find('#port-label');
|
||||
setInnerHTML(e[0], text);
|
||||
};
|
||||
|
||||
setGroupEnabled = function(parent_key, enabled)
|
||||
{
|
||||
var i, key, keys, root;
|
||||
var setGroupEnabled = function (parent_key, enabled) {
|
||||
var i, key, keys, root;
|
||||
|
||||
if (parent_key in data.groups)
|
||||
{
|
||||
root = data.elements.root,
|
||||
keys = data.groups[parent_key];
|
||||
if (parent_key in data.groups) {
|
||||
root = data.elements.root;
|
||||
keys = data.groups[parent_key];
|
||||
|
||||
for (i=0; key=keys[i]; ++i)
|
||||
root.find('#'+key).attr('disabled',!enabled);
|
||||
}
|
||||
},
|
||||
for (i = 0; key = keys[i]; ++i) {
|
||||
root.find('#' + key).attr('disabled', !enabled);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
onBlocklistUpdateClicked = function ()
|
||||
{
|
||||
data.remote.updateBlocklist();
|
||||
setBlocklistButtonEnabled(false);
|
||||
},
|
||||
setBlocklistButtonEnabled = function(b)
|
||||
{
|
||||
var e = data.elements.blocklist_button;
|
||||
e.attr('disabled',!b);
|
||||
e.val(b ? 'Update' : 'Updating...');
|
||||
},
|
||||
var onBlocklistUpdateClicked = function () {
|
||||
data.remote.updateBlocklist();
|
||||
setBlocklistButtonEnabled(false);
|
||||
};
|
||||
|
||||
getValue = function(e)
|
||||
{
|
||||
var str;
|
||||
var setBlocklistButtonEnabled = function (b) {
|
||||
var e = data.elements.blocklist_button;
|
||||
e.attr('disabled', !b);
|
||||
e.val(b ? 'Update' : 'Updating...');
|
||||
};
|
||||
|
||||
switch (e[0].type)
|
||||
{
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
return e.prop('checked');
|
||||
var getValue = function (e) {
|
||||
var str;
|
||||
|
||||
case 'text':
|
||||
case 'url':
|
||||
case 'email':
|
||||
case 'number':
|
||||
case 'search':
|
||||
case 'select-one':
|
||||
str = e.val();
|
||||
if( parseInt(str,10).toString() === str)
|
||||
return parseInt(str,10);
|
||||
if( parseFloat(str).toString() === str)
|
||||
return parseFloat(str);
|
||||
return str;
|
||||
switch (e[0].type) {
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
return e.prop('checked');
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
case 'text':
|
||||
case 'url':
|
||||
case 'email':
|
||||
case 'number':
|
||||
case 'search':
|
||||
case 'select-one':
|
||||
str = e.val();
|
||||
if (parseInt(str, 10).toString() === str) {
|
||||
return parseInt(str, 10);
|
||||
};
|
||||
if (parseFloat(str).toString() === str) {
|
||||
return parseFloat(str);
|
||||
};
|
||||
return str;
|
||||
|
||||
/* this callback is for controls whose changes can be applied
|
||||
immediately, like checkboxs, radioboxes, and selects */
|
||||
onControlChanged = function(ev)
|
||||
{
|
||||
var o = {};
|
||||
o[ev.target.id] = getValue($(ev.target));
|
||||
data.remote.savePrefs(o);
|
||||
},
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/* these two callbacks are for controls whose changes can't be applied
|
||||
immediately -- like a text entry field -- because it takes many
|
||||
change events for the user to get to the desired result */
|
||||
onControlFocused = function(ev)
|
||||
{
|
||||
data.oldValue = getValue($(ev.target));
|
||||
},
|
||||
onControlBlurred = function(ev)
|
||||
{
|
||||
var newValue = getValue($(ev.target));
|
||||
if (newValue !== data.oldValue)
|
||||
{
|
||||
var o = {};
|
||||
o[ev.target.id] = newValue;
|
||||
data.remote.savePrefs(o);
|
||||
delete data.oldValue;
|
||||
}
|
||||
},
|
||||
/* this callback is for controls whose changes can be applied
|
||||
immediately, like checkboxs, radioboxes, and selects */
|
||||
var onControlChanged = function (ev) {
|
||||
var o = {};
|
||||
o[ev.target.id] = getValue($(ev.target));
|
||||
data.remote.savePrefs(o);
|
||||
};
|
||||
|
||||
getDefaultMobileOptions = function()
|
||||
{
|
||||
return {
|
||||
width: $(window).width(),
|
||||
height: $(window).height(),
|
||||
position: [ 'left', 'top' ]
|
||||
};
|
||||
},
|
||||
/* these two callbacks are for controls whose changes can't be applied
|
||||
immediately -- like a text entry field -- because it takes many
|
||||
change events for the user to get to the desired result */
|
||||
var onControlFocused = function (ev) {
|
||||
data.oldValue = getValue($(ev.target));
|
||||
};
|
||||
|
||||
initialize = function (remote)
|
||||
{
|
||||
var i, key, e, o;
|
||||
var onControlBlurred = function (ev) {
|
||||
var newValue = getValue($(ev.target));
|
||||
if (newValue !== data.oldValue) {
|
||||
var o = {};
|
||||
o[ev.target.id] = newValue;
|
||||
data.remote.savePrefs(o);
|
||||
delete data.oldValue;
|
||||
}
|
||||
};
|
||||
|
||||
data.remote = remote;
|
||||
var getDefaultMobileOptions = function () {
|
||||
return {
|
||||
width: $(window).width(),
|
||||
height: $(window).height(),
|
||||
position: ['left', 'top']
|
||||
};
|
||||
};
|
||||
|
||||
e = $('#prefs-dialog');
|
||||
data.elements.root = e;
|
||||
var initialize = function (remote) {
|
||||
var i, key, e, o;
|
||||
|
||||
initTimeDropDown(e.find('#alt-speed-time-begin')[0]);
|
||||
initTimeDropDown(e.find('#alt-speed-time-end')[0]);
|
||||
data.remote = remote;
|
||||
|
||||
o = isMobileDevice
|
||||
? getDefaultMobileOptions()
|
||||
: { width: 350, height: 400 };
|
||||
o.autoOpen = false;
|
||||
o.show = o.hide = 'fade';
|
||||
o.close = onDialogClosed;
|
||||
e.tabbedDialog(o);
|
||||
e = $('#prefs-dialog');
|
||||
data.elements.root = e;
|
||||
|
||||
e = e.find('#blocklist-update-button');
|
||||
data.elements.blocklist_button = e;
|
||||
e.click(onBlocklistUpdateClicked);
|
||||
initTimeDropDown(e.find('#alt-speed-time-begin')[0]);
|
||||
initTimeDropDown(e.find('#alt-speed-time-end')[0]);
|
||||
|
||||
// listen for user input
|
||||
for (i=0; key=data.keys[i]; ++i)
|
||||
{
|
||||
e = data.elements.root.find('#'+key);
|
||||
switch (e[0].type)
|
||||
{
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
case 'select-one':
|
||||
e.change(onControlChanged);
|
||||
break;
|
||||
o = isMobileDevice ? getDefaultMobileOptions() : {
|
||||
width: 350,
|
||||
height: 400
|
||||
};
|
||||
o.autoOpen = false;
|
||||
o.show = o.hide = 'fade';
|
||||
o.close = onDialogClosed;
|
||||
e.tabbedDialog(o);
|
||||
|
||||
case 'text':
|
||||
case 'url':
|
||||
case 'email':
|
||||
case 'number':
|
||||
case 'search':
|
||||
e.focus(onControlFocused);
|
||||
e.blur(onControlBlurred);
|
||||
e = e.find('#blocklist-update-button');
|
||||
data.elements.blocklist_button = e;
|
||||
e.click(onBlocklistUpdateClicked);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
// listen for user input
|
||||
for (i = 0; key = data.keys[i]; ++i) {
|
||||
e = data.elements.root.find('#' + key);
|
||||
switch (e[0].type) {
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
case 'select-one':
|
||||
e.change(onControlChanged);
|
||||
break;
|
||||
|
||||
getValues = function()
|
||||
{
|
||||
var i, key, val, o={},
|
||||
keys = data.keys,
|
||||
root = data.elements.root;
|
||||
case 'text':
|
||||
case 'url':
|
||||
case 'email':
|
||||
case 'number':
|
||||
case 'search':
|
||||
e.focus(onControlFocused);
|
||||
e.blur(onControlBlurred);
|
||||
|
||||
for (i=0; key=keys[i]; ++i) {
|
||||
val = getValue(root.find('#'+key));
|
||||
if (val !== null)
|
||||
o[key] = val;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
return o;
|
||||
},
|
||||
var getValues = function () {
|
||||
var i, key, val, o = {},
|
||||
keys = data.keys,
|
||||
root = data.elements.root;
|
||||
|
||||
onDialogClosed = function()
|
||||
{
|
||||
transmission.hideMobileAddressbar();
|
||||
for (i = 0; key = keys[i]; ++i) {
|
||||
val = getValue(root.find('#' + key));
|
||||
if (val !== null) {
|
||||
o[key] = val;
|
||||
};
|
||||
};
|
||||
|
||||
$(data.dialog).trigger('closed', getValues());
|
||||
};
|
||||
return o;
|
||||
};
|
||||
|
||||
/****
|
||||
***** PUBLIC FUNCTIONS
|
||||
****/
|
||||
var onDialogClosed = function () {
|
||||
transmission.hideMobileAddressbar();
|
||||
|
||||
// update the dialog's controls
|
||||
this.set = function (o)
|
||||
{
|
||||
var e, i, key, val, option,
|
||||
keys = data.keys,
|
||||
root = data.elements.root;
|
||||
$(data.dialog).trigger('closed', getValues());
|
||||
};
|
||||
|
||||
setBlocklistButtonEnabled(true);
|
||||
/****
|
||||
***** PUBLIC FUNCTIONS
|
||||
****/
|
||||
|
||||
for (i=0; key=keys[i]; ++i)
|
||||
{
|
||||
val = o[key];
|
||||
e = root.find('#'+key);
|
||||
// update the dialog's controls
|
||||
this.set = function (o) {
|
||||
var e, i, key, val, option;
|
||||
var keys = data.keys;
|
||||
var root = data.elements.root;
|
||||
|
||||
if (key === 'blocklist-size')
|
||||
{
|
||||
// special case -- regular text area
|
||||
e.text('' + val.toStringWithCommas());
|
||||
}
|
||||
else switch (e[0].type)
|
||||
{
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
e.prop('checked', val);
|
||||
setGroupEnabled(key, val);
|
||||
break;
|
||||
case 'text':
|
||||
case 'url':
|
||||
case 'email':
|
||||
case 'number':
|
||||
case 'search':
|
||||
// don't change the text if the user's editing it.
|
||||
// it's very annoying when that happens!
|
||||
if (e[0] !== document.activeElement)
|
||||
e.val(val);
|
||||
break;
|
||||
case 'select-one':
|
||||
e.val(val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
setBlocklistButtonEnabled(true);
|
||||
|
||||
this.show = function ()
|
||||
{
|
||||
transmission.hideMobileAddressbar();
|
||||
for (i = 0; key = keys[i]; ++i) {
|
||||
val = o[key];
|
||||
e = root.find('#' + key);
|
||||
|
||||
setBlocklistButtonEnabled(true);
|
||||
data.remote.checkPort(onPortChecked,this);
|
||||
data.elements.root.dialog('open');
|
||||
};
|
||||
if (key === 'blocklist-size') {
|
||||
// special case -- regular text area
|
||||
e.text('' + val.toStringWithCommas());
|
||||
} else switch (e[0].type) {
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
e.prop('checked', val);
|
||||
setGroupEnabled(key, val);
|
||||
break;
|
||||
case 'text':
|
||||
case 'url':
|
||||
case 'email':
|
||||
case 'number':
|
||||
case 'search':
|
||||
// don't change the text if the user's editing it.
|
||||
// it's very annoying when that happens!
|
||||
if (e[0] !== document.activeElement) {
|
||||
e.val(val);
|
||||
};
|
||||
break;
|
||||
case 'select-one':
|
||||
e.val(val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
this.close = function ()
|
||||
{
|
||||
transmission.hideMobileAddressbar();
|
||||
data.elements.root.dialog('close');
|
||||
},
|
||||
this.show = function () {
|
||||
transmission.hideMobileAddressbar();
|
||||
|
||||
this.shouldAddedTorrentsStart = function()
|
||||
{
|
||||
return data.elements.root.find('#start-added-torrents')[0].checked;
|
||||
};
|
||||
setBlocklistButtonEnabled(true);
|
||||
data.remote.checkPort(onPortChecked, this);
|
||||
data.elements.root.dialog('open');
|
||||
};
|
||||
|
||||
data.dialog = this;
|
||||
initialize (remote);
|
||||
this.close = function () {
|
||||
transmission.hideMobileAddressbar();
|
||||
data.elements.root.dialog('close');
|
||||
};
|
||||
|
||||
this.shouldAddedTorrentsStart = function () {
|
||||
return data.elements.root.find('#start-added-torrents')[0].checked;
|
||||
};
|
||||
|
||||
data.dialog = this;
|
||||
initialize(remote);
|
||||
};
|
||||
|
|
|
@ -6,266 +6,283 @@
|
|||
*/
|
||||
|
||||
var RPC = {
|
||||
_DaemonVersion : 'version',
|
||||
_DownSpeedLimit : 'speed-limit-down',
|
||||
_DownSpeedLimited : 'speed-limit-down-enabled',
|
||||
_QueueMoveTop : 'queue-move-top',
|
||||
_QueueMoveBottom : 'queue-move-bottom',
|
||||
_QueueMoveUp : 'queue-move-up',
|
||||
_QueueMoveDown : 'queue-move-down',
|
||||
_Root : '../rpc',
|
||||
_TurtleDownSpeedLimit : 'alt-speed-down',
|
||||
_TurtleState : 'alt-speed-enabled',
|
||||
_TurtleUpSpeedLimit : 'alt-speed-up',
|
||||
_UpSpeedLimit : 'speed-limit-up',
|
||||
_UpSpeedLimited : 'speed-limit-up-enabled'
|
||||
_DaemonVersion: 'version',
|
||||
_DownSpeedLimit: 'speed-limit-down',
|
||||
_DownSpeedLimited: 'speed-limit-down-enabled',
|
||||
_QueueMoveTop: 'queue-move-top',
|
||||
_QueueMoveBottom: 'queue-move-bottom',
|
||||
_QueueMoveUp: 'queue-move-up',
|
||||
_QueueMoveDown: 'queue-move-down',
|
||||
_Root: '../rpc',
|
||||
_TurtleDownSpeedLimit: 'alt-speed-down',
|
||||
_TurtleState: 'alt-speed-enabled',
|
||||
_TurtleUpSpeedLimit: 'alt-speed-up',
|
||||
_UpSpeedLimit: 'speed-limit-up',
|
||||
_UpSpeedLimited: 'speed-limit-up-enabled'
|
||||
};
|
||||
|
||||
function TransmissionRemote(controller)
|
||||
{
|
||||
this.initialize(controller);
|
||||
return this;
|
||||
function TransmissionRemote(controller) {
|
||||
this.initialize(controller);
|
||||
return this;
|
||||
}
|
||||
|
||||
TransmissionRemote.prototype =
|
||||
{
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
initialize: function(controller) {
|
||||
this._controller = controller;
|
||||
this._error = '';
|
||||
this._token = '';
|
||||
},
|
||||
TransmissionRemote.prototype = {
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
initialize: function (controller) {
|
||||
this._controller = controller;
|
||||
this._error = '';
|
||||
this._token = '';
|
||||
},
|
||||
|
||||
/*
|
||||
* Display an error if an ajax request fails, and stop sending requests
|
||||
* or on a 409, globally set the X-Transmission-Session-Id and resend
|
||||
*/
|
||||
ajaxError: function(request, error_string, exception, ajaxObject) {
|
||||
var token,
|
||||
remote = this;
|
||||
/*
|
||||
* Display an error if an ajax request fails, and stop sending requests
|
||||
* or on a 409, globally set the X-Transmission-Session-Id and resend
|
||||
*/
|
||||
ajaxError: function (request, error_string, exception, ajaxObject) {
|
||||
var token;
|
||||
var remote = this;
|
||||
|
||||
// set the Transmission-Session-Id on a 409
|
||||
if (request.status === 409 && (token = request.getResponseHeader('X-Transmission-Session-Id'))){
|
||||
remote._token = token;
|
||||
$.ajax(ajaxObject);
|
||||
return;
|
||||
}
|
||||
// set the Transmission-Session-Id on a 409
|
||||
if (request.status === 409 && (token = request.getResponseHeader('X-Transmission-Session-Id'))) {
|
||||
remote._token = token;
|
||||
$.ajax(ajaxObject);
|
||||
return;
|
||||
};
|
||||
|
||||
remote._error = request.responseText
|
||||
? request.responseText.trim().replace(/(<([^>]+)>)/ig,"")
|
||||
: "";
|
||||
if (!remote._error.length)
|
||||
remote._error = 'Server not responding';
|
||||
remote._error = request.responseText ? request.responseText.trim().replace(/(<([^>]+)>)/ig, "") : "";
|
||||
if (!remote._error.length) {
|
||||
remote._error = 'Server not responding';
|
||||
};
|
||||
|
||||
dialog.confirm('Connection Failed',
|
||||
'Could not connect to the server. You may need to reload the page to reconnect.',
|
||||
'Details',
|
||||
function() {
|
||||
alert(remote._error);
|
||||
},
|
||||
'Dismiss');
|
||||
remote._controller.togglePeriodicSessionRefresh(false);
|
||||
},
|
||||
dialog.confirm('Connection Failed',
|
||||
'Could not connect to the server. You may need to reload the page to reconnect.',
|
||||
'Details',
|
||||
function () {
|
||||
alert(remote._error);
|
||||
},
|
||||
'Dismiss');
|
||||
remote._controller.togglePeriodicSessionRefresh(false);
|
||||
},
|
||||
|
||||
appendSessionId: function(XHR) {
|
||||
if (this._token) {
|
||||
XHR.setRequestHeader('X-Transmission-Session-Id', this._token);
|
||||
}
|
||||
},
|
||||
appendSessionId: function (XHR) {
|
||||
if (this._token) {
|
||||
XHR.setRequestHeader('X-Transmission-Session-Id', this._token);
|
||||
};
|
||||
},
|
||||
|
||||
sendRequest: function(data, callback, context, async) {
|
||||
var remote = this;
|
||||
if (typeof async != 'boolean')
|
||||
async = true;
|
||||
sendRequest: function (data, callback, context, async) {
|
||||
var remote = this;
|
||||
if (typeof async != 'boolean') {
|
||||
async = true;
|
||||
};
|
||||
|
||||
var ajaxSettings = {
|
||||
url: RPC._Root,
|
||||
type: 'POST',
|
||||
contentType: 'json',
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
data: JSON.stringify(data),
|
||||
beforeSend: function(XHR){ remote.appendSessionId(XHR); },
|
||||
error: function(request, error_string, exception){ remote.ajaxError(request, error_string, exception, ajaxSettings); },
|
||||
success: callback,
|
||||
context: context,
|
||||
async: async
|
||||
};
|
||||
var ajaxSettings = {
|
||||
url: RPC._Root,
|
||||
type: 'POST',
|
||||
contentType: 'json',
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
data: JSON.stringify(data),
|
||||
beforeSend: function (XHR) {
|
||||
remote.appendSessionId(XHR);
|
||||
},
|
||||
error: function (request, error_string, exception) {
|
||||
remote.ajaxError(request, error_string, exception, ajaxSettings);
|
||||
},
|
||||
success: callback,
|
||||
context: context,
|
||||
async: async
|
||||
};
|
||||
|
||||
$.ajax(ajaxSettings);
|
||||
},
|
||||
$.ajax(ajaxSettings);
|
||||
},
|
||||
|
||||
loadDaemonPrefs: function(callback, context, async) {
|
||||
var o = { method: 'session-get' };
|
||||
this.sendRequest(o, callback, context, async);
|
||||
},
|
||||
loadDaemonPrefs: function (callback, context, async) {
|
||||
var o = {
|
||||
method: 'session-get'
|
||||
};
|
||||
this.sendRequest(o, callback, context, async);
|
||||
},
|
||||
|
||||
checkPort: function(callback, context, async) {
|
||||
var o = { method: 'port-test' };
|
||||
this.sendRequest(o, callback, context, async);
|
||||
},
|
||||
checkPort: function (callback, context, async) {
|
||||
var o = {
|
||||
method: 'port-test'
|
||||
};
|
||||
this.sendRequest(o, callback, context, async);
|
||||
},
|
||||
|
||||
renameTorrent: function(torrentIds, oldpath, newname, callback, context) {
|
||||
var o = {
|
||||
method: 'torrent-rename-path',
|
||||
arguments: {
|
||||
'ids': torrentIds,
|
||||
'path': oldpath,
|
||||
'name': newname
|
||||
}
|
||||
};
|
||||
this.sendRequest(o, callback, context);
|
||||
},
|
||||
renameTorrent: function (torrentIds, oldpath, newname, callback, context) {
|
||||
var o = {
|
||||
method: 'torrent-rename-path',
|
||||
arguments: {
|
||||
'ids': torrentIds,
|
||||
'path': oldpath,
|
||||
'name': newname
|
||||
}
|
||||
};
|
||||
this.sendRequest(o, callback, context);
|
||||
},
|
||||
|
||||
loadDaemonStats: function(callback, context, async) {
|
||||
var o = { method: 'session-stats' };
|
||||
this.sendRequest(o, callback, context, async);
|
||||
},
|
||||
loadDaemonStats: function (callback, context, async) {
|
||||
var o = {
|
||||
method: 'session-stats'
|
||||
};
|
||||
this.sendRequest(o, callback, context, async);
|
||||
},
|
||||
|
||||
updateTorrents: function(torrentIds, fields, callback, context) {
|
||||
var o = {
|
||||
method: 'torrent-get',
|
||||
arguments: {
|
||||
'fields': fields
|
||||
}
|
||||
};
|
||||
if (torrentIds)
|
||||
o['arguments'].ids = torrentIds;
|
||||
this.sendRequest(o, function(response) {
|
||||
var args = response['arguments'];
|
||||
callback.call(context,args.torrents,args.removed);
|
||||
});
|
||||
},
|
||||
updateTorrents: function (torrentIds, fields, callback, context) {
|
||||
var o = {
|
||||
method: 'torrent-get',
|
||||
arguments: {
|
||||
'fields': fields
|
||||
}
|
||||
};
|
||||
if (torrentIds) {
|
||||
o['arguments'].ids = torrentIds;
|
||||
};
|
||||
this.sendRequest(o, function (response) {
|
||||
var args = response['arguments'];
|
||||
callback.call(context, args.torrents, args.removed);
|
||||
});
|
||||
},
|
||||
|
||||
getFreeSpace: function(dir, callback, context) {
|
||||
var remote = this;
|
||||
var o = {
|
||||
method: 'free-space',
|
||||
arguments: { path: dir }
|
||||
};
|
||||
this.sendRequest(o, function(response) {
|
||||
var args = response['arguments'];
|
||||
callback.call (context, args.path, args['size-bytes']);
|
||||
});
|
||||
},
|
||||
getFreeSpace: function (dir, callback, context) {
|
||||
var remote = this;
|
||||
var o = {
|
||||
method: 'free-space',
|
||||
arguments: {
|
||||
path: dir
|
||||
}
|
||||
};
|
||||
this.sendRequest(o, function (response) {
|
||||
var args = response['arguments'];
|
||||
callback.call(context, args.path, args['size-bytes']);
|
||||
});
|
||||
},
|
||||
|
||||
changeFileCommand: function(torrentId, fileIndices, command) {
|
||||
var remote = this,
|
||||
args = { ids: [torrentId] };
|
||||
args[command] = fileIndices;
|
||||
this.sendRequest({
|
||||
arguments: args,
|
||||
method: 'torrent-set'
|
||||
}, function() {
|
||||
remote._controller.refreshTorrents([torrentId]);
|
||||
});
|
||||
},
|
||||
changeFileCommand: function (torrentId, fileIndices, command) {
|
||||
var remote = this,
|
||||
args = {
|
||||
ids: [torrentId]
|
||||
};
|
||||
args[command] = fileIndices;
|
||||
this.sendRequest({
|
||||
arguments: args,
|
||||
method: 'torrent-set'
|
||||
}, function () {
|
||||
remote._controller.refreshTorrents([torrentId]);
|
||||
});
|
||||
},
|
||||
|
||||
sendTorrentSetRequests: function(method, torrent_ids, args, callback, context) {
|
||||
if (!args) args = { };
|
||||
args['ids'] = torrent_ids;
|
||||
var o = {
|
||||
method: method,
|
||||
arguments: args
|
||||
};
|
||||
this.sendRequest(o, callback, context);
|
||||
},
|
||||
sendTorrentSetRequests: function (method, torrent_ids, args, callback, context) {
|
||||
if (!args) {
|
||||
args = {};
|
||||
};
|
||||
args['ids'] = torrent_ids;
|
||||
var o = {
|
||||
method: method,
|
||||
arguments: args
|
||||
};
|
||||
this.sendRequest(o, callback, context);
|
||||
},
|
||||
|
||||
sendTorrentActionRequests: function(method, torrent_ids, callback, context) {
|
||||
this.sendTorrentSetRequests(method, torrent_ids, null, callback, context);
|
||||
},
|
||||
sendTorrentActionRequests: function (method, torrent_ids, callback, context) {
|
||||
this.sendTorrentSetRequests(method, torrent_ids, null, callback, context);
|
||||
},
|
||||
|
||||
startTorrents: function(torrent_ids, noqueue, callback, context) {
|
||||
var name = noqueue ? 'torrent-start-now' : 'torrent-start';
|
||||
this.sendTorrentActionRequests(name, torrent_ids, callback, context);
|
||||
},
|
||||
stopTorrents: function(torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests('torrent-stop', torrent_ids, callback, context);
|
||||
},
|
||||
startTorrents: function (torrent_ids, noqueue, callback, context) {
|
||||
var name = noqueue ? 'torrent-start-now' : 'torrent-start';
|
||||
this.sendTorrentActionRequests(name, torrent_ids, callback, context);
|
||||
},
|
||||
stopTorrents: function (torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests('torrent-stop', torrent_ids, callback, context);
|
||||
},
|
||||
|
||||
moveTorrents: function(torrent_ids, new_location, callback, context) {
|
||||
var remote = this;
|
||||
this.sendTorrentSetRequests( 'torrent-set-location', torrent_ids,
|
||||
{"move": true, "location": new_location}, callback, context);
|
||||
},
|
||||
moveTorrents: function (torrent_ids, new_location, callback, context) {
|
||||
var remote = this;
|
||||
this.sendTorrentSetRequests('torrent-set-location', torrent_ids, {
|
||||
"move": true,
|
||||
"location": new_location
|
||||
}, callback, context);
|
||||
},
|
||||
|
||||
removeTorrents: function(torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests('torrent-remove', torrent_ids, callback, context);
|
||||
},
|
||||
removeTorrentsAndData: function(torrents) {
|
||||
var remote = this;
|
||||
var o = {
|
||||
method: 'torrent-remove',
|
||||
arguments: {
|
||||
'delete-local-data': true,
|
||||
ids: [ ]
|
||||
}
|
||||
};
|
||||
removeTorrents: function (torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests('torrent-remove', torrent_ids, callback, context);
|
||||
},
|
||||
removeTorrentsAndData: function (torrents) {
|
||||
var remote = this;
|
||||
var o = {
|
||||
method: 'torrent-remove',
|
||||
arguments: {
|
||||
'delete-local-data': true,
|
||||
ids: []
|
||||
}
|
||||
};
|
||||
|
||||
if (torrents) {
|
||||
for (var i=0, len=torrents.length; i<len; ++i) {
|
||||
o.arguments.ids.push(torrents[i].getId());
|
||||
}
|
||||
}
|
||||
this.sendRequest(o, function() {
|
||||
remote._controller.refreshTorrents();
|
||||
});
|
||||
},
|
||||
verifyTorrents: function(torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests('torrent-verify', torrent_ids, callback, context);
|
||||
},
|
||||
reannounceTorrents: function(torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests('torrent-reannounce', torrent_ids, callback, context);
|
||||
},
|
||||
addTorrentByUrl: function(url, options) {
|
||||
var remote = this;
|
||||
if (url.match(/^[0-9a-f]{40}$/i)) {
|
||||
url = 'magnet:?xt=urn:btih:'+url;
|
||||
}
|
||||
var o = {
|
||||
method: 'torrent-add',
|
||||
arguments: {
|
||||
paused: (options.paused),
|
||||
filename: url
|
||||
}
|
||||
};
|
||||
this.sendRequest(o, function() {
|
||||
remote._controller.refreshTorrents();
|
||||
});
|
||||
},
|
||||
savePrefs: function(args) {
|
||||
var remote = this;
|
||||
var o = {
|
||||
method: 'session-set',
|
||||
arguments: args
|
||||
};
|
||||
this.sendRequest(o, function() {
|
||||
remote._controller.loadDaemonPrefs();
|
||||
});
|
||||
},
|
||||
updateBlocklist: function() {
|
||||
var remote = this;
|
||||
var o = {
|
||||
method: 'blocklist-update'
|
||||
};
|
||||
this.sendRequest(o, function() {
|
||||
remote._controller.loadDaemonPrefs();
|
||||
});
|
||||
},
|
||||
if (torrents) {
|
||||
for (var i = 0, len = torrents.length; i < len; ++i) {
|
||||
o.arguments.ids.push(torrents[i].getId());
|
||||
};
|
||||
};
|
||||
this.sendRequest(o, function () {
|
||||
remote._controller.refreshTorrents();
|
||||
});
|
||||
},
|
||||
verifyTorrents: function (torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests('torrent-verify', torrent_ids, callback, context);
|
||||
},
|
||||
reannounceTorrents: function (torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests('torrent-reannounce', torrent_ids, callback, context);
|
||||
},
|
||||
addTorrentByUrl: function (url, options) {
|
||||
var remote = this;
|
||||
if (url.match(/^[0-9a-f]{40}$/i)) {
|
||||
url = 'magnet:?xt=urn:btih:' + url;
|
||||
}
|
||||
var o = {
|
||||
method: 'torrent-add',
|
||||
arguments: {
|
||||
paused: (options.paused),
|
||||
filename: url
|
||||
}
|
||||
};
|
||||
this.sendRequest(o, function () {
|
||||
remote._controller.refreshTorrents();
|
||||
});
|
||||
},
|
||||
savePrefs: function (args) {
|
||||
var remote = this;
|
||||
var o = {
|
||||
method: 'session-set',
|
||||
arguments: args
|
||||
};
|
||||
this.sendRequest(o, function () {
|
||||
remote._controller.loadDaemonPrefs();
|
||||
});
|
||||
},
|
||||
updateBlocklist: function () {
|
||||
var remote = this;
|
||||
var o = {
|
||||
method: 'blocklist-update'
|
||||
};
|
||||
this.sendRequest(o, function () {
|
||||
remote._controller.loadDaemonPrefs();
|
||||
});
|
||||
},
|
||||
|
||||
// Added queue calls
|
||||
moveTorrentsToTop: function(torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests(RPC._QueueMoveTop, torrent_ids, callback, context);
|
||||
},
|
||||
moveTorrentsToBottom: function(torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests(RPC._QueueMoveBottom, torrent_ids, callback, context);
|
||||
},
|
||||
moveTorrentsUp: function(torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests(RPC._QueueMoveUp, torrent_ids, callback, context);
|
||||
},
|
||||
moveTorrentsDown: function(torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests(RPC._QueueMoveDown, torrent_ids, callback, context);
|
||||
}
|
||||
// Added queue calls
|
||||
moveTorrentsToTop: function (torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests(RPC._QueueMoveTop, torrent_ids, callback, context);
|
||||
},
|
||||
moveTorrentsToBottom: function (torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests(RPC._QueueMoveBottom, torrent_ids, callback, context);
|
||||
},
|
||||
moveTorrentsUp: function (torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests(RPC._QueueMoveUp, torrent_ids, callback, context);
|
||||
},
|
||||
moveTorrentsDown: function (torrent_ids, callback, context) {
|
||||
this.sendTorrentActionRequests(RPC._QueueMoveDown, torrent_ids, callback, context);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,405 +5,401 @@
|
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
function TorrentRendererHelper()
|
||||
{
|
||||
}
|
||||
function TorrentRendererHelper() {}
|
||||
|
||||
TorrentRendererHelper.getProgressInfo = function(controller, t)
|
||||
{
|
||||
var pct, extra,
|
||||
s = t.getStatus(),
|
||||
seed_ratio_limit = t.seedRatioLimit(controller);
|
||||
TorrentRendererHelper.getProgressInfo = function (controller, t) {
|
||||
var pct, extra;
|
||||
var s = t.getStatus();
|
||||
var seed_ratio_limit = t.seedRatioLimit(controller);
|
||||
|
||||
if (t.needsMetaData())
|
||||
pct = t.getMetadataPercentComplete() * 100;
|
||||
else if (!t.isDone())
|
||||
pct = Math.round(t.getPercentDone() * 100);
|
||||
else if (seed_ratio_limit > 0 && t.isSeeding()) // don't split up the bar if paused or queued
|
||||
pct = Math.round(t.getUploadRatio() * 100 / seed_ratio_limit);
|
||||
else
|
||||
pct = 100;
|
||||
if (t.needsMetaData()) {
|
||||
pct = t.getMetadataPercentComplete() * 100;
|
||||
} else if (!t.isDone()) {
|
||||
pct = Math.round(t.getPercentDone() * 100);
|
||||
} else if (seed_ratio_limit > 0 && t.isSeeding()) { // don't split up the bar if paused or queued
|
||||
pct = Math.round(t.getUploadRatio() * 100 / seed_ratio_limit);
|
||||
} else {
|
||||
pct = 100;
|
||||
};
|
||||
|
||||
if (s === Torrent._StatusStopped)
|
||||
extra = 'paused';
|
||||
else if (s === Torrent._StatusDownloadWait)
|
||||
extra = 'leeching queued';
|
||||
else if (t.needsMetaData())
|
||||
extra = 'magnet';
|
||||
else if (s === Torrent._StatusDownload)
|
||||
extra = 'leeching';
|
||||
else if (s === Torrent._StatusSeedWait)
|
||||
extra = 'seeding queued';
|
||||
else if (s === Torrent._StatusSeed)
|
||||
extra = 'seeding';
|
||||
else
|
||||
extra = '';
|
||||
if (s === Torrent._StatusStopped) {
|
||||
extra = 'paused';
|
||||
} else if (s === Torrent._StatusDownloadWait) {
|
||||
extra = 'leeching queued';
|
||||
} else if (t.needsMetaData()) {
|
||||
extra = 'magnet';
|
||||
} else if (s === Torrent._StatusDownload) {
|
||||
extra = 'leeching';
|
||||
} else if (s === Torrent._StatusSeedWait) {
|
||||
extra = 'seeding queued';
|
||||
} else if (s === Torrent._StatusSeed) {
|
||||
extra = 'seeding';
|
||||
} else {
|
||||
extra = '';
|
||||
};
|
||||
|
||||
return {
|
||||
percent: pct,
|
||||
complete: [ 'torrent_progress_bar', 'complete', extra ].join(' '),
|
||||
incomplete: [ 'torrent_progress_bar', 'incomplete', extra ].join(' ')
|
||||
};
|
||||
return {
|
||||
percent: pct,
|
||||
complete: ['torrent_progress_bar', 'complete', extra].join(' '),
|
||||
incomplete: ['torrent_progress_bar', 'incomplete', extra].join(' ')
|
||||
};
|
||||
};
|
||||
|
||||
TorrentRendererHelper.createProgressbar = function(classes)
|
||||
{
|
||||
var complete, incomplete, progressbar;
|
||||
TorrentRendererHelper.createProgressbar = function (classes) {
|
||||
var complete, incomplete, progressbar;
|
||||
|
||||
complete = document.createElement('div');
|
||||
complete.className = 'torrent_progress_bar complete';
|
||||
complete = document.createElement('div');
|
||||
complete.className = 'torrent_progress_bar complete';
|
||||
|
||||
incomplete = document.createElement('div');
|
||||
incomplete.className = 'torrent_progress_bar incomplete';
|
||||
incomplete = document.createElement('div');
|
||||
incomplete.className = 'torrent_progress_bar incomplete';
|
||||
|
||||
progressbar = document.createElement('div');
|
||||
progressbar.className = 'torrent_progress_bar_container ' + classes;
|
||||
progressbar.appendChild(complete);
|
||||
progressbar.appendChild(incomplete);
|
||||
progressbar = document.createElement('div');
|
||||
progressbar.className = 'torrent_progress_bar_container ' + classes;
|
||||
progressbar.appendChild(complete);
|
||||
progressbar.appendChild(incomplete);
|
||||
|
||||
return { 'element': progressbar, 'complete': complete, 'incomplete': incomplete };
|
||||
return {
|
||||
'element': progressbar,
|
||||
'complete': complete,
|
||||
'incomplete': incomplete
|
||||
};
|
||||
};
|
||||
|
||||
TorrentRendererHelper.renderProgressbar = function(controller, t, progressbar)
|
||||
{
|
||||
var e, style, width, display,
|
||||
info = TorrentRendererHelper.getProgressInfo(controller, t);
|
||||
TorrentRendererHelper.renderProgressbar = function (controller, t, progressbar) {
|
||||
var e, style, width, display
|
||||
var info = TorrentRendererHelper.getProgressInfo(controller, t);
|
||||
|
||||
// update the complete progressbar
|
||||
e = progressbar.complete;
|
||||
style = e.style;
|
||||
width = '' + info.percent + '%';
|
||||
display = info.percent > 0 ? 'block' : 'none';
|
||||
if (style.width!==width || style.display!==display)
|
||||
$(e).css({ width: ''+info.percent+'%', display: display });
|
||||
if (e.className !== info.complete)
|
||||
e.className = info.complete;
|
||||
// update the complete progressbar
|
||||
e = progressbar.complete;
|
||||
style = e.style;
|
||||
width = '' + info.percent + '%';
|
||||
display = info.percent > 0 ? 'block' : 'none';
|
||||
if (style.width !== width || style.display !== display) {
|
||||
$(e).css({
|
||||
width: '' + info.percent + '%',
|
||||
display: display
|
||||
});
|
||||
};
|
||||
|
||||
// update the incomplete progressbar
|
||||
e = progressbar.incomplete;
|
||||
display = (info.percent < 100) ? 'block' : 'none';
|
||||
if (e.style.display !== display)
|
||||
e.style.display = display;
|
||||
if (e.className !== info.incomplete)
|
||||
e.className = info.incomplete;
|
||||
if (e.className !== info.complete) {
|
||||
e.className = info.complete;
|
||||
};
|
||||
|
||||
// update the incomplete progressbar
|
||||
e = progressbar.incomplete;
|
||||
display = (info.percent < 100) ? 'block' : 'none';
|
||||
|
||||
if (e.style.display !== display) {
|
||||
e.style.display = display;
|
||||
};
|
||||
|
||||
if (e.className !== info.incomplete) {
|
||||
e.className = info.incomplete;
|
||||
};
|
||||
};
|
||||
|
||||
TorrentRendererHelper.formatUL = function(t)
|
||||
{
|
||||
return '↑ ' + Transmission.fmt.speedBps(t.getUploadSpeed());
|
||||
TorrentRendererHelper.formatUL = function (t) {
|
||||
return '↑ ' + Transmission.fmt.speedBps(t.getUploadSpeed());
|
||||
};
|
||||
|
||||
TorrentRendererHelper.formatDL = function(t)
|
||||
{
|
||||
return '↓ ' + Transmission.fmt.speedBps(t.getDownloadSpeed());
|
||||
TorrentRendererHelper.formatDL = function (t) {
|
||||
return '↓ ' + Transmission.fmt.speedBps(t.getDownloadSpeed());
|
||||
};
|
||||
|
||||
/****
|
||||
*****
|
||||
*****
|
||||
****/
|
||||
*****
|
||||
*****
|
||||
****/
|
||||
|
||||
function TorrentRendererFull()
|
||||
{
|
||||
}
|
||||
TorrentRendererFull.prototype =
|
||||
{
|
||||
createRow: function()
|
||||
{
|
||||
var root, name, peers, progressbar, details, image, button;
|
||||
function TorrentRendererFull() {};
|
||||
TorrentRendererFull.prototype = {
|
||||
createRow: function () {
|
||||
var root, name, peers, progressbar, details, image, button;
|
||||
|
||||
root = document.createElement('li');
|
||||
root.className = 'torrent';
|
||||
root = document.createElement('li');
|
||||
root.className = 'torrent';
|
||||
|
||||
name = document.createElement('div');
|
||||
name.className = 'torrent_name';
|
||||
name = document.createElement('div');
|
||||
name.className = 'torrent_name';
|
||||
|
||||
peers = document.createElement('div');
|
||||
peers.className = 'torrent_peer_details';
|
||||
peers = document.createElement('div');
|
||||
peers.className = 'torrent_peer_details';
|
||||
|
||||
progressbar = TorrentRendererHelper.createProgressbar('full');
|
||||
progressbar = TorrentRendererHelper.createProgressbar('full');
|
||||
|
||||
details = document.createElement('div');
|
||||
details.className = 'torrent_progress_details';
|
||||
details = document.createElement('div');
|
||||
details.className = 'torrent_progress_details';
|
||||
|
||||
image = document.createElement('div');
|
||||
button = document.createElement('a');
|
||||
button.appendChild(image);
|
||||
image = document.createElement('div');
|
||||
button = document.createElement('a');
|
||||
button.appendChild(image);
|
||||
|
||||
root.appendChild(name);
|
||||
root.appendChild(peers);
|
||||
root.appendChild(button);
|
||||
root.appendChild(progressbar.element);
|
||||
root.appendChild(details);
|
||||
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;
|
||||
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;
|
||||
},
|
||||
return root;
|
||||
},
|
||||
|
||||
getPeerDetails: function(t)
|
||||
{
|
||||
var err,
|
||||
peer_count,
|
||||
webseed_count,
|
||||
fmt = Transmission.fmt;
|
||||
getPeerDetails: function (t) {
|
||||
var err,
|
||||
peer_count,
|
||||
webseed_count,
|
||||
fmt = Transmission.fmt;
|
||||
|
||||
if ((err = t.getErrorMessage()))
|
||||
return err;
|
||||
if ((err = t.getErrorMessage())) {
|
||||
return err;
|
||||
};
|
||||
|
||||
if (t.isDownloading())
|
||||
{
|
||||
peer_count = t.getPeersConnected();
|
||||
webseed_count = t.getWebseedsSendingToUs();
|
||||
if (t.isDownloading()) {
|
||||
peer_count = t.getPeersConnected();
|
||||
webseed_count = t.getWebseedsSendingToUs();
|
||||
|
||||
if (webseed_count && peer_count)
|
||||
{
|
||||
// Downloading from 2 of 3 peer(s) and 2 webseed(s)
|
||||
return [ 'Downloading from',
|
||||
t.getPeersSendingToUs(),
|
||||
'of',
|
||||
fmt.countString('peer','peers',peer_count),
|
||||
'and',
|
||||
fmt.countString('web seed','web seeds',webseed_count),
|
||||
'-',
|
||||
TorrentRendererHelper.formatDL(t),
|
||||
TorrentRendererHelper.formatUL(t) ].join(' ');
|
||||
}
|
||||
else if (webseed_count)
|
||||
{
|
||||
// Downloading from 2 webseed(s)
|
||||
return [ 'Downloading from',
|
||||
fmt.countString('web seed','web seeds',webseed_count),
|
||||
'-',
|
||||
TorrentRendererHelper.formatDL(t),
|
||||
TorrentRendererHelper.formatUL(t) ].join(' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
// Downloading from 2 of 3 peer(s)
|
||||
return [ 'Downloading from',
|
||||
t.getPeersSendingToUs(),
|
||||
'of',
|
||||
fmt.countString('peer','peers',peer_count),
|
||||
'-',
|
||||
TorrentRendererHelper.formatDL(t),
|
||||
TorrentRendererHelper.formatUL(t) ].join(' ');
|
||||
}
|
||||
}
|
||||
if (webseed_count && peer_count) {
|
||||
// Downloading from 2 of 3 peer(s) and 2 webseed(s)
|
||||
return ['Downloading from',
|
||||
t.getPeersSendingToUs(),
|
||||
'of',
|
||||
fmt.countString('peer', 'peers', peer_count),
|
||||
'and',
|
||||
fmt.countString('web seed', 'web seeds', webseed_count),
|
||||
'-',
|
||||
TorrentRendererHelper.formatDL(t),
|
||||
TorrentRendererHelper.formatUL(t)
|
||||
].join(' ');
|
||||
} else if (webseed_count) {
|
||||
// Downloading from 2 webseed(s)
|
||||
return ['Downloading from',
|
||||
fmt.countString('web seed', 'web seeds', webseed_count),
|
||||
'-',
|
||||
TorrentRendererHelper.formatDL(t),
|
||||
TorrentRendererHelper.formatUL(t)
|
||||
].join(' ');
|
||||
} else {
|
||||
// Downloading from 2 of 3 peer(s)
|
||||
return ['Downloading from',
|
||||
t.getPeersSendingToUs(),
|
||||
'of',
|
||||
fmt.countString('peer', 'peers', peer_count),
|
||||
'-',
|
||||
TorrentRendererHelper.formatDL(t),
|
||||
TorrentRendererHelper.formatUL(t)
|
||||
].join(' ');
|
||||
};
|
||||
};
|
||||
|
||||
if (t.isSeeding())
|
||||
return [ 'Seeding to',
|
||||
t.getPeersGettingFromUs(),
|
||||
'of',
|
||||
fmt.countString ('peer','peers',t.getPeersConnected()),
|
||||
'-',
|
||||
TorrentRendererHelper.formatUL(t) ].join(' ');
|
||||
if (t.isSeeding()) {
|
||||
return ['Seeding to', t.getPeersGettingFromUs(), 'of', fmt.countString('peer', 'peers', t.getPeersConnected()), '-', TorrentRendererHelper.formatUL(t)].join(' ');
|
||||
};
|
||||
|
||||
if (t.isChecking())
|
||||
return [ 'Verifying local data (',
|
||||
Transmission.fmt.percentString(100.0 * t.getRecheckProgress()),
|
||||
'% tested)' ].join('');
|
||||
if (t.isChecking()) {
|
||||
return ['Verifying local data (', Transmission.fmt.percentString(100.0 * t.getRecheckProgress()), '% tested)'].join('');
|
||||
}
|
||||
|
||||
return t.getStateString();
|
||||
},
|
||||
return t.getStateString();
|
||||
},
|
||||
|
||||
getProgressDetails: function(controller, t)
|
||||
{
|
||||
if (t.needsMetaData()) {
|
||||
var MetaDataStatus = "retrieving";
|
||||
if (t.isStopped())
|
||||
MetaDataStatus = "needs";
|
||||
var percent = 100 * t.getMetadataPercentComplete();
|
||||
return [ "Magnetized transfer - " + MetaDataStatus + " metadata (",
|
||||
Transmission.fmt.percentString(percent),
|
||||
"%)" ].join('');
|
||||
}
|
||||
getProgressDetails: function (controller, t) {
|
||||
if (t.needsMetaData()) {
|
||||
var MetaDataStatus = "retrieving";
|
||||
if (t.isStopped()) {
|
||||
MetaDataStatus = "needs";
|
||||
};
|
||||
var percent = 100 * t.getMetadataPercentComplete();
|
||||
return ["Magnetized transfer - " + MetaDataStatus + " metadata (",
|
||||
Transmission.fmt.percentString(percent),
|
||||
"%)"
|
||||
].join('');
|
||||
}
|
||||
|
||||
var c,
|
||||
sizeWhenDone = t.getSizeWhenDone(),
|
||||
totalSize = t.getTotalSize(),
|
||||
is_done = t.isDone() || t.isSeeding();
|
||||
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(), '%)' ];
|
||||
}
|
||||
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');
|
||||
}
|
||||
// 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('');
|
||||
},
|
||||
return c.join('');
|
||||
},
|
||||
|
||||
render: function(controller, t, root)
|
||||
{
|
||||
// name
|
||||
setTextContent(root._name_container, t.getName());
|
||||
render: function (controller, t, root) {
|
||||
// name
|
||||
setTextContent(root._name_container, t.getName());
|
||||
|
||||
// progressbar
|
||||
TorrentRendererHelper.renderProgressbar(controller, t, root._progressbar);
|
||||
// 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);
|
||||
setTextContent(e, this.getPeerDetails(t));
|
||||
// peer details
|
||||
var has_error = t.getError() !== Torrent._ErrNone;
|
||||
var e = root._peer_details_container;
|
||||
$(e).toggleClass('error', has_error);
|
||||
setTextContent(e, this.getPeerDetails(t));
|
||||
|
||||
// progress details
|
||||
e = root._progress_details_container;
|
||||
setTextContent(e, this.getProgressDetails(controller, t));
|
||||
// progress details
|
||||
e = root._progress_details_container;
|
||||
setTextContent(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';
|
||||
}
|
||||
// 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, details, name, root;
|
||||
function TorrentRendererCompact() {};
|
||||
TorrentRendererCompact.prototype = {
|
||||
createRow: function () {
|
||||
var progressbar, details, name, root;
|
||||
|
||||
progressbar = TorrentRendererHelper.createProgressbar('compact');
|
||||
progressbar = TorrentRendererHelper.createProgressbar('compact');
|
||||
|
||||
details = document.createElement('div');
|
||||
details.className = 'torrent_peer_details compact';
|
||||
details = document.createElement('div');
|
||||
details.className = 'torrent_peer_details compact';
|
||||
|
||||
name = document.createElement('div');
|
||||
name.className = 'torrent_name compact';
|
||||
name = document.createElement('div');
|
||||
name.className = 'torrent_name compact';
|
||||
|
||||
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;
|
||||
},
|
||||
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()) {
|
||||
var have_dn = t.getDownloadSpeed() > 0,
|
||||
have_up = t.getUploadSpeed() > 0;
|
||||
if (!have_up && !have_dn)
|
||||
return 'Idle';
|
||||
var s = '';
|
||||
if (have_dn)
|
||||
s += TorrentRendererHelper.formatDL(t);
|
||||
if (have_dn && have_up)
|
||||
s += ' '
|
||||
if (have_up)
|
||||
s += TorrentRendererHelper.formatUL(t);
|
||||
return s;
|
||||
}
|
||||
if (t.isSeeding())
|
||||
return [ 'Ratio: ',
|
||||
Transmission.fmt.ratioString(t.getUploadRatio()),
|
||||
', ',
|
||||
TorrentRendererHelper.formatUL(t) ].join('');
|
||||
return t.getStateString();
|
||||
},
|
||||
getPeerDetails: function (t) {
|
||||
var c;
|
||||
if ((c = t.getErrorMessage())) {
|
||||
return c;
|
||||
};
|
||||
if (t.isDownloading()) {
|
||||
var have_dn = t.getDownloadSpeed() > 0;
|
||||
var have_up = t.getUploadSpeed() > 0;
|
||||
|
||||
render: function(controller, t, root)
|
||||
{
|
||||
// name
|
||||
var is_stopped = t.isStopped();
|
||||
var e = root._name_container;
|
||||
$(e).toggleClass('paused', is_stopped);
|
||||
setTextContent(e, t.getName());
|
||||
if (!have_up && !have_dn) {
|
||||
return 'Idle';
|
||||
};
|
||||
var s = '';
|
||||
if (have_dn) {
|
||||
s += TorrentRendererHelper.formatDL(t);
|
||||
};
|
||||
if (have_dn && have_up) {
|
||||
s += ' ';
|
||||
};
|
||||
if (have_up) {
|
||||
s += TorrentRendererHelper.formatUL(t);
|
||||
};
|
||||
return s;
|
||||
};
|
||||
if (t.isSeeding()) {
|
||||
return ['Ratio: ', Transmission.fmt.ratioString(t.getUploadRatio()), ', ', TorrentRendererHelper.formatUL(t)].join('');
|
||||
};
|
||||
return t.getStateString();
|
||||
},
|
||||
|
||||
// peer details
|
||||
var has_error = t.getError() !== Torrent._ErrNone;
|
||||
e = root._details_container;
|
||||
$(e).toggleClass('error', has_error);
|
||||
setTextContent(e, this.getPeerDetails(t));
|
||||
render: function (controller, t, root) {
|
||||
// name
|
||||
var is_stopped = t.isStopped();
|
||||
var e = root._name_container;
|
||||
$(e).toggleClass('paused', is_stopped);
|
||||
setTextContent(e, t.getName());
|
||||
|
||||
// progressbar
|
||||
TorrentRendererHelper.renderProgressbar(controller, t, root._progressbar);
|
||||
}
|
||||
// peer details
|
||||
var has_error = t.getError() !== Torrent._ErrNone;
|
||||
e = root._details_container;
|
||||
$(e).toggleClass('error', has_error);
|
||||
setTextContent(e, this.getPeerDetails(t));
|
||||
|
||||
// progressbar
|
||||
TorrentRendererHelper.renderProgressbar(controller, t, root._progressbar);
|
||||
}
|
||||
};
|
||||
|
||||
/****
|
||||
*****
|
||||
*****
|
||||
****/
|
||||
*****
|
||||
*****
|
||||
****/
|
||||
|
||||
function TorrentRow(view, controller, torrent)
|
||||
{
|
||||
this.initialize(view, controller, torrent);
|
||||
}
|
||||
TorrentRow.prototype =
|
||||
{
|
||||
initialize: function(view, controller, torrent) {
|
||||
var row = this;
|
||||
this._view = view;
|
||||
this._torrent = torrent;
|
||||
this._element = view.createRow();
|
||||
this.render(controller);
|
||||
$(this._torrent).bind('dataChanged.torrentRowListener',function(){row.render(controller);});
|
||||
|
||||
},
|
||||
getElement: function() {
|
||||
return this._element;
|
||||
},
|
||||
render: function(controller) {
|
||||
var tor = this.getTorrent();
|
||||
if (tor)
|
||||
this._view.render(controller, tor, this.getElement());
|
||||
},
|
||||
isSelected: function() {
|
||||
return this.getElement().className.indexOf('selected') !== -1;
|
||||
},
|
||||
|
||||
getTorrent: function() {
|
||||
return this._torrent;
|
||||
},
|
||||
getTorrentId: function() {
|
||||
return this.getTorrent().getId();
|
||||
}
|
||||
function TorrentRow(view, controller, torrent) {
|
||||
this.initialize(view, controller, torrent);
|
||||
};
|
||||
TorrentRow.prototype = {
|
||||
initialize: function (view, controller, torrent) {
|
||||
var row = this;
|
||||
this._view = view;
|
||||
this._torrent = torrent;
|
||||
this._element = view.createRow();
|
||||
this.render(controller);
|
||||
$(this._torrent).bind('dataChanged.torrentRowListener', function () {
|
||||
row.render(controller);
|
||||
});
|
||||
|
||||
},
|
||||
getElement: function () {
|
||||
return this._element;
|
||||
},
|
||||
render: function (controller) {
|
||||
var tor = this.getTorrent();
|
||||
if (tor) {
|
||||
this._view.render(controller, tor, this.getElement());
|
||||
};
|
||||
},
|
||||
isSelected: function () {
|
||||
return this.getElement().className.indexOf('selected') !== -1;
|
||||
},
|
||||
|
||||
getTorrent: function () {
|
||||
return this._torrent;
|
||||
},
|
||||
getTorrentId: function () {
|
||||
return this.getTorrent().getId();
|
||||
}
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue