mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-08-19 21:03:30 -07:00
Merge pull request #11103 from Piccirello/webui-explicit-export
Move JavaScript code into explicit namespaces
This commit is contained in:
commit
209831d3b0
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…
Add table
Add a link
Reference in a new issue