diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js
index b2a8c7f3e..212414768 100644
--- a/src/webui/www/private/scripts/client.js
+++ b/src/webui/www/private/scripts/client.js
@@ -46,18 +46,18 @@ let clipboardEvent;
const CATEGORIES_ALL = 1;
const CATEGORIES_UNCATEGORIZED = 2;
-let category_list = {};
+const category_list = new Map();
-let selected_category = CATEGORIES_ALL;
+let selected_category = Number(LocalPreferences.get('selected_category', CATEGORIES_ALL));
let setCategoryFilter = function() {};
/* Tags filter */
const TAGS_ALL = 1;
const TAGS_UNTAGGED = 2;
-let tagList = {};
+const tagList = new Map();
-let selectedTag = TAGS_ALL;
+let selectedTag = Number(LocalPreferences.get('selected_tag', TAGS_ALL));
let setTagFilter = function() {};
/* Trackers filter */
@@ -74,16 +74,6 @@ let selected_filter = LocalPreferences.get('selected_filter', 'all');
let setFilter = function() {};
let toggleFilterDisplay = function() {};
-const loadSelectedCategory = function() {
- selected_category = LocalPreferences.get('selected_category', CATEGORIES_ALL);
-};
-loadSelectedCategory();
-
-const loadSelectedTag = function() {
- selectedTag = LocalPreferences.get('selected_tag', TAGS_ALL);
-};
-loadSelectedTag();
-
const loadSelectedTracker = function() {
selectedTracker = LocalPreferences.get('selected_tracker', TRACKERS_ALL);
};
@@ -244,7 +234,7 @@ window.addEvent('load', function() {
};
setTagFilter = function(hash) {
- selectedTag = hash.toString();
+ selectedTag = hash;
LocalPreferences.set('selected_tag', selectedTag);
highlightSelectedTag();
if (torrentsTable.tableBody !== undefined)
@@ -358,14 +348,11 @@ window.addEvent('load', function() {
return false;
let removed = false;
- for (const key in category_list) {
- if (!Object.hasOwn(category_list, key))
- continue;
-
- const category = category_list[key];
+ category_list.forEach((category) => {
const deleteResult = category.torrents.delete(hash);
removed ||= deleteResult;
- }
+ });
+
return removed;
};
@@ -379,16 +366,19 @@ window.addEvent('load', function() {
removeTorrentFromCategoryList(hash);
return true;
}
+
const categoryHash = genHash(category);
- if (!category_list[categoryHash]) { // This should not happen
- category_list[categoryHash] = {
+ if (!category_list.has(categoryHash)) { // This should not happen
+ category_list.set(categoryHash, {
name: category,
- torrents: []
- };
+ torrents: new Set()
+ });
}
- if (!category_list[categoryHash].torrents.has(hash)) {
+
+ const torrents = category_list.get(categoryHash).torrents;
+ if (!torrents.has(hash)) {
removeTorrentFromCategoryList(hash);
- category_list[categoryHash].torrents.add(hash);
+ torrents.add(hash);
return true;
}
return false;
@@ -399,14 +389,11 @@ window.addEvent('load', function() {
return false;
let removed = false;
- for (const key in tagList) {
- if (!Object.hasOwn(tagList, key))
- continue;
-
- const tag = tagList[key];
+ tagList.forEach((tag) => {
const deleteResult = tag.torrents.delete(hash);
removed ||= deleteResult;
- }
+ });
+
return removed;
};
@@ -424,14 +411,16 @@ window.addEvent('load', function() {
let added = false;
for (let i = 0; i < tags.length; ++i) {
const tagHash = genHash(tags[i].trim());
- if (!tagList[tagHash]) { // This should not happen
- tagList[tagHash] = {
+ if (!tagList.has(tagHash)) { // This should not happen
+ tagList.set(tagHash, {
name: tags,
torrents: new Set()
- };
+ });
}
- if (!tagList[tagHash].torrents.has(hash)) {
- tagList[tagHash].torrents.add(hash);
+
+ const torrents = tagList.get(tagHash).torrents;
+ if (!torrents.has(hash)) {
+ torrents.add(hash);
added = true;
}
}
@@ -474,7 +463,7 @@ window.addEvent('load', function() {
margin_left = (category_path.length - 1) * 20;
}
- const html = ''
+ const html = ``
+ '
'
+ window.qBittorrent.Misc.escapeHtml(display_name) + ' (' + count + ')' + '';
const el = new Element('li', {
@@ -487,20 +476,26 @@ window.addEvent('load', function() {
const all = torrentsTable.getRowIds().length;
let uncategorized = 0;
- Object.each(torrentsTable.rows, function(row) {
+ for (const key in torrentsTable.rows) {
+ if (!Object.hasOwn(torrentsTable.rows, key))
+ continue;
+
+ const row = torrentsTable.rows[key];
if (row['full_data'].category.length === 0)
uncategorized += 1;
- });
+ }
categoryList.appendChild(create_link(CATEGORIES_ALL, 'QBT_TR(All)QBT_TR[CONTEXT=CategoryFilterModel]', all));
categoryList.appendChild(create_link(CATEGORIES_UNCATEGORIZED, 'QBT_TR(Uncategorized)QBT_TR[CONTEXT=CategoryFilterModel]', uncategorized));
const sortedCategories = [];
- Object.each(category_list, function(category) {
- sortedCategories.push(category.name);
- });
- sortedCategories.sort((leftCategory, rightCategory) => {
- const leftSegments = leftCategory.split('/');
- const rightSegments = rightCategory.split('/');
+ category_list.forEach((category, hash) => sortedCategories.push({
+ categoryName: category.name,
+ categoryHash: hash,
+ categoryCount: category.torrents.size
+ }));
+ sortedCategories.sort((left, right) => {
+ const leftSegments = left.categoryName.split('/');
+ const rightSegments = right.categoryName.split('/');
for (let i = 0, iMax = Math.min(leftSegments.length, rightSegments.length); i < iMax; ++i) {
const compareResult = window.qBittorrent.Misc.naturalSortCollator.compare(
@@ -513,15 +508,13 @@ window.addEvent('load', function() {
});
for (let i = 0; i < sortedCategories.length; ++i) {
- const categoryName = sortedCategories[i];
- const categoryHash = genHash(categoryName);
- let categoryCount = category_list[categoryHash].torrents.size;
+ const { categoryName, categoryHash } = sortedCategories[i];
+ let { categoryCount } = sortedCategories[i];
if (useSubcategories) {
for (let j = (i + 1);
- (j < sortedCategories.length) && sortedCategories[j].startsWith(categoryName + "/"); ++j) {
- const hash = genHash(sortedCategories[j]);
- categoryCount += category_list[hash].torrents.size;
+ ((j < sortedCategories.length) && sortedCategories[j].categoryName.startsWith(categoryName + "/")); ++j) {
+ categoryCount += sortedCategories[j].categoryCount;
}
}
@@ -537,7 +530,7 @@ window.addEvent('load', function() {
return;
const children = categoryList.childNodes;
for (let i = 0; i < children.length; ++i) {
- if (children[i].id == selected_category)
+ if (Number(children[i].id) === selected_category)
children[i].className = "selectedFilter";
else
children[i].className = "";
@@ -552,7 +545,7 @@ window.addEvent('load', function() {
tagFilterList.getChildren().each(c => c.destroy());
const createLink = function(hash, text, count) {
- const html = ''
+ const html = ``
+ '
'
+ window.qBittorrent.Misc.escapeHtml(text) + ' (' + count + ')' + '';
const el = new Element('li', {
@@ -573,16 +566,15 @@ window.addEvent('load', function() {
tagFilterList.appendChild(createLink(TAGS_UNTAGGED, 'QBT_TR(Untagged)QBT_TR[CONTEXT=TagFilterModel]', untagged));
const sortedTags = [];
- for (const key in tagList)
- sortedTags.push(tagList[key].name);
- sortedTags.sort(window.qBittorrent.Misc.naturalSortCollator.compare);
+ tagList.forEach((tag, hash) => sortedTags.push({
+ tagName: tag.name,
+ tagHash: hash,
+ tagSize: tag.torrents.size
+ }));
+ sortedTags.sort((left, right) => window.qBittorrent.Misc.naturalSortCollator.compare(left.tagName, right.tagName));
- for (let i = 0; i < sortedTags.length; ++i) {
- const tagName = sortedTags[i];
- const tagHash = genHash(tagName);
- const tagCount = tagList[tagHash].torrents.size;
- tagFilterList.appendChild(createLink(tagHash, tagName, tagCount));
- }
+ for (const { tagName, tagHash, tagSize } of sortedTags)
+ tagFilterList.appendChild(createLink(tagHash, tagName, tagSize));
highlightSelectedTag();
};
@@ -594,7 +586,7 @@ window.addEvent('load', function() {
const children = tagFilterList.childNodes;
for (let i = 0; i < children.length; ++i)
- children[i].className = (children[i].id === selectedTag) ? "selectedFilter" : "";
+ children[i].className = (Number(children[i].id) === selectedTag) ? "selectedFilter" : "";
};
const updateTrackerList = function() {
@@ -626,14 +618,15 @@ window.addEvent('load', function() {
trackerFilterList.appendChild(createLink(TRACKERS_TRACKERLESS, 'QBT_TR(Trackerless (%1))QBT_TR[CONTEXT=TrackerFiltersList]', trackerlessTorrentsCount));
// Sort trackers by hostname
- const sortedList = [...trackerList.entries()].sort((left, right) => {
- const leftHost = getHost(left[1].url);
- const rightHost = getHost(right[1].url);
- return window.qBittorrent.Misc.naturalSortCollator.compare(leftHost, rightHost);
- });
- for (const [hash, tracker] of sortedList) {
- trackerFilterList.appendChild(createLink(hash, (getHost(tracker.url) + ' (%1)'), tracker.torrents.length));
- }
+ const sortedList = [];
+ trackerList.forEach((tracker, hash) => sortedList.push({
+ trackerHost: getHost(tracker.url),
+ trackerHash: hash,
+ trackerCount: tracker.torrents.length
+ }));
+ sortedList.sort((left, right) => window.qBittorrent.Misc.naturalSortCollator.compare(left.trackerHost, right.trackerHost));
+ for (const { trackerHost, trackerHash, trackerCount } of sortedList)
+ trackerFilterList.appendChild(createLink(trackerHash, (trackerHost + ' (%1)'), trackerCount));
highlightSelectedTracker();
};
@@ -675,26 +668,30 @@ window.addEvent('load', function() {
if (full_update) {
torrentsTableSelectedRows = torrentsTable.selectedRowsIds();
torrentsTable.clear();
- category_list = {};
- tagList = {};
+ category_list.clear();
+ tagList.clear();
}
if (response['rid']) {
syncMainDataLastResponseId = response['rid'];
}
if (response['categories']) {
for (const key in response['categories']) {
- const category = response['categories'][key];
+ if (!Object.hasOwn(response['categories'], key))
+ continue;
+
+ const responseCategory = response['categories'][key];
const categoryHash = genHash(key);
- if (category_list[categoryHash] !== undefined) {
+ const category = category_list.get(categoryHash);
+ if (category !== undefined) {
// only the save path can change for existing categories
- category_list[categoryHash].savePath = category.savePath;
+ category.savePath = responseCategory.savePath;
}
else {
- category_list[categoryHash] = {
- name: category.name,
- savePath: category.savePath,
+ category_list.set(categoryHash, {
+ name: responseCategory.name,
+ savePath: responseCategory.savePath,
torrents: new Set()
- };
+ });
}
}
update_categories = true;
@@ -702,18 +699,18 @@ window.addEvent('load', function() {
if (response['categories_removed']) {
response['categories_removed'].each(function(category) {
const categoryHash = genHash(category);
- delete category_list[categoryHash];
+ category_list.delete(categoryHash);
});
update_categories = true;
}
if (response['tags']) {
for (const tag of response['tags']) {
const tagHash = genHash(tag);
- if (!tagList[tagHash]) {
- tagList[tagHash] = {
+ if (!tagList.has(tagHash)) {
+ tagList.set(tagHash, {
name: tag,
torrents: new Set()
- };
+ });
}
}
updateTags = true;
@@ -721,7 +718,7 @@ window.addEvent('load', function() {
if (response['tags_removed']) {
for (let i = 0; i < response['tags_removed'].length; ++i) {
const tagHash = genHash(response['tags_removed'][i]);
- delete tagList[tagHash];
+ tagList.delete(tagHash);
}
updateTags = true;
}
diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js
index 70e7fea06..c03f09e4e 100644
--- a/src/webui/www/private/scripts/contextmenu.js
+++ b/src/webui/www/private/scripts/contextmenu.js
@@ -311,10 +311,10 @@ window.qBittorrent.ContextMenu = (function() {
let all_are_super_seeding = true;
let all_are_auto_tmm = true;
let there_are_auto_tmm = false;
- const tagsSelectionState = Object.clone(tagList);
+ const tagCount = new Map();
- const h = torrentsTable.selectedRowsIds();
- h.each(function(item, index) {
+ const selectedRows = torrentsTable.selectedRowsIds();
+ selectedRows.forEach((item, index) => {
const data = torrentsTable.rows.get(item).full_data;
if (data['seq_dl'] !== true)
@@ -348,23 +348,15 @@ window.qBittorrent.ContextMenu = (function() {
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;
- else
- tag.checked = tag.checked && tagExists;
+ for (const tag of torrentTags) {
+ const count = tagCount.get(tag);
+ tagCount.set(tag, ((count !== undefined) ? (count + 1) : 1));
}
});
- let show_seq_dl = true;
-
// hide renameFiles when more than 1 torrent is selected
- if (h.length == 1) {
- const data = torrentsTable.rows.get(h[0]).full_data;
+ if (selectedRows.length == 1) {
+ const data = torrentsTable.rows.get(selectedRows[0]).full_data;
let metadata_downloaded = !(data['state'] == 'metaDL' || data['state'] == 'forcedMetaDL' || data['total_size'] == -1);
// hide renameFiles when metadata hasn't been downloaded yet
@@ -372,16 +364,9 @@ window.qBittorrent.ContextMenu = (function() {
? this.showItem('renameFiles')
: this.hideItem('renameFiles');
}
- else
+ else {
this.hideItem('renameFiles');
-
- 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');
@@ -392,6 +377,9 @@ window.qBittorrent.ContextMenu = (function() {
this.setItemChecked('superSeeding', all_are_super_seeding);
}
else {
+ const show_seq_dl = (all_are_seq_dl || !there_are_seq_dl);
+ const show_f_l_piece_prio = (all_are_f_l_piece_prio || !there_are_f_l_piece_prio);
+
if (!show_seq_dl && show_f_l_piece_prio)
this.menu.getElement('a[href$=firstLastPiecePrio]').parentNode.addClass('separator');
else
@@ -434,42 +422,45 @@ window.qBittorrent.ContextMenu = (function() {
}
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;
- }
+ tagList.forEach((tag, tagHash) => {
+ const checkbox = contextTagList.getElement(`a[href="#Tag/${tagHash}"] input[type="checkbox"]`);
+ const count = tagCount.get(tag.name);
+ const hasCount = (count !== undefined);
+ const isLesser = (count < selectedRows.length);
+ checkbox.indeterminate = (hasCount ? isLesser : false);
+ checkbox.checked = (hasCount ? !isLesser : false);
+ });
},
- updateCategoriesSubMenu: function(category_list) {
- const categoryList = $('contextCategoryList');
- categoryList.getChildren().each(c => c.destroy());
- categoryList.appendChild(new Element('li', {
+ updateCategoriesSubMenu: function(categoryList) {
+ const contextCategoryList = $('contextCategoryList');
+ contextCategoryList.getChildren().each(c => c.destroy());
+ contextCategoryList.appendChild(new Element('li', {
html: '
QBT_TR(New...)QBT_TR[CONTEXT=TransferListWidget]'
}));
- categoryList.appendChild(new Element('li', {
+ contextCategoryList.appendChild(new Element('li', {
html: '
QBT_TR(Reset)QBT_TR[CONTEXT=TransferListWidget]'
}));
const sortedCategories = [];
- Object.each(category_list, function(category) {
- sortedCategories.push(category.name);
- });
- sortedCategories.sort(window.qBittorrent.Misc.naturalSortCollator.compare);
+ categoryList.forEach((category, hash) => sortedCategories.push({
+ categoryName: category.name,
+ categoryHash: hash
+ }));
+ sortedCategories.sort((left, right) => window.qBittorrent.Misc.naturalSortCollator.compare(
+ left.categoryName, right.categoryName));
let first = true;
- Object.each(sortedCategories, function(categoryName) {
- const categoryHash = genHash(categoryName);
+ for (const { categoryName, categoryHash } of sortedCategories) {
const el = new Element('li', {
- html: '
' + window.qBittorrent.Misc.escapeHtml(categoryName) + ''
+ html: `
${window.qBittorrent.Misc.escapeHtml(categoryName)}`
});
if (first) {
el.addClass('separator');
first = false;
}
- categoryList.appendChild(el);
- });
+ contextCategoryList.appendChild(el);
+ }
},
updateTagsSubMenu: function(tagList) {
@@ -491,15 +482,16 @@ window.qBittorrent.ContextMenu = (function() {
}));
const sortedTags = [];
- for (const key in tagList)
- sortedTags.push(tagList[key].name);
- sortedTags.sort(window.qBittorrent.Misc.naturalSortCollator.compare);
+ tagList.forEach((tag, hash) => sortedTags.push({
+ tagName: tag.name,
+ tagHash: hash
+ }));
+ sortedTags.sort((left, right) => window.qBittorrent.Misc.naturalSortCollator.compare(left.tagName, right.tagName));
for (let i = 0; i < sortedTags.length; ++i) {
- const tagName = sortedTags[i];
- const tagHash = genHash(tagName);
+ const { tagName, tagHash } = sortedTags[i];
const el = new Element('li', {
- html: ''
+ html: ``
+ ' ' + window.qBittorrent.Misc.escapeHtml(tagName)
+ ''
});
@@ -513,8 +505,8 @@ window.qBittorrent.ContextMenu = (function() {
const CategoriesFilterContextMenu = new Class({
Extends: ContextMenu,
updateMenuItems: function() {
- const id = this.options.element.id;
- if ((id != CATEGORIES_ALL) && (id != CATEGORIES_UNCATEGORIZED)) {
+ const id = Number(this.options.element.id);
+ if ((id !== CATEGORIES_ALL) && (id !== CATEGORIES_UNCATEGORIZED)) {
this.showItem('editCategory');
this.showItem('deleteCategory');
if (useSubcategories) {
@@ -535,8 +527,8 @@ window.qBittorrent.ContextMenu = (function() {
const TagsFilterContextMenu = new Class({
Extends: ContextMenu,
updateMenuItems: function() {
- const id = this.options.element.id;
- if ((id !== TAGS_ALL.toString()) && (id !== TAGS_UNTAGGED.toString()))
+ const id = Number(this.options.element.id);
+ if ((id !== TAGS_ALL) && (id !== TAGS_UNTAGGED))
this.showItem('deleteTag');
else
this.hideItem('deleteTag');
diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js
index 485b867b0..b3f03a212 100644
--- a/src/webui/www/private/scripts/dynamicTable.js
+++ b/src/webui/www/private/scripts/dynamicTable.js
@@ -1386,50 +1386,41 @@ window.qBittorrent.DynamicTable = (function() {
break;
}
- const categoryHashInt = parseInt(categoryHash);
- if (!isNaN(categoryHashInt)) {
- switch (categoryHashInt) {
- case CATEGORIES_ALL:
- break; // do nothing
- case CATEGORIES_UNCATEGORIZED:
- if (row['full_data'].category.length !== 0)
+ switch (categoryHash) {
+ case CATEGORIES_ALL:
+ break; // do nothing
+ case CATEGORIES_UNCATEGORIZED:
+ if (row['full_data'].category.length !== 0)
+ return false;
+ break; // do nothing
+ default:
+ if (!useSubcategories) {
+ if (categoryHash !== genHash(row['full_data'].category))
return false;
- break; // do nothing
- default:
- if (!useSubcategories) {
- if (categoryHashInt !== genHash(row['full_data'].category))
- return false;
- }
- else {
- const selectedCategoryName = category_list[categoryHash].name + "/";
- const torrentCategoryName = row['full_data'].category + "/";
- if (!torrentCategoryName.startsWith(selectedCategoryName))
- return false;
- }
- }
+ }
+ else {
+ const selectedCategoryName = category_list.get(categoryHash).name + "/";
+ const torrentCategoryName = row['full_data'].category + "/";
+ if (!torrentCategoryName.startsWith(selectedCategoryName))
+ return false;
+ }
+ break;
}
- const tagHashInt = parseInt(tagHash);
- const isNumber = !isNaN(tagHashInt);
- if (isNumber) {
- switch (tagHashInt) {
- case TAGS_ALL:
- break; // do nothing
+ switch (tagHash) {
+ case TAGS_ALL:
+ break; // do nothing
- case TAGS_UNTAGGED:
- if (row['full_data'].tags.length !== 0)
- return false;
- break; // do nothing
+ case TAGS_UNTAGGED:
+ if (row['full_data'].tags.length !== 0)
+ return false;
+ break; // do nothing
- default: {
- let rowTags = row['full_data'].tags.split(', ');
- rowTags = rowTags.map(function(tag) {
- return genHash(tag);
- });
- if (!rowTags.contains(tagHashInt))
- return false;
- break;
- }
+ default: {
+ const tagHashes = row['full_data'].tags.split(', ').map(tag => genHash(tag));
+ if (!tagHashes.contains(tagHash))
+ return false;
+ break;
}
}
@@ -1460,9 +1451,10 @@ window.qBittorrent.DynamicTable = (function() {
let cnt = 0;
const rows = this.rows.getValues();
- for (let i = 0; i < rows.length; ++i)
+ for (let i = 0; i < rows.length; ++i) {
if (this.applyFilter(rows[i], filterName, categoryHash, tagHash, trackerHash, null))
++cnt;
+ }
return cnt;
},
@@ -1470,9 +1462,10 @@ window.qBittorrent.DynamicTable = (function() {
const rowsHashes = [];
const rows = this.rows.getValues();
- for (let i = 0; i < rows.length; ++i)
+ for (let i = 0; i < rows.length; ++i) {
if (this.applyFilter(rows[i], filterName, categoryHash, tagHash, trackerHash, null))
rowsHashes.push(rows[i]['rowId']);
+ }
return rowsHashes;
},
diff --git a/src/webui/www/private/scripts/mocha-init.js b/src/webui/www/private/scripts/mocha-init.js
index 3801bc78a..be3577b16 100644
--- a/src/webui/www/private/scripts/mocha-init.js
+++ b/src/webui/www/private/scripts/mocha-init.js
@@ -573,20 +573,21 @@ const initializeWindows = function() {
};
torrentSetCategoryFN = function(categoryHash) {
- let categoryName = '';
- if (categoryHash != 0)
- categoryName = category_list[categoryHash].name;
const hashes = torrentsTable.selectedRowsIds();
- if (hashes.length) {
- new Request({
- url: 'api/v2/torrents/setCategory',
- method: 'post',
- data: {
- hashes: hashes.join("|"),
- category: categoryName
- }
- }).send();
- }
+ if (hashes.length <= 0)
+ return;
+
+ const categoryName = category_list.has(categoryHash)
+ ? category_list.get(categoryHash).name
+ : '';
+ new Request({
+ url: 'api/v2/torrents/setCategory',
+ method: 'post',
+ data: {
+ hashes: hashes.join("|"),
+ category: categoryName
+ }
+ }).send();
};
createCategoryFN = function() {
@@ -609,7 +610,7 @@ const initializeWindows = function() {
createSubcategoryFN = function(categoryHash) {
const action = "createSubcategory";
- const categoryName = category_list[categoryHash].name + "/";
+ const categoryName = category_list.get(categoryHash).name + "/";
new MochaUI.Window({
id: 'newSubcategoryPage',
title: "QBT_TR(New Category)QBT_TR[CONTEXT=CategoryFilterWidget]",
@@ -628,13 +629,12 @@ const initializeWindows = function() {
editCategoryFN = function(categoryHash) {
const action = "edit";
- const categoryName = category_list[categoryHash].name;
- const savePath = category_list[categoryHash].savePath;
+ const category = category_list.get(categoryHash);
new MochaUI.Window({
id: 'editCategoryPage',
title: "QBT_TR(Edit Category)QBT_TR[CONTEXT=TransferListWidget]",
loadMethod: 'iframe',
- contentURL: new URI('newcategory.html').setData("action", action).setData("categoryName", categoryName).setData("savePath", savePath).toString(),
+ contentURL: new URI('newcategory.html').setData("action", action).setData("categoryName", category.name).setData("savePath", category.savePath).toString(),
scrollbars: false,
resizable: true,
maximizable: false,
@@ -647,7 +647,7 @@ const initializeWindows = function() {
};
removeCategoryFN = function(categoryHash) {
- const categoryName = category_list[categoryHash].name;
+ const categoryName = category_list.get(categoryHash).name;
new Request({
url: 'api/v2/torrents/removeCategories',
method: 'post',
@@ -660,10 +660,11 @@ const initializeWindows = function() {
deleteUnusedCategoriesFN = function() {
const categories = [];
- for (const hash in category_list) {
+ category_list.forEach((category, hash) => {
if (torrentsTable.getFilteredTorrentsNumber('all', hash, TAGS_ALL, TRACKERS_ALL) === 0)
- categories.push(category_list[hash].name);
- }
+ categories.push(category.name);
+ });
+
new Request({
url: 'api/v2/torrents/removeCategories',
method: 'post',
@@ -742,18 +743,19 @@ const initializeWindows = function() {
};
torrentSetTagsFN = function(tagHash, isSet) {
- const tagName = ((tagHash === '0') ? '' : tagList[tagHash].name);
const hashes = torrentsTable.selectedRowsIds();
- if (hashes.length) {
- new Request({
- url: (isSet ? 'api/v2/torrents/addTags' : 'api/v2/torrents/removeTags'),
- method: 'post',
- data: {
- hashes: hashes.join("|"),
- tags: tagName,
- }
- }).send();
- }
+ if (hashes.length <= 0)
+ return;
+
+ const tagName = tagList.has(tagHash) ? tagList.get(tagHash).name : '';
+ new Request({
+ url: (isSet ? 'api/v2/torrents/addTags' : 'api/v2/torrents/removeTags'),
+ method: 'post',
+ data: {
+ hashes: hashes.join("|"),
+ tags: tagName,
+ }
+ }).send();
};
torrentRemoveAllTagsFN = function() {
@@ -788,7 +790,7 @@ const initializeWindows = function() {
};
removeTagFN = function(tagHash) {
- const tagName = tagList[tagHash].name;
+ const tagName = tagList.get(tagHash).name;
new Request({
url: 'api/v2/torrents/deleteTags',
method: 'post',
@@ -801,10 +803,10 @@ const initializeWindows = function() {
deleteUnusedTagsFN = function() {
const tags = [];
- for (const hash in tagList) {
+ tagList.forEach((tag, hash) => {
if (torrentsTable.getFilteredTorrentsNumber('all', CATEGORIES_ALL, hash, TRACKERS_ALL) === 0)
- tags.push(tagList[hash].name);
- }
+ tags.push(tag.name);
+ });
new Request({
url: 'api/v2/torrents/deleteTags',
method: 'post',
diff --git a/src/webui/www/private/views/filters.html b/src/webui/www/private/views/filters.html
index d509713be..580815d8e 100644
--- a/src/webui/www/private/views/filters.html
+++ b/src/webui/www/private/views/filters.html
@@ -65,25 +65,25 @@
createCategoryFN();
},
createSubcategory: function(element, ref) {
- createSubcategoryFN(element.id);
+ createSubcategoryFN(Number(element.id));
},
editCategory: function(element, ref) {
- editCategoryFN(element.id);
+ editCategoryFN(Number(element.id));
},
deleteCategory: function(element, ref) {
- removeCategoryFN(element.id);
+ removeCategoryFN(Number(element.id));
},
deleteUnusedCategories: function(element, ref) {
deleteUnusedCategoriesFN();
},
startTorrentsByCategory: function(element, ref) {
- startTorrentsByCategoryFN(element.id);
+ startTorrentsByCategoryFN(Number(element.id));
},
pauseTorrentsByCategory: function(element, ref) {
- pauseTorrentsByCategoryFN(element.id);
+ pauseTorrentsByCategoryFN(Number(element.id));
},
deleteTorrentsByCategory: function(element, ref) {
- deleteTorrentsByCategoryFN(element.id);
+ deleteTorrentsByCategoryFN(Number(element.id));
}
},
offsets: {
@@ -103,19 +103,19 @@
createTagFN();
},
deleteTag: function(element, ref) {
- removeTagFN(element.id);
+ removeTagFN(Number(element.id));
},
deleteUnusedTags: function(element, ref) {
deleteUnusedTagsFN();
},
startTorrentsByTag: function(element, ref) {
- startTorrentsByTagFN(element.id);
+ startTorrentsByTagFN(Number(element.id));
},
pauseTorrentsByTag: function(element, ref) {
- pauseTorrentsByTagFN(element.id);
+ pauseTorrentsByTagFN(Number(element.id));
},
deleteTorrentsByTag: function(element, ref) {
- deleteTorrentsByTagFN(element.id);
+ deleteTorrentsByTagFN(Number(element.id));
}
},
offsets: {
diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html
index 387f4772c..0b2e00f0c 100644
--- a/src/webui/www/private/views/preferences.html
+++ b/src/webui/www/private/views/preferences.html
@@ -2043,7 +2043,11 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
updateExportDirFinEnabled();
// Automatically add torrents from
- for (const [folder, folderType] of Object.entries(pref.scan_dirs)) {
+ for (const folder in pref.scan_dirs) {
+ if (!Object.hasOwn(pref.scan_dirs, folder))
+ continue;
+
+ const folderType = pref.scan_dirs[folder];
let sel = "";
let other = "";
if (typeof folderType === "number") {