From 0c80386810eca0b496d92066b013364498fbb3cb Mon Sep 17 00:00:00 2001 From: skomerko <168652295+skomerko@users.noreply.github.com> Date: Mon, 16 Sep 2024 17:14:49 +0200 Subject: [PATCH 1/2] WebUI: Add onCloseComplete callback to base modal options --- src/webui/www/private/scripts/mocha-init.js | 30 +++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/webui/www/private/scripts/mocha-init.js b/src/webui/www/private/scripts/mocha-init.js index 9620ac38ef0..25fbde4b80f 100644 --- a/src/webui/www/private/scripts/mocha-init.js +++ b/src/webui/www/private/scripts/mocha-init.js @@ -48,14 +48,24 @@ window.qBittorrent.Dialog ??= (() => { const deepFreeze = (obj) => { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#examples + // accounts for circular refs + const frozen = new WeakSet(); + const deepFreezeSafe = (obj) => { + if (frozen.has(obj)) + return; + + frozen.add(obj); + + const keys = Reflect.ownKeys(obj); + for (const key of keys) { + const value = obj[key]; + if ((value && (typeof value === "object")) || (typeof value === "function")) + deepFreezeSafe(value); + } + Object.freeze(obj); + }; - 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); + deepFreezeSafe(obj); }; const baseModalOptions = Object.assign(Object.create(null), { @@ -76,7 +86,11 @@ window.qBittorrent.Dialog ??= (() => { left: 5 }, resizable: true, - width: 480 + width: 480, + onCloseComplete: function() { + // make sure overlay is properly hidden upon modal closing + document.getElementById("modalOverlay").style.display = "none"; + } }); deepFreeze(baseModalOptions); From 148a36d1299d6c7253de22549408a0a2b5d85817 Mon Sep 17 00:00:00 2001 From: skomerko <168652295+skomerko@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:36:22 +0200 Subject: [PATCH 2/2] WebUI: Add 'Confirm torrent recheck' option Closes #19557. --- src/webui/api/appcontroller.cpp | 5 ++ src/webui/www/private/css/style.css | 19 ++++-- src/webui/www/private/scripts/mocha-init.js | 34 ++++++++--- .../www/private/views/confirmRecheck.html | 59 +++++++++++++++++++ .../www/private/views/confirmdeletion.html | 2 +- src/webui/www/private/views/preferences.html | 10 ++++ src/webui/www/webui.qrc | 1 + 7 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 src/webui/www/private/views/confirmRecheck.html diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index b4ce1bc7d0e..fd6cd442c71 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -368,6 +368,8 @@ void AppController::preferencesAction() data[u"save_statistics_interval"_s] = static_cast(session->saveStatisticsInterval().count()); // .torrent file size limit data[u"torrent_file_size_limit"_s] = pref->getTorrentFileSizeLimit(); + // Confirm torrent recheck + data[u"confirm_torrent_recheck"_s] = pref->confirmTorrentRecheck(); // Recheck completed torrents data[u"recheck_completed_torrents"_s] = pref->recheckTorrentsOnCompletion(); // Customize application instance name @@ -977,6 +979,9 @@ void AppController::setPreferencesAction() // .torrent file size limit if (hasKey(u"torrent_file_size_limit"_s)) pref->setTorrentFileSizeLimit(it.value().toLongLong()); + // Confirm torrent recheck + if (hasKey(u"confirm_torrent_recheck"_s)) + pref->setConfirmTorrentRecheck(it.value().toBool()); // Recheck completed torrents if (hasKey(u"recheck_completed_torrents"_s)) pref->recheckTorrentsOnCompletion(it.value().toBool()); diff --git a/src/webui/www/private/css/style.css b/src/webui/www/private/css/style.css index 6613dcad51b..db7917cefb8 100644 --- a/src/webui/www/private/css/style.css +++ b/src/webui/www/private/css/style.css @@ -755,23 +755,23 @@ td.statusBarSeparator { color: var(--color-text-white); } -/* Confirm deletion dialog */ +/* Modals */ -#confirmDeletionPage * { +.modalDialog * { box-sizing: border-box; } -#confirmDeletionPage_content { +.modalDialog .mochaContent.pad { display: flex !important; /* override for default mocha inline style */ flex-direction: column; height: 100%; } -#confirmDeletionPage_content > :last-child { +.modalDialog .mochaContent.pad > :last-child { align-self: flex-end; } -#confirmDeletionDialog { +.modalDialog .mochaContent.pad > :first-child { margin: auto 0; } @@ -792,10 +792,11 @@ td.statusBarSeparator { vertical-align: -1px; } -#deleteTorrentMessage { +.dialogMessage { overflow-wrap: anywhere; } +.genericConfirmGrid, .confirmDeletionGrid { align-items: center; display: grid; @@ -804,6 +805,7 @@ td.statusBarSeparator { margin-bottom: 10px; } +.confirmGridItem, .deletionGridItem { padding: 3px; } @@ -812,8 +814,13 @@ td.statusBarSeparator { justify-self: center; } +.confirmWarning, .confirmDialogWarning { background: url("../images/dialog-warning.svg") center center no-repeat; height: 38px; width: 38px; } + +.confirmWarning { + background-image: url("../images/help-about.svg"); +} diff --git a/src/webui/www/private/scripts/mocha-init.js b/src/webui/www/private/scripts/mocha-init.js index 25fbde4b80f..337f704c502 100644 --- a/src/webui/www/private/scripts/mocha-init.js +++ b/src/webui/www/private/scripts/mocha-init.js @@ -555,15 +555,31 @@ const initializeWindows = function() { recheckFN = function() { const hashes = torrentsTable.selectedRowsIds(); - if (hashes.length) { - new Request({ - url: "api/v2/torrents/recheck", - method: "post", - data: { - hashes: hashes.join("|"), - } - }).send(); - updateMainData(); + if (hashes.length > 0) { + if (window.qBittorrent.Cache.preferences.get().confirm_torrent_recheck) { + new MochaUI.Modal({ + ...window.qBittorrent.Dialog.baseModalOptions, + id: "confirmRecheckDialog", + title: "QBT_TR(Recheck confirmation)QBT_TR[CONTEXT=confirmRecheckDialog]", + data: { hashes: hashes }, + contentURL: "views/confirmRecheck.html" + }); + } + else { + new Request({ + url: "api/v2/torrents/recheck", + method: "post", + data: { + "hashes": hashes.join("|"), + }, + onSuccess: function() { + updateMainData(); + }, + onFailure: function() { + alert("QBT_TR(Unable to recheck torrents.)QBT_TR[CONTEXT=HttpServer]"); + } + }).send(); + } } }; diff --git a/src/webui/www/private/views/confirmRecheck.html b/src/webui/www/private/views/confirmRecheck.html new file mode 100644 index 00000000000..06a8409bd6c --- /dev/null +++ b/src/webui/www/private/views/confirmRecheck.html @@ -0,0 +1,59 @@ +
+
+ + +
+
+
+ + +
+ + diff --git a/src/webui/www/private/views/confirmdeletion.html b/src/webui/www/private/views/confirmdeletion.html index 122709b3f6d..5b0d7dbc627 100644 --- a/src/webui/www/private/views/confirmdeletion.html +++ b/src/webui/www/private/views/confirmdeletion.html @@ -1,7 +1,7 @@
- + diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index fefb1e00c3f..31febeb8342 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -1168,6 +1168,14 @@   QBT_TR(MiB)QBT_TR[CONTEXT=OptionsDialog] + + + + + + + + @@ -2464,6 +2472,7 @@ $("saveResumeDataInterval").value = pref.save_resume_data_interval; $("saveStatisticsInterval").value = pref.save_statistics_interval; $("torrentFileSizeLimit").value = (pref.torrent_file_size_limit / 1024 / 1024); + document.getElementById("confirmTorrentRecheck").checked = pref.confirm_torrent_recheck; $("recheckTorrentsOnCompletion").checked = pref.recheck_completed_torrents; $("appInstanceName").value = pref.app_instance_name; $("refreshInterval").value = pref.refresh_interval; @@ -2920,6 +2929,7 @@ settings["save_resume_data_interval"] = Number($("saveResumeDataInterval").value); settings["save_statistics_interval"] = Number($("saveStatisticsInterval").value); settings["torrent_file_size_limit"] = ($("torrentFileSizeLimit").value * 1024 * 1024); + settings["confirm_torrent_recheck"] = document.getElementById("confirmTorrentRecheck").checked; settings["recheck_completed_torrents"] = $("recheckTorrentsOnCompletion").checked; settings["app_instance_name"] = $("appInstanceName").value; settings["refresh_interval"] = Number($("refreshInterval").value); diff --git a/src/webui/www/webui.qrc b/src/webui/www/webui.qrc index 9b5a256c488..df27f335ed1 100644 --- a/src/webui/www/webui.qrc +++ b/src/webui/www/webui.qrc @@ -421,6 +421,7 @@ private/views/about.html private/views/aboutToolbar.html private/views/confirmdeletion.html + private/views/confirmRecheck.html private/views/filters.html private/views/installsearchplugin.html private/views/log.html