From d19f7b12d950e23c739412d8a9d85da0cff7bb5a Mon Sep 17 00:00:00 2001
From: skomerko <168652295+skomerko@users.noreply.github.com>
Date: Mon, 16 Sep 2024 11:41:14 +0200
Subject: [PATCH] WebUI: Improve hash copy actions in context menu
This PR provides better feedback for hash context menu actions and now it is clearly shown if there is anything to copy.
PR #21321.
---
src/webui/www/private/css/style.css | 30 ++++++++++----------
src/webui/www/private/index.html | 4 +--
src/webui/www/private/scripts/contextmenu.js | 41 ++++++++++++++++++++++------
3 files changed, 48 insertions(+), 27 deletions(-)
diff --git a/src/webui/www/private/css/style.css b/src/webui/www/private/css/style.css
index 9e6947f7a..6613dcad5 100644
--- a/src/webui/www/private/css/style.css
+++ b/src/webui/www/private/css/style.css
@@ -225,6 +225,18 @@ a.propButton img {
.contextMenu li {
margin: 0;
padding: 0;
+ user-select: none;
+}
+
+.contextMenu li.disabled {
+ background-color: transparent;
+ cursor: default;
+ filter: grayscale(1);
+ opacity: 0.6;
+}
+
+.contextMenu li.disabled a {
+ pointer-events: none;
}
.contextMenu li a {
@@ -248,14 +260,6 @@ a.propButton img {
filter: var(--color-icon-hover);
}
-.contextMenu li a.disabled {
- font-style: italic;
-}
-
-.contextMenu li a.disabled:hover {
- color: var(--color-text-disabled);
-}
-
.contextMenu li ul {
background: var(--color-background-default);
border: 1px solid var(--color-border-default);
@@ -272,19 +276,13 @@ a.propButton img {
position: relative;
}
-.contextMenu li a.arrow-right,
-.contextMenu li a:hover.arrow-right {
+.contextMenu li:not(.disabled) .arrow-right {
background-image: url("../images/arrow-right.gif");
background-position: right center;
background-repeat: no-repeat;
}
-.contextMenu li:hover ul,
-.contextMenu li.ieHover ul,
-.contextMenu li li.ieHover ul,
-.contextMenu li li li.ieHover ul,
-.contextMenu li li:hover ul,
-.contextMenu li li li:hover ul {
+.contextMenu li:not(.disabled):hover > ul {
/* lists nested under hovered list items */
left: auto;
}
diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html
index 0b243cc18..44f3c1af6 100644
--- a/src/webui/www/private/index.html
+++ b/src/webui/www/private/index.html
@@ -198,8 +198,8 @@
QBT_TR(Copy)QBT_TR[CONTEXT=TransferListWidget]
- QBT_TR(Name)QBT_TR[CONTEXT=TransferListWidget]
- - QBT_TR(Info hash v1)QBT_TR[CONTEXT=TransferListWidget]
- - QBT_TR(Info hash v2)QBT_TR[CONTEXT=TransferListWidget]
+ - QBT_TR(Info hash v1)QBT_TR[CONTEXT=TransferListWidget]
+ - QBT_TR(Info hash v2)QBT_TR[CONTEXT=TransferListWidget]
- QBT_TR(Magnet link)QBT_TR[CONTEXT=TransferListWidget]
- QBT_TR(Torrent ID)QBT_TR[CONTEXT=TransferListWidget]
diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js
index be523c278..7df02d14c 100644
--- a/src/webui/www/private/scripts/contextmenu.js
+++ b/src/webui/www/private/scripts/contextmenu.js
@@ -207,15 +207,21 @@ window.qBittorrent.ContextMenu ??= (() => {
}, this);
/* menu items */
- this.menu.getElements("a").each(function(item) {
- item.addEventListener("click", (e) => {
- e.preventDefault();
- if (!item.hasClass("disabled")) {
- this.execute(item.href.split("#")[1], $(this.options.element));
- this.fireEvent("click", [item, e]);
- }
- });
- }, this);
+ this.menu.addEventListener("click", (e) => {
+ const menuItem = e.target.closest("li");
+ if (!menuItem)
+ return;
+
+ e.preventDefault();
+ if (!menuItem.classList.contains("disabled")) {
+ const anchor = menuItem.firstElementChild;
+ this.execute(anchor.href.split("#")[1], this.options.element);
+ this.fireEvent("click", [anchor, e]);
+ }
+ else {
+ e.stopPropagation();
+ }
+ });
// hide on body click
$(document.body).addEventListener("click", () => {
@@ -267,6 +273,12 @@ window.qBittorrent.ContextMenu ??= (() => {
return this;
},
+ // enable/disable an item
+ setEnabled: function(item, enabled) {
+ this.menu.querySelector(`:scope a[href$="${item}"]`).parentElement.classList.toggle("disabled", !enabled);
+ return this;
+ },
+
// disable the entire menu
disable: function() {
this.options.disabled = true;
@@ -303,6 +315,8 @@ window.qBittorrent.ContextMenu ??= (() => {
let all_are_super_seeding = true;
let all_are_auto_tmm = true;
let there_are_auto_tmm = false;
+ let thereAreV1Hashes = false;
+ let thereAreV2Hashes = false;
const tagCount = new Map();
const categoryCount = new Map();
@@ -340,6 +354,12 @@ window.qBittorrent.ContextMenu ??= (() => {
else
all_are_auto_tmm = false;
+ if (data["infohash_v1"] !== "")
+ thereAreV1Hashes = true;
+
+ if (data["infohash_v2"] !== "")
+ thereAreV2Hashes = true;
+
const torrentTags = data["tags"].split(", ");
for (const tag of torrentTags) {
const count = tagCount.get(tag);
@@ -418,6 +438,9 @@ window.qBittorrent.ContextMenu ??= (() => {
this.setItemChecked("autoTorrentManagement", all_are_auto_tmm);
}
+ this.setEnabled("copyInfohash1", thereAreV1Hashes);
+ this.setEnabled("copyInfohash2", thereAreV2Hashes);
+
const contextTagList = $("contextTagList");
tagList.forEach((tag, tagHash) => {
const checkbox = contextTagList.getElement(`a[href="#Tag/${tag.name}"] input[type="checkbox"]`);
--
2.11.4.GIT