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:
skomerko 2024-08-24 08:09:10 +02:00 committed by GitHub
parent a91bac8aa0
commit fda797cb76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 73 additions and 97 deletions

View file

@ -455,7 +455,7 @@ a.propButton img {
#torrentFilesFilterToolbar {
float: right;
margin-right: 30px;
margin-right: 5px;
}
#torrentFilesFilterInput {
@ -464,7 +464,7 @@ a.propButton img {
background-repeat: no-repeat;
background-size: 1.5em;
padding-left: 2em;
width: 160px;
width: 250px;
}
/* Tri-state checkbox */
@ -591,7 +591,7 @@ td.generalLabel {
user-select: none;
}
#prop_general {
#propGeneral {
padding: 2px;
}

View file

@ -1464,7 +1464,6 @@ window.addEventListener("DOMContentLoaded", () => {
new MochaUI.Panel({
id: "propertiesPanel",
title: "Panel",
header: true,
padding: {
top: 0,
right: 0,
@ -1473,92 +1472,79 @@ window.addEventListener("DOMContentLoaded", () => {
},
contentURL: "views/properties.html",
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"],
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",
tabsOnload: function() {
MochaUI.initializeTabs("propertiesTabs");
tabsOnload: function() {}, // must be included, otherwise panel won't load properly
onContentLoaded: function() {
this.panelHeaderCollapseBoxEl.classList.add("invisible");
updatePropertiesPanel = function() {
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();
}
const togglePropertiesPanel = () => {
this.collapseToggleEl.click();
LocalPreferences.set("properties_panel_collapsed", this.isCollapsed.toString());
};
$("PropGeneralLink").addEventListener("click", function(e) {
$$(".propertiesTabContent").addClass("invisible");
$("prop_general").removeClass("invisible");
hideFilesFilter();
updatePropertiesPanel();
LocalPreferences.set("selected_tab", this.id);
});
const selectTab = (tabID) => {
const isAlreadySelected = this.panelHeaderEl.getElementById(tabID).classList.contains("selected");
if (!isAlreadySelected) {
for (const tab of this.panelHeaderEl.getElementById("propertiesTabs").children)
tab.classList.toggle("selected", tab.id === tabID);
$("PropTrackersLink").addEventListener("click", function(e) {
$$(".propertiesTabContent").addClass("invisible");
$("prop_trackers").removeClass("invisible");
hideFilesFilter();
updatePropertiesPanel();
LocalPreferences.set("selected_tab", this.id);
});
const tabContentID = tabID.replace("Link", "");
for (const tabContent of this.contentEl.children)
tabContent.classList.toggle("invisible", tabContent.id !== tabContentID);
$("PropPeersLink").addEventListener("click", function(e) {
$$(".propertiesTabContent").addClass("invisible");
$("prop_peers").removeClass("invisible");
hideFilesFilter();
updatePropertiesPanel();
LocalPreferences.set("selected_tab", this.id);
});
LocalPreferences.set("selected_properties_tab", tabID);
}
$("PropWebSeedsLink").addEventListener("click", function(e) {
$$(".propertiesTabContent").addClass("invisible");
$("prop_webseeds").removeClass("invisible");
hideFilesFilter();
updatePropertiesPanel();
LocalPreferences.set("selected_tab", this.id);
});
if (isAlreadySelected || this.isCollapsed)
togglePropertiesPanel();
};
$("PropFilesLink").addEventListener("click", function(e) {
$$(".propertiesTabContent").addClass("invisible");
$("prop_files").removeClass("invisible");
showFilesFilter();
updatePropertiesPanel();
LocalPreferences.set("selected_tab", this.id);
});
const lastUsedTab = LocalPreferences.get("selected_properties_tab", "propGeneralLink");
selectTab(lastUsedTab);
$("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();
const showFilesFilter = (selectedTab.id === "propFilesLink") && !this.isCollapsed;
document.getElementById("torrentFilesFilterToolbar").classList.toggle("invisible", !showFilesFilter);
});
},
column: "mainColumn",
height: prop_h
});
const showFilesFilter = function() {
$("torrentFilesFilterToolbar").removeClass("invisible");
};
const hideFilesFilter = function() {
$("torrentFilesFilterToolbar").addClass("invisible");
};
// listen for changes to torrentsFilterInput
let torrentsFilterInputTimer = -1;
$("torrentsFilterInput").addEventListener("input", () => {

View file

@ -334,7 +334,7 @@ window.qBittorrent.PropFiles ??= (() => {
let loadTorrentFilesDataTimer = -1;
const loadTorrentFilesData = function() {
if ($("prop_files").hasClass("invisible")
if ($("propFiles").hasClass("invisible")
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
// Tab changed, don't do anything
return;

View file

@ -74,7 +74,7 @@ window.qBittorrent.PropGeneral ??= (() => {
let loadTorrentDataTimer = -1;
const loadTorrentData = function() {
if ($("prop_general").hasClass("invisible")
if ($("propGeneral").hasClass("invisible")
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
// Tab changed, don't do anything
return;

View file

@ -42,7 +42,7 @@ window.qBittorrent.PropPeers ??= (() => {
let show_flags = true;
const loadTorrentPeersData = function() {
if ($("prop_peers").hasClass("invisible")
if ($("propPeers").hasClass("invisible")
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
syncTorrentPeersLastResponseId = 0;
torrentPeersTable.clear();

View file

@ -42,7 +42,7 @@ window.qBittorrent.PropTrackers ??= (() => {
let loadTrackersDataTimer = -1;
const loadTrackersData = function() {
if ($("prop_trackers").hasClass("invisible")
if ($("propTrackers").hasClass("invisible")
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
// Tab changed, don't do anything
return;

View file

@ -90,7 +90,7 @@ window.qBittorrent.PropWebseeds ??= (() => {
let loadWebSeedsDataTimer = -1;
const loadWebSeedsData = function() {
if ($("prop_webseeds").hasClass("invisible")
if ($("propWebSeeds").hasClass("invisible")
|| $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
// Tab changed, don't do anything
return;

View file

@ -1,4 +1,4 @@
<div id="prop_general" class="propertiesTabContent">
<div id="propGeneral" class="propertiesTabContent invisible unselectable">
<table style="width: 100%; padding: 0 3px">
<tbody>
<tr>
@ -104,7 +104,7 @@
</fieldset>
</div>
<div id="prop_trackers" class="propertiesTabContent invisible unselectable">
<div id="propTrackers" class="propertiesTabContent invisible unselectable">
<div id="trackers">
<div id="torrentTrackersTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
<table class="dynamicTable" style="position:relative;">
@ -124,7 +124,7 @@
</div>
</div>
<div id="prop_peers" class="propertiesTabContent invisible unselectable">
<div id="propPeers" class="propertiesTabContent invisible unselectable">
<div>
<div id="torrentPeersTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
<table class="dynamicTable" style="position:relative;">
@ -144,7 +144,7 @@
</div>
</div>
<div id="prop_webseeds" class="propertiesTabContent invisible unselectable">
<div id="propWebSeeds" class="propertiesTabContent invisible unselectable">
<div id="webseeds">
<table class="dynamicTable" style="width: 100%">
<thead>
@ -157,7 +157,7 @@
</div>
</div>
<div id="prop_files" class="propertiesTabContent invisible unselectable">
<div id="propFiles" class="propertiesTabContent invisible unselectable">
<div id="torrentFiles">
<div id="torrentFilesTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
<table class="dynamicTable" style="position:relative;">
@ -176,13 +176,3 @@
</div>
</div>
</div>
<script>
"use strict";
(function() {
const selectedTab = $(LocalPreferences.get("selected_tab", "PropGeneralLink"));
if (selectedTab)
selectedTab.click();
})();
</script>

View file

@ -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">
</div>
<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>
</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>
</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>
</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>
</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>
</li>
</menu>