mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-15 01:33:07 -07:00
WebUI: Improve torrent deletion dialog
This PR improves torrent deletion dialog. 1. Now shows different message depending on the number of selected torrents 2. Visually pretty much inline with the GUI 3. Adjusts to content on load 4. Now uses XHR load method. Panels / windows loaded using this method become part of the current document so there is no need to import styles or scripts (they should load marginally faster now). PR #21185. --------- Co-authored-by: Chocobo1 <Chocobo1@users.noreply.github.com>
This commit is contained in:
parent
9a9c375b9d
commit
39dd415d43
7 changed files with 249 additions and 142 deletions
|
@ -1,102 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="${LANG}">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]</title>
|
||||
<link rel="stylesheet" href="css/style.css?v=${CACHEID}" type="text/css">
|
||||
<script src="scripts/lib/MooTools-Core-1.6.0-compat-compressed.js"></script>
|
||||
<script src="scripts/lib/MooTools-More-1.6.0-compat-compressed.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
function setRememberBtnEnabled(enable) {
|
||||
const btn = $("rememberBtn");
|
||||
btn.disabled = !enable;
|
||||
|
||||
const icon = btn.getElementsByTagName("path")[0];
|
||||
if (enable)
|
||||
icon.style.removeProperty("fill");
|
||||
else
|
||||
icon.style.fill = "var(--color-border-default)";
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
new Request({
|
||||
url: "images/object-locked.svg",
|
||||
method: "get",
|
||||
onSuccess: function(text, xml) {
|
||||
const newIcon = xml.childNodes[0];
|
||||
newIcon.style.height = "24px";
|
||||
newIcon.style.width = "24px";
|
||||
$("rememberBtn").appendChild(newIcon);
|
||||
setRememberBtnEnabled(false);
|
||||
}
|
||||
}).send();
|
||||
|
||||
const isDeletingFiles = (new URI().getData("deleteFiles") === "true");
|
||||
$("deleteFromDiskCB").checked = isDeletingFiles;
|
||||
|
||||
const prefCache = window.parent.qBittorrent.Cache.preferences.get();
|
||||
let prefDeleteContentFiles = prefCache.delete_torrent_content_files;
|
||||
|
||||
$("deleteFromDiskCB").checked ||= prefDeleteContentFiles;
|
||||
$("deleteFromDiskCB").addEventListener("click", (e) => {
|
||||
setRememberBtnEnabled($("deleteFromDiskCB").checked !== prefDeleteContentFiles);
|
||||
});
|
||||
|
||||
// Set current "Delete files" choice as the default
|
||||
$("rememberBtn").addEventListener("click", (e) => {
|
||||
window.parent.qBittorrent.Cache.preferences.set({
|
||||
data: {
|
||||
"delete_torrent_content_files": $("deleteFromDiskCB").checked
|
||||
},
|
||||
onSuccess: function() {
|
||||
prefDeleteContentFiles = $("deleteFromDiskCB").checked;
|
||||
setRememberBtnEnabled(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const hashes = new URI().getData("hashes").split("|");
|
||||
$("cancelBtn").focus();
|
||||
$("cancelBtn").addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
window.parent.qBittorrent.Client.closeWindows();
|
||||
});
|
||||
$("confirmBtn").addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
parent.torrentsTable.deselectAll();
|
||||
const cmd = "api/v2/torrents/delete";
|
||||
const deleteFiles = $("deleteFromDiskCB").checked;
|
||||
new Request({
|
||||
url: cmd,
|
||||
method: "post",
|
||||
data: {
|
||||
"hashes": hashes.join("|"),
|
||||
"deleteFiles": deleteFiles
|
||||
},
|
||||
onComplete: function() {
|
||||
window.parent.qBittorrent.Client.closeWindows();
|
||||
}
|
||||
}).send();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<br>
|
||||
|
||||
<p> QBT_TR(Are you sure you want to remove the selected torrents from the transfer list?)QBT_TR[CONTEXT=HttpServer]</p>
|
||||
<button type="button" id="rememberBtn" title="QBT_TR(Remember choice)QBT_TR[CONTEXT=HttpServer]" aria-label="QBT_TR(Remember choice)QBT_TR[CONTEXT=HttpServer]" style="vertical-align: middle; padding: 4px 6px;"></button>
|
||||
<input type="checkbox" id="deleteFromDiskCB"> <label for="deleteFromDiskCB"><i>QBT_TR(Also remove the content files)QBT_TR[CONTEXT=confirmDeletionDlg]</i></label><br><br>
|
||||
<div style="text-align: right;">
|
||||
<input type="button" id="cancelBtn" value="QBT_TR(Cancel)QBT_TR[CONTEXT=MainWindow]"> <input type="button" id="confirmBtn" value="QBT_TR(Remove)QBT_TR[CONTEXT=MainWindow]">
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -720,3 +720,66 @@ td.statusBarSeparator {
|
|||
background-color: var(--color-background-hover);
|
||||
color: var(--color-text-white);
|
||||
}
|
||||
|
||||
/* Confirm deletion dialog */
|
||||
|
||||
#confirmDeletionPage * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#confirmDeletionPage_content {
|
||||
display: flex !important; /* override for default mocha inline style */
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#confirmDeletionPage_content > :last-child {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
#confirmDeletionDialog {
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
#rememberBtn {
|
||||
background: url("../images/object-locked.svg") center center / 24px
|
||||
no-repeat var(--color-background-popup);
|
||||
height: 38px;
|
||||
padding: 4px 6px;
|
||||
width: 38px;
|
||||
}
|
||||
|
||||
#rememberBtn.disabled {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
#deleteFromDiskCB {
|
||||
margin: 0 2px 0 0;
|
||||
vertical-align: -1px;
|
||||
}
|
||||
|
||||
#deleteTorrentMessage {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.confirmDeletionGrid {
|
||||
align-items: center;
|
||||
display: grid;
|
||||
gap: 3px 4px;
|
||||
grid-template-columns: max-content 1fr;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.deletionGridItem {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.deletionGridItem:first-child {
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.confirmDialogWarning {
|
||||
background: url("../images/dialog-warning.svg") center center no-repeat;
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ window.qBittorrent ??= {};
|
|||
window.qBittorrent.Client ??= (() => {
|
||||
const exports = () => {
|
||||
return {
|
||||
closeWindow: closeWindow,
|
||||
closeWindows: closeWindows,
|
||||
genHash: genHash,
|
||||
getSyncMainDataInterval: getSyncMainDataInterval,
|
||||
|
@ -44,6 +45,13 @@ window.qBittorrent.Client ??= (() => {
|
|||
};
|
||||
};
|
||||
|
||||
const closeWindow = function(windowID) {
|
||||
const window = document.getElementById(windowID);
|
||||
if (!window)
|
||||
return;
|
||||
MochaUI.closeWindow(window);
|
||||
};
|
||||
|
||||
const closeWindows = function() {
|
||||
MochaUI.closeAll();
|
||||
};
|
||||
|
|
|
@ -657,6 +657,10 @@ window.qBittorrent.DynamicTable ??= (() => {
|
|||
}
|
||||
},
|
||||
|
||||
getRow: function(rowId) {
|
||||
return this.rows.get(rowId);
|
||||
},
|
||||
|
||||
getFilteredAndSortedRows: function() {
|
||||
const filteredRows = [];
|
||||
|
||||
|
|
|
@ -393,23 +393,35 @@ const initializeWindows = function() {
|
|||
}
|
||||
};
|
||||
|
||||
deleteFN = function(deleteFiles = false) {
|
||||
deleteFN = function(forceDeleteFiles = false) {
|
||||
const hashes = torrentsTable.selectedRowsIds();
|
||||
if (hashes.length) {
|
||||
if (hashes.length > 0) {
|
||||
window.qBittorrent.Client.closeWindow("confirmDeletionPage");
|
||||
|
||||
new MochaUI.Window({
|
||||
id: "confirmDeletionPage",
|
||||
icon: "images/qbittorrent-tray.svg",
|
||||
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
|
||||
loadMethod: "iframe",
|
||||
contentURL: new URI("confirmdeletion.html").setData("hashes", hashes.join("|")).setData("deleteFiles", deleteFiles).toString(),
|
||||
scrollbars: false,
|
||||
resizable: true,
|
||||
data: {
|
||||
hashes: hashes,
|
||||
forceDeleteFiles: forceDeleteFiles
|
||||
},
|
||||
loadMethod: "xhr",
|
||||
contentURL: "views/confirmdeletion.html",
|
||||
maximizable: false,
|
||||
padding: 10,
|
||||
width: 424,
|
||||
height: 160
|
||||
collapsible: false,
|
||||
padding: {
|
||||
left: 5,
|
||||
right: 10,
|
||||
top: 15,
|
||||
bottom: 15
|
||||
},
|
||||
width: 480,
|
||||
onContentLoaded: function(w) {
|
||||
MochaUI.resizeWindow(w, { centered: true });
|
||||
MochaUI.centerWindow(w);
|
||||
}
|
||||
});
|
||||
updateMainData();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -732,21 +744,30 @@ const initializeWindows = function() {
|
|||
|
||||
deleteTorrentsByCategoryFN = function(categoryHash) {
|
||||
const hashes = torrentsTable.getFilteredTorrentsHashes("all", categoryHash, TAGS_ALL, TRACKERS_ALL);
|
||||
if (hashes.length) {
|
||||
if (hashes.length > 0) {
|
||||
window.qBittorrent.Client.closeWindow("confirmDeletionPage");
|
||||
|
||||
new MochaUI.Window({
|
||||
id: "confirmDeletionPage",
|
||||
icon: "images/qbittorrent-tray.svg",
|
||||
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
|
||||
loadMethod: "iframe",
|
||||
contentURL: new URI("confirmdeletion.html").setData("hashes", hashes.join("|")).toString(),
|
||||
scrollbars: false,
|
||||
resizable: true,
|
||||
data: { hashes: hashes },
|
||||
loadMethod: "xhr",
|
||||
contentURL: "views/confirmdeletion.html",
|
||||
maximizable: false,
|
||||
padding: 10,
|
||||
width: 424,
|
||||
height: 160
|
||||
collapsible: false,
|
||||
padding: {
|
||||
left: 5,
|
||||
right: 10,
|
||||
top: 15,
|
||||
bottom: 15
|
||||
},
|
||||
width: 480,
|
||||
onContentLoaded: function(w) {
|
||||
MochaUI.resizeWindow(w, { centered: true });
|
||||
MochaUI.centerWindow(w);
|
||||
}
|
||||
});
|
||||
updateMainData();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -877,21 +898,30 @@ const initializeWindows = function() {
|
|||
|
||||
deleteTorrentsByTagFN = function(tagHash) {
|
||||
const hashes = torrentsTable.getFilteredTorrentsHashes("all", CATEGORIES_ALL, tagHash, TRACKERS_ALL);
|
||||
if (hashes.length) {
|
||||
if (hashes.length > 0) {
|
||||
window.qBittorrent.Client.closeWindow("confirmDeletionPage");
|
||||
|
||||
new MochaUI.Window({
|
||||
id: "confirmDeletionPage",
|
||||
icon: "images/qbittorrent-tray.svg",
|
||||
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
|
||||
loadMethod: "iframe",
|
||||
contentURL: new URI("confirmdeletion.html").setData("hashes", hashes.join("|")).toString(),
|
||||
scrollbars: false,
|
||||
resizable: true,
|
||||
data: { hashes: hashes },
|
||||
loadMethod: "xhr",
|
||||
contentURL: "views/confirmdeletion.html",
|
||||
maximizable: false,
|
||||
padding: 10,
|
||||
width: 424,
|
||||
height: 160
|
||||
collapsible: false,
|
||||
padding: {
|
||||
left: 5,
|
||||
right: 10,
|
||||
top: 15,
|
||||
bottom: 15
|
||||
},
|
||||
width: 480,
|
||||
onContentLoaded: function(w) {
|
||||
MochaUI.resizeWindow(w, { centered: true });
|
||||
MochaUI.centerWindow(w);
|
||||
}
|
||||
});
|
||||
updateMainData();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -982,22 +1012,31 @@ const initializeWindows = function() {
|
|||
}
|
||||
}
|
||||
|
||||
if (hashes.length) {
|
||||
if (hashes.length > 0) {
|
||||
window.qBittorrent.Client.closeWindow("confirmDeletionPage");
|
||||
|
||||
new MochaUI.Window({
|
||||
id: "confirmDeletionPage",
|
||||
icon: "images/qbittorrent-tray.svg",
|
||||
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
|
||||
loadMethod: "iframe",
|
||||
contentURL: new URI("confirmdeletion.html").setData("hashes", hashes.join("|")).toString(),
|
||||
scrollbars: false,
|
||||
resizable: true,
|
||||
data: {
|
||||
hashes: hashes,
|
||||
filterList: "tracker"
|
||||
},
|
||||
loadMethod: "xhr",
|
||||
contentURL: "views/confirmdeletion.html",
|
||||
maximizable: false,
|
||||
padding: 10,
|
||||
width: 424,
|
||||
height: 160,
|
||||
onCloseComplete: function() {
|
||||
updateMainData();
|
||||
setTrackerFilter(TRACKERS_ALL);
|
||||
collapsible: false,
|
||||
padding: {
|
||||
left: 5,
|
||||
right: 10,
|
||||
top: 15,
|
||||
bottom: 15
|
||||
},
|
||||
width: 480,
|
||||
onContentLoaded: function(w) {
|
||||
MochaUI.resizeWindow(w, { centered: true });
|
||||
MochaUI.centerWindow(w);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
95
src/webui/www/private/views/confirmdeletion.html
Normal file
95
src/webui/www/private/views/confirmdeletion.html
Normal file
|
@ -0,0 +1,95 @@
|
|||
<div id="confirmDeletionDialog">
|
||||
<div class="confirmDeletionGrid">
|
||||
<span class="deletionGridItem confirmDialogWarning"></span>
|
||||
<span class="deletionGridItem" id="deleteTorrentMessage"></span>
|
||||
<span class="deletionGridItem">
|
||||
<button class="disabled" type="button" id="rememberBtn" title="QBT_TR(Remember choice)QBT_TR[CONTEXT=HttpServer]" aria-label="QBT_TR(Remember choice)QBT_TR[CONTEXT=HttpServer]" disabled></button>
|
||||
</span>
|
||||
<span class="deletionGridItem">
|
||||
<input type="checkbox" id="deleteFromDiskCB">
|
||||
<label for="deleteFromDiskCB">
|
||||
<em>QBT_TR(Also remove the content files)QBT_TR[CONTEXT=confirmDeletionDlg]</em>
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<input type="button" value="QBT_TR(Remove)QBT_TR[CONTEXT=MainWindow]" id="confirmDeletionButton">
|
||||
<input type="button" value="QBT_TR(Cancel)QBT_TR[CONTEXT=MainWindow]" id="cancelDeletionButton">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
(() => {
|
||||
const setRememberBtnEnabled = (enable) => {
|
||||
rememberButton.disabled = !enable;
|
||||
rememberButton.classList.toggle("disabled", !enable);
|
||||
};
|
||||
|
||||
const confirmButton = document.getElementById("confirmDeletionButton");
|
||||
const cancelButton = document.getElementById("cancelDeletionButton");
|
||||
const rememberButton = document.getElementById("rememberBtn");
|
||||
const deleteCB = document.getElementById("deleteFromDiskCB");
|
||||
const deletionText = document.getElementById("deleteTorrentMessage");
|
||||
|
||||
const {
|
||||
hashes,
|
||||
forceDeleteFiles = false,
|
||||
filterList = null
|
||||
} = window.MUI.Windows.instances["confirmDeletionPage"].options.data;
|
||||
let prefDeleteContentFiles = window.qBittorrent.Cache.preferences.get().delete_torrent_content_files;
|
||||
deleteCB.checked = forceDeleteFiles || prefDeleteContentFiles;
|
||||
|
||||
let deleteMessage;
|
||||
if (hashes.length === 1) {
|
||||
const { full_data: { name } } = torrentsTable.getRow(hashes[0]);
|
||||
deleteMessage = "QBT_TR(Are you sure you want to remove %1 from the transfer list?)QBT_TR[CONTEXT=HttpServer]".replace("%1", `"${name}"`);
|
||||
}
|
||||
else {
|
||||
deleteMessage = "QBT_TR(Are you sure you want to remove these %1 torrents from the transfer list?)QBT_TR[CONTEXT=HttpServer]".replace("%1", hashes.length);
|
||||
}
|
||||
|
||||
deletionText.textContent = deleteMessage;
|
||||
|
||||
// Enable "Remember" button if the current choice is different from the saved preference
|
||||
deleteCB.addEventListener("click", (e) => { setRememberBtnEnabled(deleteCB.checked !== prefDeleteContentFiles); });
|
||||
|
||||
// Set current "Delete files" choice as the default
|
||||
rememberButton.addEventListener("click", (e) => {
|
||||
window.qBittorrent.Cache.preferences.set({
|
||||
data: {
|
||||
"delete_torrent_content_files": deleteCB.checked
|
||||
},
|
||||
onSuccess: function() {
|
||||
prefDeleteContentFiles = deleteCB.checked;
|
||||
setRememberBtnEnabled(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
cancelButton.focus();
|
||||
cancelButton.addEventListener("click", (e) => { window.qBittorrent.Client.closeWindows(); });
|
||||
|
||||
confirmButton.addEventListener("click", (e) => {
|
||||
torrentsTable.deselectAll();
|
||||
new Request({
|
||||
url: "api/v2/torrents/delete",
|
||||
method: "post",
|
||||
data: {
|
||||
"hashes": hashes.join("|"),
|
||||
"deleteFiles": deleteCB.checked
|
||||
},
|
||||
onSuccess: function() {
|
||||
if (filterList === "tracker")
|
||||
setTrackerFilter(TRACKERS_ALL);
|
||||
updateMainData();
|
||||
window.qBittorrent.Client.closeWindows();
|
||||
},
|
||||
onFailure: function() {
|
||||
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
|
||||
},
|
||||
}).send();
|
||||
});
|
||||
})();
|
||||
</script>
|
|
@ -2,7 +2,6 @@
|
|||
<qresource prefix="/www">
|
||||
<file>private/addpeers.html</file>
|
||||
<file>private/addtrackers.html</file>
|
||||
<file>private/confirmdeletion.html</file>
|
||||
<file>private/confirmfeeddeletion.html</file>
|
||||
<file>private/confirmruleclear.html</file>
|
||||
<file>private/confirmruledeletion.html</file>
|
||||
|
@ -418,6 +417,7 @@
|
|||
<file>private/uploadlimit.html</file>
|
||||
<file>private/views/about.html</file>
|
||||
<file>private/views/aboutToolbar.html</file>
|
||||
<file>private/views/confirmdeletion.html</file>
|
||||
<file>private/views/filters.html</file>
|
||||
<file>private/views/installsearchplugin.html</file>
|
||||
<file>private/views/log.html</file>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue