Skip to content

Commit 0ea35c5

Browse files
authored
WebUI: Improve torrent deletion
* Added 'Confirm when deleting torrents' option to the WebUI * Confirm deletion dialog now uses MUI.Modal PR #21289. Closes #18345.
1 parent a0c3211 commit 0ea35c5

File tree

4 files changed

+202
-99
lines changed

4 files changed

+202
-99
lines changed

src/webui/api/appcontroller.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ void AppController::preferencesAction()
127127
// Language
128128
data[u"locale"_s] = pref->getLocale();
129129
data[u"performance_warning"_s] = session->isPerformanceWarningEnabled();
130+
// Transfer List
131+
data[u"confirm_torrent_deletion"_s] = pref->confirmTorrentDeletion();
130132
// Log file
131133
data[u"file_log_enabled"_s] = app()->isFileLoggerEnabled();
132134
data[u"file_log_path"_s] = app()->fileLoggerPath().toString();
@@ -504,6 +506,9 @@ void AppController::setPreferencesAction()
504506
}
505507
if (hasKey(u"performance_warning"_s))
506508
session->setPerformanceWarningEnabled(it.value().toBool());
509+
// Transfer List
510+
if (hasKey(u"confirm_torrent_deletion"_s))
511+
pref->setConfirmTorrentDeletion(it.value().toBool());
507512
// Log file
508513
if (hasKey(u"file_log_enabled"_s))
509514
app()->setFileLoggerEnabled(it.value().toBool());

src/webui/www/private/css/Window.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ div.mochaToolbarWrapper.bottom {
205205
---------------------------------------------------------------- */
206206

207207
#modalOverlay {
208-
background: #000;
208+
background: hsla(0deg 0 0 / 30%);
209209
display: none;
210210
left: 0;
211211
opacity: 0;

src/webui/www/private/scripts/mocha-init.js

Lines changed: 190 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,53 @@
3838
----------------------------------------------------------------- */
3939
"use strict";
4040

41+
window.qBittorrent ??= {};
42+
window.qBittorrent.Dialog ??= (() => {
43+
const exports = () => {
44+
return {
45+
baseModalOptions: baseModalOptions
46+
};
47+
};
48+
49+
const deepFreeze = (obj) => {
50+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#examples
51+
52+
const keys = Reflect.ownKeys(obj);
53+
for (const key of keys) {
54+
const value = obj[key];
55+
if ((value && (typeof value === "object")) || (typeof value === "function"))
56+
deepFreeze(value);
57+
}
58+
Object.freeze(obj);
59+
};
60+
61+
const baseModalOptions = Object.assign(Object.create(null), {
62+
addClass: "modalDialog",
63+
collapsible: false,
64+
cornerRadius: 5,
65+
draggable: true,
66+
footerHeight: 20,
67+
icon: "images/qbittorrent-tray.svg",
68+
loadMethod: "xhr",
69+
maximizable: false,
70+
method: "post",
71+
minimizable: false,
72+
padding: {
73+
top: 15,
74+
right: 10,
75+
bottom: 15,
76+
left: 5
77+
},
78+
resizable: true,
79+
width: 480
80+
});
81+
82+
deepFreeze(baseModalOptions);
83+
84+
return exports();
85+
})();
86+
Object.freeze(window.qBittorrent.Dialog);
87+
4188
const LocalPreferences = new window.qBittorrent.LocalPreferences.LocalPreferencesClass();
4289

4390
let saveWindowSize = function() {};
@@ -396,32 +443,43 @@ const initializeWindows = function() {
396443
deleteFN = function(forceDeleteFiles = false) {
397444
const hashes = torrentsTable.selectedRowsIds();
398445
if (hashes.length > 0) {
399-
window.qBittorrent.Client.closeWindow("confirmDeletionPage");
400-
401-
new MochaUI.Window({
402-
id: "confirmDeletionPage",
403-
icon: "images/qbittorrent-tray.svg",
404-
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
405-
data: {
406-
hashes: hashes,
407-
forceDeleteFiles: forceDeleteFiles
408-
},
409-
loadMethod: "xhr",
410-
contentURL: "views/confirmdeletion.html",
411-
maximizable: false,
412-
collapsible: false,
413-
padding: {
414-
left: 5,
415-
right: 10,
416-
top: 15,
417-
bottom: 15
418-
},
419-
width: 480,
420-
onContentLoaded: function(w) {
421-
MochaUI.resizeWindow(w, { centered: true });
422-
MochaUI.centerWindow(w);
423-
}
424-
});
446+
if (window.qBittorrent.Cache.preferences.get().confirm_torrent_deletion) {
447+
new MochaUI.Modal({
448+
...window.qBittorrent.Dialog.baseModalOptions,
449+
id: "confirmDeletionPage",
450+
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
451+
data: {
452+
hashes: hashes,
453+
forceDeleteFiles: forceDeleteFiles
454+
},
455+
contentURL: "views/confirmdeletion.html",
456+
onContentLoaded: function(w) {
457+
MochaUI.resizeWindow(w, { centered: true });
458+
MochaUI.centerWindow(w);
459+
},
460+
onCloseComplete: function() {
461+
// make sure overlay is properly hidden upon modal closing
462+
document.getElementById("modalOverlay").style.display = "none";
463+
}
464+
});
465+
}
466+
else {
467+
new Request({
468+
url: "api/v2/torrents/delete",
469+
method: "post",
470+
data: {
471+
hashes: hashes.join("|"),
472+
deleteFiles: forceDeleteFiles
473+
},
474+
onSuccess: function() {
475+
torrentsTable.deselectAll();
476+
updateMainData();
477+
},
478+
onFailure: function() {
479+
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
480+
}
481+
}).send();
482+
}
425483
}
426484
};
427485

@@ -745,29 +803,40 @@ const initializeWindows = function() {
745803
deleteTorrentsByCategoryFN = function(categoryHash) {
746804
const hashes = torrentsTable.getFilteredTorrentsHashes("all", categoryHash, TAGS_ALL, TRACKERS_ALL);
747805
if (hashes.length > 0) {
748-
window.qBittorrent.Client.closeWindow("confirmDeletionPage");
749-
750-
new MochaUI.Window({
751-
id: "confirmDeletionPage",
752-
icon: "images/qbittorrent-tray.svg",
753-
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
754-
data: { hashes: hashes },
755-
loadMethod: "xhr",
756-
contentURL: "views/confirmdeletion.html",
757-
maximizable: false,
758-
collapsible: false,
759-
padding: {
760-
left: 5,
761-
right: 10,
762-
top: 15,
763-
bottom: 15
764-
},
765-
width: 480,
766-
onContentLoaded: function(w) {
767-
MochaUI.resizeWindow(w, { centered: true });
768-
MochaUI.centerWindow(w);
769-
}
770-
});
806+
if (window.qBittorrent.Cache.preferences.get().confirm_torrent_deletion) {
807+
new MochaUI.Modal({
808+
...window.qBittorrent.Dialog.baseModalOptions,
809+
id: "confirmDeletionPage",
810+
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
811+
data: { hashes: hashes },
812+
contentURL: "views/confirmdeletion.html",
813+
onContentLoaded: function(w) {
814+
MochaUI.resizeWindow(w, { centered: true });
815+
MochaUI.centerWindow(w);
816+
},
817+
onCloseComplete: function() {
818+
// make sure overlay is properly hidden upon modal closing
819+
document.getElementById("modalOverlay").style.display = "none";
820+
}
821+
});
822+
}
823+
else {
824+
new Request({
825+
url: "api/v2/torrents/delete",
826+
method: "post",
827+
data: {
828+
hashes: hashes.join("|"),
829+
deleteFiles: false,
830+
},
831+
onSuccess: function() {
832+
torrentsTable.deselectAll();
833+
updateMainData();
834+
},
835+
onFailure: function() {
836+
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
837+
}
838+
}).send();
839+
}
771840
}
772841
};
773842

@@ -899,29 +968,40 @@ const initializeWindows = function() {
899968
deleteTorrentsByTagFN = function(tagHash) {
900969
const hashes = torrentsTable.getFilteredTorrentsHashes("all", CATEGORIES_ALL, tagHash, TRACKERS_ALL);
901970
if (hashes.length > 0) {
902-
window.qBittorrent.Client.closeWindow("confirmDeletionPage");
903-
904-
new MochaUI.Window({
905-
id: "confirmDeletionPage",
906-
icon: "images/qbittorrent-tray.svg",
907-
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
908-
data: { hashes: hashes },
909-
loadMethod: "xhr",
910-
contentURL: "views/confirmdeletion.html",
911-
maximizable: false,
912-
collapsible: false,
913-
padding: {
914-
left: 5,
915-
right: 10,
916-
top: 15,
917-
bottom: 15
918-
},
919-
width: 480,
920-
onContentLoaded: function(w) {
921-
MochaUI.resizeWindow(w, { centered: true });
922-
MochaUI.centerWindow(w);
923-
}
924-
});
971+
if (window.qBittorrent.Cache.preferences.get().confirm_torrent_deletion) {
972+
new MochaUI.Modal({
973+
...window.qBittorrent.Dialog.baseModalOptions,
974+
id: "confirmDeletionPage",
975+
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
976+
data: { hashes: hashes },
977+
contentURL: "views/confirmdeletion.html",
978+
onContentLoaded: function(w) {
979+
MochaUI.resizeWindow(w, { centered: true });
980+
MochaUI.centerWindow(w);
981+
},
982+
onCloseComplete: function() {
983+
// make sure overlay is properly hidden upon modal closing
984+
document.getElementById("modalOverlay").style.display = "none";
985+
}
986+
});
987+
}
988+
else {
989+
new Request({
990+
url: "api/v2/torrents/delete",
991+
method: "post",
992+
data: {
993+
hashes: hashes.join("|"),
994+
deleteFiles: false,
995+
},
996+
onSuccess: function() {
997+
torrentsTable.deselectAll();
998+
updateMainData();
999+
},
1000+
onFailure: function() {
1001+
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
1002+
}
1003+
}).send();
1004+
}
9251005
}
9261006
};
9271007

@@ -1013,32 +1093,44 @@ const initializeWindows = function() {
10131093
}
10141094

10151095
if (hashes.length > 0) {
1016-
window.qBittorrent.Client.closeWindow("confirmDeletionPage");
1017-
1018-
new MochaUI.Window({
1019-
id: "confirmDeletionPage",
1020-
icon: "images/qbittorrent-tray.svg",
1021-
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
1022-
data: {
1023-
hashes: hashes,
1024-
filterList: "tracker"
1025-
},
1026-
loadMethod: "xhr",
1027-
contentURL: "views/confirmdeletion.html",
1028-
maximizable: false,
1029-
collapsible: false,
1030-
padding: {
1031-
left: 5,
1032-
right: 10,
1033-
top: 15,
1034-
bottom: 15
1035-
},
1036-
width: 480,
1037-
onContentLoaded: function(w) {
1038-
MochaUI.resizeWindow(w, { centered: true });
1039-
MochaUI.centerWindow(w);
1040-
}
1041-
});
1096+
if (window.qBittorrent.Cache.preferences.get().confirm_torrent_deletion) {
1097+
new MochaUI.Modal({
1098+
...window.qBittorrent.Dialog.baseModalOptions,
1099+
id: "confirmDeletionPage",
1100+
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
1101+
data: {
1102+
hashes: hashes,
1103+
filterList: "tracker"
1104+
},
1105+
contentURL: "views/confirmdeletion.html",
1106+
onContentLoaded: function(w) {
1107+
MochaUI.resizeWindow(w, { centered: true });
1108+
MochaUI.centerWindow(w);
1109+
},
1110+
onCloseComplete: function() {
1111+
// make sure overlay is properly hidden upon modal closing
1112+
document.getElementById("modalOverlay").style.display = "none";
1113+
}
1114+
});
1115+
}
1116+
else {
1117+
new Request({
1118+
url: "api/v2/torrents/delete",
1119+
method: "post",
1120+
data: {
1121+
hashes: hashes.join("|"),
1122+
deleteFiles: false,
1123+
},
1124+
onSuccess: function() {
1125+
torrentsTable.deselectAll();
1126+
setTrackerFilter(TRACKERS_ALL);
1127+
updateMainData();
1128+
},
1129+
onFailure: function() {
1130+
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
1131+
},
1132+
}).send();
1133+
}
10421134
}
10431135
};
10441136

src/webui/www/private/views/preferences.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
<fieldset class="settings">
1111
<legend>QBT_TR(Transfer list)QBT_TR[CONTEXT=OptionsDialog]</legend>
12+
<div class="formRow" style="margin-bottom: 3px;" title="QBT_TR(Shows a confirmation dialog upon torrent deletion)QBT_TR[CONTEXT=OptionsDialog]">
13+
<input type="checkbox" id="confirmTorrentDeletion">
14+
<label for="confirmTorrentDeletion">QBT_TR(Confirm when deleting torrents)QBT_TR[CONTEXT=OptionsDialog]</label>
15+
</div>
1216
<div class="formRow" style="margin-bottom: 3px;">
1317
<input type="checkbox" id="useAltRowColorsInput">
1418
<label for="useAltRowColorsInput">QBT_TR(Use alternating row colors)QBT_TR[CONTEXT=OptionsDialog]</label>
@@ -2107,6 +2111,7 @@
21072111
document.getElementById("hideZeroFiltersCheckbox").checked = (LocalPreferences.get("hide_zero_status_filters", "false") === "true");
21082112
$("dblclickDownloadSelect").value = LocalPreferences.get("dblclick_download", "1");
21092113
$("dblclickCompleteSelect").value = LocalPreferences.get("dblclick_complete", "1");
2114+
document.getElementById("confirmTorrentDeletion").checked = pref.confirm_torrent_deletion;
21102115
document.getElementById("useAltRowColorsInput").checked = (LocalPreferences.get("use_alt_row_colors", "true") === "true");
21112116
$("filelog_checkbox").checked = pref.file_log_enabled;
21122117
$("filelog_save_path_input").value = pref.file_log_path;
@@ -2522,6 +2527,7 @@
25222527
LocalPreferences.set("hide_zero_status_filters", document.getElementById("hideZeroFiltersCheckbox").checked.toString());
25232528
LocalPreferences.set("dblclick_download", $("dblclickDownloadSelect").value);
25242529
LocalPreferences.set("dblclick_complete", $("dblclickCompleteSelect").value);
2530+
settings["confirm_torrent_deletion"] = document.getElementById("confirmTorrentDeletion").checked;
25252531
LocalPreferences.set("use_alt_row_colors", document.getElementById("useAltRowColorsInput").checked.toString());
25262532
settings["file_log_enabled"] = $("filelog_checkbox").checked;
25272533
settings["file_log_path"] = $("filelog_save_path_input").value;

0 commit comments

Comments
 (0)