mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-13 16:53:08 -07:00
WebUI: Improve subcategories
Now they should fully match GUI behavior, please let me know if I missed something. Still plenty of room to improve them further (e.g styling/CSS) but for now I wanted to keep the changes to the minimum. Also included small tweaks to category context menu actions. PR #21269.
This commit is contained in:
parent
f00c5c9fa3
commit
1b53fdf9ee
5 changed files with 179 additions and 72 deletions
|
@ -175,26 +175,19 @@ hr {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Filters {
|
||||||
|
overflow-x: hidden !important; /* override for default mocha inline style */
|
||||||
|
}
|
||||||
|
|
||||||
#Filters ul {
|
#Filters ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#Filters ul li {
|
|
||||||
margin-left: -16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#Filters ul img {
|
#Filters ul img {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
padding: 0 4px;
|
|
||||||
vertical-align: middle;
|
|
||||||
width: 16px;
|
width: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.selectedFilter {
|
|
||||||
background-color: var(--color-background-blue) !important;
|
|
||||||
color: var(--color-text-white) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#properties {
|
#properties {
|
||||||
background-color: var(--color-background-default);
|
background-color: var(--color-background-default);
|
||||||
}
|
}
|
||||||
|
@ -514,57 +507,101 @@ div.formRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
.filterTitle {
|
.filterTitle {
|
||||||
display: block;
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
gap: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding-left: 5px;
|
padding: 4px 0 4px 6px;
|
||||||
padding-top: 5px;
|
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filterTitle img {
|
.filterTitle img {
|
||||||
|
box-sizing: border-box;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
margin-bottom: -3px;
|
padding: 2px;
|
||||||
padding: 0 5px;
|
|
||||||
width: 16px;
|
width: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collapsedCategory > ul {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsedCategory .categoryToggle,
|
||||||
.filterTitle img.rotate {
|
.filterTitle img.rotate {
|
||||||
transform: rotate(270deg);
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.filterList * {
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.filterList {
|
ul.filterList {
|
||||||
margin: 0 0 0 16px;
|
margin: 0;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.filterList li:hover img,
|
ul.filterList span.link:hover :is(img, button),
|
||||||
ul.filterList .selectedFilter img {
|
ul.filterList .selectedFilter > .link :is(img, button) {
|
||||||
filter: var(--color-icon-hover);
|
filter: var(--color-icon-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.filterList span.link {
|
ul.filterList span.link {
|
||||||
align-items: center;
|
|
||||||
color: inherit;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 4px 6px;
|
padding: 4px 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.filterList span.link:hover {
|
||||||
|
background-color: var(--color-background-hover);
|
||||||
|
color: var(--color-text-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
span.link :last-child {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.filterList li {
|
span.link :is(img, button) {
|
||||||
color: var(--color-text-default);
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.filterList li:hover {
|
.selectedFilter > span.link {
|
||||||
background-color: var(--color-background-hover);
|
background-color: var(--color-background-blue);
|
||||||
color: var(--color-text-white);
|
color: var(--color-text-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.subcategories,
|
||||||
|
.subcategories ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subcategories .categoryToggle {
|
||||||
|
display: inline-block;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.categoryToggle {
|
||||||
|
background: url("../images/go-down.svg") center center / 10px no-repeat
|
||||||
|
transparent;
|
||||||
|
border: none;
|
||||||
|
display: none;
|
||||||
|
height: 16px;
|
||||||
|
margin-right: -2px;
|
||||||
|
padding: 2px;
|
||||||
|
transition: transform 0.3s;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
td.generalLabel {
|
td.generalLabel {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
|
|
@ -90,13 +90,17 @@
|
||||||
hashes: uriHashes,
|
hashes: uriHashes,
|
||||||
category: categoryName
|
category: categoryName
|
||||||
},
|
},
|
||||||
onComplete: function() {
|
onSuccess: function() {
|
||||||
|
window.parent.updateMainData();
|
||||||
window.parent.qBittorrent.Client.closeWindows();
|
window.parent.qBittorrent.Client.closeWindows();
|
||||||
|
},
|
||||||
|
onFailure: function() {
|
||||||
|
alert("QBT_TR(Unable to set category)QBT_TR[CONTEXT=Category]");
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
},
|
},
|
||||||
onFailure: function() {
|
onFailure: function() {
|
||||||
alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=HttpServer] " + window.qBittorrent.Misc.escapeHtml(categoryName));
|
alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=Category] " + window.qBittorrent.Misc.escapeHtml(categoryName));
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
break;
|
break;
|
||||||
|
@ -112,8 +116,12 @@
|
||||||
category: categoryName,
|
category: categoryName,
|
||||||
savePath: savePath
|
savePath: savePath
|
||||||
},
|
},
|
||||||
onComplete: function() {
|
onSuccess: function() {
|
||||||
|
window.parent.updateMainData();
|
||||||
window.parent.qBittorrent.Client.closeWindows();
|
window.parent.qBittorrent.Client.closeWindows();
|
||||||
|
},
|
||||||
|
onFailure: function() {
|
||||||
|
alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=Category]");
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
break;
|
break;
|
||||||
|
@ -125,8 +133,12 @@
|
||||||
category: uriCategoryName, // category name can't be changed
|
category: uriCategoryName, // category name can't be changed
|
||||||
savePath: savePath
|
savePath: savePath
|
||||||
},
|
},
|
||||||
onComplete: function() {
|
onSuccess: function() {
|
||||||
|
window.parent.updateMainData();
|
||||||
window.parent.qBittorrent.Client.closeWindows();
|
window.parent.qBittorrent.Client.closeWindows();
|
||||||
|
},
|
||||||
|
onFailure: function() {
|
||||||
|
alert("QBT_TR(Unable to edit category)QBT_TR[CONTEXT=Category]");
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -175,15 +175,14 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
MochaUI.Desktop.initialize();
|
MochaUI.Desktop.initialize();
|
||||||
|
|
||||||
const buildTransfersTab = function() {
|
const buildTransfersTab = function() {
|
||||||
const filt_w = Number(LocalPreferences.get("filters_width", 120));
|
|
||||||
new MochaUI.Column({
|
new MochaUI.Column({
|
||||||
id: "filtersColumn",
|
id: "filtersColumn",
|
||||||
placement: "left",
|
placement: "left",
|
||||||
onResize: window.qBittorrent.Misc.createDebounceHandler(500, (e) => {
|
onResize: window.qBittorrent.Misc.createDebounceHandler(500, (e) => {
|
||||||
saveColumnSizes();
|
saveColumnSizes();
|
||||||
}),
|
}),
|
||||||
width: filt_w,
|
width: Number(LocalPreferences.get("filters_width", 210)),
|
||||||
resizeLimit: [1, 300]
|
resizeLimit: [1, 1000]
|
||||||
});
|
});
|
||||||
new MochaUI.Column({
|
new MochaUI.Column({
|
||||||
id: "mainColumn",
|
id: "mainColumn",
|
||||||
|
@ -443,33 +442,47 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateCategoryList = function() {
|
const updateCategoryList = function() {
|
||||||
const categoryList = $("categoryFilterList");
|
const categoryList = document.getElementById("categoryFilterList");
|
||||||
if (!categoryList)
|
if (!categoryList)
|
||||||
return;
|
return;
|
||||||
categoryList.getChildren().each(c => c.destroy());
|
categoryList.getChildren().each(c => c.destroy());
|
||||||
|
|
||||||
const categoryItemTemplate = document.getElementById("categoryFilterItem");
|
const categoryItemTemplate = document.getElementById("categoryFilterItem");
|
||||||
|
|
||||||
const create_link = function(hash, text, count) {
|
const createCategoryLink = (hash, name, count) => {
|
||||||
let display_name = text;
|
|
||||||
let margin_left = 0;
|
|
||||||
if (useSubcategories) {
|
|
||||||
const category_path = text.split("/");
|
|
||||||
display_name = category_path[category_path.length - 1];
|
|
||||||
margin_left = (category_path.length - 1) * 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
const categoryFilterItem = categoryItemTemplate.content.cloneNode(true).firstElementChild;
|
const categoryFilterItem = categoryItemTemplate.content.cloneNode(true).firstElementChild;
|
||||||
categoryFilterItem.id = hash;
|
categoryFilterItem.id = hash;
|
||||||
categoryFilterItem.classList.toggle("selectedFilter", hash === selectedCategory);
|
categoryFilterItem.classList.toggle("selectedFilter", hash === selectedCategory);
|
||||||
|
|
||||||
const span = categoryFilterItem.firstElementChild;
|
const span = categoryFilterItem.firstElementChild;
|
||||||
span.style.marginLeft = `${margin_left}px`;
|
span.lastElementChild.textContent = `${name} (${count})`;
|
||||||
span.lastChild.textContent = `${display_name} (${count})`;
|
|
||||||
|
|
||||||
return categoryFilterItem;
|
return categoryFilterItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createCategoryTree = (category) => {
|
||||||
|
const stack = [{ parent: categoriesFragment, category: category }];
|
||||||
|
while (stack.length > 0) {
|
||||||
|
const { parent, category } = stack.pop();
|
||||||
|
const displayName = category.nameSegments.at(-1);
|
||||||
|
const listItem = createCategoryLink(category.categoryHash, displayName, category.categoryCount);
|
||||||
|
listItem.firstElementChild.style.paddingLeft = `${(category.nameSegments.length - 1) * 20 + 6}px`;
|
||||||
|
|
||||||
|
parent.appendChild(listItem);
|
||||||
|
|
||||||
|
if (category.children.length > 0) {
|
||||||
|
listItem.querySelector(".categoryToggle").style.visibility = "visible";
|
||||||
|
const unorderedList = document.createElement("ul");
|
||||||
|
listItem.appendChild(unorderedList);
|
||||||
|
for (const subcategory of category.children.reverse())
|
||||||
|
stack.push({ parent: unorderedList, category: subcategory });
|
||||||
|
}
|
||||||
|
const categoryLocalPref = `category_${category.categoryHash}_collapsed`;
|
||||||
|
const isCollapsed = !category.forceExpand && (LocalPreferences.get(categoryLocalPref, "false") === "true");
|
||||||
|
LocalPreferences.set(categoryLocalPref, listItem.classList.toggle("collapsedCategory", isCollapsed).toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const all = torrentsTable.getRowIds().length;
|
const all = torrentsTable.getRowIds().length;
|
||||||
let uncategorized = 0;
|
let uncategorized = 0;
|
||||||
for (const key in torrentsTable.rows) {
|
for (const key in torrentsTable.rows) {
|
||||||
|
@ -480,18 +493,22 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
if (row["full_data"].category.length === 0)
|
if (row["full_data"].category.length === 0)
|
||||||
uncategorized += 1;
|
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 = [];
|
const sortedCategories = [];
|
||||||
category_list.forEach((category, hash) => sortedCategories.push({
|
category_list.forEach((category, hash) => sortedCategories.push({
|
||||||
categoryName: category.name,
|
categoryName: category.name,
|
||||||
categoryHash: hash,
|
categoryHash: hash,
|
||||||
categoryCount: category.torrents.size
|
categoryCount: category.torrents.size,
|
||||||
|
nameSegments: category.name.split("/"),
|
||||||
|
...(useSubcategories && {
|
||||||
|
children: [],
|
||||||
|
parentID: null,
|
||||||
|
forceExpand: LocalPreferences.get(`category_${hash}_collapsed`) === null
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
sortedCategories.sort((left, right) => {
|
sortedCategories.sort((left, right) => {
|
||||||
const leftSegments = left.categoryName.split("/");
|
const leftSegments = left.nameSegments;
|
||||||
const rightSegments = right.categoryName.split("/");
|
const rightSegments = right.nameSegments;
|
||||||
|
|
||||||
for (let i = 0, iMax = Math.min(leftSegments.length, rightSegments.length); i < iMax; ++i) {
|
for (let i = 0, iMax = Math.min(leftSegments.length, rightSegments.length); i < iMax; ++i) {
|
||||||
const compareResult = window.qBittorrent.Misc.naturalSortCollator.compare(
|
const compareResult = window.qBittorrent.Misc.naturalSortCollator.compare(
|
||||||
|
@ -503,19 +520,39 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
return leftSegments.length - rightSegments.length;
|
return leftSegments.length - rightSegments.length;
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let i = 0; i < sortedCategories.length; ++i) {
|
const categoriesFragment = new DocumentFragment();
|
||||||
const { categoryName, categoryHash } = sortedCategories[i];
|
categoriesFragment.appendChild(createCategoryLink(CATEGORIES_ALL, "QBT_TR(All)QBT_TR[CONTEXT=CategoryFilterModel]", all));
|
||||||
let { categoryCount } = sortedCategories[i];
|
categoriesFragment.appendChild(createCategoryLink(CATEGORIES_UNCATEGORIZED, "QBT_TR(Uncategorized)QBT_TR[CONTEXT=CategoryFilterModel]", uncategorized));
|
||||||
|
|
||||||
if (useSubcategories) {
|
if (useSubcategories) {
|
||||||
|
categoryList.classList.add("subcategories");
|
||||||
|
for (let i = 0; i < sortedCategories.length; ++i) {
|
||||||
|
const category = sortedCategories[i];
|
||||||
for (let j = (i + 1);
|
for (let j = (i + 1);
|
||||||
((j < sortedCategories.length) && sortedCategories[j].categoryName.startsWith(categoryName + "/")); ++j)
|
((j < sortedCategories.length) && sortedCategories[j].categoryName.startsWith(`${category.categoryName}/`)); ++j) {
|
||||||
categoryCount += sortedCategories[j].categoryCount;
|
const subcategory = sortedCategories[j];
|
||||||
}
|
category.categoryCount += subcategory.categoryCount;
|
||||||
|
category.forceExpand ||= subcategory.forceExpand;
|
||||||
|
|
||||||
categoryList.appendChild(create_link(categoryHash, categoryName, categoryCount));
|
const isDirectSubcategory = (subcategory.nameSegments.length - category.nameSegments.length) === 1;
|
||||||
|
if (isDirectSubcategory) {
|
||||||
|
subcategory.parentID = category.categoryHash;
|
||||||
|
category.children.push(subcategory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const category of sortedCategories) {
|
||||||
|
if (category.parentID === null)
|
||||||
|
createCategoryTree(category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
categoryList.classList.remove("subcategories");
|
||||||
|
for (const { categoryHash, categoryName, categoryCount } of sortedCategories)
|
||||||
|
categoriesFragment.appendChild(createCategoryLink(categoryHash, categoryName, categoryCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
categoryList.appendChild(categoriesFragment);
|
||||||
window.qBittorrent.Filters.categoriesFilterContextMenu.searchAndAddTargets();
|
window.qBittorrent.Filters.categoriesFilterContextMenu.searchAndAddTargets();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -524,7 +561,7 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
if (!categoryList)
|
if (!categoryList)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (const category of categoryList.children)
|
for (const category of categoryList.getElementsByTagName("li"))
|
||||||
category.classList.toggle("selectedFilter", (Number(category.id) === selectedCategory));
|
category.classList.toggle("selectedFilter", (Number(category.id) === selectedCategory));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -597,10 +597,7 @@ const initializeWindows = function() {
|
||||||
paddingVertical: 0,
|
paddingVertical: 0,
|
||||||
paddingHorizontal: 0,
|
paddingHorizontal: 0,
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 150,
|
height: 150
|
||||||
onCloseComplete: function() {
|
|
||||||
updateMainData();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -642,7 +639,6 @@ const initializeWindows = function() {
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 150
|
height: 150
|
||||||
});
|
});
|
||||||
updateMainData();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
createSubcategoryFN = function(categoryHash) {
|
createSubcategoryFN = function(categoryHash) {
|
||||||
|
@ -662,7 +658,6 @@ const initializeWindows = function() {
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 150
|
height: 150
|
||||||
});
|
});
|
||||||
updateMainData();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
editCategoryFN = function(categoryHash) {
|
editCategoryFN = function(categoryHash) {
|
||||||
|
@ -682,7 +677,6 @@ const initializeWindows = function() {
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 150
|
height: 150
|
||||||
});
|
});
|
||||||
updateMainData();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
removeCategoryFN = function(categoryHash) {
|
removeCategoryFN = function(categoryHash) {
|
||||||
|
@ -692,9 +686,12 @@ const initializeWindows = function() {
|
||||||
method: "post",
|
method: "post",
|
||||||
data: {
|
data: {
|
||||||
categories: categoryName
|
categories: categoryName
|
||||||
|
},
|
||||||
|
onSuccess: function() {
|
||||||
|
setCategoryFilter(CATEGORIES_ALL);
|
||||||
|
updateMainData();
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
setCategoryFilter(CATEGORIES_ALL);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteUnusedCategoriesFN = function() {
|
deleteUnusedCategoriesFN = function() {
|
||||||
|
@ -709,9 +706,12 @@ const initializeWindows = function() {
|
||||||
method: "post",
|
method: "post",
|
||||||
data: {
|
data: {
|
||||||
categories: categories.join("\n")
|
categories: categories.join("\n")
|
||||||
|
},
|
||||||
|
onSuccess: function() {
|
||||||
|
setCategoryFilter(CATEGORIES_ALL);
|
||||||
|
updateMainData();
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
setCategoryFilter(CATEGORIES_ALL);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
startTorrentsByCategoryFN = function(categoryHash) {
|
startTorrentsByCategoryFN = function(categoryHash) {
|
||||||
|
|
|
@ -44,7 +44,9 @@
|
||||||
<template id="categoryFilterItem">
|
<template id="categoryFilterItem">
|
||||||
<li class="categoriesFilterContextMenuTarget">
|
<li class="categoriesFilterContextMenuTarget">
|
||||||
<span class="link">
|
<span class="link">
|
||||||
<img src="images/view-categories.svg" alt="">
|
<button class="categoryToggle" type="button" aria-label="QBT_TR(Collapse/expand category)QBT_TR[CONTEXT=TransferListFiltersWidget]"></button>
|
||||||
|
<img src="images/view-categories.svg" width="16" height="16" alt="">
|
||||||
|
<span></span>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
@ -76,6 +78,11 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleCategoryDisplay = (filterItemID) => {
|
||||||
|
const filterItem = document.getElementById(filterItemID);
|
||||||
|
LocalPreferences.set(`category_${filterItemID}_collapsed`, filterItem.classList.toggle("collapsedCategory").toString());
|
||||||
|
};
|
||||||
|
|
||||||
const categoriesFilterContextMenu = new window.qBittorrent.ContextMenu.CategoriesFilterContextMenu({
|
const categoriesFilterContextMenu = new window.qBittorrent.ContextMenu.CategoriesFilterContextMenu({
|
||||||
targets: ".categoriesFilterContextMenuTarget",
|
targets: ".categoriesFilterContextMenuTarget",
|
||||||
menu: "categoriesFilterMenu",
|
menu: "categoriesFilterMenu",
|
||||||
|
@ -183,11 +190,9 @@
|
||||||
|
|
||||||
document.getElementById("Filters_pad").addEventListener("click", (event) => {
|
document.getElementById("Filters_pad").addEventListener("click", (event) => {
|
||||||
const filterItem = event.target.closest("li");
|
const filterItem = event.target.closest("li");
|
||||||
if (!filterItem)
|
if (filterItem?.classList?.contains("selectedFilter"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event.stopImmediatePropagation();
|
|
||||||
|
|
||||||
const { id: filterItemID } = filterItem;
|
const { id: filterItemID } = filterItem;
|
||||||
const { id: filterListID } = filterItem.closest("ul[id]");
|
const { id: filterListID } = filterItem.closest("ul[id]");
|
||||||
switch (filterListID) {
|
switch (filterListID) {
|
||||||
|
@ -218,6 +223,22 @@
|
||||||
toggleFilterDisplay(filterList);
|
toggleFilterDisplay(filterList);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById("categoryFilterList").addEventListener("click", (event) => {
|
||||||
|
if (event.target.className !== "categoryToggle")
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
toggleCategoryDisplay(event.target.closest("li").id);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("categoryFilterList").addEventListener("dblclick", function(event) {
|
||||||
|
const filterItem = event.target.closest("li");
|
||||||
|
if (!this.classList.contains("subcategories") || !(filterItem?.querySelector("ul")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
toggleCategoryDisplay(filterItem.id);
|
||||||
|
});
|
||||||
|
|
||||||
return exports();
|
return exports();
|
||||||
})();
|
})();
|
||||||
Object.freeze(window.qBittorrent.Filters);
|
Object.freeze(window.qBittorrent.Filters);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue