Skip to content

Commit

Permalink
WebUI: Improve torrent deletion
Browse files Browse the repository at this point in the history
* Added 'Confirm when deleting torrents' option to the WebUI
* Confirm deletion dialog now uses MUI.Modal

PR #21289.
Closes #18345.
  • Loading branch information
skomerko authored Sep 13, 2024
1 parent a0c3211 commit 0ea35c5
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 99 deletions.
5 changes: 5 additions & 0 deletions src/webui/api/appcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ void AppController::preferencesAction()
// Language
data[u"locale"_s] = pref->getLocale();
data[u"performance_warning"_s] = session->isPerformanceWarningEnabled();
// Transfer List
data[u"confirm_torrent_deletion"_s] = pref->confirmTorrentDeletion();
// Log file
data[u"file_log_enabled"_s] = app()->isFileLoggerEnabled();
data[u"file_log_path"_s] = app()->fileLoggerPath().toString();
Expand Down Expand Up @@ -504,6 +506,9 @@ void AppController::setPreferencesAction()
}
if (hasKey(u"performance_warning"_s))
session->setPerformanceWarningEnabled(it.value().toBool());
// Transfer List
if (hasKey(u"confirm_torrent_deletion"_s))
pref->setConfirmTorrentDeletion(it.value().toBool());
// Log file
if (hasKey(u"file_log_enabled"_s))
app()->setFileLoggerEnabled(it.value().toBool());
Expand Down
2 changes: 1 addition & 1 deletion src/webui/www/private/css/Window.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ div.mochaToolbarWrapper.bottom {
---------------------------------------------------------------- */

#modalOverlay {
background: #000;
background: hsla(0deg 0 0 / 30%);
display: none;
left: 0;
opacity: 0;
Expand Down
288 changes: 190 additions & 98 deletions src/webui/www/private/scripts/mocha-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,53 @@
----------------------------------------------------------------- */
"use strict";

window.qBittorrent ??= {};
window.qBittorrent.Dialog ??= (() => {
const exports = () => {
return {
baseModalOptions: baseModalOptions
};
};

const deepFreeze = (obj) => {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#examples

const keys = Reflect.ownKeys(obj);
for (const key of keys) {
const value = obj[key];
if ((value && (typeof value === "object")) || (typeof value === "function"))
deepFreeze(value);
}
Object.freeze(obj);
};

const baseModalOptions = Object.assign(Object.create(null), {
addClass: "modalDialog",
collapsible: false,
cornerRadius: 5,
draggable: true,
footerHeight: 20,
icon: "images/qbittorrent-tray.svg",
loadMethod: "xhr",
maximizable: false,
method: "post",
minimizable: false,
padding: {
top: 15,
right: 10,
bottom: 15,
left: 5
},
resizable: true,
width: 480
});

deepFreeze(baseModalOptions);

return exports();
})();
Object.freeze(window.qBittorrent.Dialog);

const LocalPreferences = new window.qBittorrent.LocalPreferences.LocalPreferencesClass();

let saveWindowSize = function() {};
Expand Down Expand Up @@ -396,32 +443,43 @@ const initializeWindows = function() {
deleteFN = function(forceDeleteFiles = false) {
const hashes = torrentsTable.selectedRowsIds();
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]",
data: {
hashes: hashes,
forceDeleteFiles: forceDeleteFiles
},
loadMethod: "xhr",
contentURL: "views/confirmdeletion.html",
maximizable: false,
collapsible: false,
padding: {
left: 5,
right: 10,
top: 15,
bottom: 15
},
width: 480,
onContentLoaded: function(w) {
MochaUI.resizeWindow(w, { centered: true });
MochaUI.centerWindow(w);
}
});
if (window.qBittorrent.Cache.preferences.get().confirm_torrent_deletion) {
new MochaUI.Modal({
...window.qBittorrent.Dialog.baseModalOptions,
id: "confirmDeletionPage",
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
data: {
hashes: hashes,
forceDeleteFiles: forceDeleteFiles
},
contentURL: "views/confirmdeletion.html",
onContentLoaded: function(w) {
MochaUI.resizeWindow(w, { centered: true });
MochaUI.centerWindow(w);
},
onCloseComplete: function() {
// make sure overlay is properly hidden upon modal closing
document.getElementById("modalOverlay").style.display = "none";
}
});
}
else {
new Request({
url: "api/v2/torrents/delete",
method: "post",
data: {
hashes: hashes.join("|"),
deleteFiles: forceDeleteFiles
},
onSuccess: function() {
torrentsTable.deselectAll();
updateMainData();
},
onFailure: function() {
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
}
}
};

Expand Down Expand Up @@ -745,29 +803,40 @@ const initializeWindows = function() {
deleteTorrentsByCategoryFN = function(categoryHash) {
const hashes = torrentsTable.getFilteredTorrentsHashes("all", categoryHash, TAGS_ALL, TRACKERS_ALL);
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]",
data: { hashes: hashes },
loadMethod: "xhr",
contentURL: "views/confirmdeletion.html",
maximizable: false,
collapsible: false,
padding: {
left: 5,
right: 10,
top: 15,
bottom: 15
},
width: 480,
onContentLoaded: function(w) {
MochaUI.resizeWindow(w, { centered: true });
MochaUI.centerWindow(w);
}
});
if (window.qBittorrent.Cache.preferences.get().confirm_torrent_deletion) {
new MochaUI.Modal({
...window.qBittorrent.Dialog.baseModalOptions,
id: "confirmDeletionPage",
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
data: { hashes: hashes },
contentURL: "views/confirmdeletion.html",
onContentLoaded: function(w) {
MochaUI.resizeWindow(w, { centered: true });
MochaUI.centerWindow(w);
},
onCloseComplete: function() {
// make sure overlay is properly hidden upon modal closing
document.getElementById("modalOverlay").style.display = "none";
}
});
}
else {
new Request({
url: "api/v2/torrents/delete",
method: "post",
data: {
hashes: hashes.join("|"),
deleteFiles: false,
},
onSuccess: function() {
torrentsTable.deselectAll();
updateMainData();
},
onFailure: function() {
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
}
}
};

Expand Down Expand Up @@ -899,29 +968,40 @@ const initializeWindows = function() {
deleteTorrentsByTagFN = function(tagHash) {
const hashes = torrentsTable.getFilteredTorrentsHashes("all", CATEGORIES_ALL, tagHash, TRACKERS_ALL);
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]",
data: { hashes: hashes },
loadMethod: "xhr",
contentURL: "views/confirmdeletion.html",
maximizable: false,
collapsible: false,
padding: {
left: 5,
right: 10,
top: 15,
bottom: 15
},
width: 480,
onContentLoaded: function(w) {
MochaUI.resizeWindow(w, { centered: true });
MochaUI.centerWindow(w);
}
});
if (window.qBittorrent.Cache.preferences.get().confirm_torrent_deletion) {
new MochaUI.Modal({
...window.qBittorrent.Dialog.baseModalOptions,
id: "confirmDeletionPage",
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
data: { hashes: hashes },
contentURL: "views/confirmdeletion.html",
onContentLoaded: function(w) {
MochaUI.resizeWindow(w, { centered: true });
MochaUI.centerWindow(w);
},
onCloseComplete: function() {
// make sure overlay is properly hidden upon modal closing
document.getElementById("modalOverlay").style.display = "none";
}
});
}
else {
new Request({
url: "api/v2/torrents/delete",
method: "post",
data: {
hashes: hashes.join("|"),
deleteFiles: false,
},
onSuccess: function() {
torrentsTable.deselectAll();
updateMainData();
},
onFailure: function() {
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
}
}
};

Expand Down Expand Up @@ -1013,32 +1093,44 @@ const initializeWindows = function() {
}

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]",
data: {
hashes: hashes,
filterList: "tracker"
},
loadMethod: "xhr",
contentURL: "views/confirmdeletion.html",
maximizable: false,
collapsible: false,
padding: {
left: 5,
right: 10,
top: 15,
bottom: 15
},
width: 480,
onContentLoaded: function(w) {
MochaUI.resizeWindow(w, { centered: true });
MochaUI.centerWindow(w);
}
});
if (window.qBittorrent.Cache.preferences.get().confirm_torrent_deletion) {
new MochaUI.Modal({
...window.qBittorrent.Dialog.baseModalOptions,
id: "confirmDeletionPage",
title: "QBT_TR(Remove torrent(s))QBT_TR[CONTEXT=confirmDeletionDlg]",
data: {
hashes: hashes,
filterList: "tracker"
},
contentURL: "views/confirmdeletion.html",
onContentLoaded: function(w) {
MochaUI.resizeWindow(w, { centered: true });
MochaUI.centerWindow(w);
},
onCloseComplete: function() {
// make sure overlay is properly hidden upon modal closing
document.getElementById("modalOverlay").style.display = "none";
}
});
}
else {
new Request({
url: "api/v2/torrents/delete",
method: "post",
data: {
hashes: hashes.join("|"),
deleteFiles: false,
},
onSuccess: function() {
torrentsTable.deselectAll();
setTrackerFilter(TRACKERS_ALL);
updateMainData();
},
onFailure: function() {
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
},
}).send();
}
}
};

