mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-16 02:03:07 -07:00
WebUI: Improve properties panel
It is now possible to expand & collapse it by clicking directly on tabs, just like in GUI. In addition, collapse state is saved and applied on page load. Fixed one minor bug and now files search input is properly hidden even when panel is collapsed. PR #21209.
This commit is contained in:
parent
a91bac8aa0
commit
fda797cb76
9 changed files with 73 additions and 97 deletions
|
@ -455,7 +455,7 @@ a.propButton img {
|
||||||
|
|
||||||
#torrentFilesFilterToolbar {
|
#torrentFilesFilterToolbar {
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 30px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#torrentFilesFilterInput {
|
#torrentFilesFilterInput {
|
||||||
|
@ -464,7 +464,7 @@ a.propButton img {
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 1.5em;
|
background-size: 1.5em;
|
||||||
padding-left: 2em;
|
padding-left: 2em;
|
||||||
width: 160px;
|
width: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tri-state checkbox */
|
/* Tri-state checkbox */
|
||||||
|
@ -591,7 +591,7 @@ td.generalLabel {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#prop_general {
|
#propGeneral {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1464,7 +1464,6 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
new MochaUI.Panel({
|
new MochaUI.Panel({
|
||||||
id: "propertiesPanel",
|
id: "propertiesPanel",
|
||||||
title: "Panel",
|
title: "Panel",
|
||||||
header: true,
|
|
||||||
padding: {
|
padding: {
|
||||||
top: 0,
|
top: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
|
@ -1473,92 +1472,79 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
},
|
},
|
||||||
contentURL: "views/properties.html",
|
contentURL: "views/properties.html",
|
||||||
require: {
|
require: {
|
||||||
css: ["css/Tabs.css", "css/dynamicTable.css"],
|
|
||||||
js: ["scripts/prop-general.js", "scripts/prop-trackers.js", "scripts/prop-peers.js", "scripts/prop-webseeds.js", "scripts/prop-files.js"],
|
js: ["scripts/prop-general.js", "scripts/prop-trackers.js", "scripts/prop-peers.js", "scripts/prop-webseeds.js", "scripts/prop-files.js"],
|
||||||
|
onload: function() {
|
||||||
|
updatePropertiesPanel = function() {
|
||||||
|
switch (LocalPreferences.get("selected_properties_tab")) {
|
||||||
|
case "propGeneralLink":
|
||||||
|
window.qBittorrent.PropGeneral.updateData();
|
||||||
|
break;
|
||||||
|
case "propTrackersLink":
|
||||||
|
window.qBittorrent.PropTrackers.updateData();
|
||||||
|
break;
|
||||||
|
case "propPeersLink":
|
||||||
|
window.qBittorrent.PropPeers.updateData();
|
||||||
|
break;
|
||||||
|
case "propWebSeedsLink":
|
||||||
|
window.qBittorrent.PropWebseeds.updateData();
|
||||||
|
break;
|
||||||
|
case "propFilesLink":
|
||||||
|
window.qBittorrent.PropFiles.updateData();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
tabsURL: "views/propertiesToolbar.html",
|
tabsURL: "views/propertiesToolbar.html",
|
||||||
tabsOnload: function() {
|
tabsOnload: function() {}, // must be included, otherwise panel won't load properly
|
||||||
MochaUI.initializeTabs("propertiesTabs");
|
onContentLoaded: function() {
|
||||||
|
this.panelHeaderCollapseBoxEl.classList.add("invisible");
|
||||||
|
|
||||||
updatePropertiesPanel = function() {
|
const togglePropertiesPanel = () => {
|
||||||
if (!$("prop_general").hasClass("invisible")) {
|
this.collapseToggleEl.click();
|
||||||
if (window.qBittorrent.PropGeneral !== undefined)
|
LocalPreferences.set("properties_panel_collapsed", this.isCollapsed.toString());
|
||||||
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").addEventListener("click", function(e) {
|
const selectTab = (tabID) => {
|
||||||
$$(".propertiesTabContent").addClass("invisible");
|
const isAlreadySelected = this.panelHeaderEl.getElementById(tabID).classList.contains("selected");
|
||||||
$("prop_general").removeClass("invisible");
|
if (!isAlreadySelected) {
|
||||||
hideFilesFilter();
|
for (const tab of this.panelHeaderEl.getElementById("propertiesTabs").children)
|
||||||
updatePropertiesPanel();
|
tab.classList.toggle("selected", tab.id === tabID);
|
||||||
LocalPreferences.set("selected_tab", this.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("PropTrackersLink").addEventListener("click", function(e) {
|
const tabContentID = tabID.replace("Link", "");
|
||||||
$$(".propertiesTabContent").addClass("invisible");
|
for (const tabContent of this.contentEl.children)
|
||||||
$("prop_trackers").removeClass("invisible");
|
tabContent.classList.toggle("invisible", tabContent.id !== tabContentID);
|
||||||
hideFilesFilter();
|
|
||||||
updatePropertiesPanel();
|
|
||||||
LocalPreferences.set("selected_tab", this.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("PropPeersLink").addEventListener("click", function(e) {
|
LocalPreferences.set("selected_properties_tab", tabID);
|
||||||
$$(".propertiesTabContent").addClass("invisible");
|
}
|
||||||
$("prop_peers").removeClass("invisible");
|
|
||||||
hideFilesFilter();
|
|
||||||
updatePropertiesPanel();
|
|
||||||
LocalPreferences.set("selected_tab", this.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("PropWebSeedsLink").addEventListener("click", function(e) {
|
if (isAlreadySelected || this.isCollapsed)
|
||||||
$$(".propertiesTabContent").addClass("invisible");
|
togglePropertiesPanel();
|
||||||
$("prop_webseeds").removeClass("invisible");
|
};
|
||||||
hideFilesFilter();
|
|
||||||
updatePropertiesPanel();
|
|
||||||
LocalPreferences.set("selected_tab", this.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("PropFilesLink").addEventListener("click", function(e) {
|
const lastUsedTab = LocalPreferences.get("selected_properties_tab", "propGeneralLink");
|
||||||
$$(".propertiesTabContent").addClass("invisible");
|
selectTab(lastUsedTab);
|
||||||
$("prop_files").removeClass("invisible");
|
|
||||||
showFilesFilter();
|
|
||||||
updatePropertiesPanel();
|
|
||||||
LocalPreferences.set("selected_tab", this.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("propertiesPanel_collapseToggle").addEventListener("click", (e) => {
|
const startCollapsed = LocalPreferences.get("properties_panel_collapsed", "false") === "true";
|
||||||
|
if (startCollapsed)
|
||||||
|
togglePropertiesPanel();
|
||||||
|
|
||||||
|
this.panelHeaderContentEl.addEventListener("click", (e) => {
|
||||||
|
const selectedTab = e.target.closest("li");
|
||||||
|
if (!selectedTab)
|
||||||
|
return;
|
||||||
|
|
||||||
|
selectTab(selectedTab.id);
|
||||||
updatePropertiesPanel();
|
updatePropertiesPanel();
|
||||||
|
|
||||||
|
const showFilesFilter = (selectedTab.id === "propFilesLink") && !this.isCollapsed;
|
||||||
|
document.getElementById("torrentFilesFilterToolbar").classList.toggle("invisible", !showFilesFilter);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
column: "mainColumn",
|
column: "mainColumn",
|
||||||
height: prop_h
|
height: prop_h
|
||||||
});
|
});
|
||||||
|
|
||||||
const showFilesFilter = function() {
|
|
||||||
$("torrentFilesFilterToolbar").removeClass("invisible");
|
|
||||||
};
|
|
||||||
|
|
||||||
const hideFilesFilter = function() {
|
|
||||||
$("torrentFilesFilterToolbar").addClass("invisible");
|
|
||||||
};
|
|
||||||
|
|
||||||
// listen for changes to torrentsFilterInput
|
// listen for changes to torrentsFilterInput
|
||||||
let torrentsFilterInputTimer = -1;
|
let torrentsFilterInputTimer = -1;
|
||||||
$("torrentsFilterInput").addEventListener("input", () => {
|
$("torrentsFilterInput").addEventListener("input", () => {
|
||||||
|
|
|
@ -334,7 +334,7 @@ window.qBittorrent.PropFiles ??= (() => {
|
||||||
|
|
||||||
let loadTorrentFilesDataTimer = -1;
|
let loadTorrentFilesDataTimer = -1;
|
||||||
const loadTorrentFilesData = function() {
|
const loadTorrentFilesData = function() {
|
||||||
if ($("prop_files").hasClass("invisible")
|
if ($("propFiles").hasClass("invisible")
|
||||||
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
||||||
// Tab changed, don't do anything
|
// Tab changed, don't do anything
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -74,7 +74,7 @@ window.qBittorrent.PropGeneral ??= (() => {
|
||||||
|
|
||||||
let loadTorrentDataTimer = -1;
|
let loadTorrentDataTimer = -1;
|
||||||
const loadTorrentData = function() {
|
const loadTorrentData = function() {
|
||||||
if ($("prop_general").hasClass("invisible")
|
if ($("propGeneral").hasClass("invisible")
|
||||||
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
||||||
// Tab changed, don't do anything
|
// Tab changed, don't do anything
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -42,7 +42,7 @@ window.qBittorrent.PropPeers ??= (() => {
|
||||||
let show_flags = true;
|
let show_flags = true;
|
||||||
|
|
||||||
const loadTorrentPeersData = function() {
|
const loadTorrentPeersData = function() {
|
||||||
if ($("prop_peers").hasClass("invisible")
|
if ($("propPeers").hasClass("invisible")
|
||||||
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
||||||
syncTorrentPeersLastResponseId = 0;
|
syncTorrentPeersLastResponseId = 0;
|
||||||
torrentPeersTable.clear();
|
torrentPeersTable.clear();
|
||||||
|
|
|
@ -42,7 +42,7 @@ window.qBittorrent.PropTrackers ??= (() => {
|
||||||
let loadTrackersDataTimer = -1;
|
let loadTrackersDataTimer = -1;
|
||||||
|
|
||||||
const loadTrackersData = function() {
|
const loadTrackersData = function() {
|
||||||
if ($("prop_trackers").hasClass("invisible")
|
if ($("propTrackers").hasClass("invisible")
|
||||||
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
||||||
// Tab changed, don't do anything
|
// Tab changed, don't do anything
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -90,7 +90,7 @@ window.qBittorrent.PropWebseeds ??= (() => {
|
||||||
|
|
||||||
let loadWebSeedsDataTimer = -1;
|
let loadWebSeedsDataTimer = -1;
|
||||||
const loadWebSeedsData = function() {
|
const loadWebSeedsData = function() {
|
||||||
if ($("prop_webseeds").hasClass("invisible")
|
if ($("propWebSeeds").hasClass("invisible")
|
||||||
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
|
||||||
// Tab changed, don't do anything
|
// Tab changed, don't do anything
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div id="prop_general" class="propertiesTabContent">
|
<div id="propGeneral" class="propertiesTabContent invisible unselectable">
|
||||||
<table style="width: 100%; padding: 0 3px">
|
<table style="width: 100%; padding: 0 3px">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="prop_trackers" class="propertiesTabContent invisible unselectable">
|
<div id="propTrackers" class="propertiesTabContent invisible unselectable">
|
||||||
<div id="trackers">
|
<div id="trackers">
|
||||||
<div id="torrentTrackersTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
|
<div id="torrentTrackersTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
|
||||||
<table class="dynamicTable" style="position:relative;">
|
<table class="dynamicTable" style="position:relative;">
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="prop_peers" class="propertiesTabContent invisible unselectable">
|
<div id="propPeers" class="propertiesTabContent invisible unselectable">
|
||||||
<div>
|
<div>
|
||||||
<div id="torrentPeersTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
|
<div id="torrentPeersTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
|
||||||
<table class="dynamicTable" style="position:relative;">
|
<table class="dynamicTable" style="position:relative;">
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="prop_webseeds" class="propertiesTabContent invisible unselectable">
|
<div id="propWebSeeds" class="propertiesTabContent invisible unselectable">
|
||||||
<div id="webseeds">
|
<div id="webseeds">
|
||||||
<table class="dynamicTable" style="width: 100%">
|
<table class="dynamicTable" style="width: 100%">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -157,7 +157,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="prop_files" class="propertiesTabContent invisible unselectable">
|
<div id="propFiles" class="propertiesTabContent invisible unselectable">
|
||||||
<div id="torrentFiles">
|
<div id="torrentFiles">
|
||||||
<div id="torrentFilesTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
|
<div id="torrentFilesTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
|
||||||
<table class="dynamicTable" style="position:relative;">
|
<table class="dynamicTable" style="position:relative;">
|
||||||
|
@ -176,13 +176,3 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
const selectedTab = $(LocalPreferences.get("selected_tab", "PropGeneralLink"));
|
|
||||||
if (selectedTab)
|
|
||||||
selectedTab.click();
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
<input type="text" id="torrentFilesFilterInput" placeholder="QBT_TR(Filter files...)QBT_TR[CONTEXT=PropertiesWidget]" aria-label="QBT_TR(Filter files...)QBT_TR[CONTEXT=PropertiesWidget]" autocorrect="off" autocapitalize="none">
|
<input type="text" id="torrentFilesFilterInput" placeholder="QBT_TR(Filter files...)QBT_TR[CONTEXT=PropertiesWidget]" aria-label="QBT_TR(Filter files...)QBT_TR[CONTEXT=PropertiesWidget]" autocorrect="off" autocapitalize="none">
|
||||||
</div>
|
</div>
|
||||||
<menu id="propertiesTabs" class="tab-menu">
|
<menu id="propertiesTabs" class="tab-menu">
|
||||||
<li id="PropGeneralLink" class="selected">
|
<li id="propGeneralLink">
|
||||||
<a><img alt="QBT_TR(General)QBT_TR[CONTEXT=PropTabBar]" src="images/help-about.svg" width="16" height="16">QBT_TR(General)QBT_TR[CONTEXT=PropTabBar]</a>
|
<a><img alt="QBT_TR(General)QBT_TR[CONTEXT=PropTabBar]" src="images/help-about.svg" width="16" height="16">QBT_TR(General)QBT_TR[CONTEXT=PropTabBar]</a>
|
||||||
</li>
|
</li>
|
||||||
<li id="PropTrackersLink">
|
<li id="propTrackersLink">
|
||||||
<a><img alt="QBT_TR(Trackers)QBT_TR[CONTEXT=PropTabBar]" src="images/trackers.svg" width="16" height="16">QBT_TR(Trackers)QBT_TR[CONTEXT=PropTabBar]</a>
|
<a><img alt="QBT_TR(Trackers)QBT_TR[CONTEXT=PropTabBar]" src="images/trackers.svg" width="16" height="16">QBT_TR(Trackers)QBT_TR[CONTEXT=PropTabBar]</a>
|
||||||
</li>
|
</li>
|
||||||
<li id="PropPeersLink">
|
<li id="propPeersLink">
|
||||||
<a><img alt="QBT_TR(Peers)QBT_TR[CONTEXT=PropTabBar]" src="images/peers.svg" width="16" height="16">QBT_TR(Peers)QBT_TR[CONTEXT=PropTabBar]</a>
|
<a><img alt="QBT_TR(Peers)QBT_TR[CONTEXT=PropTabBar]" src="images/peers.svg" width="16" height="16">QBT_TR(Peers)QBT_TR[CONTEXT=PropTabBar]</a>
|
||||||
</li>
|
</li>
|
||||||
<li id="PropWebSeedsLink">
|
<li id="propWebSeedsLink">
|
||||||
<a><img alt="QBT_TR(HTTP Sources)QBT_TR[CONTEXT=PropTabBar]" src="images/network-server.svg" width="16" height="16">QBT_TR(HTTP Sources)QBT_TR[CONTEXT=PropTabBar]</a>
|
<a><img alt="QBT_TR(HTTP Sources)QBT_TR[CONTEXT=PropTabBar]" src="images/network-server.svg" width="16" height="16">QBT_TR(HTTP Sources)QBT_TR[CONTEXT=PropTabBar]</a>
|
||||||
</li>
|
</li>
|
||||||
<li id="PropFilesLink">
|
<li id="propFilesLink">
|
||||||
<a><img alt="QBT_TR(Content)QBT_TR[CONTEXT=PropTabBar]" src="images/directory.svg" width="16" height="16">QBT_TR(Content)QBT_TR[CONTEXT=PropTabBar]</a>
|
<a><img alt="QBT_TR(Content)QBT_TR[CONTEXT=PropTabBar]" src="images/directory.svg" width="16" height="16">QBT_TR(Content)QBT_TR[CONTEXT=PropTabBar]</a>
|
||||||
</li>
|
</li>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue