Skip to content

Commit

Permalink
WebUI: Improve properties panel
Browse files Browse the repository at this point in the history
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 qbittorrent#21209.
  • Loading branch information
skomerko authored Aug 24, 2024
1 parent a91bac8 commit fda797c
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 97 deletions.
6 changes: 3 additions & 3 deletions src/webui/www/private/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ a.propButton img {

#torrentFilesFilterToolbar {
float: right;
margin-right: 30px;
margin-right: 5px;
}

#torrentFilesFilterInput {
Expand All @@ -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 */
Expand Down Expand Up @@ -591,7 +591,7 @@ td.generalLabel {
user-select: none;
}

#prop_general {
#propGeneral {
padding: 2px;
}

Expand Down
124 changes: 55 additions & 69 deletions src/webui/www/private/scripts/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,6 @@ window.addEventListener("DOMContentLoaded", () => {
new MochaUI.Panel({
id: "propertiesPanel",
title: "Panel",
header: true,
padding: {
top: 0,
right: 0,
Expand All @@ -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);

const startCollapsed = LocalPreferences.get("properties_panel_collapsed", "false") === "true";
if (startCollapsed)
togglePropertiesPanel();

$("propertiesPanel_collapseToggle").addEventListener("click", (e) => {
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", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/webui/www/private/scripts/prop-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/webui/www/private/scripts/prop-general.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/webui/www/private/scripts/prop-peers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/webui/www/private/scripts/prop-trackers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/webui/www/private/scripts/prop-webseeds.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 5 additions & 15 deletions src/webui/www/private/views/properties.html
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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;">
Expand All @@ -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;">
Expand All @@ -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>
Expand All @@ -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;">
Expand All @@ -176,13 +176,3 @@
</div>
</div>
</div>

<script>
"use strict";

(function() {
const selectedTab = $(LocalPreferences.get("selected_tab", "PropGeneralLink"));
if (selectedTab)
selectedTab.click();
})();
</script>
10 changes: 5 additions & 5 deletions src/webui/www/private/views/propertiesToolbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit fda797c

Please sign in to comment.