Expand Down
6 changes: 6 additions & 0 deletions src/webui/www/private/views/preferences.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

<fieldset class="settings">
<legend>QBT_TR(Transfer list)QBT_TR[CONTEXT=OptionsDialog]</legend>
<div class="formRow" style="margin-bottom: 3px;" title="QBT_TR(Shows a confirmation dialog upon torrent deletion)QBT_TR[CONTEXT=OptionsDialog]">
<input type="checkbox" id="confirmTorrentDeletion">
<label for="confirmTorrentDeletion">QBT_TR(Confirm when deleting torrents)QBT_TR[CONTEXT=OptionsDialog]</label>
</div>
<div class="formRow" style="margin-bottom: 3px;">
<input type="checkbox" id="useAltRowColorsInput">
<label for="useAltRowColorsInput">QBT_TR(Use alternating row colors)QBT_TR[CONTEXT=OptionsDialog]</label>
Expand Down Expand Up @@ -2107,6 +2111,7 @@
document.getElementById("hideZeroFiltersCheckbox").checked = (LocalPreferences.get("hide_zero_status_filters", "false") === "true");
$("dblclickDownloadSelect").value = LocalPreferences.get("dblclick_download", "1");
$("dblclickCompleteSelect").value = LocalPreferences.get("dblclick_complete", "1");
document.getElementById("confirmTorrentDeletion").checked = pref.confirm_torrent_deletion;
document.getElementById("useAltRowColorsInput").checked = (LocalPreferences.get("use_alt_row_colors", "true") === "true");
$("filelog_checkbox").checked = pref.file_log_enabled;
$("filelog_save_path_input").value = pref.file_log_path;
Expand Down Expand Up @@ -2522,6 +2527,7 @@
LocalPreferences.set("hide_zero_status_filters", document.getElementById("hideZeroFiltersCheckbox").checked.toString());
LocalPreferences.set("dblclick_download", $("dblclickDownloadSelect").value);
LocalPreferences.set("dblclick_complete", $("dblclickCompleteSelect").value);
settings["confirm_torrent_deletion"] = document.getElementById("confirmTorrentDeletion").checked;
LocalPreferences.set("use_alt_row_colors", document.getElementById("useAltRowColorsInput").checked.toString());
settings["file_log_enabled"] = $("filelog_checkbox").checked;
settings["file_log_path"] = $("filelog_save_path_input").value;
Expand Down

0 comments on commit 0ea35c5

Please sign in to comment.