mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-28 05:27:15 +03:00
Move JavaScript code into explicit namespaces
This cleans up the global namespace by explicitly exporting shared values. All html and JavaScript files have been converted to use explicit exports except for client.js and mocha-init.js
This commit is contained in:
parent
b144d3b797
commit
1439bcc864
32 changed files with 6204 additions and 5838 deletions
|
@ -61,7 +61,7 @@
|
|||
<p>QBT_TR(List of peers to add (one IP per line):)QBT_TR[CONTEXT=PeersAdditionDialog]</p>
|
||||
<textarea id="peers" rows="10" style="width: 100%;" placeholder="QBT_TR(Format: IPv4:port / [IPv6]:port)QBT_TR[CONTEXT=PeersAdditionDialog]"></textarea>
|
||||
<div style="margin-top: 10px; text-align: center;">
|
||||
<button onclick="window.parent.closeWindows();">QBT_TR(Cancel)QBT_TR[CONTEXT=PeersAdditionDialog]</button>
|
||||
<button onclick="parent.closeWindows();">QBT_TR(Cancel)QBT_TR[CONTEXT=PeersAdditionDialog]</button>
|
||||
<button id="addPeersOk">QBT_TR(Ok)QBT_TR[CONTEXT=PeersAdditionDialog]</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<label for="autoTMM">QBT_TR(Torrent Management Mode:)QBT_TR[CONTEXT=AddNewTorrentDialog]</label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="autoTMM" name="autoTMM" onchange="changeTMM(this)">
|
||||
<select id="autoTMM" name="autoTMM" onchange="qBittorrent.Download.changeTMM(this)">
|
||||
<option selected value="false">Manual</option>
|
||||
<option value="true">Automatic</option>
|
||||
</select>
|
||||
|
@ -63,7 +63,7 @@
|
|||
</td>
|
||||
<td>
|
||||
<div class="select-watched-folder-editable">
|
||||
<select id="categorySelect" onchange="changeCategorySelect(this)">
|
||||
<select id="categorySelect" onchange="qBittorrent.Download.changeCategorySelect(this)">
|
||||
<option selected value="\other"></option>
|
||||
</select>
|
||||
<input name="category" type="text" value="" />
|
||||
|
|
|
@ -30,18 +30,18 @@
|
|||
}).activate();
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
const uriAction = safeTrim(new URI().getData('action'));
|
||||
const uriHashes = safeTrim(new URI().getData('hashes'));
|
||||
const uriCategoryName = safeTrim(new URI().getData('categoryName'));
|
||||
const uriSavePath = safeTrim(new URI().getData('savePath'));
|
||||
const uriAction = window.qBittorrent.Misc.safeTrim(new URI().getData('action'));
|
||||
const uriHashes = window.qBittorrent.Misc.safeTrim(new URI().getData('hashes'));
|
||||
const uriCategoryName = window.qBittorrent.Misc.safeTrim(new URI().getData('categoryName'));
|
||||
const uriSavePath = window.qBittorrent.Misc.safeTrim(new URI().getData('savePath'));
|
||||
|
||||
if (uriAction === "edit") {
|
||||
if (!uriCategoryName)
|
||||
return false;
|
||||
|
||||
$('categoryName').set('disabled', true);
|
||||
$('categoryName').set('value', escapeHtml(uriCategoryName));
|
||||
$('savePath').set('value', escapeHtml(uriSavePath));
|
||||
$('categoryName').set('value', window.qBittorrent.Misc.escapeHtml(uriCategoryName));
|
||||
$('savePath').set('value', window.qBittorrent.Misc.escapeHtml(uriSavePath));
|
||||
$('savePath').focus();
|
||||
}
|
||||
else {
|
||||
|
@ -90,7 +90,7 @@
|
|||
}).send();
|
||||
},
|
||||
onError: function() {
|
||||
alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=HttpServer] " + escapeHtml(categoryName));
|
||||
alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=HttpServer] " + window.qBittorrent.Misc.escapeHtml(categoryName));
|
||||
}
|
||||
}).send();
|
||||
break;
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
}).activate();
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
const uriAction = safeTrim(new URI().getData('action'));
|
||||
const uriHashes = safeTrim(new URI().getData('hashes'));
|
||||
const uriAction = window.qBittorrent.Misc.safeTrim(new URI().getData('action'));
|
||||
const uriHashes = window.qBittorrent.Misc.safeTrim(new URI().getData('hashes'));
|
||||
|
||||
if (uriAction === 'create')
|
||||
$('legendText').innerText = 'QBT_TR(Tag:)QBT_TR[CONTEXT=TagFilterWidget]';
|
||||
|
|
|
@ -24,21 +24,10 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
this.torrentsTable = new TorrentsTable();
|
||||
const torrentTrackersTable = new TorrentTrackersTable();
|
||||
const torrentPeersTable = new TorrentPeersTable();
|
||||
const torrentFilesTable = new TorrentFilesTable();
|
||||
const searchResultsTable = new SearchResultsTable();
|
||||
const searchPluginsTable = new SearchPluginsTable();
|
||||
this.torrentsTable = new window.qBittorrent.DynamicTable.TorrentsTable();
|
||||
|
||||
let updatePropertiesPanel = function() {};
|
||||
|
||||
let updateTorrentData = function() {};
|
||||
let updateTrackersData = function() {};
|
||||
let updateTorrentPeersData = function() {};
|
||||
let updateWebSeedsData = function() {};
|
||||
let updateTorrentFilesData = function() {};
|
||||
|
||||
this.updateMainData = function() {};
|
||||
let alternativeSpeedLimits = false;
|
||||
let queueing_enabled = true;
|
||||
|
@ -365,12 +354,12 @@ window.addEvent('load', function() {
|
|||
const create_link = function(hash, text, count) {
|
||||
const html = '<a href="#" onclick="setCategoryFilter(' + hash + ');return false;">'
|
||||
+ '<img src="images/qbt-theme/inode-directory.svg"/>'
|
||||
+ escapeHtml(text) + ' (' + count + ')' + '</a>';
|
||||
+ window.qBittorrent.Misc.escapeHtml(text) + ' (' + count + ')' + '</a>';
|
||||
const el = new Element('li', {
|
||||
id: hash,
|
||||
html: html
|
||||
});
|
||||
categoriesFilterContextMenu.addTarget(el);
|
||||
window.qBittorrent.Filters.categoriesFilterContextMenu.addTarget(el);
|
||||
return el;
|
||||
};
|
||||
|
||||
|
@ -422,12 +411,12 @@ window.addEvent('load', function() {
|
|||
const createLink = function(hash, text, count) {
|
||||
const html = '<a href="#" onclick="setTagFilter(' + hash + ');return false;">'
|
||||
+ '<img src="images/qbt-theme/inode-directory.svg"/>'
|
||||
+ escapeHtml(text) + ' (' + count + ')' + '</a>';
|
||||
+ window.qBittorrent.Misc.escapeHtml(text) + ' (' + count + ')' + '</a>';
|
||||
const el = new Element('li', {
|
||||
id: hash,
|
||||
html: html
|
||||
});
|
||||
tagsFilterContextMenu.addTarget(el);
|
||||
window.qBittorrent.Filters.tagsFilterContextMenu.addTarget(el);
|
||||
return el;
|
||||
};
|
||||
|
||||
|
@ -579,11 +568,11 @@ window.addEvent('load', function() {
|
|||
updateFiltersList();
|
||||
if (update_categories) {
|
||||
updateCategoryList();
|
||||
torrentsTableContextMenu.updateCategoriesSubMenu(category_list);
|
||||
window.qBittorrent.TransferList.contextMenu.updateCategoriesSubMenu(category_list);
|
||||
}
|
||||
if (updateTags) {
|
||||
updateTagList();
|
||||
torrentsTableContextMenu.updateTagsSubMenu(tagList);
|
||||
window.qBittorrent.TransferList.contextMenu.updateTagsSubMenu(tagList);
|
||||
}
|
||||
|
||||
if (full_update)
|
||||
|
@ -603,39 +592,39 @@ window.addEvent('load', function() {
|
|||
};
|
||||
|
||||
const processServerState = function() {
|
||||
let transfer_info = friendlyUnit(serverState.dl_info_speed, true);
|
||||
let transfer_info = window.qBittorrent.Misc.friendlyUnit(serverState.dl_info_speed, true);
|
||||
if (serverState.dl_rate_limit > 0)
|
||||
transfer_info += " [" + friendlyUnit(serverState.dl_rate_limit, true) + "]";
|
||||
transfer_info += " (" + friendlyUnit(serverState.dl_info_data, false) + ")";
|
||||
transfer_info += " [" + window.qBittorrent.Misc.friendlyUnit(serverState.dl_rate_limit, true) + "]";
|
||||
transfer_info += " (" + window.qBittorrent.Misc.friendlyUnit(serverState.dl_info_data, false) + ")";
|
||||
$("DlInfos").set('html', transfer_info);
|
||||
transfer_info = friendlyUnit(serverState.up_info_speed, true);
|
||||
transfer_info = window.qBittorrent.Misc.friendlyUnit(serverState.up_info_speed, true);
|
||||
if (serverState.up_rate_limit > 0)
|
||||
transfer_info += " [" + friendlyUnit(serverState.up_rate_limit, true) + "]";
|
||||
transfer_info += " (" + friendlyUnit(serverState.up_info_data, false) + ")";
|
||||
transfer_info += " [" + window.qBittorrent.Misc.friendlyUnit(serverState.up_rate_limit, true) + "]";
|
||||
transfer_info += " (" + window.qBittorrent.Misc.friendlyUnit(serverState.up_info_data, false) + ")";
|
||||
$("UpInfos").set('html', transfer_info);
|
||||
if (speedInTitle) {
|
||||
document.title = "QBT_TR([D: %1, U: %2] qBittorrent %3)QBT_TR[CONTEXT=MainWindow]".replace("%1", friendlyUnit(serverState.dl_info_speed, true)).replace("%2", friendlyUnit(serverState.up_info_speed, true)).replace("%3", qbtVersion());
|
||||
document.title = "QBT_TR([D: %1, U: %2] qBittorrent %3)QBT_TR[CONTEXT=MainWindow]".replace("%1", window.qBittorrent.Misc.friendlyUnit(serverState.dl_info_speed, true)).replace("%2", window.qBittorrent.Misc.friendlyUnit(serverState.up_info_speed, true)).replace("%3", qbtVersion());
|
||||
document.title += " QBT_TR(Web UI)QBT_TR[CONTEXT=OptionsDialog]";
|
||||
}
|
||||
else
|
||||
document.title = ("qBittorrent " + qbtVersion() + " QBT_TR(Web UI)QBT_TR[CONTEXT=OptionsDialog]");
|
||||
$('freeSpaceOnDisk').set('html', 'QBT_TR(Free space: %1)QBT_TR[CONTEXT=HttpServer]'.replace("%1", friendlyUnit(serverState.free_space_on_disk)));
|
||||
$('freeSpaceOnDisk').set('html', 'QBT_TR(Free space: %1)QBT_TR[CONTEXT=HttpServer]'.replace("%1", window.qBittorrent.Misc.friendlyUnit(serverState.free_space_on_disk)));
|
||||
$('DHTNodes').set('html', 'QBT_TR(DHT: %1 nodes)QBT_TR[CONTEXT=StatusBar]'.replace("%1", serverState.dht_nodes));
|
||||
|
||||
// Statistics dialog
|
||||
if (document.getElementById("statisticspage")) {
|
||||
$('AlltimeDL').set('html', friendlyUnit(serverState.alltime_dl, false));
|
||||
$('AlltimeUL').set('html', friendlyUnit(serverState.alltime_ul, false));
|
||||
$('TotalWastedSession').set('html', friendlyUnit(serverState.total_wasted_session, false));
|
||||
$('AlltimeDL').set('html', window.qBittorrent.Misc.friendlyUnit(serverState.alltime_dl, false));
|
||||
$('AlltimeUL').set('html', window.qBittorrent.Misc.friendlyUnit(serverState.alltime_ul, false));
|
||||
$('TotalWastedSession').set('html', window.qBittorrent.Misc.friendlyUnit(serverState.total_wasted_session, false));
|
||||
$('GlobalRatio').set('html', serverState.global_ratio);
|
||||
$('TotalPeerConnections').set('html', serverState.total_peer_connections);
|
||||
$('ReadCacheHits').set('html', serverState.read_cache_hits + "%");
|
||||
$('TotalBuffersSize').set('html', friendlyUnit(serverState.total_buffers_size, false));
|
||||
$('TotalBuffersSize').set('html', window.qBittorrent.Misc.friendlyUnit(serverState.total_buffers_size, false));
|
||||
$('WriteCacheOverload').set('html', serverState.write_cache_overload + "%");
|
||||
$('ReadCacheOverload').set('html', serverState.read_cache_overload + "%");
|
||||
$('QueuedIOJobs').set('html', serverState.queued_io_jobs);
|
||||
$('AverageTimeInQueue').set('html', serverState.average_time_queue + " ms");
|
||||
$('TotalQueuedSize').set('html', friendlyUnit(serverState.total_queued_size, false));
|
||||
$('TotalQueuedSize').set('html', window.qBittorrent.Misc.friendlyUnit(serverState.total_queued_size, false));
|
||||
}
|
||||
|
||||
if (serverState.connection_status == "connected")
|
||||
|
@ -790,7 +779,7 @@ window.addEvent('load', function() {
|
|||
|
||||
const showSearchTab = function() {
|
||||
if (!searchTabInitialized) {
|
||||
initSearchTab();
|
||||
window.qBittorrent.Search.init();
|
||||
searchTabInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -878,16 +867,26 @@ window.addEvent('load', function() {
|
|||
MochaUI.initializeTabs('propertiesTabs');
|
||||
|
||||
updatePropertiesPanel = function() {
|
||||
if (!$('prop_general').hasClass('invisible'))
|
||||
updateTorrentData();
|
||||
else if (!$('prop_trackers').hasClass('invisible'))
|
||||
updateTrackersData();
|
||||
else if (!$('prop_peers').hasClass('invisible'))
|
||||
updateTorrentPeersData();
|
||||
else if (!$('prop_webseeds').hasClass('invisible'))
|
||||
updateWebSeedsData();
|
||||
else if (!$('prop_files').hasClass('invisible'))
|
||||
updateTorrentFilesData();
|
||||
if (!$('prop_general').hasClass('invisible')) {
|
||||
if (window.qBittorrent.PropGeneral !== undefined)
|
||||
window.qBittorrent.PropGeneral.updateData();
|
||||
}
|
||||
else if (!$('prop_trackers').hasClass('invisible')) {
|
||||
if (window.qBittorrent.PropTrackers !== undefined)
|
||||
window.qBittorrent.PropTrackers.updateData();
|
||||
}
|
||||
else if (!$('prop_peers').hasClass('invisible')) {
|
||||
if (window.qBittorrent.PropPeers !== undefined)
|
||||
window.qBittorrent.PropPeers.updateData();
|
||||
}
|
||||
else if (!$('prop_webseeds').hasClass('invisible')) {
|
||||
if (window.qBittorrent.PropWebseeds !== undefined)
|
||||
window.qBittorrent.PropWebseeds.updateData();
|
||||
}
|
||||
else if (!$('prop_files').hasClass('invisible')) {
|
||||
if (window.qBittorrent.PropFiles !== undefined)
|
||||
window.qBittorrent.PropFiles.updateData();
|
||||
}
|
||||
};
|
||||
|
||||
$('PropGeneralLink').addEvent('click', function(e) {
|
||||
|
|
|
@ -28,497 +28,515 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
let lastShownContextMenu = null;
|
||||
const ContextMenu = new Class({
|
||||
//implements
|
||||
Implements: [Options, Events],
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
//options
|
||||
options: {
|
||||
actions: {},
|
||||
menu: 'menu_id',
|
||||
stopEvent: true,
|
||||
targets: 'body',
|
||||
offsets: {
|
||||
x: 0,
|
||||
y: 0
|
||||
window.qBittorrent.ContextMenu = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
ContextMenu: ContextMenu,
|
||||
TorrentsTableContextMenu: TorrentsTableContextMenu,
|
||||
CategoriesFilterContextMenu: CategoriesFilterContextMenu,
|
||||
TagsFilterContextMenu: TagsFilterContextMenu,
|
||||
SearchPluginsTableContextMenu: SearchPluginsTableContextMenu
|
||||
};
|
||||
};
|
||||
|
||||
let lastShownContextMenu = null;
|
||||
const ContextMenu = new Class({
|
||||
//implements
|
||||
Implements: [Options, Events],
|
||||
|
||||
//options
|
||||
options: {
|
||||
actions: {},
|
||||
menu: 'menu_id',
|
||||
stopEvent: true,
|
||||
targets: 'body',
|
||||
offsets: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
onShow: $empty,
|
||||
onHide: $empty,
|
||||
onClick: $empty,
|
||||
fadeSpeed: 200,
|
||||
touchTimer: 600
|
||||
},
|
||||
onShow: $empty,
|
||||
onHide: $empty,
|
||||
onClick: $empty,
|
||||
fadeSpeed: 200,
|
||||
touchTimer: 600
|
||||
},
|
||||
|
||||
//initialization
|
||||
initialize: function(options) {
|
||||
//set options
|
||||
this.setOptions(options);
|
||||
//initialization
|
||||
initialize: function(options) {
|
||||
//set options
|
||||
this.setOptions(options);
|
||||
|
||||
//option diffs menu
|
||||
this.menu = $(this.options.menu);
|
||||
this.targets = $$(this.options.targets);
|
||||
//option diffs menu
|
||||
this.menu = $(this.options.menu);
|
||||
this.targets = $$(this.options.targets);
|
||||
|
||||
//fx
|
||||
this.fx = new Fx.Tween(this.menu, {
|
||||
property: 'opacity',
|
||||
duration: this.options.fadeSpeed,
|
||||
onComplete: function() {
|
||||
if (this.getStyle('opacity')) {
|
||||
this.setStyle('visibility', 'visible');
|
||||
}
|
||||
else {
|
||||
this.setStyle('visibility', 'hidden');
|
||||
}
|
||||
}.bind(this.menu)
|
||||
});
|
||||
//fx
|
||||
this.fx = new Fx.Tween(this.menu, {
|
||||
property: 'opacity',
|
||||
duration: this.options.fadeSpeed,
|
||||
onComplete: function() {
|
||||
if (this.getStyle('opacity')) {
|
||||
this.setStyle('visibility', 'visible');
|
||||
}
|
||||
else {
|
||||
this.setStyle('visibility', 'hidden');
|
||||
}
|
||||
}.bind(this.menu)
|
||||
});
|
||||
|
||||
//hide and begin the listener
|
||||
this.hide().startListener();
|
||||
//hide and begin the listener
|
||||
this.hide().startListener();
|
||||
|
||||
//hide the menu
|
||||
this.menu.setStyles({
|
||||
'position': 'absolute',
|
||||
'top': '-900000px',
|
||||
'display': 'block'
|
||||
});
|
||||
},
|
||||
|
||||
adjustMenuPosition: function(e) {
|
||||
this.updateMenuItems();
|
||||
|
||||
const scrollableMenuMaxHeight = document.documentElement.clientHeight * 0.75;
|
||||
|
||||
if (this.menu.hasClass('scrollableMenu'))
|
||||
this.menu.setStyle('max-height', scrollableMenuMaxHeight);
|
||||
|
||||
// draw the menu off-screen to know the menu dimensions
|
||||
this.menu.setStyles({
|
||||
left: '-999em',
|
||||
top: '-999em'
|
||||
});
|
||||
|
||||
// position the menu
|
||||
let xPosMenu = e.page.x + this.options.offsets.x;
|
||||
let yPosMenu = e.page.y + this.options.offsets.y;
|
||||
if (xPosMenu + this.menu.offsetWidth > document.documentElement.clientWidth)
|
||||
xPosMenu -= this.menu.offsetWidth;
|
||||
if (yPosMenu + this.menu.offsetHeight > document.documentElement.clientHeight)
|
||||
yPosMenu = document.documentElement.clientHeight - this.menu.offsetHeight;
|
||||
if (xPosMenu < 0)
|
||||
xPosMenu = 0;
|
||||
if (yPosMenu < 0)
|
||||
yPosMenu = 0;
|
||||
this.menu.setStyles({
|
||||
left: xPosMenu,
|
||||
top: yPosMenu,
|
||||
position: 'absolute',
|
||||
'z-index': '2000'
|
||||
});
|
||||
|
||||
// position the sub-menu
|
||||
const uls = this.menu.getElementsByTagName('ul');
|
||||
for (let i = 0; i < uls.length; ++i) {
|
||||
const ul = uls[i];
|
||||
if (ul.hasClass('scrollableMenu'))
|
||||
ul.setStyle('max-height', scrollableMenuMaxHeight);
|
||||
const rectParent = ul.parentNode.getBoundingClientRect();
|
||||
const xPosOrigin = rectParent.left;
|
||||
const yPosOrigin = rectParent.bottom;
|
||||
let xPos = xPosOrigin + rectParent.width - 1;
|
||||
let yPos = yPosOrigin - rectParent.height - 1;
|
||||
if (xPos + ul.offsetWidth > document.documentElement.clientWidth)
|
||||
xPos -= (ul.offsetWidth + rectParent.width - 2);
|
||||
if (yPos + ul.offsetHeight > document.documentElement.clientHeight)
|
||||
yPos = document.documentElement.clientHeight - ul.offsetHeight;
|
||||
if (xPos < 0)
|
||||
xPos = 0;
|
||||
if (yPos < 0)
|
||||
yPos = 0;
|
||||
ul.setStyles({
|
||||
'margin-left': xPos - xPosOrigin,
|
||||
'margin-top': yPos - yPosOrigin
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
setupEventListeners: function(elem) {
|
||||
elem.addEvent('contextmenu', function(e) {
|
||||
this.triggerMenu(e, elem);
|
||||
}.bind(this));
|
||||
elem.addEvent('click', function(e) {
|
||||
this.hide();
|
||||
}.bind(this));
|
||||
|
||||
elem.addEvent('touchstart', function(e) {
|
||||
e.preventDefault();
|
||||
clearTimeout(this.touchstartTimer);
|
||||
this.hide();
|
||||
|
||||
const touchstartEvent = e;
|
||||
this.touchstartTimer = setTimeout(function() {
|
||||
this.triggerMenu(touchstartEvent, elem);
|
||||
}.bind(this), this.options.touchTimer);
|
||||
}.bind(this));
|
||||
elem.addEvent('touchend', function(e) {
|
||||
e.preventDefault();
|
||||
clearTimeout(this.touchstartTimer);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
addTarget: function(t) {
|
||||
this.targets[this.targets.length] = t;
|
||||
this.setupEventListeners(t);
|
||||
},
|
||||
|
||||
triggerMenu: function(e, el) {
|
||||
if (this.options.disabled)
|
||||
return;
|
||||
|
||||
//prevent default, if told to
|
||||
if (this.options.stopEvent) {
|
||||
e.stop();
|
||||
}
|
||||
//record this as the trigger
|
||||
this.options.element = $(el);
|
||||
this.adjustMenuPosition(e);
|
||||
//show the menu
|
||||
this.show();
|
||||
},
|
||||
|
||||
//get things started
|
||||
startListener: function() {
|
||||
/* all elements */
|
||||
this.targets.each(function(el) {
|
||||
this.setupEventListeners(el);
|
||||
}.bind(this), this);
|
||||
|
||||
/* menu items */
|
||||
this.menu.getElements('a').each(function(item) {
|
||||
item.addEvent('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (!item.hasClass('disabled')) {
|
||||
this.execute(item.get('href').split('#')[1], $(this.options.element));
|
||||
this.fireEvent('click', [item, e]);
|
||||
}
|
||||
}.bind(this));
|
||||
}, this);
|
||||
|
||||
//hide on body click
|
||||
$(document.body).addEvent('click', function() {
|
||||
this.hide();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
updateMenuItems: function() {},
|
||||
|
||||
//show menu
|
||||
show: function(trigger) {
|
||||
if (lastShownContextMenu && lastShownContextMenu != this)
|
||||
lastShownContextMenu.hide();
|
||||
this.fx.start(1);
|
||||
this.fireEvent('show');
|
||||
this.shown = true;
|
||||
lastShownContextMenu = this;
|
||||
return this;
|
||||
},
|
||||
|
||||
//hide the menu
|
||||
this.menu.setStyles({
|
||||
'position': 'absolute',
|
||||
'top': '-900000px',
|
||||
'display': 'block'
|
||||
});
|
||||
},
|
||||
hide: function(trigger) {
|
||||
if (this.shown) {
|
||||
this.fx.start(0);
|
||||
//this.menu.fade('out');
|
||||
this.fireEvent('hide');
|
||||
this.shown = false;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
adjustMenuPosition: function(e) {
|
||||
this.updateMenuItems();
|
||||
setItemChecked: function(item, checked) {
|
||||
this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity =
|
||||
checked ? '1' : '0';
|
||||
return this;
|
||||
},
|
||||
|
||||
const scrollableMenuMaxHeight = document.documentElement.clientHeight * 0.75;
|
||||
getItemChecked: function(item) {
|
||||
return '0' != this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity;
|
||||
},
|
||||
|
||||
if (this.menu.hasClass('scrollableMenu'))
|
||||
this.menu.setStyle('max-height', scrollableMenuMaxHeight);
|
||||
//hide an item
|
||||
hideItem: function(item) {
|
||||
this.menu.getElement('a[href$=' + item + ']').parentNode.addClass('invisible');
|
||||
return this;
|
||||
},
|
||||
|
||||
// draw the menu off-screen to know the menu dimensions
|
||||
this.menu.setStyles({
|
||||
left: '-999em',
|
||||
top: '-999em'
|
||||
});
|
||||
//show an item
|
||||
showItem: function(item) {
|
||||
this.menu.getElement('a[href$=' + item + ']').parentNode.removeClass('invisible');
|
||||
return this;
|
||||
},
|
||||
|
||||
// position the menu
|
||||
let xPosMenu = e.page.x + this.options.offsets.x;
|
||||
let yPosMenu = e.page.y + this.options.offsets.y;
|
||||
if (xPosMenu + this.menu.offsetWidth > document.documentElement.clientWidth)
|
||||
xPosMenu -= this.menu.offsetWidth;
|
||||
if (yPosMenu + this.menu.offsetHeight > document.documentElement.clientHeight)
|
||||
yPosMenu = document.documentElement.clientHeight - this.menu.offsetHeight;
|
||||
if (xPosMenu < 0)
|
||||
xPosMenu = 0;
|
||||
if (yPosMenu < 0)
|
||||
yPosMenu = 0;
|
||||
this.menu.setStyles({
|
||||
left: xPosMenu,
|
||||
top: yPosMenu,
|
||||
position: 'absolute',
|
||||
'z-index': '2000'
|
||||
});
|
||||
//disable the entire menu
|
||||
disable: function() {
|
||||
this.options.disabled = true;
|
||||
return this;
|
||||
},
|
||||
|
||||
// position the sub-menu
|
||||
const uls = this.menu.getElementsByTagName('ul');
|
||||
for (let i = 0; i < uls.length; ++i) {
|
||||
const ul = uls[i];
|
||||
if (ul.hasClass('scrollableMenu'))
|
||||
ul.setStyle('max-height', scrollableMenuMaxHeight);
|
||||
const rectParent = ul.parentNode.getBoundingClientRect();
|
||||
const xPosOrigin = rectParent.left;
|
||||
const yPosOrigin = rectParent.bottom;
|
||||
let xPos = xPosOrigin + rectParent.width - 1;
|
||||
let yPos = yPosOrigin - rectParent.height - 1;
|
||||
if (xPos + ul.offsetWidth > document.documentElement.clientWidth)
|
||||
xPos -= (ul.offsetWidth + rectParent.width - 2);
|
||||
if (yPos + ul.offsetHeight > document.documentElement.clientHeight)
|
||||
yPos = document.documentElement.clientHeight - ul.offsetHeight;
|
||||
if (xPos < 0)
|
||||
xPos = 0;
|
||||
if (yPos < 0)
|
||||
yPos = 0;
|
||||
ul.setStyles({
|
||||
'margin-left': xPos - xPosOrigin,
|
||||
'margin-top': yPos - yPosOrigin
|
||||
});
|
||||
//enable the entire menu
|
||||
enable: function() {
|
||||
this.options.disabled = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
//execute an action
|
||||
execute: function(action, element) {
|
||||
if (this.options.actions[action]) {
|
||||
this.options.actions[action](element, this, action);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
setupEventListeners: function(elem) {
|
||||
elem.addEvent('contextmenu', function(e) {
|
||||
this.triggerMenu(e, elem);
|
||||
}.bind(this));
|
||||
elem.addEvent('click', function(e) {
|
||||
this.hide();
|
||||
}.bind(this));
|
||||
const TorrentsTableContextMenu = new Class({
|
||||
Extends: ContextMenu,
|
||||
|
||||
elem.addEvent('touchstart', function(e) {
|
||||
e.preventDefault();
|
||||
clearTimeout(this.touchstartTimer);
|
||||
this.hide();
|
||||
updateMenuItems: function() {
|
||||
let all_are_seq_dl = true;
|
||||
let there_are_seq_dl = false;
|
||||
let all_are_f_l_piece_prio = true;
|
||||
let there_are_f_l_piece_prio = false;
|
||||
let all_are_downloaded = true;
|
||||
let all_are_paused = true;
|
||||
let there_are_paused = false;
|
||||
let all_are_force_start = true;
|
||||
let there_are_force_start = false;
|
||||
let all_are_super_seeding = true;
|
||||
let all_are_auto_tmm = true;
|
||||
let there_are_auto_tmm = false;
|
||||
const tagsSelectionState = Object.clone(tagList);
|
||||
|
||||
const touchstartEvent = e;
|
||||
this.touchstartTimer = setTimeout(function() {
|
||||
this.triggerMenu(touchstartEvent, elem);
|
||||
}.bind(this), this.options.touchTimer);
|
||||
}.bind(this));
|
||||
elem.addEvent('touchend', function(e) {
|
||||
e.preventDefault();
|
||||
clearTimeout(this.touchstartTimer);
|
||||
}.bind(this));
|
||||
},
|
||||
const h = torrentsTable.selectedRowsIds();
|
||||
h.each(function(item, index) {
|
||||
const data = torrentsTable.rows.get(item).full_data;
|
||||
|
||||
addTarget: function(t) {
|
||||
this.targets[this.targets.length] = t;
|
||||
this.setupEventListeners(t);
|
||||
},
|
||||
|
||||
triggerMenu: function(e, el) {
|
||||
if (this.options.disabled)
|
||||
return;
|
||||
|
||||
//prevent default, if told to
|
||||
if (this.options.stopEvent) {
|
||||
e.stop();
|
||||
}
|
||||
//record this as the trigger
|
||||
this.options.element = $(el);
|
||||
this.adjustMenuPosition(e);
|
||||
//show the menu
|
||||
this.show();
|
||||
},
|
||||
|
||||
//get things started
|
||||
startListener: function() {
|
||||
/* all elements */
|
||||
this.targets.each(function(el) {
|
||||
this.setupEventListeners(el);
|
||||
}.bind(this), this);
|
||||
|
||||
/* menu items */
|
||||
this.menu.getElements('a').each(function(item) {
|
||||
item.addEvent('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (!item.hasClass('disabled')) {
|
||||
this.execute(item.get('href').split('#')[1], $(this.options.element));
|
||||
this.fireEvent('click', [item, e]);
|
||||
}
|
||||
}.bind(this));
|
||||
}, this);
|
||||
|
||||
//hide on body click
|
||||
$(document.body).addEvent('click', function() {
|
||||
this.hide();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
updateMenuItems: function() {},
|
||||
|
||||
//show menu
|
||||
show: function(trigger) {
|
||||
if (lastShownContextMenu && lastShownContextMenu != this)
|
||||
lastShownContextMenu.hide();
|
||||
this.fx.start(1);
|
||||
this.fireEvent('show');
|
||||
this.shown = true;
|
||||
lastShownContextMenu = this;
|
||||
return this;
|
||||
},
|
||||
|
||||
//hide the menu
|
||||
hide: function(trigger) {
|
||||
if (this.shown) {
|
||||
this.fx.start(0);
|
||||
//this.menu.fade('out');
|
||||
this.fireEvent('hide');
|
||||
this.shown = false;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
setItemChecked: function(item, checked) {
|
||||
this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity =
|
||||
checked ? '1' : '0';
|
||||
return this;
|
||||
},
|
||||
|
||||
getItemChecked: function(item) {
|
||||
return '0' != this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity;
|
||||
},
|
||||
|
||||
//hide an item
|
||||
hideItem: function(item) {
|
||||
this.menu.getElement('a[href$=' + item + ']').parentNode.addClass('invisible');
|
||||
return this;
|
||||
},
|
||||
|
||||
//show an item
|
||||
showItem: function(item) {
|
||||
this.menu.getElement('a[href$=' + item + ']').parentNode.removeClass('invisible');
|
||||
return this;
|
||||
},
|
||||
|
||||
//disable the entire menu
|
||||
disable: function() {
|
||||
this.options.disabled = true;
|
||||
return this;
|
||||
},
|
||||
|
||||
//enable the entire menu
|
||||
enable: function() {
|
||||
this.options.disabled = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
//execute an action
|
||||
execute: function(action, element) {
|
||||
if (this.options.actions[action]) {
|
||||
this.options.actions[action](element, this, action);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
const TorrentsTableContextMenu = new Class({
|
||||
Extends: ContextMenu,
|
||||
|
||||
updateMenuItems: function() {
|
||||
let all_are_seq_dl = true;
|
||||
let there_are_seq_dl = false;
|
||||
let all_are_f_l_piece_prio = true;
|
||||
let there_are_f_l_piece_prio = false;
|
||||
let all_are_downloaded = true;
|
||||
let all_are_paused = true;
|
||||
let there_are_paused = false;
|
||||
let all_are_force_start = true;
|
||||
let there_are_force_start = false;
|
||||
let all_are_super_seeding = true;
|
||||
let all_are_auto_tmm = true;
|
||||
let there_are_auto_tmm = false;
|
||||
const tagsSelectionState = Object.clone(tagList);
|
||||
|
||||
const h = torrentsTable.selectedRowsIds();
|
||||
h.each(function(item, index) {
|
||||
const data = torrentsTable.rows.get(item).full_data;
|
||||
|
||||
if (data['seq_dl'] !== true)
|
||||
all_are_seq_dl = false;
|
||||
else
|
||||
there_are_seq_dl = true;
|
||||
|
||||
if (data['f_l_piece_prio'] !== true)
|
||||
all_are_f_l_piece_prio = false;
|
||||
else
|
||||
there_are_f_l_piece_prio = true;
|
||||
|
||||
if (data['progress'] != 1.0) // not downloaded
|
||||
all_are_downloaded = false;
|
||||
else if (data['super_seeding'] !== true)
|
||||
all_are_super_seeding = false;
|
||||
|
||||
if (data['state'] != 'pausedUP' && data['state'] != 'pausedDL')
|
||||
all_are_paused = false;
|
||||
else
|
||||
there_are_paused = true;
|
||||
|
||||
if (data['force_start'] !== true)
|
||||
all_are_force_start = false;
|
||||
else
|
||||
there_are_force_start = true;
|
||||
|
||||
if (data['auto_tmm'] === true)
|
||||
there_are_auto_tmm = true;
|
||||
else
|
||||
all_are_auto_tmm = false;
|
||||
|
||||
const torrentTags = data['tags'].split(', ');
|
||||
for (const key in tagsSelectionState) {
|
||||
const tag = tagsSelectionState[key];
|
||||
const tagExists = torrentTags.contains(tag.name);
|
||||
if ((tag.checked !== undefined) && (tag.checked != tagExists))
|
||||
tag.indeterminate = true;
|
||||
if (tag.checked === undefined)
|
||||
tag.checked = tagExists;
|
||||
if (data['seq_dl'] !== true)
|
||||
all_are_seq_dl = false;
|
||||
else
|
||||
tag.checked = tag.checked && tagExists;
|
||||
}
|
||||
});
|
||||
there_are_seq_dl = true;
|
||||
|
||||
let show_seq_dl = true;
|
||||
if (data['f_l_piece_prio'] !== true)
|
||||
all_are_f_l_piece_prio = false;
|
||||
else
|
||||
there_are_f_l_piece_prio = true;
|
||||
|
||||
if (!all_are_seq_dl && there_are_seq_dl)
|
||||
show_seq_dl = false;
|
||||
if (data['progress'] != 1.0) // not downloaded
|
||||
all_are_downloaded = false;
|
||||
else if (data['super_seeding'] !== true)
|
||||
all_are_super_seeding = false;
|
||||
|
||||
let show_f_l_piece_prio = true;
|
||||
if (data['state'] != 'pausedUP' && data['state'] != 'pausedDL')
|
||||
all_are_paused = false;
|
||||
else
|
||||
there_are_paused = true;
|
||||
|
||||
if (!all_are_f_l_piece_prio && there_are_f_l_piece_prio)
|
||||
show_f_l_piece_prio = false;
|
||||
if (data['force_start'] !== true)
|
||||
all_are_force_start = false;
|
||||
else
|
||||
there_are_force_start = true;
|
||||
|
||||
if (all_are_downloaded) {
|
||||
this.hideItem('downloadLimit');
|
||||
this.menu.getElement('a[href$=uploadLimit]').parentNode.addClass('separator');
|
||||
this.hideItem('sequentialDownload');
|
||||
this.hideItem('firstLastPiecePrio');
|
||||
this.showItem('superSeeding');
|
||||
this.setItemChecked('superSeeding', all_are_super_seeding);
|
||||
}
|
||||
else {
|
||||
if (!show_seq_dl && show_f_l_piece_prio)
|
||||
this.menu.getElement('a[href$=firstLastPiecePrio]').parentNode.addClass('separator');
|
||||
else
|
||||
this.menu.getElement('a[href$=firstLastPiecePrio]').parentNode.removeClass('separator');
|
||||
if (data['auto_tmm'] === true)
|
||||
there_are_auto_tmm = true;
|
||||
else
|
||||
all_are_auto_tmm = false;
|
||||
|
||||
if (show_seq_dl)
|
||||
this.showItem('sequentialDownload');
|
||||
else
|
||||
const torrentTags = data['tags'].split(', ');
|
||||
for (const key in tagsSelectionState) {
|
||||
const tag = tagsSelectionState[key];
|
||||
const tagExists = torrentTags.contains(tag.name);
|
||||
if ((tag.checked !== undefined) && (tag.checked != tagExists))
|
||||
tag.indeterminate = true;
|
||||
if (tag.checked === undefined)
|
||||
tag.checked = tagExists;
|
||||
else
|
||||
tag.checked = tag.checked && tagExists;
|
||||
}
|
||||
});
|
||||
|
||||
let show_seq_dl = true;
|
||||
|
||||
if (!all_are_seq_dl && there_are_seq_dl)
|
||||
show_seq_dl = false;
|
||||
|
||||
let show_f_l_piece_prio = true;
|
||||
|
||||
if (!all_are_f_l_piece_prio && there_are_f_l_piece_prio)
|
||||
show_f_l_piece_prio = false;
|
||||
|
||||
if (all_are_downloaded) {
|
||||
this.hideItem('downloadLimit');
|
||||
this.menu.getElement('a[href$=uploadLimit]').parentNode.addClass('separator');
|
||||
this.hideItem('sequentialDownload');
|
||||
|
||||
if (show_f_l_piece_prio)
|
||||
this.showItem('firstLastPiecePrio');
|
||||
else
|
||||
this.hideItem('firstLastPiecePrio');
|
||||
|
||||
this.setItemChecked('sequentialDownload', all_are_seq_dl);
|
||||
this.setItemChecked('firstLastPiecePrio', all_are_f_l_piece_prio);
|
||||
|
||||
this.showItem('downloadLimit');
|
||||
this.menu.getElement('a[href$=uploadLimit]').parentNode.removeClass('separator');
|
||||
this.hideItem('superSeeding');
|
||||
}
|
||||
|
||||
this.showItem('start');
|
||||
this.showItem('pause');
|
||||
this.showItem('forceStart');
|
||||
if (all_are_paused)
|
||||
this.hideItem('pause');
|
||||
else if (all_are_force_start)
|
||||
this.hideItem('forceStart');
|
||||
else if (!there_are_paused && !there_are_force_start)
|
||||
this.hideItem('start');
|
||||
|
||||
if (!all_are_auto_tmm && there_are_auto_tmm) {
|
||||
this.hideItem('autoTorrentManagement');
|
||||
}
|
||||
else {
|
||||
this.showItem('autoTorrentManagement');
|
||||
this.setItemChecked('autoTorrentManagement', all_are_auto_tmm);
|
||||
}
|
||||
|
||||
const contextTagList = $('contextTagList');
|
||||
for (const tagHash in tagList) {
|
||||
const checkbox = contextTagList.getElement('a[href=#Tag/' + tagHash + '] input[type=checkbox]');
|
||||
const checkboxState = tagsSelectionState[tagHash];
|
||||
checkbox.indeterminate = checkboxState.indeterminate;
|
||||
checkbox.checked = checkboxState.checked;
|
||||
}
|
||||
},
|
||||
|
||||
updateCategoriesSubMenu: function(category_list) {
|
||||
const categoryList = $('contextCategoryList');
|
||||
categoryList.empty();
|
||||
categoryList.appendChild(new Element('li', {
|
||||
html: '<a href="javascript:torrentNewCategoryFN();"><img src="images/qbt-theme/list-add.svg" alt="QBT_TR(New...)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(New...)QBT_TR[CONTEXT=TransferListWidget]</a>'
|
||||
}));
|
||||
categoryList.appendChild(new Element('li', {
|
||||
html: '<a href="javascript:torrentSetCategoryFN(0);"><img src="images/qbt-theme/edit-clear.svg" alt="QBT_TR(Reset)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Reset)QBT_TR[CONTEXT=TransferListWidget]</a>'
|
||||
}));
|
||||
|
||||
const sortedCategories = [];
|
||||
Object.each(category_list, function(category) {
|
||||
sortedCategories.push(category.name);
|
||||
});
|
||||
sortedCategories.sort();
|
||||
|
||||
let first = true;
|
||||
Object.each(sortedCategories, function(categoryName) {
|
||||
const categoryHash = genHash(categoryName);
|
||||
const el = new Element('li', {
|
||||
html: '<a href="javascript:torrentSetCategoryFN(\'' + categoryHash + '\');"><img src="images/qbt-theme/inode-directory.svg"/> ' + escapeHtml(categoryName) + '</a>'
|
||||
});
|
||||
if (first) {
|
||||
el.addClass('separator');
|
||||
first = false;
|
||||
this.showItem('superSeeding');
|
||||
this.setItemChecked('superSeeding', all_are_super_seeding);
|
||||
}
|
||||
categoryList.appendChild(el);
|
||||
});
|
||||
},
|
||||
else {
|
||||
if (!show_seq_dl && show_f_l_piece_prio)
|
||||
this.menu.getElement('a[href$=firstLastPiecePrio]').parentNode.addClass('separator');
|
||||
else
|
||||
this.menu.getElement('a[href$=firstLastPiecePrio]').parentNode.removeClass('separator');
|
||||
|
||||
updateTagsSubMenu: function(tagList) {
|
||||
const contextTagList = $('contextTagList');
|
||||
while (contextTagList.firstChild !== null)
|
||||
contextTagList.removeChild(contextTagList.firstChild);
|
||||
if (show_seq_dl)
|
||||
this.showItem('sequentialDownload');
|
||||
else
|
||||
this.hideItem('sequentialDownload');
|
||||
|
||||
contextTagList.appendChild(new Element('li', {
|
||||
html: '<a href="javascript:torrentAddTagsFN();">'
|
||||
+ '<img src="images/qbt-theme/list-add.svg" alt="QBT_TR(Add...)QBT_TR[CONTEXT=TransferListWidget]"/>'
|
||||
+ ' QBT_TR(Add...)QBT_TR[CONTEXT=TransferListWidget]'
|
||||
+ '</a>'
|
||||
}));
|
||||
contextTagList.appendChild(new Element('li', {
|
||||
html: '<a href="javascript:torrentRemoveAllTagsFN();">'
|
||||
+ '<img src="images/qbt-theme/edit-clear.svg" alt="QBT_TR(Remove All)QBT_TR[CONTEXT=TransferListWidget]"/>'
|
||||
+ ' QBT_TR(Remove All)QBT_TR[CONTEXT=TransferListWidget]'
|
||||
+ '</a>'
|
||||
}));
|
||||
if (show_f_l_piece_prio)
|
||||
this.showItem('firstLastPiecePrio');
|
||||
else
|
||||
this.hideItem('firstLastPiecePrio');
|
||||
|
||||
const sortedTags = [];
|
||||
for (const key in tagList)
|
||||
sortedTags.push(tagList[key].name);
|
||||
sortedTags.sort();
|
||||
this.setItemChecked('sequentialDownload', all_are_seq_dl);
|
||||
this.setItemChecked('firstLastPiecePrio', all_are_f_l_piece_prio);
|
||||
|
||||
for (let i = 0; i < sortedTags.length; ++i) {
|
||||
const tagName = sortedTags[i];
|
||||
const tagHash = genHash(tagName);
|
||||
const el = new Element('li', {
|
||||
html: '<a href="#Tag/' + tagHash + '" onclick="event.preventDefault(); torrentSetTagsFN(\'' + tagHash + '\', !event.currentTarget.getElement(\'input[type=checkbox]\').checked);">'
|
||||
+ '<input type="checkbox" onclick="this.checked = !this.checked;"> ' + escapeHtml(tagName)
|
||||
+ '</a>'
|
||||
this.showItem('downloadLimit');
|
||||
this.menu.getElement('a[href$=uploadLimit]').parentNode.removeClass('separator');
|
||||
this.hideItem('superSeeding');
|
||||
}
|
||||
|
||||
this.showItem('start');
|
||||
this.showItem('pause');
|
||||
this.showItem('forceStart');
|
||||
if (all_are_paused)
|
||||
this.hideItem('pause');
|
||||
else if (all_are_force_start)
|
||||
this.hideItem('forceStart');
|
||||
else if (!there_are_paused && !there_are_force_start)
|
||||
this.hideItem('start');
|
||||
|
||||
if (!all_are_auto_tmm && there_are_auto_tmm) {
|
||||
this.hideItem('autoTorrentManagement');
|
||||
}
|
||||
else {
|
||||
this.showItem('autoTorrentManagement');
|
||||
this.setItemChecked('autoTorrentManagement', all_are_auto_tmm);
|
||||
}
|
||||
|
||||
const contextTagList = $('contextTagList');
|
||||
for (const tagHash in tagList) {
|
||||
const checkbox = contextTagList.getElement('a[href=#Tag/' + tagHash + '] input[type=checkbox]');
|
||||
const checkboxState = tagsSelectionState[tagHash];
|
||||
checkbox.indeterminate = checkboxState.indeterminate;
|
||||
checkbox.checked = checkboxState.checked;
|
||||
}
|
||||
},
|
||||
|
||||
updateCategoriesSubMenu: function(category_list) {
|
||||
const categoryList = $('contextCategoryList');
|
||||
categoryList.empty();
|
||||
categoryList.appendChild(new Element('li', {
|
||||
html: '<a href="javascript:torrentNewCategoryFN();"><img src="images/qbt-theme/list-add.svg" alt="QBT_TR(New...)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(New...)QBT_TR[CONTEXT=TransferListWidget]</a>'
|
||||
}));
|
||||
categoryList.appendChild(new Element('li', {
|
||||
html: '<a href="javascript:torrentSetCategoryFN(0);"><img src="images/qbt-theme/edit-clear.svg" alt="QBT_TR(Reset)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Reset)QBT_TR[CONTEXT=TransferListWidget]</a>'
|
||||
}));
|
||||
|
||||
const sortedCategories = [];
|
||||
Object.each(category_list, function(category) {
|
||||
sortedCategories.push(category.name);
|
||||
});
|
||||
if (i === 0)
|
||||
el.addClass('separator');
|
||||
contextTagList.appendChild(el);
|
||||
sortedCategories.sort();
|
||||
|
||||
let first = true;
|
||||
Object.each(sortedCategories, function(categoryName) {
|
||||
const categoryHash = genHash(categoryName);
|
||||
const el = new Element('li', {
|
||||
html: '<a href="javascript:torrentSetCategoryFN(\'' + categoryHash + '\');"><img src="images/qbt-theme/inode-directory.svg"/> ' + window.qBittorrent.Misc.escapeHtml(categoryName) + '</a>'
|
||||
});
|
||||
if (first) {
|
||||
el.addClass('separator');
|
||||
first = false;
|
||||
}
|
||||
categoryList.appendChild(el);
|
||||
});
|
||||
},
|
||||
|
||||
updateTagsSubMenu: function(tagList) {
|
||||
const contextTagList = $('contextTagList');
|
||||
while (contextTagList.firstChild !== null)
|
||||
contextTagList.removeChild(contextTagList.firstChild);
|
||||
|
||||
contextTagList.appendChild(new Element('li', {
|
||||
html: '<a href="javascript:torrentAddTagsFN();">'
|
||||
+ '<img src="images/qbt-theme/list-add.svg" alt="QBT_TR(Add...)QBT_TR[CONTEXT=TransferListWidget]"/>'
|
||||
+ ' QBT_TR(Add...)QBT_TR[CONTEXT=TransferListWidget]'
|
||||
+ '</a>'
|
||||
}));
|
||||
contextTagList.appendChild(new Element('li', {
|
||||
html: '<a href="javascript:torrentRemoveAllTagsFN();">'
|
||||
+ '<img src="images/qbt-theme/edit-clear.svg" alt="QBT_TR(Remove All)QBT_TR[CONTEXT=TransferListWidget]"/>'
|
||||
+ ' QBT_TR(Remove All)QBT_TR[CONTEXT=TransferListWidget]'
|
||||
+ '</a>'
|
||||
}));
|
||||
|
||||
const sortedTags = [];
|
||||
for (const key in tagList)
|
||||
sortedTags.push(tagList[key].name);
|
||||
sortedTags.sort();
|
||||
|
||||
for (let i = 0; i < sortedTags.length; ++i) {
|
||||
const tagName = sortedTags[i];
|
||||
const tagHash = genHash(tagName);
|
||||
const el = new Element('li', {
|
||||
html: '<a href="#Tag/' + tagHash + '" onclick="event.preventDefault(); torrentSetTagsFN(\'' + tagHash + '\', !event.currentTarget.getElement(\'input[type=checkbox]\').checked);">'
|
||||
+ '<input type="checkbox" onclick="this.checked = !this.checked;"> ' + window.qBittorrent.Misc.escapeHtml(tagName)
|
||||
+ '</a>'
|
||||
});
|
||||
if (i === 0)
|
||||
el.addClass('separator');
|
||||
contextTagList.appendChild(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const CategoriesFilterContextMenu = new Class({
|
||||
Extends: ContextMenu,
|
||||
updateMenuItems: function() {
|
||||
const id = this.options.element.id;
|
||||
if ((id != CATEGORIES_ALL) && (id != CATEGORIES_UNCATEGORIZED)) {
|
||||
this.showItem('editCategory');
|
||||
this.showItem('deleteCategory');
|
||||
const CategoriesFilterContextMenu = new Class({
|
||||
Extends: ContextMenu,
|
||||
updateMenuItems: function() {
|
||||
const id = this.options.element.id;
|
||||
if ((id != CATEGORIES_ALL) && (id != CATEGORIES_UNCATEGORIZED)) {
|
||||
this.showItem('editCategory');
|
||||
this.showItem('deleteCategory');
|
||||
}
|
||||
else {
|
||||
this.hideItem('editCategory');
|
||||
this.hideItem('deleteCategory');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.hideItem('editCategory');
|
||||
this.hideItem('deleteCategory');
|
||||
});
|
||||
|
||||
const TagsFilterContextMenu = new Class({
|
||||
Extends: ContextMenu,
|
||||
updateMenuItems: function() {
|
||||
const id = this.options.element.id;
|
||||
if ((id !== TAGS_ALL.toString()) && (id !== TAGS_UNTAGGED.toString()))
|
||||
this.showItem('deleteTag');
|
||||
else
|
||||
this.hideItem('deleteTag');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const TagsFilterContextMenu = new Class({
|
||||
Extends: ContextMenu,
|
||||
updateMenuItems: function() {
|
||||
const id = this.options.element.id;
|
||||
if ((id !== TAGS_ALL.toString()) && (id !== TAGS_UNTAGGED.toString()))
|
||||
this.showItem('deleteTag');
|
||||
else
|
||||
this.hideItem('deleteTag');
|
||||
}
|
||||
});
|
||||
const SearchPluginsTableContextMenu = new Class({
|
||||
Extends: ContextMenu,
|
||||
|
||||
const SearchPluginsTableContextMenu = new Class({
|
||||
Extends: ContextMenu,
|
||||
updateMenuItems: function() {
|
||||
const enabledColumnIndex = function(text) {
|
||||
const columns = $("searchPluginsTableFixedHeaderRow").getChildren("th");
|
||||
for (let i = 0; i < columns.length; ++i)
|
||||
if (columns[i].get("html") === "Enabled")
|
||||
return i;
|
||||
};
|
||||
|
||||
updateMenuItems: function() {
|
||||
const enabledColumnIndex = function(text) {
|
||||
const columns = $("searchPluginsTableFixedHeaderRow").getChildren("th");
|
||||
for (let i = 0; i < columns.length; ++i)
|
||||
if (columns[i].get("html") === "Enabled")
|
||||
return i;
|
||||
};
|
||||
this.showItem('Enabled');
|
||||
this.setItemChecked('Enabled', this.options.element.getChildren("td")[enabledColumnIndex()].get("html") === "Yes");
|
||||
|
||||
this.showItem('Enabled');
|
||||
this.setItemChecked('Enabled', this.options.element.getChildren("td")[enabledColumnIndex()].get("html") === "Yes");
|
||||
this.showItem('Uninstall');
|
||||
}
|
||||
});
|
||||
|
||||
this.showItem('Uninstall');
|
||||
}
|
||||
});
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -23,98 +23,113 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
let categories = {};
|
||||
let defaultSavePath = "";
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
const getCategories = function() {
|
||||
new Request.JSON({
|
||||
url: 'api/v2/torrents/categories',
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onSuccess: function(data) {
|
||||
if (data) {
|
||||
categories = data;
|
||||
for (const i in data) {
|
||||
const category = data[i];
|
||||
const option = new Element("option");
|
||||
option.set('value', category.name);
|
||||
option.set('html', category.name);
|
||||
$('categorySelect').appendChild(option);
|
||||
window.qBittorrent.Download = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
changeCategorySelect: changeCategorySelect,
|
||||
changeTMM: changeTMM
|
||||
};
|
||||
};
|
||||
|
||||
let categories = {};
|
||||
let defaultSavePath = "";
|
||||
|
||||
const getCategories = function() {
|
||||
new Request.JSON({
|
||||
url: 'api/v2/torrents/categories',
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onSuccess: function(data) {
|
||||
if (data) {
|
||||
categories = data;
|
||||
for (const i in data) {
|
||||
const category = data[i];
|
||||
const option = new Element("option");
|
||||
option.set('value', category.name);
|
||||
option.set('html', category.name);
|
||||
$('categorySelect').appendChild(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
}).send();
|
||||
};
|
||||
|
||||
const getPreferences = function() {
|
||||
new Request.JSON({
|
||||
url: 'api/v2/app/preferences',
|
||||
method: 'get',
|
||||
noCache: true,
|
||||
onFailure: function() {
|
||||
alert("Could not contact qBittorrent");
|
||||
},
|
||||
onSuccess: function(pref) {
|
||||
if (!pref)
|
||||
return;
|
||||
const getPreferences = function() {
|
||||
new Request.JSON({
|
||||
url: 'api/v2/app/preferences',
|
||||
method: 'get',
|
||||
noCache: true,
|
||||
onFailure: function() {
|
||||
alert("Could not contact qBittorrent");
|
||||
},
|
||||
onSuccess: function(pref) {
|
||||
if (!pref)
|
||||
return;
|
||||
|
||||
defaultSavePath = pref.save_path;
|
||||
$('savepath').setProperty('value', defaultSavePath);
|
||||
$('rootFolder').checked = pref.create_subfolder_enabled;
|
||||
$('startTorrent').checked = !pref.start_paused_enabled;
|
||||
defaultSavePath = pref.save_path;
|
||||
$('savepath').setProperty('value', defaultSavePath);
|
||||
$('rootFolder').checked = pref.create_subfolder_enabled;
|
||||
$('startTorrent').checked = !pref.start_paused_enabled;
|
||||
|
||||
if (pref.auto_tmm_enabled == 1) {
|
||||
$('autoTMM').selectedIndex = 1;
|
||||
$('savepath').disabled = true;
|
||||
if (pref.auto_tmm_enabled == 1) {
|
||||
$('autoTMM').selectedIndex = 1;
|
||||
$('savepath').disabled = true;
|
||||
}
|
||||
else {
|
||||
$('autoTMM').selectedIndex = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('autoTMM').selectedIndex = 0;
|
||||
}).send();
|
||||
};
|
||||
|
||||
const changeCategorySelect = function(item) {
|
||||
if (item.value == "\\other") {
|
||||
item.nextElementSibling.hidden = false;
|
||||
item.nextElementSibling.value = "";
|
||||
item.nextElementSibling.select();
|
||||
|
||||
if ($('autoTMM').selectedIndex == 1)
|
||||
$('savepath').value = defaultSavePath;
|
||||
}
|
||||
else {
|
||||
item.nextElementSibling.hidden = true;
|
||||
const text = item.options[item.selectedIndex].innerHTML;
|
||||
item.nextElementSibling.value = text;
|
||||
|
||||
if ($('autoTMM').selectedIndex == 1) {
|
||||
const categoryName = item.value;
|
||||
const category = categories[categoryName];
|
||||
let savePath = defaultSavePath;
|
||||
if (category !== undefined)
|
||||
savePath = (category['savePath'] !== "") ? category['savePath'] : (defaultSavePath + categoryName);
|
||||
$('savepath').value = savePath;
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
};
|
||||
|
||||
const changeCategorySelect = function(item) {
|
||||
if (item.value == "\\other") {
|
||||
item.nextElementSibling.hidden = false;
|
||||
item.nextElementSibling.value = "";
|
||||
item.nextElementSibling.select();
|
||||
const changeTMM = function(item) {
|
||||
if (item.selectedIndex == 1) {
|
||||
$('savepath').disabled = true;
|
||||
|
||||
if ($('autoTMM').selectedIndex == 1)
|
||||
$('savepath').value = defaultSavePath;
|
||||
}
|
||||
else {
|
||||
item.nextElementSibling.hidden = true;
|
||||
const text = item.options[item.selectedIndex].innerHTML;
|
||||
item.nextElementSibling.value = text;
|
||||
|
||||
if ($('autoTMM').selectedIndex == 1) {
|
||||
const categoryName = item.value;
|
||||
const categorySelect = $('categorySelect');
|
||||
const categoryName = categorySelect.options[categorySelect.selectedIndex].value;
|
||||
const category = categories[categoryName];
|
||||
let savePath = defaultSavePath;
|
||||
if (category !== undefined)
|
||||
savePath = (category['savePath'] !== "") ? category['savePath'] : (defaultSavePath + categoryName);
|
||||
$('savepath').value = savePath;
|
||||
$('savepath').value = (category === undefined) ? "" : category['savePath'];
|
||||
}
|
||||
}
|
||||
};
|
||||
else {
|
||||
$('savepath').disabled = false;
|
||||
$('savepath').value = defaultSavePath;
|
||||
}
|
||||
};
|
||||
|
||||
const changeTMM = function(item) {
|
||||
if (item.selectedIndex == 1) {
|
||||
$('savepath').disabled = true;
|
||||
$(window).addEventListener("load", function() {
|
||||
getPreferences();
|
||||
getCategories();
|
||||
});
|
||||
|
||||
const categorySelect = $('categorySelect');
|
||||
const categoryName = categorySelect.options[categorySelect.selectedIndex].value;
|
||||
const category = categories[categoryName];
|
||||
$('savepath').value = (category === undefined) ? "" : category['savePath'];
|
||||
}
|
||||
else {
|
||||
$('savepath').disabled = false;
|
||||
$('savepath').value = defaultSavePath;
|
||||
}
|
||||
};
|
||||
|
||||
$(window).addEventListener("load", function() {
|
||||
getPreferences();
|
||||
getCategories();
|
||||
});
|
||||
return exports();
|
||||
})();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,149 +28,167 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const FilePriority = {
|
||||
"Ignored": 0,
|
||||
"Normal": 1,
|
||||
"High": 6,
|
||||
"Maximum": 7,
|
||||
"Mixed": -1
|
||||
};
|
||||
Object.freeze(FilePriority);
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
const TriState = {
|
||||
"Unchecked": 0,
|
||||
"Checked": 1,
|
||||
"Partial": 2
|
||||
};
|
||||
Object.freeze(TriState);
|
||||
window.qBittorrent.FileTree = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
FilePriority: FilePriority,
|
||||
TriState: TriState,
|
||||
FileTree: FileTree,
|
||||
FileNode: FileNode,
|
||||
FolderNode: FolderNode,
|
||||
};
|
||||
};
|
||||
|
||||
const FileTree = new Class({
|
||||
root: null,
|
||||
nodeMap: {},
|
||||
const FilePriority = {
|
||||
"Ignored": 0,
|
||||
"Normal": 1,
|
||||
"High": 6,
|
||||
"Maximum": 7,
|
||||
"Mixed": -1
|
||||
};
|
||||
Object.freeze(FilePriority);
|
||||
|
||||
setRoot: function(root) {
|
||||
this.root = root;
|
||||
this.generateNodeMap(root);
|
||||
const TriState = {
|
||||
"Unchecked": 0,
|
||||
"Checked": 1,
|
||||
"Partial": 2
|
||||
};
|
||||
Object.freeze(TriState);
|
||||
|
||||
if (this.root.isFolder)
|
||||
this.root.calculateSize();
|
||||
},
|
||||
const FileTree = new Class({
|
||||
root: null,
|
||||
nodeMap: {},
|
||||
|
||||
getRoot: function() {
|
||||
return this.root;
|
||||
},
|
||||
setRoot: function(root) {
|
||||
this.root = root;
|
||||
this.generateNodeMap(root);
|
||||
|
||||
generateNodeMap: function(node) {
|
||||
// don't store root node in map
|
||||
if (node.root !== null) {
|
||||
this.nodeMap[node.rowId] = node;
|
||||
if (this.root.isFolder)
|
||||
this.root.calculateSize();
|
||||
},
|
||||
|
||||
getRoot: function() {
|
||||
return this.root;
|
||||
},
|
||||
|
||||
generateNodeMap: function(node) {
|
||||
// don't store root node in map
|
||||
if (node.root !== null) {
|
||||
this.nodeMap[node.rowId] = node;
|
||||
}
|
||||
|
||||
node.children.each(function(child) {
|
||||
this.generateNodeMap(child);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
getNode: function(rowId) {
|
||||
return (this.nodeMap[rowId] === undefined)
|
||||
? null
|
||||
: this.nodeMap[rowId];
|
||||
},
|
||||
|
||||
getRowId: function(node) {
|
||||
return node.rowId;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the nodes in dfs order
|
||||
*/
|
||||
toArray: function() {
|
||||
const nodes = [];
|
||||
this.root.children.each(function(node) {
|
||||
this._getArrayOfNodes(node, nodes);
|
||||
}.bind(this));
|
||||
return nodes;
|
||||
},
|
||||
|
||||
_getArrayOfNodes: function(node, array) {
|
||||
array.push(node);
|
||||
node.children.each(function(child) {
|
||||
this._getArrayOfNodes(child, array);
|
||||
}.bind(this));
|
||||
}
|
||||
});
|
||||
|
||||
node.children.each(function(child) {
|
||||
this.generateNodeMap(child);
|
||||
}.bind(this));
|
||||
},
|
||||
const FileNode = new Class({
|
||||
name: "",
|
||||
rowId: null,
|
||||
size: 0,
|
||||
checked: TriState.Unchecked,
|
||||
remaining: 0,
|
||||
progress: 0,
|
||||
priority: FilePriority.Normal,
|
||||
availability: 0,
|
||||
depth: 0,
|
||||
root: null,
|
||||
data: null,
|
||||
isFolder: false,
|
||||
children: [],
|
||||
});
|
||||
|
||||
getNode: function(rowId) {
|
||||
return (this.nodeMap[rowId] === undefined)
|
||||
? null
|
||||
: this.nodeMap[rowId];
|
||||
},
|
||||
const FolderNode = new Class({
|
||||
Extends: FileNode,
|
||||
|
||||
getRowId: function(node) {
|
||||
return node.rowId;
|
||||
},
|
||||
initialize: function() {
|
||||
this.isFolder = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the nodes in dfs order
|
||||
*/
|
||||
toArray: function() {
|
||||
const nodes = [];
|
||||
this.root.children.each(function(node) {
|
||||
this._getArrayOfNodes(node, nodes);
|
||||
}.bind(this));
|
||||
return nodes;
|
||||
},
|
||||
addChild(node) {
|
||||
this.children.push(node);
|
||||
},
|
||||
|
||||
_getArrayOfNodes: function(node, array) {
|
||||
array.push(node);
|
||||
node.children.each(function(child) {
|
||||
this._getArrayOfNodes(child, array);
|
||||
}.bind(this));
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Recursively calculate size of node and its children
|
||||
*/
|
||||
calculateSize: function() {
|
||||
let size = 0;
|
||||
let remaining = 0;
|
||||
let progress = 0;
|
||||
let availability = 0;
|
||||
let checked = TriState.Unchecked;
|
||||
let priority = FilePriority.Normal;
|
||||
|
||||
const FileNode = new Class({
|
||||
name: "",
|
||||
rowId: null,
|
||||
size: 0,
|
||||
checked: TriState.Unchecked,
|
||||
remaining: 0,
|
||||
progress: 0,
|
||||
priority: FilePriority.Normal,
|
||||
availability: 0,
|
||||
depth: 0,
|
||||
root: null,
|
||||
data: null,
|
||||
isFolder: false,
|
||||
children: [],
|
||||
});
|
||||
let isFirstFile = true;
|
||||
|
||||
const FolderNode = new Class({
|
||||
Extends: FileNode,
|
||||
this.children.each(function(node) {
|
||||
if (node.isFolder)
|
||||
node.calculateSize();
|
||||
|
||||
initialize: function() {
|
||||
this.isFolder = true;
|
||||
},
|
||||
size += node.size;
|
||||
|
||||
addChild(node) {
|
||||
this.children.push(node);
|
||||
},
|
||||
if (isFirstFile) {
|
||||
priority = node.priority;
|
||||
checked = node.checked;
|
||||
isFirstFile = false;
|
||||
}
|
||||
else {
|
||||
if (priority !== node.priority)
|
||||
priority = FilePriority.Mixed;
|
||||
if (checked !== node.checked)
|
||||
checked = TriState.Partial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively calculate size of node and its children
|
||||
*/
|
||||
calculateSize: function() {
|
||||
let size = 0;
|
||||
let remaining = 0;
|
||||
let progress = 0;
|
||||
let availability = 0;
|
||||
let checked = TriState.Unchecked;
|
||||
let priority = FilePriority.Normal;
|
||||
const isIgnored = (node.priority === FilePriority.Ignored);
|
||||
if (!isIgnored) {
|
||||
remaining += node.remaining;
|
||||
progress += (node.progress * node.size);
|
||||
availability += (node.availability * node.size);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
let isFirstFile = true;
|
||||
this.size = size;
|
||||
this.remaining = remaining;
|
||||
this.checked = checked;
|
||||
this.progress = (progress / size);
|
||||
this.priority = priority;
|
||||
this.availability = (availability / size);
|
||||
}
|
||||
});
|
||||
|
||||
this.children.each(function(node) {
|
||||
if (node.isFolder)
|
||||
node.calculateSize();
|
||||
|
||||
size += node.size;
|
||||
|
||||
if (isFirstFile) {
|
||||
priority = node.priority;
|
||||
checked = node.checked;
|
||||
isFirstFile = false;
|
||||
}
|
||||
else {
|
||||
if (priority !== node.priority)
|
||||
priority = FilePriority.Mixed;
|
||||
if (checked !== node.checked)
|
||||
checked = TriState.Partial;
|
||||
}
|
||||
|
||||
const isIgnored = (node.priority === FilePriority.Ignored);
|
||||
if (!isIgnored) {
|
||||
remaining += node.remaining;
|
||||
progress += (node.progress * node.size);
|
||||
availability += (node.availability * node.size);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
this.size = size;
|
||||
this.remaining = remaining;
|
||||
this.checked = checked;
|
||||
this.progress = (progress / size);
|
||||
this.priority = priority;
|
||||
this.availability = (availability / size);
|
||||
}
|
||||
});
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -30,32 +30,49 @@
|
|||
|
||||
// This file is the JavaScript implementation of base/utils/fs.cpp
|
||||
|
||||
const QB_EXT = '.!qB';
|
||||
const PathSeparator = '/';
|
||||
|
||||
/**
|
||||
* Returns the file extension part of a file name.
|
||||
*/
|
||||
function fileExtension(filename) {
|
||||
const name = filename.endsWith(QB_EXT)
|
||||
? filename.substring(0, filename.length - QB_EXT.length)
|
||||
: filename;
|
||||
const pointIndex = name.lastIndexOf('.');
|
||||
if (pointIndex === -1)
|
||||
return '';
|
||||
return name.substring(pointIndex + 1);
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
function fileName(filepath) {
|
||||
const slashIndex = filepath.lastIndexOf(PathSeparator);
|
||||
if (slashIndex === -1)
|
||||
return filepath;
|
||||
return filepath.substring(slashIndex + 1);
|
||||
}
|
||||
window.qBittorrent.Filesystem = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
PathSeparator: PathSeparator,
|
||||
fileExtension: fileExtension,
|
||||
fileName: fileName,
|
||||
folderName: folderName
|
||||
};
|
||||
};
|
||||
|
||||
function folderName(filepath) {
|
||||
const slashIndex = filepath.lastIndexOf(PathSeparator);
|
||||
if (slashIndex === -1)
|
||||
return filepath;
|
||||
return filepath.substring(0, slashIndex);
|
||||
}
|
||||
const QB_EXT = '.!qB';
|
||||
const PathSeparator = '/';
|
||||
|
||||
/**
|
||||
* Returns the file extension part of a file name.
|
||||
*/
|
||||
const fileExtension = function(filename) {
|
||||
const name = filename.endsWith(QB_EXT)
|
||||
? filename.substring(0, filename.length - QB_EXT.length)
|
||||
: filename;
|
||||
const pointIndex = name.lastIndexOf('.');
|
||||
if (pointIndex === -1)
|
||||
return '';
|
||||
return name.substring(pointIndex + 1);
|
||||
};
|
||||
|
||||
const fileName = function(filepath) {
|
||||
const slashIndex = filepath.lastIndexOf(PathSeparator);
|
||||
if (slashIndex === -1)
|
||||
return filepath;
|
||||
return filepath.substring(slashIndex + 1);
|
||||
};
|
||||
|
||||
const folderName = function(filepath) {
|
||||
const slashIndex = filepath.lastIndexOf(PathSeparator);
|
||||
if (slashIndex === -1)
|
||||
return filepath;
|
||||
return filepath.substring(0, slashIndex);
|
||||
};
|
||||
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -28,166 +28,188 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* JS counterpart of the function in src/misc.cpp
|
||||
*/
|
||||
function friendlyUnit(value, isSpeed) {
|
||||
const units = [
|
||||
"QBT_TR(B)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(KiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(MiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(GiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(TiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(PiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(EiB)QBT_TR[CONTEXT=misc]"
|
||||
];
|
||||
|
||||
if ((value === undefined) || (value === null) || (value < 0))
|
||||
return "QBT_TR(Unknown)QBT_TR[CONTEXT=misc]";
|
||||
|
||||
let i = 0;
|
||||
while (value >= 1024.0 && i < 6) {
|
||||
value /= 1024.0;
|
||||
++i;
|
||||
}
|
||||
|
||||
function friendlyUnitPrecision(sizeUnit) {
|
||||
if (sizeUnit <= 2) return 1; // KiB, MiB
|
||||
else if (sizeUnit === 3) return 2; // GiB
|
||||
else return 3; // TiB, PiB, EiB
|
||||
}
|
||||
|
||||
let ret;
|
||||
if (i === 0)
|
||||
ret = value + " " + units[i];
|
||||
else {
|
||||
const precision = friendlyUnitPrecision(i);
|
||||
const offset = Math.pow(10, precision);
|
||||
// Don't round up
|
||||
ret = (Math.floor(offset * value) / offset).toFixed(precision) + " " + units[i];
|
||||
}
|
||||
|
||||
if (isSpeed)
|
||||
ret += "QBT_TR(/s)QBT_TR[CONTEXT=misc]";
|
||||
return ret;
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
/*
|
||||
* JS counterpart of the function in src/misc.cpp
|
||||
*/
|
||||
function friendlyDuration(seconds) {
|
||||
const MAX_ETA = 8640000;
|
||||
if (seconds < 0 || seconds >= MAX_ETA)
|
||||
return "∞";
|
||||
if (seconds === 0)
|
||||
return "0";
|
||||
if (seconds < 60)
|
||||
return "QBT_TR(< 1m)QBT_TR[CONTEXT=misc]";
|
||||
let minutes = seconds / 60;
|
||||
if (minutes < 60)
|
||||
return "QBT_TR(%1m)QBT_TR[CONTEXT=misc]".replace("%1", parseInt(minutes));
|
||||
let hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
if (hours < 24)
|
||||
return "QBT_TR(%1h %2m)QBT_TR[CONTEXT=misc]".replace("%1", parseInt(hours)).replace("%2", parseInt(minutes));
|
||||
const days = hours / 24;
|
||||
hours = hours % 24;
|
||||
if (days < 100)
|
||||
return "QBT_TR(%1d %2h)QBT_TR[CONTEXT=misc]".replace("%1", parseInt(days)).replace("%2", parseInt(hours));
|
||||
return "∞";
|
||||
}
|
||||
|
||||
function friendlyPercentage(value) {
|
||||
let percentage = (value * 100).round(1);
|
||||
if (isNaN(percentage) || (percentage < 0))
|
||||
percentage = 0;
|
||||
if (percentage > 100)
|
||||
percentage = 100;
|
||||
return percentage.toFixed(1) + "%";
|
||||
}
|
||||
|
||||
function friendlyFloat(value, precision) {
|
||||
return parseFloat(value).toFixed(precision);
|
||||
}
|
||||
|
||||
/*
|
||||
* From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
|
||||
*/
|
||||
if (!Date.prototype.toISOString) {
|
||||
(function() {
|
||||
|
||||
function pad(number) {
|
||||
if (number < 10) {
|
||||
return '0' + number;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
Date.prototype.toISOString = function() {
|
||||
return this.getUTCFullYear()
|
||||
+ '-' + pad(this.getUTCMonth() + 1)
|
||||
+ '-' + pad(this.getUTCDate())
|
||||
+ 'T' + pad(this.getUTCHours())
|
||||
+ ':' + pad(this.getUTCMinutes())
|
||||
+ ':' + pad(this.getUTCSeconds())
|
||||
+ '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5)
|
||||
+ 'Z';
|
||||
window.qBittorrent.Misc = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
friendlyUnit: friendlyUnit,
|
||||
friendlyDuration: friendlyDuration,
|
||||
friendlyPercentage: friendlyPercentage,
|
||||
friendlyFloat: friendlyFloat,
|
||||
parseHtmlLinks: parseHtmlLinks,
|
||||
escapeHtml: escapeHtml,
|
||||
safeTrim: safeTrim,
|
||||
toFixedPointString: toFixedPointString,
|
||||
containsAllTerms: containsAllTerms
|
||||
};
|
||||
};
|
||||
|
||||
}());
|
||||
}
|
||||
/*
|
||||
* JS counterpart of the function in src/misc.cpp
|
||||
*/
|
||||
const friendlyUnit = function(value, isSpeed) {
|
||||
const units = [
|
||||
"QBT_TR(B)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(KiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(MiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(GiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(TiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(PiB)QBT_TR[CONTEXT=misc]",
|
||||
"QBT_TR(EiB)QBT_TR[CONTEXT=misc]"
|
||||
];
|
||||
|
||||
/*
|
||||
* JS counterpart of the function in src/misc.cpp
|
||||
*/
|
||||
function parseHtmlLinks(text) {
|
||||
const exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
|
||||
return text.replace(exp, "<a target='_blank' href='$1'>$1</a>");
|
||||
}
|
||||
if ((value === undefined) || (value === null) || (value < 0))
|
||||
return "QBT_TR(Unknown)QBT_TR[CONTEXT=misc]";
|
||||
|
||||
function escapeHtml(str) {
|
||||
const div = document.createElement('div');
|
||||
div.appendChild(document.createTextNode(str));
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function safeTrim(value) {
|
||||
try {
|
||||
return value.trim();
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof TypeError)
|
||||
return "";
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
function toFixedPointString(number, digits) {
|
||||
// Do not round up number
|
||||
const power = Math.pow(10, digits);
|
||||
return (Math.floor(power * number) / power).toFixed(digits);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} text the text to search
|
||||
* @param {Array<String>} terms terms to search for within the text
|
||||
* @returns {Boolean} true if all terms match the text, false otherwise
|
||||
*/
|
||||
function containsAllTerms(text, terms) {
|
||||
const textToSearch = text.toLowerCase();
|
||||
return terms.every((function(term) {
|
||||
const isTermRequired = (term[0] === '+');
|
||||
const isTermExcluded = (term[0] === '-');
|
||||
if (isTermRequired || isTermExcluded) {
|
||||
// ignore lonely +/-
|
||||
if (term.length === 1)
|
||||
return true;
|
||||
|
||||
term = term.substring(1);
|
||||
let i = 0;
|
||||
while (value >= 1024.0 && i < 6) {
|
||||
value /= 1024.0;
|
||||
++i;
|
||||
}
|
||||
|
||||
const textContainsTerm = (textToSearch.indexOf(term) !== -1);
|
||||
return isTermExcluded ? !textContainsTerm : textContainsTerm;
|
||||
}));
|
||||
}
|
||||
function friendlyUnitPrecision(sizeUnit) {
|
||||
if (sizeUnit <= 2) return 1; // KiB, MiB
|
||||
else if (sizeUnit === 3) return 2; // GiB
|
||||
else return 3; // TiB, PiB, EiB
|
||||
}
|
||||
|
||||
let ret;
|
||||
if (i === 0)
|
||||
ret = value + " " + units[i];
|
||||
else {
|
||||
const precision = friendlyUnitPrecision(i);
|
||||
const offset = Math.pow(10, precision);
|
||||
// Don't round up
|
||||
ret = (Math.floor(offset * value) / offset).toFixed(precision) + " " + units[i];
|
||||
}
|
||||
|
||||
if (isSpeed)
|
||||
ret += "QBT_TR(/s)QBT_TR[CONTEXT=misc]";
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* JS counterpart of the function in src/misc.cpp
|
||||
*/
|
||||
const friendlyDuration = function(seconds) {
|
||||
const MAX_ETA = 8640000;
|
||||
if (seconds < 0 || seconds >= MAX_ETA)
|
||||
return "∞";
|
||||
if (seconds === 0)
|
||||
return "0";
|
||||
if (seconds < 60)
|
||||
return "QBT_TR(< 1m)QBT_TR[CONTEXT=misc]";
|
||||
let minutes = seconds / 60;
|
||||
if (minutes < 60)
|
||||
return "QBT_TR(%1m)QBT_TR[CONTEXT=misc]".replace("%1", parseInt(minutes));
|
||||
let hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
if (hours < 24)
|
||||
return "QBT_TR(%1h %2m)QBT_TR[CONTEXT=misc]".replace("%1", parseInt(hours)).replace("%2", parseInt(minutes));
|
||||
const days = hours / 24;
|
||||
hours = hours % 24;
|
||||
if (days < 100)
|
||||
return "QBT_TR(%1d %2h)QBT_TR[CONTEXT=misc]".replace("%1", parseInt(days)).replace("%2", parseInt(hours));
|
||||
return "∞";
|
||||
}
|
||||
|
||||
const friendlyPercentage = function(value) {
|
||||
let percentage = (value * 100).round(1);
|
||||
if (isNaN(percentage) || (percentage < 0))
|
||||
percentage = 0;
|
||||
if (percentage > 100)
|
||||
percentage = 100;
|
||||
return percentage.toFixed(1) + "%";
|
||||
}
|
||||
|
||||
const friendlyFloat = function(value, precision) {
|
||||
return parseFloat(value).toFixed(precision);
|
||||
}
|
||||
|
||||
/*
|
||||
* From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
|
||||
*/
|
||||
if (!Date.prototype.toISOString) {
|
||||
(function() {
|
||||
|
||||
function pad(number) {
|
||||
if (number < 10) {
|
||||
return '0' + number;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
Date.prototype.toISOString = function() {
|
||||
return this.getUTCFullYear()
|
||||
+ '-' + pad(this.getUTCMonth() + 1)
|
||||
+ '-' + pad(this.getUTCDate())
|
||||
+ 'T' + pad(this.getUTCHours())
|
||||
+ ':' + pad(this.getUTCMinutes())
|
||||
+ ':' + pad(this.getUTCSeconds())
|
||||
+ '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5)
|
||||
+ 'Z';
|
||||
};
|
||||
|
||||
}());
|
||||
}
|
||||
|
||||
/*
|
||||
* JS counterpart of the function in src/misc.cpp
|
||||
*/
|
||||
const parseHtmlLinks = function(text) {
|
||||
const exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
|
||||
return text.replace(exp, "<a target='_blank' href='$1'>$1</a>");
|
||||
}
|
||||
|
||||
const escapeHtml = function(str) {
|
||||
const div = document.createElement('div');
|
||||
div.appendChild(document.createTextNode(str));
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
const safeTrim = function(value) {
|
||||
try {
|
||||
return value.trim();
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof TypeError)
|
||||
return "";
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
const toFixedPointString = function(number, digits) {
|
||||
// Do not round up number
|
||||
const power = Math.pow(10, digits);
|
||||
return (Math.floor(power * number) / power).toFixed(digits);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} text the text to search
|
||||
* @param {Array<String>} terms terms to search for within the text
|
||||
* @returns {Boolean} true if all terms match the text, false otherwise
|
||||
*/
|
||||
const containsAllTerms = function(text, terms) {
|
||||
const textToSearch = text.toLowerCase();
|
||||
return terms.every((function(term) {
|
||||
const isTermRequired = (term[0] === '+');
|
||||
const isTermExcluded = (term[0] === '-');
|
||||
if (isTermRequired || isTermExcluded) {
|
||||
// ignore lonely +/-
|
||||
if (term.length === 1)
|
||||
return true;
|
||||
|
||||
term = term.substring(1);
|
||||
}
|
||||
|
||||
const textContainsTerm = (textToSearch.indexOf(term) !== -1);
|
||||
return isTermExcluded ? !textContainsTerm : textContainsTerm;
|
||||
}));
|
||||
}
|
||||
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
----------------------------------------------------------------- */
|
||||
'use strict';
|
||||
|
||||
const LocalPreferences = new LocalPreferencesClass();
|
||||
const LocalPreferences = new window.qBittorrent.LocalPreferences.LocalPreferencesClass();
|
||||
|
||||
let saveWindowSize = function() {};
|
||||
let loadWindowWidth = function() {};
|
||||
|
|
|
@ -28,20 +28,34 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const LocalPreferencesClass = new Class({
|
||||
get: function(key, defaultValue) {
|
||||
const value = localStorage.getItem(key);
|
||||
return ((value === null) && (defaultValue !== undefined))
|
||||
? defaultValue
|
||||
: value;
|
||||
},
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
set: function(key, value) {
|
||||
try {
|
||||
localStorage.setItem(key, value);
|
||||
window.qBittorrent.LocalPreferences = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
LocalPreferencesClass: LocalPreferencesClass
|
||||
};
|
||||
};
|
||||
|
||||
const LocalPreferencesClass = new Class({
|
||||
get: function(key, defaultValue) {
|
||||
const value = localStorage.getItem(key);
|
||||
return ((value === null) && (defaultValue !== undefined))
|
||||
? defaultValue
|
||||
: value;
|
||||
},
|
||||
|
||||
set: function(key, value) {
|
||||
try {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -28,113 +28,126 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const ProgressBar = new Class({
|
||||
initialize: function(value, parameters) {
|
||||
const vals = {
|
||||
'id': 'progressbar_' + (ProgressBars++),
|
||||
'value': $pick(value, 0),
|
||||
'width': 0,
|
||||
'height': 0,
|
||||
'darkbg': '#006',
|
||||
'darkfg': '#fff',
|
||||
'lightbg': '#fff',
|
||||
'lightfg': '#000'
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
window.qBittorrent.ProgressBar = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
ProgressBar: ProgressBar
|
||||
};
|
||||
if (parameters && $type(parameters) == 'object') $extend(vals, parameters);
|
||||
if (vals.height < 12) vals.height = 12;
|
||||
const obj = new Element('div', {
|
||||
'id': vals.id,
|
||||
'class': 'progressbar_wrapper',
|
||||
'styles': {
|
||||
'border': '1px solid #000',
|
||||
'width': vals.width,
|
||||
'height': vals.height,
|
||||
'position': 'relative',
|
||||
'margin': '0 auto'
|
||||
}
|
||||
});
|
||||
obj.vals = vals;
|
||||
obj.vals.value = $pick(value, 0); // Fix by Chris
|
||||
obj.vals.dark = new Element('div', {
|
||||
'id': vals.id + '_dark',
|
||||
'class': 'progressbar_dark',
|
||||
'styles': {
|
||||
'width': vals.width,
|
||||
'height': vals.height,
|
||||
'background': vals.darkbg,
|
||||
'color': vals.darkfg,
|
||||
'position': 'absolute',
|
||||
'text-align': 'center',
|
||||
'left': 0,
|
||||
'top': 0,
|
||||
'line-height': vals.height
|
||||
}
|
||||
});
|
||||
obj.vals.light = new Element('div', {
|
||||
'id': vals.id + '_light',
|
||||
'class': 'progressbar_light',
|
||||
'styles': {
|
||||
'width': vals.width,
|
||||
'height': vals.height,
|
||||
'background': vals.lightbg,
|
||||
'color': vals.lightfg,
|
||||
'position': 'absolute',
|
||||
'text-align': 'center',
|
||||
'left': 0,
|
||||
'top': 0,
|
||||
'line-height': vals.height
|
||||
}
|
||||
});
|
||||
obj.appendChild(obj.vals.dark);
|
||||
obj.appendChild(obj.vals.light);
|
||||
obj.getValue = ProgressBar_getValue;
|
||||
obj.setValue = ProgressBar_setValue;
|
||||
obj.setWidth = ProgressBar_setWidth;
|
||||
if (vals.width) obj.setValue(vals.value);
|
||||
else setTimeout('ProgressBar_checkForParent("' + obj.id + '")', 1);
|
||||
return obj;
|
||||
};
|
||||
|
||||
let ProgressBars = 0;
|
||||
const ProgressBar = new Class({
|
||||
initialize: function(value, parameters) {
|
||||
const vals = {
|
||||
'id': 'progressbar_' + (ProgressBars++),
|
||||
'value': $pick(value, 0),
|
||||
'width': 0,
|
||||
'height': 0,
|
||||
'darkbg': '#006',
|
||||
'darkfg': '#fff',
|
||||
'lightbg': '#fff',
|
||||
'lightfg': '#000'
|
||||
};
|
||||
if (parameters && $type(parameters) == 'object') $extend(vals, parameters);
|
||||
if (vals.height < 12) vals.height = 12;
|
||||
const obj = new Element('div', {
|
||||
'id': vals.id,
|
||||
'class': 'progressbar_wrapper',
|
||||
'styles': {
|
||||
'border': '1px solid #000',
|
||||
'width': vals.width,
|
||||
'height': vals.height,
|
||||
'position': 'relative',
|
||||
'margin': '0 auto'
|
||||
}
|
||||
});
|
||||
obj.vals = vals;
|
||||
obj.vals.value = $pick(value, 0); // Fix by Chris
|
||||
obj.vals.dark = new Element('div', {
|
||||
'id': vals.id + '_dark',
|
||||
'class': 'progressbar_dark',
|
||||
'styles': {
|
||||
'width': vals.width,
|
||||
'height': vals.height,
|
||||
'background': vals.darkbg,
|
||||
'color': vals.darkfg,
|
||||
'position': 'absolute',
|
||||
'text-align': 'center',
|
||||
'left': 0,
|
||||
'top': 0,
|
||||
'line-height': vals.height
|
||||
}
|
||||
});
|
||||
obj.vals.light = new Element('div', {
|
||||
'id': vals.id + '_light',
|
||||
'class': 'progressbar_light',
|
||||
'styles': {
|
||||
'width': vals.width,
|
||||
'height': vals.height,
|
||||
'background': vals.lightbg,
|
||||
'color': vals.lightfg,
|
||||
'position': 'absolute',
|
||||
'text-align': 'center',
|
||||
'left': 0,
|
||||
'top': 0,
|
||||
'line-height': vals.height
|
||||
}
|
||||
});
|
||||
obj.appendChild(obj.vals.dark);
|
||||
obj.appendChild(obj.vals.light);
|
||||
obj.getValue = ProgressBar_getValue;
|
||||
obj.setValue = ProgressBar_setValue;
|
||||
obj.setWidth = ProgressBar_setWidth;
|
||||
if (vals.width) obj.setValue(vals.value);
|
||||
else setTimeout('ProgressBar_checkForParent("' + obj.id + '")', 1);
|
||||
return obj;
|
||||
}
|
||||
});
|
||||
|
||||
function ProgressBar_getValue() {
|
||||
return this.vals.value;
|
||||
}
|
||||
});
|
||||
|
||||
function ProgressBar_getValue() {
|
||||
return this.vals.value;
|
||||
}
|
||||
|
||||
function ProgressBar_setValue(value) {
|
||||
value = parseFloat(value);
|
||||
if (isNaN(value)) value = 0;
|
||||
if (value > 100) value = 100;
|
||||
if (value < 0) value = 0;
|
||||
this.vals.value = value;
|
||||
this.vals.dark.empty();
|
||||
this.vals.light.empty();
|
||||
this.vals.dark.appendText(value.round(1).toFixed(1) + '%');
|
||||
this.vals.light.appendText(value.round(1).toFixed(1) + '%');
|
||||
const r = parseInt(this.vals.width * (value / 100));
|
||||
this.vals.dark.setStyle('clip', 'rect(0,' + r + 'px,' + this.vals.height + 'px,0)');
|
||||
this.vals.light.setStyle('clip', 'rect(0,' + this.vals.width + 'px,' + this.vals.height + 'px,' + r + 'px)');
|
||||
}
|
||||
|
||||
function ProgressBar_setWidth(value) {
|
||||
if (this.vals.width !== value) {
|
||||
this.vals.width = value;
|
||||
this.setStyle('width', value);
|
||||
this.vals.dark.setStyle('width', value);
|
||||
this.vals.light.setStyle('width', value);
|
||||
this.setValue(this.vals.value);
|
||||
function ProgressBar_setValue(value) {
|
||||
value = parseFloat(value);
|
||||
if (isNaN(value)) value = 0;
|
||||
if (value > 100) value = 100;
|
||||
if (value < 0) value = 0;
|
||||
this.vals.value = value;
|
||||
this.vals.dark.empty();
|
||||
this.vals.light.empty();
|
||||
this.vals.dark.appendText(value.round(1).toFixed(1) + '%');
|
||||
this.vals.light.appendText(value.round(1).toFixed(1) + '%');
|
||||
const r = parseInt(this.vals.width * (value / 100));
|
||||
this.vals.dark.setStyle('clip', 'rect(0,' + r + 'px,' + this.vals.height + 'px,0)');
|
||||
this.vals.light.setStyle('clip', 'rect(0,' + this.vals.width + 'px,' + this.vals.height + 'px,' + r + 'px)');
|
||||
}
|
||||
}
|
||||
|
||||
function ProgressBar_checkForParent(id) {
|
||||
const obj = $(id);
|
||||
if (!obj) return;
|
||||
if (!obj.parentNode) return setTimeout('ProgressBar_checkForParent("' + id + '")', 1);
|
||||
obj.setStyle('width', '100%');
|
||||
const w = obj.offsetWidth;
|
||||
obj.vals.dark.setStyle('width', w);
|
||||
obj.vals.light.setStyle('width', w);
|
||||
obj.vals.width = w;
|
||||
obj.setValue(obj.vals.value);
|
||||
}
|
||||
function ProgressBar_setWidth(value) {
|
||||
if (this.vals.width !== value) {
|
||||
this.vals.width = value;
|
||||
this.setStyle('width', value);
|
||||
this.vals.dark.setStyle('width', value);
|
||||
this.vals.light.setStyle('width', value);
|
||||
this.setValue(this.vals.value);
|
||||
}
|
||||
}
|
||||
|
||||
let ProgressBars = 0;
|
||||
function ProgressBar_checkForParent(id) {
|
||||
const obj = $(id);
|
||||
if (!obj) return;
|
||||
if (!obj.parentNode) return setTimeout('ProgressBar_checkForParent("' + id + '")', 1);
|
||||
obj.setStyle('width', '100%');
|
||||
const w = obj.offsetWidth;
|
||||
obj.vals.dark.setStyle('width', w);
|
||||
obj.vals.light.setStyle('width', w);
|
||||
obj.vals.width = w;
|
||||
obj.setValue(obj.vals.value);
|
||||
}
|
||||
|
||||
return exports();
|
||||
})();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,172 +28,186 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const clearData = function() {
|
||||
$('time_elapsed').set('html', '');
|
||||
$('eta').set('html', '');
|
||||
$('nb_connections').set('html', '');
|
||||
$('total_downloaded').set('html', '');
|
||||
$('total_uploaded').set('html', '');
|
||||
$('dl_speed').set('html', '');
|
||||
$('up_speed').set('html', '');
|
||||
$('dl_limit').set('html', '');
|
||||
$('up_limit').set('html', '');
|
||||
$('total_wasted').set('html', '');
|
||||
$('seeds').set('html', '');
|
||||
$('peers').set('html', '');
|
||||
$('share_ratio').set('html', '');
|
||||
$('reannounce').set('html', '');
|
||||
$('last_seen').set('html', '');
|
||||
$('total_size').set('html', '');
|
||||
$('pieces').set('html', '');
|
||||
$('created_by').set('html', '');
|
||||
$('addition_date').set('html', '');
|
||||
$('completion_date').set('html', '');
|
||||
$('creation_date').set('html', '');
|
||||
$('torrent_hash').set('html', '');
|
||||
$('save_path').set('html', '');
|
||||
$('comment').set('html', '');
|
||||
};
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
let loadTorrentDataTimer;
|
||||
const loadTorrentData = function() {
|
||||
if ($('prop_general').hasClass('invisible')
|
||||
|| $('propertiesPanel_collapseToggle').hasClass('panel-expand')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
const current_hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (current_hash === "") {
|
||||
clearData();
|
||||
clearTimeout(loadTorrentDataTimer);
|
||||
loadTorrentDataTimer = loadTorrentData.delay(5000);
|
||||
return;
|
||||
}
|
||||
// Display hash
|
||||
$('torrent_hash').set('html', current_hash);
|
||||
const url = new URI('api/v2/torrents/properties?hash=' + current_hash);
|
||||
new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onFailure: function() {
|
||||
$('error_div').set('html', 'QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]');
|
||||
clearTimeout(loadTorrentDataTimer);
|
||||
loadTorrentDataTimer = loadTorrentData.delay(10000);
|
||||
},
|
||||
onSuccess: function(data) {
|
||||
$('error_div').set('html', '');
|
||||
if (data) {
|
||||
let temp;
|
||||
// Update Torrent data
|
||||
if (data.seeding_time > 0)
|
||||
temp = "QBT_TR(%1 (%2 this session))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", friendlyDuration(data.time_elapsed))
|
||||
.replace("%2", friendlyDuration(data.seeding_time));
|
||||
else
|
||||
temp = friendlyDuration(data.time_elapsed);
|
||||
$('time_elapsed').set('html', temp);
|
||||
window.qBittorrent.PropGeneral = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
updateData: updateData
|
||||
};
|
||||
};
|
||||
|
||||
$('eta').set('html', friendlyDuration(data.eta));
|
||||
const clearData = function() {
|
||||
$('time_elapsed').set('html', '');
|
||||
$('eta').set('html', '');
|
||||
$('nb_connections').set('html', '');
|
||||
$('total_downloaded').set('html', '');
|
||||
$('total_uploaded').set('html', '');
|
||||
$('dl_speed').set('html', '');
|
||||
$('up_speed').set('html', '');
|
||||
$('dl_limit').set('html', '');
|
||||
$('up_limit').set('html', '');
|
||||
$('total_wasted').set('html', '');
|
||||
$('seeds').set('html', '');
|
||||
$('peers').set('html', '');
|
||||
$('share_ratio').set('html', '');
|
||||
$('reannounce').set('html', '');
|
||||
$('last_seen').set('html', '');
|
||||
$('total_size').set('html', '');
|
||||
$('pieces').set('html', '');
|
||||
$('created_by').set('html', '');
|
||||
$('addition_date').set('html', '');
|
||||
$('completion_date').set('html', '');
|
||||
$('creation_date').set('html', '');
|
||||
$('torrent_hash').set('html', '');
|
||||
$('save_path').set('html', '');
|
||||
$('comment').set('html', '');
|
||||
};
|
||||
|
||||
temp = "QBT_TR(%1 (%2 max))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", data.nb_connections)
|
||||
.replace("%2", data.nb_connections_limit < 0 ? "∞" : data.nb_connections_limit);
|
||||
$('nb_connections').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 this session))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", friendlyUnit(data.total_downloaded))
|
||||
.replace("%2", friendlyUnit(data.total_downloaded_session));
|
||||
$('total_downloaded').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 this session))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", friendlyUnit(data.total_uploaded))
|
||||
.replace("%2", friendlyUnit(data.total_uploaded_session));
|
||||
$('total_uploaded').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 avg.))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", friendlyUnit(data.dl_speed, true))
|
||||
.replace("%2", friendlyUnit(data.dl_speed_avg, true));
|
||||
$('dl_speed').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 avg.))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", friendlyUnit(data.up_speed, true))
|
||||
.replace("%2", friendlyUnit(data.up_speed_avg, true));
|
||||
$('up_speed').set('html', temp);
|
||||
|
||||
temp = (data.dl_limit == -1 ? "∞" : friendlyUnit(data.dl_limit, true));
|
||||
$('dl_limit').set('html', temp);
|
||||
|
||||
temp = (data.up_limit == -1 ? "∞" : friendlyUnit(data.up_limit, true));
|
||||
$('up_limit').set('html', temp);
|
||||
|
||||
$('total_wasted').set('html', friendlyUnit(data.total_wasted));
|
||||
|
||||
temp = "QBT_TR(%1 (%2 total))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", data.seeds)
|
||||
.replace("%2", data.seeds_total);
|
||||
$('seeds').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 total))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", data.peers)
|
||||
.replace("%2", data.peers_total);
|
||||
$('peers').set('html', temp);
|
||||
|
||||
$('share_ratio').set('html', data.share_ratio.toFixed(2));
|
||||
|
||||
$('reannounce').set('html', friendlyDuration(data.reannounce));
|
||||
|
||||
if (data.last_seen != -1)
|
||||
temp = new Date(data.last_seen * 1000).toLocaleString();
|
||||
else
|
||||
temp = "QBT_TR(Never)QBT_TR[CONTEXT=PropertiesWidget]";
|
||||
$('last_seen').set('html', temp);
|
||||
|
||||
$('total_size').set('html', friendlyUnit(data.total_size));
|
||||
|
||||
if (data.pieces_num != -1)
|
||||
temp = "QBT_TR(%1 x %2 (have %3))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", data.pieces_num)
|
||||
.replace("%2", friendlyUnit(data.piece_size))
|
||||
.replace("%3", data.pieces_have);
|
||||
else
|
||||
temp = "QBT_TR(Unknown)QBT_TR[CONTEXT=HttpServer]";
|
||||
$('pieces').set('html', temp);
|
||||
|
||||
$('created_by').set('html', escapeHtml(data.created_by));
|
||||
if (data.addition_date != -1)
|
||||
temp = new Date(data.addition_date * 1000).toLocaleString();
|
||||
else
|
||||
temp = "QBT_TR(Unknown)QBT_TR[CONTEXT=HttpServer]";
|
||||
|
||||
$('addition_date').set('html', temp);
|
||||
if (data.completion_date != -1)
|
||||
temp = new Date(data.completion_date * 1000).toLocaleString();
|
||||
else
|
||||
temp = "";
|
||||
|
||||
$('completion_date').set('html', temp);
|
||||
|
||||
if (data.creation_date != -1)
|
||||
temp = new Date(data.creation_date * 1000).toLocaleString();
|
||||
else
|
||||
temp = "QBT_TR(Unknown)QBT_TR[CONTEXT=HttpServer]";
|
||||
$('creation_date').set('html', temp);
|
||||
|
||||
$('save_path').set('html', data.save_path);
|
||||
|
||||
$('comment').set('html', parseHtmlLinks(escapeHtml(data.comment)));
|
||||
}
|
||||
else {
|
||||
clearData();
|
||||
}
|
||||
let loadTorrentDataTimer;
|
||||
const loadTorrentData = function() {
|
||||
if ($('prop_general').hasClass('invisible')
|
||||
|| $('propertiesPanel_collapseToggle').hasClass('panel-expand')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
const current_hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (current_hash === "") {
|
||||
clearData();
|
||||
clearTimeout(loadTorrentDataTimer);
|
||||
loadTorrentDataTimer = loadTorrentData.delay(5000);
|
||||
return;
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
// Display hash
|
||||
$('torrent_hash').set('html', current_hash);
|
||||
const url = new URI('api/v2/torrents/properties?hash=' + current_hash);
|
||||
new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onFailure: function() {
|
||||
$('error_div').set('html', 'QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]');
|
||||
clearTimeout(loadTorrentDataTimer);
|
||||
loadTorrentDataTimer = loadTorrentData.delay(10000);
|
||||
},
|
||||
onSuccess: function(data) {
|
||||
$('error_div').set('html', '');
|
||||
if (data) {
|
||||
let temp;
|
||||
// Update Torrent data
|
||||
if (data.seeding_time > 0)
|
||||
temp = "QBT_TR(%1 (%2 this session))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", window.qBittorrent.Misc.friendlyDuration(data.time_elapsed))
|
||||
.replace("%2", window.qBittorrent.Misc.friendlyDuration(data.seeding_time));
|
||||
else
|
||||
temp = window.qBittorrent.Misc.friendlyDuration(data.time_elapsed);
|
||||
$('time_elapsed').set('html', temp);
|
||||
|
||||
updateTorrentData = function() {
|
||||
clearTimeout(loadTorrentDataTimer);
|
||||
loadTorrentData();
|
||||
};
|
||||
$('eta').set('html', window.qBittorrent.Misc.friendlyDuration(data.eta));
|
||||
|
||||
temp = "QBT_TR(%1 (%2 max))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", data.nb_connections)
|
||||
.replace("%2", data.nb_connections_limit < 0 ? "∞" : data.nb_connections_limit);
|
||||
$('nb_connections').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 this session))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", window.qBittorrent.Misc.friendlyUnit(data.total_downloaded))
|
||||
.replace("%2", window.qBittorrent.Misc.friendlyUnit(data.total_downloaded_session));
|
||||
$('total_downloaded').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 this session))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", window.qBittorrent.Misc.friendlyUnit(data.total_uploaded))
|
||||
.replace("%2", window.qBittorrent.Misc.friendlyUnit(data.total_uploaded_session));
|
||||
$('total_uploaded').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 avg.))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", window.qBittorrent.Misc.friendlyUnit(data.dl_speed, true))
|
||||
.replace("%2", window.qBittorrent.Misc.friendlyUnit(data.dl_speed_avg, true));
|
||||
$('dl_speed').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 avg.))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", window.qBittorrent.Misc.friendlyUnit(data.up_speed, true))
|
||||
.replace("%2", window.qBittorrent.Misc.friendlyUnit(data.up_speed_avg, true));
|
||||
$('up_speed').set('html', temp);
|
||||
|
||||
temp = (data.dl_limit == -1 ? "∞" : window.qBittorrent.Misc.friendlyUnit(data.dl_limit, true));
|
||||
$('dl_limit').set('html', temp);
|
||||
|
||||
temp = (data.up_limit == -1 ? "∞" : window.qBittorrent.Misc.friendlyUnit(data.up_limit, true));
|
||||
$('up_limit').set('html', temp);
|
||||
|
||||
$('total_wasted').set('html', window.qBittorrent.Misc.friendlyUnit(data.total_wasted));
|
||||
|
||||
temp = "QBT_TR(%1 (%2 total))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", data.seeds)
|
||||
.replace("%2", data.seeds_total);
|
||||
$('seeds').set('html', temp);
|
||||
|
||||
temp = "QBT_TR(%1 (%2 total))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", data.peers)
|
||||
.replace("%2", data.peers_total);
|
||||
$('peers').set('html', temp);
|
||||
|
||||
$('share_ratio').set('html', data.share_ratio.toFixed(2));
|
||||
|
||||
$('reannounce').set('html', window.qBittorrent.Misc.friendlyDuration(data.reannounce));
|
||||
|
||||
if (data.last_seen != -1)
|
||||
temp = new Date(data.last_seen * 1000).toLocaleString();
|
||||
else
|
||||
temp = "QBT_TR(Never)QBT_TR[CONTEXT=PropertiesWidget]";
|
||||
$('last_seen').set('html', temp);
|
||||
|
||||
$('total_size').set('html', window.qBittorrent.Misc.friendlyUnit(data.total_size));
|
||||
|
||||
if (data.pieces_num != -1)
|
||||
temp = "QBT_TR(%1 x %2 (have %3))QBT_TR[CONTEXT=PropertiesWidget]"
|
||||
.replace("%1", data.pieces_num)
|
||||
.replace("%2", window.qBittorrent.Misc.friendlyUnit(data.piece_size))
|
||||
.replace("%3", data.pieces_have);
|
||||
else
|
||||
temp = "QBT_TR(Unknown)QBT_TR[CONTEXT=HttpServer]";
|
||||
$('pieces').set('html', temp);
|
||||
|
||||
$('created_by').set('html', window.qBittorrent.Misc.escapeHtml(data.created_by));
|
||||
if (data.addition_date != -1)
|
||||
temp = new Date(data.addition_date * 1000).toLocaleString();
|
||||
else
|
||||
temp = "QBT_TR(Unknown)QBT_TR[CONTEXT=HttpServer]";
|
||||
|
||||
$('addition_date').set('html', temp);
|
||||
if (data.completion_date != -1)
|
||||
temp = new Date(data.completion_date * 1000).toLocaleString();
|
||||
else
|
||||
temp = "";
|
||||
|
||||
$('completion_date').set('html', temp);
|
||||
|
||||
if (data.creation_date != -1)
|
||||
temp = new Date(data.creation_date * 1000).toLocaleString();
|
||||
else
|
||||
temp = "QBT_TR(Unknown)QBT_TR[CONTEXT=HttpServer]";
|
||||
$('creation_date').set('html', temp);
|
||||
|
||||
$('save_path').set('html', data.save_path);
|
||||
|
||||
$('comment').set('html', window.qBittorrent.Misc.parseHtmlLinks(window.qBittorrent.Misc.escapeHtml(data.comment)));
|
||||
}
|
||||
else {
|
||||
clearData();
|
||||
}
|
||||
clearTimeout(loadTorrentDataTimer);
|
||||
loadTorrentDataTimer = loadTorrentData.delay(5000);
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
const updateData = function() {
|
||||
clearTimeout(loadTorrentDataTimer);
|
||||
loadTorrentData();
|
||||
};
|
||||
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -28,144 +28,160 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
let loadTorrentPeersTimer;
|
||||
let syncTorrentPeersLastResponseId = 0;
|
||||
let show_flags = true;
|
||||
const loadTorrentPeersData = function() {
|
||||
if ($('prop_peers').hasClass('invisible')
|
||||
|| $('propertiesPanel_collapseToggle').hasClass('panel-expand')) {
|
||||
syncTorrentPeersLastResponseId = 0;
|
||||
torrentPeersTable.clear();
|
||||
return;
|
||||
}
|
||||
const current_hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (current_hash === "") {
|
||||
syncTorrentPeersLastResponseId = 0;
|
||||
torrentPeersTable.clear();
|
||||
clearTimeout(loadTorrentPeersTimer);
|
||||
loadTorrentPeersTimer = loadTorrentPeersData.delay(getSyncMainDataInterval());
|
||||
return;
|
||||
}
|
||||
const url = new URI('api/v2/sync/torrentPeers');
|
||||
url.setData('rid', syncTorrentPeersLastResponseId);
|
||||
url.setData('hash', current_hash);
|
||||
new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onComplete: function() {
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
window.qBittorrent.PropPeers = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
updateData: updateData
|
||||
}
|
||||
};
|
||||
|
||||
const torrentPeersTable = new window.qBittorrent.DynamicTable.TorrentPeersTable();
|
||||
let loadTorrentPeersTimer;
|
||||
let syncTorrentPeersLastResponseId = 0;
|
||||
let show_flags = true;
|
||||
|
||||
const loadTorrentPeersData = function() {
|
||||
if ($('prop_peers').hasClass('invisible')
|
||||
|| $('propertiesPanel_collapseToggle').hasClass('panel-expand')) {
|
||||
syncTorrentPeersLastResponseId = 0;
|
||||
torrentPeersTable.clear();
|
||||
return;
|
||||
}
|
||||
const current_hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (current_hash === "") {
|
||||
syncTorrentPeersLastResponseId = 0;
|
||||
torrentPeersTable.clear();
|
||||
clearTimeout(loadTorrentPeersTimer);
|
||||
loadTorrentPeersTimer = loadTorrentPeersData.delay(getSyncMainDataInterval());
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
$('error_div').set('html', '');
|
||||
if (response) {
|
||||
const full_update = (response['full_update'] === true);
|
||||
if (full_update)
|
||||
return;
|
||||
}
|
||||
const url = new URI('api/v2/sync/torrentPeers');
|
||||
url.setData('rid', syncTorrentPeersLastResponseId);
|
||||
url.setData('hash', current_hash);
|
||||
new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onComplete: function() {
|
||||
clearTimeout(loadTorrentPeersTimer);
|
||||
loadTorrentPeersTimer = loadTorrentPeersData.delay(getSyncMainDataInterval());
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
$('error_div').set('html', '');
|
||||
if (response) {
|
||||
const full_update = (response['full_update'] === true);
|
||||
if (full_update)
|
||||
torrentPeersTable.clear();
|
||||
if (response['rid'])
|
||||
syncTorrentPeersLastResponseId = response['rid'];
|
||||
if (response['peers']) {
|
||||
for (const key in response['peers']) {
|
||||
response['peers'][key]['rowId'] = key;
|
||||
|
||||
if (response['peers'][key]['client'])
|
||||
response['peers'][key]['client'] = window.qBittorrent.Misc.escapeHtml(response['peers'][key]['client']);
|
||||
|
||||
torrentPeersTable.updateRowData(response['peers'][key]);
|
||||
}
|
||||
}
|
||||
if (response['peers_removed']) {
|
||||
response['peers_removed'].each(function(hash) {
|
||||
torrentPeersTable.removeRow(hash);
|
||||
});
|
||||
}
|
||||
torrentPeersTable.updateTable(full_update);
|
||||
torrentPeersTable.altRow();
|
||||
|
||||
if (response['show_flags']) {
|
||||
if (show_flags != response['show_flags']) {
|
||||
show_flags = response['show_flags'];
|
||||
torrentPeersTable.columns['country'].force_hide = !show_flags;
|
||||
torrentPeersTable.updateColumn('country');
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
torrentPeersTable.clear();
|
||||
if (response['rid'])
|
||||
syncTorrentPeersLastResponseId = response['rid'];
|
||||
if (response['peers']) {
|
||||
for (const key in response['peers']) {
|
||||
response['peers'][key]['rowId'] = key;
|
||||
|
||||
if (response['peers'][key]['client'])
|
||||
response['peers'][key]['client'] = escapeHtml(response['peers'][key]['client']);
|
||||
|
||||
torrentPeersTable.updateRowData(response['peers'][key]);
|
||||
}
|
||||
}
|
||||
if (response['peers_removed']) {
|
||||
response['peers_removed'].each(function(hash) {
|
||||
torrentPeersTable.removeRow(hash);
|
||||
});
|
||||
}
|
||||
torrentPeersTable.updateTable(full_update);
|
||||
torrentPeersTable.altRow();
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
if (response['show_flags']) {
|
||||
if (show_flags != response['show_flags']) {
|
||||
show_flags = response['show_flags'];
|
||||
torrentPeersTable.columns['country'].force_hide = !show_flags;
|
||||
torrentPeersTable.updateColumn('country');
|
||||
}
|
||||
const updateData = function() {
|
||||
clearTimeout(loadTorrentPeersTimer);
|
||||
loadTorrentPeersData();
|
||||
};
|
||||
|
||||
const torrentPeersContextMenu = new window.qBittorrent.ContextMenu.ContextMenu({
|
||||
targets: '#torrentPeersTableDiv',
|
||||
menu: 'torrentPeersMenu',
|
||||
actions: {
|
||||
addPeer: function(element, ref) {
|
||||
const hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (!hash)
|
||||
return;
|
||||
|
||||
new MochaUI.Window({
|
||||
id: 'addPeersPage',
|
||||
title: "QBT_TR(Add Peers)QBT_TR[CONTEXT=PeersAdditionDialog]",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'addpeers.html?hash=' + hash,
|
||||
scrollbars: false,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 350,
|
||||
height: 240
|
||||
});
|
||||
},
|
||||
banPeer: function(element, ref) {
|
||||
const selectedPeers = torrentPeersTable.selectedRowsIds();
|
||||
if (selectedPeers.length === 0)
|
||||
return;
|
||||
|
||||
if (confirm('QBT_TR(Are you sure you want to permanently ban the selected peers?)QBT_TR[CONTEXT=PeerListWidget]')) {
|
||||
new Request({
|
||||
url: 'api/v2/torrents/banPeers',
|
||||
noCache: true,
|
||||
method: 'post',
|
||||
data: {
|
||||
hash: torrentsTable.getCurrentTorrentHash(),
|
||||
peers: selectedPeers.join('|')
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
}
|
||||
},
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
},
|
||||
onShow: function() {
|
||||
const selectedPeers = torrentPeersTable.selectedRowsIds();
|
||||
|
||||
if (selectedPeers.length >= 1) {
|
||||
this.showItem('copyPeer');
|
||||
this.showItem('banPeer');
|
||||
}
|
||||
else {
|
||||
torrentPeersTable.clear();
|
||||
this.hideItem('copyPeer');
|
||||
this.hideItem('banPeer');
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
});
|
||||
|
||||
updateTorrentPeersData = function() {
|
||||
clearTimeout(loadTorrentPeersTimer);
|
||||
loadTorrentPeersData();
|
||||
};
|
||||
|
||||
const torrentPeersContextMenu = new ContextMenu({
|
||||
targets: '#torrentPeersTableDiv',
|
||||
menu: 'torrentPeersMenu',
|
||||
actions: {
|
||||
addPeer: function(element, ref) {
|
||||
const hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (!hash)
|
||||
return;
|
||||
|
||||
new MochaUI.Window({
|
||||
id: 'addPeersPage',
|
||||
title: "QBT_TR(Add Peers)QBT_TR[CONTEXT=PeersAdditionDialog]",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'addpeers.html?hash=' + hash,
|
||||
scrollbars: false,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 350,
|
||||
height: 240
|
||||
});
|
||||
},
|
||||
banPeer: function(element, ref) {
|
||||
const selectedPeers = torrentPeersTable.selectedRowsIds();
|
||||
if (selectedPeers.length === 0)
|
||||
return;
|
||||
|
||||
if (confirm('QBT_TR(Are you sure you want to permanently ban the selected peers?)QBT_TR[CONTEXT=PeerListWidget]')) {
|
||||
new Request({
|
||||
url: 'api/v2/torrents/banPeers',
|
||||
noCache: true,
|
||||
method: 'post',
|
||||
data: {
|
||||
hash: torrentsTable.getCurrentTorrentHash(),
|
||||
peers: selectedPeers.join('|')
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
new ClipboardJS('#CopyPeerInfo', {
|
||||
text: function(trigger) {
|
||||
return torrentPeersTable.selectedRowsIds().join("\n");
|
||||
}
|
||||
},
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
},
|
||||
onShow: function() {
|
||||
const selectedPeers = torrentPeersTable.selectedRowsIds();
|
||||
});
|
||||
|
||||
if (selectedPeers.length >= 1) {
|
||||
this.showItem('copyPeer');
|
||||
this.showItem('banPeer');
|
||||
}
|
||||
else {
|
||||
this.hideItem('copyPeer');
|
||||
this.hideItem('banPeer');
|
||||
}
|
||||
}
|
||||
});
|
||||
torrentPeersTable.setup('torrentPeersTableDiv', 'torrentPeersTableFixedHeaderDiv', torrentPeersContextMenu);
|
||||
|
||||
new ClipboardJS('#CopyPeerInfo', {
|
||||
text: function(trigger) {
|
||||
return torrentPeersTable.selectedRowsIds().join("\n");
|
||||
}
|
||||
});
|
||||
|
||||
torrentPeersTable.setup('torrentPeersTableDiv', 'torrentPeersTableFixedHeaderDiv', torrentPeersContextMenu);
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -28,195 +28,211 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
this.current_hash = "";
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
let loadTrackersDataTimer;
|
||||
const loadTrackersData = function() {
|
||||
if ($('prop_trackers').hasClass('invisible')
|
||||
|| $('propertiesPanel_collapseToggle').hasClass('panel-expand')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
const new_hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (new_hash === "") {
|
||||
torrentTrackersTable.clear();
|
||||
clearTimeout(loadTrackersDataTimer);
|
||||
loadTrackersDataTimer = loadTrackersData.delay(10000);
|
||||
return;
|
||||
}
|
||||
if (new_hash != current_hash) {
|
||||
torrentTrackersTable.clear();
|
||||
current_hash = new_hash;
|
||||
}
|
||||
const url = new URI('api/v2/torrents/trackers?hash=' + current_hash);
|
||||
new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onComplete: function() {
|
||||
window.qBittorrent.PropTrackers = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
updateData: updateData
|
||||
};
|
||||
};
|
||||
|
||||
let current_hash = "";
|
||||
|
||||
const torrentTrackersTable = new window.qBittorrent.DynamicTable.TorrentTrackersTable();
|
||||
let loadTrackersDataTimer;
|
||||
|
||||
const loadTrackersData = function() {
|
||||
if ($('prop_trackers').hasClass('invisible')
|
||||
|| $('propertiesPanel_collapseToggle').hasClass('panel-expand')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
const new_hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (new_hash === "") {
|
||||
torrentTrackersTable.clear();
|
||||
clearTimeout(loadTrackersDataTimer);
|
||||
loadTrackersDataTimer = loadTrackersData.delay(10000);
|
||||
},
|
||||
onSuccess: function(trackers) {
|
||||
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
|
||||
return;
|
||||
}
|
||||
if (new_hash != current_hash) {
|
||||
torrentTrackersTable.clear();
|
||||
current_hash = new_hash;
|
||||
}
|
||||
const url = new URI('api/v2/torrents/trackers?hash=' + current_hash);
|
||||
new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onComplete: function() {
|
||||
clearTimeout(loadTrackersDataTimer);
|
||||
loadTrackersDataTimer = loadTrackersData.delay(10000);
|
||||
},
|
||||
onSuccess: function(trackers) {
|
||||
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
|
||||
torrentTrackersTable.clear();
|
||||
|
||||
if (trackers) {
|
||||
trackers.each(function(tracker) {
|
||||
const url = escapeHtml(tracker.url);
|
||||
let status;
|
||||
switch (tracker.status) {
|
||||
case 0:
|
||||
status = "QBT_TR(Disabled)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
case 1:
|
||||
status = "QBT_TR(Not contacted yet)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
case 2:
|
||||
status = "QBT_TR(Working)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
case 3:
|
||||
status = "QBT_TR(Updating...)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
case 4:
|
||||
status = "QBT_TR(Not working)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
}
|
||||
if (trackers) {
|
||||
trackers.each(function(tracker) {
|
||||
const url = window.qBittorrent.Misc.escapeHtml(tracker.url);
|
||||
let status;
|
||||
switch (tracker.status) {
|
||||
case 0:
|
||||
status = "QBT_TR(Disabled)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
case 1:
|
||||
status = "QBT_TR(Not contacted yet)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
case 2:
|
||||
status = "QBT_TR(Working)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
case 3:
|
||||
status = "QBT_TR(Updating...)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
case 4:
|
||||
status = "QBT_TR(Not working)QBT_TR[CONTEXT=TrackerListWidget]";
|
||||
break;
|
||||
}
|
||||
|
||||
const row = {
|
||||
rowId: url,
|
||||
tier: tracker.tier,
|
||||
url: url,
|
||||
status: status,
|
||||
peers: tracker.num_peers,
|
||||
seeds: (tracker.num_seeds >= 0) ? tracker.num_seeds : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
|
||||
leeches: (tracker.num_leeches >= 0) ? tracker.num_leeches : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
|
||||
downloaded: (tracker.num_downloaded >= 0) ? tracker.num_downloaded : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
|
||||
message: escapeHtml(tracker.msg)
|
||||
};
|
||||
const row = {
|
||||
rowId: url,
|
||||
tier: tracker.tier,
|
||||
url: url,
|
||||
status: status,
|
||||
peers: tracker.num_peers,
|
||||
seeds: (tracker.num_seeds >= 0) ? tracker.num_seeds : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
|
||||
leeches: (tracker.num_leeches >= 0) ? tracker.num_leeches : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
|
||||
downloaded: (tracker.num_downloaded >= 0) ? tracker.num_downloaded : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
|
||||
message: window.qBittorrent.Misc.escapeHtml(tracker.msg)
|
||||
};
|
||||
|
||||
torrentTrackersTable.updateRowData(row);
|
||||
});
|
||||
torrentTrackersTable.updateRowData(row);
|
||||
});
|
||||
|
||||
torrentTrackersTable.updateTable(false);
|
||||
torrentTrackersTable.altRow();
|
||||
torrentTrackersTable.updateTable(false);
|
||||
torrentTrackersTable.altRow();
|
||||
|
||||
if (selectedTrackers.length > 0)
|
||||
torrentTrackersTable.reselectRows(selectedTrackers);
|
||||
if (selectedTrackers.length > 0)
|
||||
torrentTrackersTable.reselectRows(selectedTrackers);
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
const updateData = function() {
|
||||
clearTimeout(loadTrackersDataTimer);
|
||||
loadTrackersData();
|
||||
};
|
||||
|
||||
const torrentTrackersContextMenu = new window.qBittorrent.ContextMenu.ContextMenu({
|
||||
targets: '#torrentTrackersTableDiv',
|
||||
menu: 'torrentTrackersMenu',
|
||||
actions: {
|
||||
AddTracker: function(element, ref) {
|
||||
addTrackerFN();
|
||||
},
|
||||
EditTracker: function(element, ref) {
|
||||
// only allow editing of one row
|
||||
element.firstChild.click();
|
||||
editTrackerFN(element);
|
||||
},
|
||||
RemoveTracker: function(element, ref) {
|
||||
removeTrackerFN(element);
|
||||
}
|
||||
},
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
},
|
||||
onShow: function() {
|
||||
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
|
||||
const containsStaticTracker = selectedTrackers.some(function(tracker) {
|
||||
return (tracker.indexOf("** [") === 0);
|
||||
});
|
||||
|
||||
if (containsStaticTracker || (selectedTrackers.length === 0)) {
|
||||
this.hideItem('EditTracker');
|
||||
this.hideItem('RemoveTracker');
|
||||
this.hideItem('CopyTrackerUrl');
|
||||
}
|
||||
else {
|
||||
this.showItem('EditTracker');
|
||||
this.showItem('RemoveTracker');
|
||||
this.showItem('CopyTrackerUrl');
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
});
|
||||
|
||||
updateTrackersData = function() {
|
||||
clearTimeout(loadTrackersDataTimer);
|
||||
loadTrackersData();
|
||||
};
|
||||
|
||||
const torrentTrackersContextMenu = new ContextMenu({
|
||||
targets: '#torrentTrackersTableDiv',
|
||||
menu: 'torrentTrackersMenu',
|
||||
actions: {
|
||||
AddTracker: function(element, ref) {
|
||||
addTrackerFN();
|
||||
},
|
||||
EditTracker: function(element, ref) {
|
||||
// only allow editing of one row
|
||||
element.firstChild.click();
|
||||
editTrackerFN(element);
|
||||
},
|
||||
RemoveTracker: function(element, ref) {
|
||||
removeTrackerFN(element);
|
||||
}
|
||||
},
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
},
|
||||
onShow: function() {
|
||||
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
|
||||
const containsStaticTracker = selectedTrackers.some(function(tracker) {
|
||||
return (tracker.indexOf("** [") === 0);
|
||||
const addTrackerFN = function() {
|
||||
if (current_hash.length === 0) return;
|
||||
new MochaUI.Window({
|
||||
id: 'trackersPage',
|
||||
title: "QBT_TR(Trackers addition dialog)QBT_TR[CONTEXT=TrackersAdditionDialog]",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'addtrackers.html?hash=' + current_hash,
|
||||
scrollbars: true,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
closable: true,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 500,
|
||||
height: 250,
|
||||
onCloseComplete: function() {
|
||||
updateData();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (containsStaticTracker || (selectedTrackers.length === 0)) {
|
||||
this.hideItem('EditTracker');
|
||||
this.hideItem('RemoveTracker');
|
||||
this.hideItem('CopyTrackerUrl');
|
||||
}
|
||||
else {
|
||||
this.showItem('EditTracker');
|
||||
this.showItem('RemoveTracker');
|
||||
this.showItem('CopyTrackerUrl');
|
||||
}
|
||||
}
|
||||
});
|
||||
const editTrackerFN = function(element) {
|
||||
if (current_hash.length === 0) return;
|
||||
|
||||
const addTrackerFN = function() {
|
||||
if (current_hash.length === 0) return;
|
||||
new MochaUI.Window({
|
||||
id: 'trackersPage',
|
||||
title: "QBT_TR(Trackers addition dialog)QBT_TR[CONTEXT=TrackersAdditionDialog]",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'addtrackers.html?hash=' + current_hash,
|
||||
scrollbars: true,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
closable: true,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 500,
|
||||
height: 250,
|
||||
onCloseComplete: function() {
|
||||
updateTrackersData();
|
||||
const trackerUrl = encodeURIComponent(element.childNodes[1].innerText);
|
||||
new MochaUI.Window({
|
||||
id: 'trackersPage',
|
||||
title: "QBT_TR(Tracker editing)QBT_TR[CONTEXT=TrackerListWidget]",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'edittracker.html?hash=' + current_hash + '&url=' + trackerUrl,
|
||||
scrollbars: true,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
closable: true,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 500,
|
||||
height: 150,
|
||||
onCloseComplete: function() {
|
||||
updateData();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const removeTrackerFN = function(element) {
|
||||
if (current_hash.length === 0) return;
|
||||
|
||||
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
|
||||
new Request({
|
||||
url: 'api/v2/torrents/removeTrackers',
|
||||
method: 'post',
|
||||
data: {
|
||||
hash: current_hash,
|
||||
urls: selectedTrackers.join("|")
|
||||
},
|
||||
onSuccess: function() {
|
||||
updateData();
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
new ClipboardJS('#CopyTrackerUrl', {
|
||||
text: function(trigger) {
|
||||
return torrentTrackersTable.selectedRowsIds().join("\n");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const editTrackerFN = function(element) {
|
||||
if (current_hash.length === 0) return;
|
||||
torrentTrackersTable.setup('torrentTrackersTableDiv', 'torrentTrackersTableFixedHeaderDiv', torrentTrackersContextMenu);
|
||||
|
||||
const trackerUrl = encodeURIComponent(element.childNodes[1].innerText);
|
||||
new MochaUI.Window({
|
||||
id: 'trackersPage',
|
||||
title: "QBT_TR(Tracker editing)QBT_TR[CONTEXT=TrackerListWidget]",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'edittracker.html?hash=' + current_hash + '&url=' + trackerUrl,
|
||||
scrollbars: true,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
closable: true,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 500,
|
||||
height: 150,
|
||||
onCloseComplete: function() {
|
||||
updateTrackersData();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const removeTrackerFN = function(element) {
|
||||
if (current_hash.length === 0) return;
|
||||
|
||||
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
|
||||
new Request({
|
||||
url: 'api/v2/torrents/removeTrackers',
|
||||
method: 'post',
|
||||
data: {
|
||||
hash: current_hash,
|
||||
urls: selectedTrackers.join("|")
|
||||
},
|
||||
onSuccess: function() {
|
||||
updateTrackersData();
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
new ClipboardJS('#CopyTrackerUrl', {
|
||||
text: function(trigger) {
|
||||
return torrentTrackersTable.selectedRowsIds().join("\n");
|
||||
}
|
||||
});
|
||||
|
||||
torrentTrackersTable.setup('torrentTrackersTableDiv', 'torrentTrackersTableFixedHeaderDiv', torrentTrackersContextMenu);
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -28,112 +28,126 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const webseedsDynTable = new Class({
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
initialize: function() {},
|
||||
window.qBittorrent.PropWebseeds = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
updateData: updateData
|
||||
};
|
||||
};
|
||||
|
||||
setup: function(table) {
|
||||
this.table = $(table);
|
||||
this.rows = new Hash();
|
||||
},
|
||||
const webseedsDynTable = new Class({
|
||||
|
||||
removeRow: function(url) {
|
||||
if (this.rows.has(url)) {
|
||||
const tr = this.rows.get(url);
|
||||
tr.dispose();
|
||||
this.rows.erase(url);
|
||||
initialize: function() {},
|
||||
|
||||
setup: function(table) {
|
||||
this.table = $(table);
|
||||
this.rows = new Hash();
|
||||
},
|
||||
|
||||
removeRow: function(url) {
|
||||
if (this.rows.has(url)) {
|
||||
const tr = this.rows.get(url);
|
||||
tr.dispose();
|
||||
this.rows.erase(url);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
removeAllRows: function() {
|
||||
this.rows.each(function(tr, url) {
|
||||
this.removeRow(url);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
updateRow: function(tr, row) {
|
||||
const tds = tr.getElements('td');
|
||||
for (let i = 0; i < row.length; ++i) {
|
||||
tds[i].set('html', row[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
|
||||
removeAllRows: function() {
|
||||
this.rows.each(function(tr, url) {
|
||||
this.removeRow(url);
|
||||
}.bind(this));
|
||||
},
|
||||
insertRow: function(row) {
|
||||
const url = row[0];
|
||||
if (this.rows.has(url)) {
|
||||
const tableRow = this.rows.get(url);
|
||||
this.updateRow(tableRow, row);
|
||||
return;
|
||||
}
|
||||
//this.removeRow(id);
|
||||
const tr = new Element('tr');
|
||||
this.rows.set(url, tr);
|
||||
for (let i = 0; i < row.length; ++i) {
|
||||
const td = new Element('td');
|
||||
td.set('html', row[i]);
|
||||
td.injectInside(tr);
|
||||
}
|
||||
tr.injectInside(this.table);
|
||||
},
|
||||
});
|
||||
|
||||
updateRow: function(tr, row) {
|
||||
const tds = tr.getElements('td');
|
||||
for (let i = 0; i < row.length; ++i) {
|
||||
tds[i].set('html', row[i]);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
let current_hash = "";
|
||||
|
||||
insertRow: function(row) {
|
||||
const url = row[0];
|
||||
if (this.rows.has(url)) {
|
||||
const tableRow = this.rows.get(url);
|
||||
this.updateRow(tableRow, row);
|
||||
let loadWebSeedsDataTimer;
|
||||
const loadWebSeedsData = function() {
|
||||
if ($('prop_webseeds').hasClass('invisible')
|
||||
|| $('propertiesPanel_collapseToggle').hasClass('panel-expand')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
//this.removeRow(id);
|
||||
const tr = new Element('tr');
|
||||
this.rows.set(url, tr);
|
||||
for (let i = 0; i < row.length; ++i) {
|
||||
const td = new Element('td');
|
||||
td.set('html', row[i]);
|
||||
td.injectInside(tr);
|
||||
}
|
||||
tr.injectInside(this.table);
|
||||
},
|
||||
});
|
||||
|
||||
this.current_hash = "";
|
||||
|
||||
let loadWebSeedsDataTimer;
|
||||
const loadWebSeedsData = function() {
|
||||
if ($('prop_webseeds').hasClass('invisible')
|
||||
|| $('propertiesPanel_collapseToggle').hasClass('panel-expand')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
const new_hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (new_hash === "") {
|
||||
wsTable.removeAllRows();
|
||||
clearTimeout(loadWebSeedsDataTimer);
|
||||
loadWebSeedsDataTimer = loadWebSeedsData.delay(10000);
|
||||
return;
|
||||
}
|
||||
if (new_hash != current_hash) {
|
||||
wsTable.removeAllRows();
|
||||
current_hash = new_hash;
|
||||
}
|
||||
const url = new URI('api/v2/torrents/webseeds?hash=' + current_hash);
|
||||
new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onFailure: function() {
|
||||
$('error_div').set('html', 'QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]');
|
||||
clearTimeout(loadWebSeedsDataTimer);
|
||||
loadWebSeedsDataTimer = loadWebSeedsData.delay(20000);
|
||||
},
|
||||
onSuccess: function(webseeds) {
|
||||
$('error_div').set('html', '');
|
||||
if (webseeds) {
|
||||
// Update WebSeeds data
|
||||
webseeds.each(function(webseed) {
|
||||
const row = [];
|
||||
row.length = 1;
|
||||
row[0] = webseed.url;
|
||||
wsTable.insertRow(row);
|
||||
});
|
||||
}
|
||||
else {
|
||||
wsTable.removeAllRows();
|
||||
}
|
||||
const new_hash = torrentsTable.getCurrentTorrentHash();
|
||||
if (new_hash === "") {
|
||||
wsTable.removeAllRows();
|
||||
clearTimeout(loadWebSeedsDataTimer);
|
||||
loadWebSeedsDataTimer = loadWebSeedsData.delay(10000);
|
||||
return;
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
if (new_hash != current_hash) {
|
||||
wsTable.removeAllRows();
|
||||
current_hash = new_hash;
|
||||
}
|
||||
const url = new URI('api/v2/torrents/webseeds?hash=' + current_hash);
|
||||
new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onFailure: function() {
|
||||
$('error_div').set('html', 'QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]');
|
||||
clearTimeout(loadWebSeedsDataTimer);
|
||||
loadWebSeedsDataTimer = loadWebSeedsData.delay(20000);
|
||||
},
|
||||
onSuccess: function(webseeds) {
|
||||
$('error_div').set('html', '');
|
||||
if (webseeds) {
|
||||
// Update WebSeeds data
|
||||
webseeds.each(function(webseed) {
|
||||
const row = [];
|
||||
row.length = 1;
|
||||
row[0] = webseed.url;
|
||||
wsTable.insertRow(row);
|
||||
});
|
||||
}
|
||||
else {
|
||||
wsTable.removeAllRows();
|
||||
}
|
||||
clearTimeout(loadWebSeedsDataTimer);
|
||||
loadWebSeedsDataTimer = loadWebSeedsData.delay(10000);
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
updateWebSeedsData = function() {
|
||||
clearTimeout(loadWebSeedsDataTimer);
|
||||
loadWebSeedsData();
|
||||
};
|
||||
const updateData = function() {
|
||||
clearTimeout(loadWebSeedsDataTimer);
|
||||
loadWebSeedsData();
|
||||
};
|
||||
|
||||
const wsTable = new webseedsDynTable();
|
||||
wsTable.setup($('webseedsTable'));
|
||||
const wsTable = new webseedsDynTable();
|
||||
wsTable.setup($('webseedsTable'));
|
||||
|
||||
return exports();
|
||||
})();
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
const path = new URI().getData('path');
|
||||
// set text field to current value
|
||||
if (path)
|
||||
$('setLocation').value = escapeHtml(decodeURIComponent(path));
|
||||
$('setLocation').value = window.qBittorrent.Misc.escapeHtml(decodeURIComponent(path));
|
||||
|
||||
$('setLocation').focus();
|
||||
$('setLocationButton').addEvent('click', function(e) {
|
||||
|
|
|
@ -37,9 +37,9 @@
|
|||
const origValues = new URI().getData('orig').split('|');
|
||||
|
||||
const values = {
|
||||
ratioLimit: friendlyFloat(origValues[0], 2),
|
||||
ratioLimit: window.qBittorrent.Misc.friendlyFloat(origValues[0], 2),
|
||||
seedingTimeLimit: parseInt(origValues[1]),
|
||||
maxRatio: friendlyFloat(origValues[2], 2),
|
||||
maxRatio: window.qBittorrent.Misc.friendlyFloat(origValues[2], 2),
|
||||
maxSeedingTime: parseInt(origValues[3])
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<label for="autoTMM">QBT_TR(Torrent Management Mode:)QBT_TR[CONTEXT=AddNewTorrentDialog]</label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="autoTMM" name="autoTMM" onchange="changeTMM(this)">
|
||||
<select id="autoTMM" name="autoTMM" onchange="qBittorrent.Download.changeTMM(this)">
|
||||
<option selected value="false">Manual</option>
|
||||
<option value="true">Automatic</option>
|
||||
</select>
|
||||
|
@ -51,7 +51,7 @@
|
|||
</td>
|
||||
<td>
|
||||
<div class="select-watched-folder-editable">
|
||||
<select id="categorySelect" onchange="changeCategorySelect(this)">
|
||||
<select id="categorySelect" onchange="qBittorrent.Download.changeCategorySelect(this)">
|
||||
<option selected value="\other"></option>
|
||||
</select>
|
||||
<input name="category" type="text" value="" />
|
||||
|
|
|
@ -681,22 +681,24 @@
|
|||
<script>
|
||||
'use strict';
|
||||
|
||||
$('qbittorrentVersion').innerText = ("qBittorrent " + qbtVersion()
|
||||
(function() {
|
||||
$('qbittorrentVersion').innerText = ("qBittorrent " + qbtVersion()
|
||||
+ " QBT_TR(Web UI)QBT_TR[CONTEXT=OptionsDialog]");
|
||||
|
||||
new Request.JSON({
|
||||
url: 'api/v2/app/buildInfo',
|
||||
method: 'get',
|
||||
noCache: true,
|
||||
onSuccess: function(info) {
|
||||
if (!info) return;
|
||||
new Request.JSON({
|
||||
url: 'api/v2/app/buildInfo',
|
||||
method: 'get',
|
||||
noCache: true,
|
||||
onSuccess: function(info) {
|
||||
if (!info) return;
|
||||
|
||||
$('qtVersion').textContent = info.qt;
|
||||
$('libtorrentVersion').textContent = info.libtorrent;
|
||||
$('boostVersion').textContent = info.boost;
|
||||
$('opensslVersion').textContent = info.openssl;
|
||||
$('zlibVersion').textContent = info.zlib;
|
||||
$('qbittorrentVersion').textContent += " (" + info.bitness + "-bit)";
|
||||
}
|
||||
}).send();
|
||||
$('qtVersion').textContent = info.qt;
|
||||
$('libtorrentVersion').textContent = info.libtorrent;
|
||||
$('boostVersion').textContent = info.boost;
|
||||
$('opensslVersion').textContent = info.openssl;
|
||||
$('zlibVersion').textContent = info.zlib;
|
||||
$('qbittorrentVersion').textContent += " (" + info.bitness + "-bit)";
|
||||
}
|
||||
}).send();
|
||||
})();
|
||||
</script>
|
||||
|
|
|
@ -13,35 +13,37 @@
|
|||
<script>
|
||||
'use strict';
|
||||
|
||||
MochaUI.initializeTabs('aboutTabs');
|
||||
(function() {
|
||||
MochaUI.initializeTabs('aboutTabs');
|
||||
|
||||
$('aboutAboutLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutAboutContent').removeClass('invisible');
|
||||
});
|
||||
$('aboutAboutLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutAboutContent').removeClass('invisible');
|
||||
});
|
||||
|
||||
$('aboutAuthorLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutAuthorContent').removeClass('invisible');
|
||||
});
|
||||
$('aboutAuthorLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutAuthorContent').removeClass('invisible');
|
||||
});
|
||||
|
||||
$('aboutSpecialThanksLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutSpecialThanksContent').removeClass('invisible');
|
||||
});
|
||||
$('aboutSpecialThanksLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutSpecialThanksContent').removeClass('invisible');
|
||||
});
|
||||
|
||||
$('aboutTranslatorsLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutTranslatorsContent').removeClass('invisible');
|
||||
});
|
||||
$('aboutTranslatorsLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutTranslatorsContent').removeClass('invisible');
|
||||
});
|
||||
|
||||
$('aboutLicenseLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutLicenseContent').removeClass('invisible');
|
||||
});
|
||||
$('aboutLicenseLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutLicenseContent').removeClass('invisible');
|
||||
});
|
||||
|
||||
$('aboutLibrariesLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutLibrariesContent').removeClass('invisible');
|
||||
});
|
||||
$('aboutLibrariesLink').addEvent('click', function() {
|
||||
$$('.aboutTabContent').addClass('invisible');
|
||||
$('aboutLibrariesContent').removeClass('invisible');
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
|
|
@ -32,79 +32,94 @@
|
|||
<script>
|
||||
'use strict';
|
||||
|
||||
const categoriesFilterContextMenu = new CategoriesFilterContextMenu({
|
||||
targets: '.categoriesFilterContextMenuTarget',
|
||||
menu: 'categoriesFilterMenu',
|
||||
actions: {
|
||||
createCategory: function(element, ref) {
|
||||
createCategoryFN();
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
window.qBittorrent.Filters = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
categoriesFilterContextMenu: categoriesFilterContextMenu,
|
||||
tagsFilterContextMenu: tagsFilterContextMenu
|
||||
};
|
||||
};
|
||||
|
||||
const categoriesFilterContextMenu = new window.qBittorrent.ContextMenu.CategoriesFilterContextMenu({
|
||||
targets: '.categoriesFilterContextMenuTarget',
|
||||
menu: 'categoriesFilterMenu',
|
||||
actions: {
|
||||
createCategory: function(element, ref) {
|
||||
createCategoryFN();
|
||||
},
|
||||
editCategory: function(element, ref) {
|
||||
editCategoryFN(element.id);
|
||||
},
|
||||
deleteCategory: function(element, ref) {
|
||||
removeCategoryFN(element.id);
|
||||
},
|
||||
deleteUnusedCategories: function(element, ref) {
|
||||
deleteUnusedCategoriesFN();
|
||||
},
|
||||
startTorrentsByCategory: function(element, ref) {
|
||||
startTorrentsByCategoryFN(element.id);
|
||||
},
|
||||
pauseTorrentsByCategory: function(element, ref) {
|
||||
pauseTorrentsByCategoryFN(element.id);
|
||||
},
|
||||
deleteTorrentsByCategory: function(element, ref) {
|
||||
deleteTorrentsByCategoryFN(element.id);
|
||||
}
|
||||
},
|
||||
editCategory: function(element, ref) {
|
||||
editCategoryFN(element.id);
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
},
|
||||
deleteCategory: function(element, ref) {
|
||||
removeCategoryFN(element.id);
|
||||
},
|
||||
deleteUnusedCategories: function(element, ref) {
|
||||
deleteUnusedCategoriesFN();
|
||||
},
|
||||
startTorrentsByCategory: function(element, ref) {
|
||||
startTorrentsByCategoryFN(element.id);
|
||||
},
|
||||
pauseTorrentsByCategory: function(element, ref) {
|
||||
pauseTorrentsByCategoryFN(element.id);
|
||||
},
|
||||
deleteTorrentsByCategory: function(element, ref) {
|
||||
deleteTorrentsByCategoryFN(element.id);
|
||||
onShow: function() {
|
||||
this.options.element.firstChild.click();
|
||||
}
|
||||
},
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
},
|
||||
onShow: function() {
|
||||
this.options.element.firstChild.click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const tagsFilterContextMenu = new TagsFilterContextMenu({
|
||||
targets: '.tagsFilterContextMenuTarget',
|
||||
menu: 'tagsFilterMenu',
|
||||
actions: {
|
||||
createTag: function(element, ref) {
|
||||
createTagFN();
|
||||
const tagsFilterContextMenu = new window.qBittorrent.ContextMenu.TagsFilterContextMenu({
|
||||
targets: '.tagsFilterContextMenuTarget',
|
||||
menu: 'tagsFilterMenu',
|
||||
actions: {
|
||||
createTag: function(element, ref) {
|
||||
createTagFN();
|
||||
},
|
||||
deleteTag: function(element, ref) {
|
||||
removeTagFN(element.id);
|
||||
},
|
||||
deleteUnusedTags: function(element, ref) {
|
||||
deleteUnusedTagsFN();
|
||||
},
|
||||
startTorrentsByTag: function(element, ref) {
|
||||
startTorrentsByTagFN(element.id);
|
||||
},
|
||||
pauseTorrentsByTag: function(element, ref) {
|
||||
pauseTorrentsByTagFN(element.id);
|
||||
},
|
||||
deleteTorrentsByTag: function(element, ref) {
|
||||
deleteTorrentsByTagFN(element.id);
|
||||
}
|
||||
},
|
||||
deleteTag: function(element, ref) {
|
||||
removeTagFN(element.id);
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
},
|
||||
deleteUnusedTags: function(element, ref) {
|
||||
deleteUnusedTagsFN();
|
||||
},
|
||||
startTorrentsByTag: function(element, ref) {
|
||||
startTorrentsByTagFN(element.id);
|
||||
},
|
||||
pauseTorrentsByTag: function(element, ref) {
|
||||
pauseTorrentsByTagFN(element.id);
|
||||
},
|
||||
deleteTorrentsByTag: function(element, ref) {
|
||||
deleteTorrentsByTagFN(element.id);
|
||||
onShow: function() {
|
||||
this.options.element.firstChild.click();
|
||||
}
|
||||
},
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
},
|
||||
onShow: function() {
|
||||
this.options.element.firstChild.click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (LocalPreferences.get('filter_status_collapsed') === "true")
|
||||
toggleFilterDisplay('status');
|
||||
if (LocalPreferences.get('filter_status_collapsed') === "true")
|
||||
toggleFilterDisplay('status');
|
||||
|
||||
if (LocalPreferences.get('filter_category_collapsed') === "true")
|
||||
toggleFilterDisplay('category');
|
||||
if (LocalPreferences.get('filter_category_collapsed') === "true")
|
||||
toggleFilterDisplay('category');
|
||||
|
||||
if (LocalPreferences.get('filter_tag_collapsed') === "true")
|
||||
toggleFilterDisplay('tag');
|
||||
if (LocalPreferences.get('filter_tag_collapsed') === "true")
|
||||
toggleFilterDisplay('tag');
|
||||
|
||||
return exports();
|
||||
})();
|
||||
</script>
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
<div>
|
||||
<input type="text" id="newPluginPath" placeholder="QBT_TR(URL or local directory)QBT_TR[CONTEXT=PluginSourceDlg]" autocorrect="off" autocapitalize="none" />
|
||||
<div style="margin-top: 10px; text-align: center;">
|
||||
<button id="newPluginCancel" onclick="closeSearchWindow('installSearchPlugin');">QBT_TR(Cancel)QBT_TR[CONTEXT=PluginSourceDlg]</button>
|
||||
<button id="newPluginOk" onclick="newPluginOk();">QBT_TR(Ok)QBT_TR[CONTEXT=PluginSourceDlg]</button>
|
||||
<button id="newPluginCancel" onclick="qBittorrent.SearchPlugins.closeSearchWindow('installSearchPlugin');">QBT_TR(Cancel)QBT_TR[CONTEXT=PluginSourceDlg]</button>
|
||||
<button id="newPluginOk" onclick="qBittorrent.InstallSearchPlugin.newPluginOk();">QBT_TR(Ok)QBT_TR[CONTEXT=PluginSourceDlg]</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -29,41 +29,55 @@
|
|||
<script>
|
||||
'use strict';
|
||||
|
||||
this.initInstallSearchPlugin = function() {
|
||||
new Keyboard({
|
||||
defaultEventType: 'keydown',
|
||||
events: {
|
||||
'Enter': function(e) {
|
||||
// accept enter key as a click
|
||||
new Event(e).stop();
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
const elem = e.event.srcElement;
|
||||
if ((elem.id === "newPluginPath") || (elem.id === "newPluginOk"))
|
||||
newPluginOk();
|
||||
else if (elem.id === "newPluginCancel")
|
||||
closeSearchWindow('installSearchPlugin');
|
||||
window.qBittorrent.InstallSearchPlugin = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
newPluginOk: newPluginOk
|
||||
};
|
||||
};
|
||||
|
||||
const init = function() {
|
||||
new Keyboard({
|
||||
defaultEventType: 'keydown',
|
||||
events: {
|
||||
'Enter': function(e) {
|
||||
// accept enter key as a click
|
||||
new Event(e).stop();
|
||||
|
||||
const elem = e.event.srcElement;
|
||||
if ((elem.id === "newPluginPath") || (elem.id === "newPluginOk"))
|
||||
newPluginOk();
|
||||
else if (elem.id === "newPluginCancel")
|
||||
window.qBittorrent.SearchPlugins.closeSearchWindow('installSearchPlugin');
|
||||
}
|
||||
}
|
||||
}
|
||||
}).activate();
|
||||
}).activate();
|
||||
|
||||
$('newPluginPath').select();
|
||||
};
|
||||
$('newPluginPath').select();
|
||||
};
|
||||
|
||||
this.newPluginOk = function() {
|
||||
const path = $("newPluginPath").get("value").trim();
|
||||
if (path)
|
||||
new Request({
|
||||
url: 'api/v2/search/installPlugin',
|
||||
noCache: true,
|
||||
method: 'post',
|
||||
data: {
|
||||
sources: path,
|
||||
},
|
||||
onRequest: function() {
|
||||
closeSearchWindow('installSearchPlugin');
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
const newPluginOk = function() {
|
||||
const path = $("newPluginPath").get("value").trim();
|
||||
if (path)
|
||||
new Request({
|
||||
url: 'api/v2/search/installPlugin',
|
||||
noCache: true,
|
||||
method: 'post',
|
||||
data: {
|
||||
sources: path,
|
||||
},
|
||||
onRequest: function() {
|
||||
window.qBittorrent.SearchPlugins.closeSearchWindow('installSearchPlugin');
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
initInstallSearchPlugin();
|
||||
init();
|
||||
|
||||
return exports();
|
||||
})();
|
||||
</script>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,31 +14,33 @@
|
|||
<script>
|
||||
'use strict';
|
||||
|
||||
// Tabs
|
||||
MochaUI.initializeTabs('preferencesTabs');
|
||||
(function() {
|
||||
// Tabs
|
||||
MochaUI.initializeTabs('preferencesTabs');
|
||||
|
||||
$('PrefDownloadsLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('DownloadsTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefConnectionLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('ConnectionTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefSpeedLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('SpeedTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefBittorrentLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('BittorrentTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefWebUILink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('WebUITab').removeClass('invisible');
|
||||
});
|
||||
$('PrefAdvancedLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('AdvancedTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefDownloadsLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('DownloadsTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefConnectionLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('ConnectionTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefSpeedLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('SpeedTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefBittorrentLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('BittorrentTab').removeClass('invisible');
|
||||
});
|
||||
$('PrefWebUILink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('WebUITab').removeClass('invisible');
|
||||
});
|
||||
$('PrefAdvancedLink').addEvent('click', function(e) {
|
||||
$$('.PrefTab').addClass('invisible');
|
||||
$('AdvancedTab').removeClass('invisible');
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
|
|
@ -155,7 +155,9 @@
|
|||
<script>
|
||||
'use strict';
|
||||
|
||||
const selectedTab = $(LocalPreferences.get('selected_tab', 'PropGeneralLink'));
|
||||
if (selectedTab)
|
||||
selectedTab.click();
|
||||
(function() {
|
||||
const selectedTab = $(LocalPreferences.get('selected_tab', 'PropGeneralLink'));
|
||||
if (selectedTab)
|
||||
selectedTab.click();
|
||||
})();
|
||||
</script>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -65,9 +65,9 @@
|
|||
<span>QBT_TR(Warning: Be sure to comply with your country's copyright laws when downloading torrents from any of these search engines.)QBT_TR[CONTEXT=PluginSelectDlg]</span>
|
||||
<span style="font-style: italic;">QBT_TR(You can get new search engine plugins here:)QBT_TR[CONTEXT=PluginSelectDlg] <a href="http://plugins.qbittorrent.org" target="_blank">http://plugins.qbittorrent.org</a></span>
|
||||
<div style="width: 100%; margin-top: 10px;">
|
||||
<button style="width: 33%; line-height: 1.4em;" onclick="installPlugin();">QBT_TR(Install new plugin)QBT_TR[CONTEXT=PluginSelectDlg]</button>
|
||||
<button style="width: 33%; line-height: 1.4em;" onclick="checkForUpdates();">QBT_TR(Check for updates)QBT_TR[CONTEXT=PluginSelectDlg]</button>
|
||||
<button style="width: 32%; line-height: 1.4em;" onclick="closeSearchWindow('searchPlugins');">QBT_TR(Close)QBT_TR[CONTEXT=PluginSelectDlg]</button>
|
||||
<button style="width: 33%; line-height: 1.4em;" onclick="qBittorrent.SearchPlugins.installPlugin();">QBT_TR(Install new plugin)QBT_TR[CONTEXT=PluginSelectDlg]</button>
|
||||
<button style="width: 33%; line-height: 1.4em;" onclick="qBittorrent.SearchPlugins.checkForUpdates();">QBT_TR(Check for updates)QBT_TR[CONTEXT=PluginSelectDlg]</button>
|
||||
<button style="width: 32%; line-height: 1.4em;" onclick="qBittorrent.SearchPlugins.closeSearchWindow('searchPlugins');">QBT_TR(Close)QBT_TR[CONTEXT=PluginSelectDlg]</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -79,142 +79,161 @@
|
|||
<script>
|
||||
'use strict';
|
||||
|
||||
this.searchPluginsTableContextMenu = undefined;
|
||||
this.prevOffsetLeft = undefined;
|
||||
this.prevOffsetTop = undefined;
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
this.initSearchPlugins = function() {
|
||||
searchPluginsTableContextMenu = new SearchPluginsTableContextMenu({
|
||||
targets: '.searchPluginsTableRow',
|
||||
menu: 'searchPluginsTableMenu',
|
||||
actions: {
|
||||
Enabled: enablePlugin,
|
||||
Uninstall: uninstallPlugin
|
||||
},
|
||||
offsets: calculateContextMenuOffsets()
|
||||
});
|
||||
searchPluginsTable.setup('searchPluginsTableDiv', 'searchPluginsTableFixedHeaderDiv', searchPluginsTableContextMenu);
|
||||
updateSearchPluginsTable();
|
||||
};
|
||||
|
||||
this.closeSearchWindow = function(id) {
|
||||
window.parent.MochaUI.closeWindow(window.parent.$(id));
|
||||
};
|
||||
|
||||
this.installPlugin = function(path) {
|
||||
new MochaUI.Window({
|
||||
id: 'installSearchPlugin',
|
||||
title: "QBT_TR(Install plugin)QBT_TR[CONTEXT=PluginSourceDlg]",
|
||||
loadMethod: 'xhr',
|
||||
contentURL: 'views/installsearchplugin.html',
|
||||
scrollbars: false,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 500,
|
||||
height: 120
|
||||
});
|
||||
};
|
||||
|
||||
this.uninstallPlugin = function() {
|
||||
const plugins = searchPluginsTable.selectedRowsIds().join('|');
|
||||
const url = new URI('api/v2/search/uninstallPlugin');
|
||||
new Request({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'post',
|
||||
data: {
|
||||
names: plugins,
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
this.enablePlugin = function() {
|
||||
const plugins = searchPluginsTable.selectedRowsIds();
|
||||
let enable = true;
|
||||
if (plugins && plugins.length)
|
||||
enable = !getPlugin(plugins[0]).enabled;
|
||||
|
||||
const url = new URI('api/v2/search/enablePlugin');
|
||||
new Request({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'post',
|
||||
data: {
|
||||
names: plugins.join('|'),
|
||||
enable: enable
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
this.checkForUpdates = function() {
|
||||
const url = new URI('api/v2/search/updatePlugins');
|
||||
new Request({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'post'
|
||||
}).send();
|
||||
};
|
||||
|
||||
this.calculateContextMenuOffsets = function() {
|
||||
prevOffsetLeft = document.getElementById("searchPlugins").getBoundingClientRect().left;
|
||||
prevOffsetTop = document.getElementById("searchPlugins").getBoundingClientRect().top;
|
||||
|
||||
return {
|
||||
x: -(prevOffsetLeft + 20),
|
||||
y: -(prevOffsetTop + 2)
|
||||
window.qBittorrent.SearchPlugins = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
closeSearchWindow: closeSearchWindow,
|
||||
installPlugin: installPlugin,
|
||||
checkForUpdates: checkForUpdates,
|
||||
updateTable: updateTable
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
this.updateSearchPluginsTableContextMenuOffset = function() {
|
||||
// only re-calculate if window has moved
|
||||
if ((prevOffsetLeft !== document.getElementById("searchPlugins").getBoundingClientRect().left) || (prevOffsetTop !== document.getElementById("searchPlugins").getBoundingClientRect().top))
|
||||
searchPluginsTableContextMenu.options.offsets = calculateContextMenuOffsets();
|
||||
};
|
||||
let searchPluginsTable;
|
||||
let searchPluginsTableContextMenu;
|
||||
let prevOffsetLeft;
|
||||
let prevOffsetTop;
|
||||
|
||||
this.setupSearchPluginTableEvents = function(enable) {
|
||||
if (enable)
|
||||
$$(".searchPluginsTableRow").each(function(target) {
|
||||
target.addEventListener('dblclick', enablePlugin, false);
|
||||
target.addEventListener('contextmenu', updateSearchPluginsTableContextMenuOffset, true);
|
||||
const initSearchPlugins = function() {
|
||||
searchPluginsTable = new window.qBittorrent.DynamicTable.SearchPluginsTable();
|
||||
searchPluginsTableContextMenu = new window.qBittorrent.ContextMenu.SearchPluginsTableContextMenu({
|
||||
targets: '.searchPluginsTableRow',
|
||||
menu: 'searchPluginsTableMenu',
|
||||
actions: {
|
||||
Enabled: enablePlugin,
|
||||
Uninstall: uninstallPlugin
|
||||
},
|
||||
offsets: calculateContextMenuOffsets()
|
||||
});
|
||||
else
|
||||
$$(".searchPluginsTableRow").each(function(target) {
|
||||
target.removeEventListener('dblclick', enablePlugin, false);
|
||||
target.removeEventListener('contextmenu', updateSearchPluginsTableContextMenuOffset, true);
|
||||
searchPluginsTable.setup('searchPluginsTableDiv', 'searchPluginsTableFixedHeaderDiv', searchPluginsTableContextMenu);
|
||||
updateTable();
|
||||
};
|
||||
|
||||
const closeSearchWindow = function(id) {
|
||||
window.parent.MochaUI.closeWindow(window.parent.$(id));
|
||||
};
|
||||
|
||||
const installPlugin = function(path) {
|
||||
new MochaUI.Window({
|
||||
id: 'installSearchPlugin',
|
||||
title: "QBT_TR(Install plugin)QBT_TR[CONTEXT=PluginSourceDlg]",
|
||||
loadMethod: 'xhr',
|
||||
contentURL: 'views/installsearchplugin.html',
|
||||
scrollbars: false,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 500,
|
||||
height: 120
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
this.updateSearchPluginsTable = function() {
|
||||
// clear event listeners
|
||||
setupSearchPluginTableEvents(false);
|
||||
|
||||
const oldPlugins = Object.keys(searchPluginsTable.rows);
|
||||
// remove old rows from the table
|
||||
for (let i = 0; i < oldPlugins.length; ++i) {
|
||||
let found = false;
|
||||
for (let j = 0; j < searchPlugins.length; ++j) {
|
||||
if (searchPlugins[j].name === oldPlugins[i]) {
|
||||
found = true;
|
||||
break;
|
||||
const uninstallPlugin = function() {
|
||||
const plugins = searchPluginsTable.selectedRowsIds().join('|');
|
||||
const url = new URI('api/v2/search/uninstallPlugin');
|
||||
new Request({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'post',
|
||||
data: {
|
||||
names: plugins,
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
const enablePlugin = function() {
|
||||
const plugins = searchPluginsTable.selectedRowsIds();
|
||||
let enable = true;
|
||||
if (plugins && plugins.length)
|
||||
enable = !window.qBittorrent.Search.getPlugin(plugins[0]).enabled;
|
||||
|
||||
const url = new URI('api/v2/search/enablePlugin');
|
||||
new Request({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'post',
|
||||
data: {
|
||||
names: plugins.join('|'),
|
||||
enable: enable
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
const checkForUpdates = function() {
|
||||
const url = new URI('api/v2/search/updatePlugins');
|
||||
new Request({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'post'
|
||||
}).send();
|
||||
};
|
||||
|
||||
const calculateContextMenuOffsets = function() {
|
||||
prevOffsetLeft = document.getElementById("searchPlugins").getBoundingClientRect().left;
|
||||
prevOffsetTop = document.getElementById("searchPlugins").getBoundingClientRect().top;
|
||||
|
||||
return {
|
||||
x: -(prevOffsetLeft + 20),
|
||||
y: -(prevOffsetTop + 2)
|
||||
};
|
||||
};
|
||||
|
||||
const updateSearchPluginsTableContextMenuOffset = function() {
|
||||
// only re-calculate if window has moved
|
||||
if ((prevOffsetLeft !== document.getElementById("searchPlugins").getBoundingClientRect().left) || (prevOffsetTop !== document.getElementById("searchPlugins").getBoundingClientRect().top))
|
||||
searchPluginsTableContextMenu.options.offsets = calculateContextMenuOffsets();
|
||||
};
|
||||
|
||||
const setupSearchPluginTableEvents = function(enable) {
|
||||
if (enable)
|
||||
$$(".searchPluginsTableRow").each(function(target) {
|
||||
target.addEventListener('dblclick', enablePlugin, false);
|
||||
target.addEventListener('contextmenu', updateSearchPluginsTableContextMenuOffset, true);
|
||||
});
|
||||
else
|
||||
$$(".searchPluginsTableRow").each(function(target) {
|
||||
target.removeEventListener('dblclick', enablePlugin, false);
|
||||
target.removeEventListener('contextmenu', updateSearchPluginsTableContextMenuOffset, true);
|
||||
});
|
||||
};
|
||||
|
||||
const updateTable = function() {
|
||||
// clear event listeners
|
||||
setupSearchPluginTableEvents(false);
|
||||
|
||||
const oldPlugins = Object.keys(searchPluginsTable.rows);
|
||||
// remove old rows from the table
|
||||
for (let i = 0; i < oldPlugins.length; ++i) {
|
||||
let found = false;
|
||||
for (let j = 0; j < window.qBittorrent.Search.searchPlugins.length; ++j) {
|
||||
if (window.qBittorrent.Search.searchPlugins[j].name === oldPlugins[i]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
searchPluginsTable.removeRow(oldPlugins[i]);
|
||||
}
|
||||
if (!found)
|
||||
searchPluginsTable.removeRow(oldPlugins[i]);
|
||||
}
|
||||
|
||||
for (let i = 0; i < searchPlugins.length; ++i) {
|
||||
searchPlugins[i].rowId = searchPlugins[i].name;
|
||||
searchPluginsTable.updateRowData(searchPlugins[i]);
|
||||
}
|
||||
for (let i = 0; i < window.qBittorrent.Search.searchPlugins.length; ++i) {
|
||||
window.qBittorrent.Search.searchPlugins[i].rowId = window.qBittorrent.Search.searchPlugins[i].name;
|
||||
searchPluginsTable.updateRowData(window.qBittorrent.Search.searchPlugins[i]);
|
||||
}
|
||||
|
||||
searchPluginsTable.updateTable();
|
||||
searchPluginsTable.altRow();
|
||||
searchPluginsTable.updateTable();
|
||||
searchPluginsTable.altRow();
|
||||
|
||||
// add event listeners
|
||||
setupSearchPluginTableEvents(true);
|
||||
};
|
||||
// add event listeners
|
||||
setupSearchPluginTableEvents(true);
|
||||
};
|
||||
|
||||
initSearchPlugins();
|
||||
initSearchPlugins();
|
||||
|
||||
return exports();
|
||||
})();
|
||||
</script>
|
||||
|
|
|
@ -18,81 +18,95 @@
|
|||
<script>
|
||||
'use strict';
|
||||
|
||||
//create a context menu
|
||||
const torrentsTableContextMenu = new TorrentsTableContextMenu({
|
||||
targets: '.torrentsTableContextMenuTarget',
|
||||
menu: 'torrentsTableMenu',
|
||||
actions: {
|
||||
start: function(element, ref) {
|
||||
startFN();
|
||||
},
|
||||
pause: function(element, ref) {
|
||||
pauseFN();
|
||||
},
|
||||
forceStart: function(element, ref) {
|
||||
setForceStartFN();
|
||||
},
|
||||
if (window.qBittorrent === undefined) {
|
||||
window.qBittorrent = {};
|
||||
}
|
||||
|
||||
delete: function(element, ref) {
|
||||
deleteFN();
|
||||
},
|
||||
window.qBittorrent.TransferList = (function() {
|
||||
const exports = function() {
|
||||
return {
|
||||
contextMenu: contextMenu,
|
||||
};
|
||||
};
|
||||
|
||||
setLocation: function(element, ref) {
|
||||
setLocationFN();
|
||||
},
|
||||
//create a context menu
|
||||
const contextMenu = new window.qBittorrent.ContextMenu.TorrentsTableContextMenu({
|
||||
targets: '.torrentsTableContextMenuTarget',
|
||||
menu: 'torrentsTableMenu',
|
||||
actions: {
|
||||
start: function(element, ref) {
|
||||
startFN();
|
||||
},
|
||||
pause: function(element, ref) {
|
||||
pauseFN();
|
||||
},
|
||||
forceStart: function(element, ref) {
|
||||
setForceStartFN();
|
||||
},
|
||||
|
||||
rename: function(element, ref) {
|
||||
renameFN();
|
||||
},
|
||||
queueTop: function(element, ref) {
|
||||
setQueuePositionFN('topPrio');
|
||||
},
|
||||
queueUp: function(element, ref) {
|
||||
setQueuePositionFN('increasePrio');
|
||||
},
|
||||
queueDown: function(element, ref) {
|
||||
setQueuePositionFN('decreasePrio');
|
||||
},
|
||||
queueBottom: function(element, ref) {
|
||||
setQueuePositionFN('bottomPrio');
|
||||
},
|
||||
delete: function(element, ref) {
|
||||
deleteFN();
|
||||
},
|
||||
|
||||
downloadLimit: function(element, ref) {
|
||||
downloadLimitFN();
|
||||
},
|
||||
uploadLimit: function(element, ref) {
|
||||
uploadLimitFN();
|
||||
},
|
||||
shareRatio: function(element, ref) {
|
||||
shareRatioFN();
|
||||
},
|
||||
setLocation: function(element, ref) {
|
||||
setLocationFN();
|
||||
},
|
||||
|
||||
sequentialDownload: function(element, ref) {
|
||||
toggleSequentialDownloadFN();
|
||||
},
|
||||
firstLastPiecePrio: function(element, ref) {
|
||||
toggleFirstLastPiecePrioFN();
|
||||
},
|
||||
rename: function(element, ref) {
|
||||
renameFN();
|
||||
},
|
||||
queueTop: function(element, ref) {
|
||||
setQueuePositionFN('topPrio');
|
||||
},
|
||||
queueUp: function(element, ref) {
|
||||
setQueuePositionFN('increasePrio');
|
||||
},
|
||||
queueDown: function(element, ref) {
|
||||
setQueuePositionFN('decreasePrio');
|
||||
},
|
||||
queueBottom: function(element, ref) {
|
||||
setQueuePositionFN('bottomPrio');
|
||||
},
|
||||
|
||||
autoTorrentManagement: function(element, ref) {
|
||||
autoTorrentManagementFN();
|
||||
},
|
||||
forceRecheck: function(element, ref) {
|
||||
recheckFN();
|
||||
},
|
||||
forceReannounce: function(element, ref) {
|
||||
reannounceFN();
|
||||
},
|
||||
downloadLimit: function(element, ref) {
|
||||
downloadLimitFN();
|
||||
},
|
||||
uploadLimit: function(element, ref) {
|
||||
uploadLimitFN();
|
||||
},
|
||||
shareRatio: function(element, ref) {
|
||||
shareRatioFN();
|
||||
},
|
||||
|
||||
superSeeding: function(element, ref) {
|
||||
setSuperSeedingFN(!ref.getItemChecked('superSeeding'));
|
||||
sequentialDownload: function(element, ref) {
|
||||
toggleSequentialDownloadFN();
|
||||
},
|
||||
firstLastPiecePrio: function(element, ref) {
|
||||
toggleFirstLastPiecePrioFN();
|
||||
},
|
||||
|
||||
autoTorrentManagement: function(element, ref) {
|
||||
autoTorrentManagementFN();
|
||||
},
|
||||
forceRecheck: function(element, ref) {
|
||||
recheckFN();
|
||||
},
|
||||
forceReannounce: function(element, ref) {
|
||||
reannounceFN();
|
||||
},
|
||||
|
||||
superSeeding: function(element, ref) {
|
||||
setSuperSeedingFN(!ref.getItemChecked('superSeeding'));
|
||||
}
|
||||
},
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
}
|
||||
},
|
||||
offsets: {
|
||||
x: -15,
|
||||
y: 2
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
torrentsTable.setup('torrentsTableDiv', 'torrentsTableFixedHeaderDiv', torrentsTableContextMenu);
|
||||
torrentsTable.setup('torrentsTableDiv', 'torrentsTableFixedHeaderDiv', contextMenu);
|
||||
|
||||
return exports();
|
||||
})();
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue