mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-01-07 08:02:30 -06:00
WebUI: Store persistent settings in client data API
This PR moves persistent WebUI settings from browser local storage to the new client data API. This allows these settings to be shared across multiple WebUI instances. This does not include settings that are specific to the local client, like window sizes, selected filters, selected tabs, and sorted columns. Depends on #23088. Closes #12100. PR #23191.
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
<script defer src="scripts/monkeypatch.js?v=${CACHEID}"></script>
|
||||
<script defer src="scripts/cache.js?v=${CACHEID}"></script>
|
||||
<script defer src="scripts/localpreferences.js?v=${CACHEID}"></script>
|
||||
<script defer src="scripts/client-data.js?v=${CACHEID}"></script>
|
||||
<script defer src="scripts/color-scheme.js?v=${CACHEID}"></script>
|
||||
<script defer src="scripts/mocha-init.js?locale=${LANG}&v=${CACHEID}"></script>
|
||||
<script defer src="scripts/lib/clipboard-copy.js"></script>
|
||||
|
||||
@@ -45,10 +45,10 @@ window.qBittorrent.AddTorrent ??= (() => {
|
||||
let source = "";
|
||||
let downloader = "";
|
||||
|
||||
const localPreferences = new window.qBittorrent.LocalPreferences.LocalPreferences();
|
||||
const clientData = window.parent.qBittorrent.ClientData;
|
||||
|
||||
const getCategories = () => {
|
||||
const defaultCategory = localPreferences.get("add_torrent_default_category", "");
|
||||
const defaultCategory = clientData.get("add_torrent_default_category") ?? "";
|
||||
const categorySelect = document.getElementById("categorySelect");
|
||||
for (const name of window.parent.qBittorrent.Client.categoryMap.keys()) {
|
||||
const option = document.createElement("option");
|
||||
@@ -320,10 +320,7 @@ window.qBittorrent.AddTorrent ??= (() => {
|
||||
|
||||
if (document.getElementById("setDefaultCategory").checked) {
|
||||
const category = document.getElementById("category").value.trim();
|
||||
if (category.length === 0)
|
||||
localPreferences.remove("add_torrent_default_category");
|
||||
else
|
||||
localPreferences.set("add_torrent_default_category", category);
|
||||
clientData.set({ add_torrent_default_category: (category.length > 0) ? category : null }).catch(console.error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
126
src/webui/www/private/scripts/client-data.js
Normal file
126
src/webui/www/private/scripts/client-data.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2025 Thomas Piccirello <thomas@piccirello.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
window.qBittorrent ??= {};
|
||||
window.qBittorrent.ClientData ??= (() => {
|
||||
const exports = () => {
|
||||
return new ClientData();
|
||||
};
|
||||
|
||||
// this is exposed as a singleton
|
||||
class ClientData {
|
||||
/**
|
||||
* @type Map<string, any>
|
||||
*/
|
||||
#cache = new Map();
|
||||
|
||||
#keyPrefix = "qbt_";
|
||||
|
||||
#addKeyPrefix(data) {
|
||||
return Object.fromEntries(Object.entries(data).map(([key, value]) => ([`${this.#keyPrefix}${key}`, value])));
|
||||
}
|
||||
|
||||
#removeKeyPrefix(data) {
|
||||
return Object.fromEntries(Object.entries(data).map(([key, value]) => ([key.substring(this.#keyPrefix.length), value])));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} keys
|
||||
* @returns {Record<string, any>}
|
||||
*/
|
||||
async #fetch(keys) {
|
||||
keys = keys.map(key => `${this.#keyPrefix}${key}`);
|
||||
return await fetch("api/v2/clientdata/load", {
|
||||
method: "POST",
|
||||
body: new URLSearchParams({
|
||||
keys: JSON.stringify(keys)
|
||||
})
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (!response.ok)
|
||||
return;
|
||||
|
||||
const data = await response.json();
|
||||
return this.#removeKeyPrefix(data);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, any>} data
|
||||
*/
|
||||
async #set(data) {
|
||||
data = this.#addKeyPrefix(data);
|
||||
await fetch("api/v2/clientdata/store", {
|
||||
method: "POST",
|
||||
body: new URLSearchParams({
|
||||
data: JSON.stringify(data)
|
||||
})
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok)
|
||||
throw new Error("Failed to store client data");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @returns {any}
|
||||
*/
|
||||
get(key) {
|
||||
return this.#cache.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} keys
|
||||
*/
|
||||
async fetch(keys = []) {
|
||||
const keysToFetch = keys.filter((key) => !this.#cache.has(key));
|
||||
if (keysToFetch.length > 0) {
|
||||
const fetchedData = await this.#fetch(keysToFetch);
|
||||
for (const [key, value] of Object.entries(fetchedData))
|
||||
this.#cache.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, any>} data
|
||||
*/
|
||||
async set(data) {
|
||||
await this.#set(data);
|
||||
|
||||
// update cache
|
||||
for (const [key, value] of Object.entries(data))
|
||||
this.#cache.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return exports();
|
||||
})();
|
||||
Object.freeze(window.qBittorrent.ClientData);
|
||||
@@ -31,6 +31,7 @@ window.qBittorrent.Client ??= (() => {
|
||||
return {
|
||||
setup: setup,
|
||||
initializeCaches: initializeCaches,
|
||||
initializeClientData: initializeClientData,
|
||||
closeWindow: closeWindow,
|
||||
closeFrameWindow: closeFrameWindow,
|
||||
getSyncMainDataInterval: getSyncMainDataInterval,
|
||||
@@ -56,15 +57,48 @@ window.qBittorrent.Client ??= (() => {
|
||||
const tagMap = new Map();
|
||||
|
||||
let cacheAllSettled;
|
||||
let clientDataPromise;
|
||||
const setup = () => {
|
||||
// fetch various data and store it in memory
|
||||
clientDataPromise = window.qBittorrent.ClientData.fetch([
|
||||
"add_torrent_default_category",
|
||||
"color_scheme",
|
||||
"dblclick_complete",
|
||||
"dblclick_download",
|
||||
"dblclick_filter",
|
||||
"full_url_tracker_column",
|
||||
"hide_zero_status_filters",
|
||||
"qbt_selected_log_levels",
|
||||
"search_in_filter",
|
||||
"show_filters_sidebar",
|
||||
"show_log_viewer",
|
||||
"show_rss_reader",
|
||||
"show_search_engine",
|
||||
"show_status_bar",
|
||||
"show_top_toolbar",
|
||||
"speed_in_browser_title_bar",
|
||||
"torrent_creator",
|
||||
"use_alt_row_colors",
|
||||
"use_virtual_list",
|
||||
]);
|
||||
|
||||
cacheAllSettled = Promise.allSettled([
|
||||
window.qBittorrent.Cache.buildInfo.init(),
|
||||
window.qBittorrent.Cache.preferences.init(),
|
||||
window.qBittorrent.Cache.qbtVersion.init()
|
||||
window.qBittorrent.Cache.qbtVersion.init(),
|
||||
clientDataPromise,
|
||||
]);
|
||||
};
|
||||
|
||||
const initializeClientData = async () => {
|
||||
try {
|
||||
await clientDataPromise;
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`Failed to initialize client data. Reason: "${error}".`);
|
||||
}
|
||||
};
|
||||
|
||||
const initializeCaches = async () => {
|
||||
const results = await cacheAllSettled;
|
||||
for (const [idx, result] of results.entries()) {
|
||||
@@ -222,8 +256,8 @@ let alternativeSpeedLimits = false;
|
||||
let queueing_enabled = true;
|
||||
let serverSyncMainDataInterval = 1500;
|
||||
let customSyncMainDataInterval = null;
|
||||
const useAutoHideZeroStatusFilters = localPreferences.get("hide_zero_status_filters", "false") === "true";
|
||||
const displayFullURLTrackerColumn = localPreferences.get("full_url_tracker_column", "false") === "true";
|
||||
let useAutoHideZeroStatusFilters = false;
|
||||
let displayFullURLTrackerColumn = false;
|
||||
|
||||
/* Categories filter */
|
||||
const CATEGORIES_ALL = "b4af0e4c-e76d-4bac-a392-46cbc18d9655";
|
||||
@@ -249,6 +283,8 @@ const TRACKERS_WARNING = "82a702c5-210c-412b-829f-97632d7557e9";
|
||||
// Map<trackerHost: String, Map<trackerURL: String, torrents: Set>>
|
||||
const trackerMap = new Map();
|
||||
|
||||
const clientData = window.qBittorrent.ClientData;
|
||||
|
||||
let selectedTracker = localPreferences.get("selected_tracker", TRACKERS_ALL);
|
||||
let setTrackerFilter = () => {};
|
||||
|
||||
@@ -257,9 +293,16 @@ let selectedStatus = localPreferences.get("selected_filter", "all");
|
||||
let setStatusFilter = () => {};
|
||||
let toggleFilterDisplay = () => {};
|
||||
|
||||
window.addEventListener("DOMContentLoaded", (event) => {
|
||||
window.addEventListener("DOMContentLoaded", async (event) => {
|
||||
// execute this first
|
||||
window.qBittorrent.LocalPreferences.upgrade();
|
||||
|
||||
await window.qBittorrent.Client.initializeClientData();
|
||||
window.qBittorrent.ColorScheme.update();
|
||||
|
||||
useAutoHideZeroStatusFilters = clientData.get("hide_zero_status_filters") === true;
|
||||
displayFullURLTrackerColumn = clientData.get("full_url_tracker_column") === true;
|
||||
|
||||
let isSearchPanelLoaded = false;
|
||||
let isLogPanelLoaded = false;
|
||||
let isRssPanelLoaded = false;
|
||||
@@ -404,6 +447,13 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
localPreferences.set(`filter_${filterListID.replace("FilterList", "")}_collapsed`, filterList.classList.toggle("invisible").toString());
|
||||
};
|
||||
|
||||
const highlightSelectedStatus = () => {
|
||||
const statusFilter = document.getElementById("statusFilterList");
|
||||
const filterID = `${selectedStatus}_filter`;
|
||||
for (const status of statusFilter.children)
|
||||
status.classList.toggle("selectedFilter", (status.id === filterID));
|
||||
};
|
||||
|
||||
new MochaUI.Panel({
|
||||
id: "Filters",
|
||||
title: "Panel",
|
||||
@@ -425,35 +475,35 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
initializeWindows();
|
||||
|
||||
// Show Top Toolbar is enabled by default
|
||||
let showTopToolbar = localPreferences.get("show_top_toolbar", "true") === "true";
|
||||
let showTopToolbar = (clientData.get("show_top_toolbar") ?? true) === true;
|
||||
if (!showTopToolbar) {
|
||||
document.getElementById("showTopToolbarLink").firstElementChild.style.opacity = "0";
|
||||
document.getElementById("mochaToolbar").classList.add("invisible");
|
||||
}
|
||||
|
||||
// Show Status Bar is enabled by default
|
||||
let showStatusBar = localPreferences.get("show_status_bar", "true") === "true";
|
||||
let showStatusBar = (clientData.get("show_status_bar") ?? true) === true;
|
||||
if (!showStatusBar) {
|
||||
document.getElementById("showStatusBarLink").firstElementChild.style.opacity = "0";
|
||||
document.getElementById("desktopFooterWrapper").classList.add("invisible");
|
||||
}
|
||||
|
||||
// Show Filters Sidebar is enabled by default
|
||||
let showFiltersSidebar = localPreferences.get("show_filters_sidebar", "true") === "true";
|
||||
let showFiltersSidebar = (clientData.get("show_filters_sidebar") ?? true) === true;
|
||||
if (!showFiltersSidebar) {
|
||||
document.getElementById("showFiltersSidebarLink").firstElementChild.style.opacity = "0";
|
||||
document.getElementById("filtersColumn").classList.add("invisible");
|
||||
document.getElementById("filtersColumn_handle").classList.add("invisible");
|
||||
}
|
||||
|
||||
let speedInTitle = localPreferences.get("speed_in_browser_title_bar") === "true";
|
||||
let speedInTitle = clientData.get("speed_in_browser_title_bar") === true;
|
||||
if (!speedInTitle)
|
||||
document.getElementById("speedInBrowserTitleBarLink").firstElementChild.style.opacity = "0";
|
||||
|
||||
// After showing/hiding the toolbar + status bar
|
||||
window.qBittorrent.Client.showSearchEngine(localPreferences.get("show_search_engine") !== "false");
|
||||
window.qBittorrent.Client.showRssReader(localPreferences.get("show_rss_reader") !== "false");
|
||||
window.qBittorrent.Client.showLogViewer(localPreferences.get("show_log_viewer") === "true");
|
||||
window.qBittorrent.Client.showSearchEngine((clientData.get("show_search_engine") ?? true) === true);
|
||||
window.qBittorrent.Client.showRssReader((clientData.get("show_rss_reader") ?? true) === true);
|
||||
window.qBittorrent.Client.showLogViewer(clientData.get("show_log_viewer") === true);
|
||||
|
||||
// After Show Top Toolbar
|
||||
MochaUI.Desktop.setDesktopSize();
|
||||
@@ -570,13 +620,6 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
window.qBittorrent.Filters.clearStatusFilter();
|
||||
};
|
||||
|
||||
const highlightSelectedStatus = () => {
|
||||
const statusFilter = document.getElementById("statusFilterList");
|
||||
const filterID = `${selectedStatus}_filter`;
|
||||
for (const status of statusFilter.children)
|
||||
status.classList.toggle("selectedFilter", (status.id === filterID));
|
||||
};
|
||||
|
||||
const updateCategoryList = () => {
|
||||
const categoryList = document.getElementById("categoryFilterList");
|
||||
if (!categoryList)
|
||||
@@ -1210,7 +1253,7 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
|
||||
document.getElementById("showTopToolbarLink").addEventListener("click", (e) => {
|
||||
showTopToolbar = !showTopToolbar;
|
||||
localPreferences.set("show_top_toolbar", showTopToolbar.toString());
|
||||
clientData.set({ show_top_toolbar: showTopToolbar }).catch(console.error);
|
||||
if (showTopToolbar) {
|
||||
document.getElementById("showTopToolbarLink").firstElementChild.style.opacity = "1";
|
||||
document.getElementById("mochaToolbar").classList.remove("invisible");
|
||||
@@ -1224,7 +1267,7 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
|
||||
document.getElementById("showStatusBarLink").addEventListener("click", (e) => {
|
||||
showStatusBar = !showStatusBar;
|
||||
localPreferences.set("show_status_bar", showStatusBar.toString());
|
||||
clientData.set({ show_status_bar: showStatusBar }).catch(console.error);
|
||||
if (showStatusBar) {
|
||||
document.getElementById("showStatusBarLink").firstElementChild.style.opacity = "1";
|
||||
document.getElementById("desktopFooterWrapper").classList.remove("invisible");
|
||||
@@ -1261,7 +1304,7 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
|
||||
document.getElementById("showFiltersSidebarLink").addEventListener("click", (e) => {
|
||||
showFiltersSidebar = !showFiltersSidebar;
|
||||
localPreferences.set("show_filters_sidebar", showFiltersSidebar.toString());
|
||||
clientData.set({ show_filters_sidebar: showFiltersSidebar }).catch(console.error);
|
||||
if (showFiltersSidebar) {
|
||||
document.getElementById("showFiltersSidebarLink").firstElementChild.style.opacity = "1";
|
||||
document.getElementById("filtersColumn").classList.remove("invisible");
|
||||
@@ -1277,7 +1320,7 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
|
||||
document.getElementById("speedInBrowserTitleBarLink").addEventListener("click", (e) => {
|
||||
speedInTitle = !speedInTitle;
|
||||
localPreferences.set("speed_in_browser_title_bar", speedInTitle.toString());
|
||||
clientData.set({ speed_in_browser_title_bar: speedInTitle }).catch(console.error);
|
||||
if (speedInTitle)
|
||||
document.getElementById("speedInBrowserTitleBarLink").firstElementChild.style.opacity = "1";
|
||||
else
|
||||
@@ -1287,19 +1330,19 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
|
||||
document.getElementById("showSearchEngineLink").addEventListener("click", (e) => {
|
||||
window.qBittorrent.Client.showSearchEngine(!window.qBittorrent.Client.isShowSearchEngine());
|
||||
localPreferences.set("show_search_engine", window.qBittorrent.Client.isShowSearchEngine().toString());
|
||||
clientData.set({ show_search_engine: window.qBittorrent.Client.isShowSearchEngine() }).catch(console.error);
|
||||
updateTabDisplay();
|
||||
});
|
||||
|
||||
document.getElementById("showRssReaderLink").addEventListener("click", (e) => {
|
||||
window.qBittorrent.Client.showRssReader(!window.qBittorrent.Client.isShowRssReader());
|
||||
localPreferences.set("show_rss_reader", window.qBittorrent.Client.isShowRssReader().toString());
|
||||
clientData.set({ show_rss_reader: window.qBittorrent.Client.isShowRssReader() }).catch(console.error);
|
||||
updateTabDisplay();
|
||||
});
|
||||
|
||||
document.getElementById("showLogViewerLink").addEventListener("click", (e) => {
|
||||
window.qBittorrent.Client.showLogViewer(!window.qBittorrent.Client.isShowLogViewer());
|
||||
localPreferences.set("show_log_viewer", window.qBittorrent.Client.isShowLogViewer().toString());
|
||||
clientData.set({ show_log_viewer: window.qBittorrent.Client.isShowLogViewer() }).catch(console.error);
|
||||
updateTabDisplay();
|
||||
});
|
||||
|
||||
@@ -1356,7 +1399,7 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
// main window tabs
|
||||
|
||||
const showTransfersTab = () => {
|
||||
const showFiltersSidebar = localPreferences.get("show_filters_sidebar", "true") === "true";
|
||||
const showFiltersSidebar = (clientData.get("show_filters_sidebar") ?? true) === true;
|
||||
if (showFiltersSidebar) {
|
||||
document.getElementById("filtersColumn").classList.remove("invisible");
|
||||
document.getElementById("filtersColumn_handle").classList.remove("invisible");
|
||||
|
||||
@@ -36,12 +36,12 @@ window.qBittorrent.ColorScheme ??= (() => {
|
||||
};
|
||||
};
|
||||
|
||||
const localPreferences = new window.qBittorrent.LocalPreferences.LocalPreferences();
|
||||
const colorSchemeQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
const clientData = window.parent.qBittorrent.ClientData;
|
||||
|
||||
const update = () => {
|
||||
const root = document.documentElement;
|
||||
const colorScheme = localPreferences.get("color_scheme");
|
||||
const colorScheme = clientData.get("color_scheme");
|
||||
const validScheme = (colorScheme === "light") || (colorScheme === "dark");
|
||||
const isDark = colorSchemeQuery.matches;
|
||||
root.classList.toggle("dark", ((!validScheme && isDark) || (colorScheme === "dark")));
|
||||
@@ -52,5 +52,3 @@ window.qBittorrent.ColorScheme ??= (() => {
|
||||
return exports();
|
||||
})();
|
||||
Object.freeze(window.qBittorrent.ColorScheme);
|
||||
|
||||
window.qBittorrent.ColorScheme.update();
|
||||
|
||||
@@ -66,6 +66,7 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||
};
|
||||
|
||||
const localPreferences = new window.qBittorrent.LocalPreferences.LocalPreferences();
|
||||
const clientData = window.qBittorrent.ClientData ?? window.parent.qBittorrent.ClientData;
|
||||
|
||||
class DynamicTable {
|
||||
#DynamicTableHeaderContextMenuClass = null;
|
||||
@@ -74,7 +75,7 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||
this.dynamicTableDivId = dynamicTableDivId;
|
||||
this.dynamicTableFixedHeaderDivId = dynamicTableFixedHeaderDivId;
|
||||
this.dynamicTableDiv = document.getElementById(dynamicTableDivId);
|
||||
this.useVirtualList = useVirtualList && (localPreferences.get("use_virtual_list", "false") === "true");
|
||||
this.useVirtualList = useVirtualList && (clientData.get("use_virtual_list") === true);
|
||||
this.fixedTableHeader = document.querySelector(`#${dynamicTableFixedHeaderDivId} thead tr`);
|
||||
this.hiddenTableHeader = this.dynamicTableDiv.querySelector("thead tr");
|
||||
this.table = this.dynamicTableDiv.querySelector("table");
|
||||
@@ -726,7 +727,7 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||
}
|
||||
|
||||
setupAltRow() {
|
||||
const useAltRowColors = (localPreferences.get("use_alt_row_colors", "true") === "true");
|
||||
const useAltRowColors = (clientData.get("use_alt_row_colors") ?? true) === true;
|
||||
if (useAltRowColors)
|
||||
document.getElementById(this.dynamicTableDivId).classList.add("altRowColors");
|
||||
}
|
||||
@@ -1792,7 +1793,7 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||
? "dblclick_download"
|
||||
: "dblclick_complete";
|
||||
|
||||
if (localPreferences.get(prefKey, "1") !== "1")
|
||||
if (clientData.get(prefKey) !== "1")
|
||||
return true;
|
||||
|
||||
if (state.includes("stopped"))
|
||||
|
||||
@@ -109,8 +109,7 @@ window.qBittorrent.Search ??= (() => {
|
||||
});
|
||||
|
||||
const init = () => {
|
||||
// load "Search in" preference from local storage
|
||||
document.getElementById("searchInTorrentName").value = (localPreferences.get("search_in_filter") === "names") ? "names" : "everywhere";
|
||||
document.getElementById("searchInTorrentName").value = (window.qBittorrent.ClientData.get("search_in_filter") === "names") ? "names" : "everywhere";
|
||||
const searchResultsTableContextMenu = new window.qBittorrent.ContextMenu.ContextMenu({
|
||||
targets: "#searchResultsTableDiv tbody tr",
|
||||
menu: "searchResultsTableMenu",
|
||||
@@ -802,7 +801,8 @@ window.qBittorrent.Search ??= (() => {
|
||||
};
|
||||
|
||||
const searchInTorrentName = () => {
|
||||
localPreferences.set("search_in_filter", getSearchInTorrentName());
|
||||
// don't await this
|
||||
window.qBittorrent.ClientData.set({ search_in_filter: getSearchInTorrentName() }).catch(console.error);
|
||||
searchFilterChanged();
|
||||
};
|
||||
|
||||
|
||||
@@ -127,8 +127,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
const localPreferences = new window.qBittorrent.LocalPreferences.LocalPreferences();
|
||||
|
||||
const formatUrls = (urls) => {
|
||||
return urls.split("\n").map(encodeURIComponent).join("|");
|
||||
};
|
||||
@@ -209,11 +207,12 @@
|
||||
comments: document.getElementById("comments").value,
|
||||
source: document.getElementById("source").value,
|
||||
};
|
||||
localPreferences.set("torrent_creator", JSON.stringify(preference));
|
||||
window.parent.qBittorrent.ClientData.set({ torrent_creator: preference }).catch(console.error);
|
||||
};
|
||||
|
||||
const loadPreference = () => {
|
||||
const preference = JSON.parse(localPreferences.get("torrent_creator") ?? "{}");
|
||||
const preference = window.parent.qBittorrent.ClientData.get("torrent_creator") ?? {};
|
||||
|
||||
document.getElementById("sourcePath").value = preference.sourcePath ?? "";
|
||||
document.getElementById("torrentFormat").value = preference.torrentFormat ?? "hybrid";
|
||||
document.getElementById("pieceSize").value = preference.pieceSize ?? 0;
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
});
|
||||
|
||||
document.getElementById("Filters_pad").addEventListener("dblclick", (event) => {
|
||||
if (localPreferences.get("dblclick_filter", "1") !== "1")
|
||||
if ((window.qBittorrent.ClientData.get("dblclick_filter") ?? "1") !== "1")
|
||||
return;
|
||||
|
||||
const filterItem = event.target.closest("li");
|
||||
|
||||
@@ -182,12 +182,10 @@
|
||||
}
|
||||
};
|
||||
|
||||
const localPreferences = new window.qBittorrent.LocalPreferences.LocalPreferences();
|
||||
|
||||
let logFilterTimer = -1;
|
||||
let inputtedFilterText = "";
|
||||
let selectBox;
|
||||
let selectedLogLevels = JSON.parse(localPreferences.get("qbt_selected_log_levels")) || ["1", "2", "4", "8"];
|
||||
let selectedLogLevels = window.qBittorrent.ClientData.get("qbt_selected_log_levels") ?? ["1", "2", "4", "8"];
|
||||
|
||||
const init = () => {
|
||||
for (const option of document.getElementById("logLevelSelect").options)
|
||||
@@ -277,7 +275,8 @@
|
||||
if (selectedLogLevels !== value) {
|
||||
tableInfo[currentSelectedTab].last_id = -1;
|
||||
selectedLogLevels = value;
|
||||
localPreferences.set("qbt_selected_log_levels", JSON.stringify(selectedLogLevels));
|
||||
// don't await this
|
||||
window.qBittorrent.ClientData.set({ qbt_selected_log_levels: selectedLogLevels }).catch(console.error);
|
||||
logFilterChanged();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1829,8 +1829,6 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
};
|
||||
};
|
||||
|
||||
const localPreferences = new window.qBittorrent.LocalPreferences.LocalPreferences();
|
||||
|
||||
// Behavior tab
|
||||
const numberInputLimiter = (input) => {
|
||||
const inputNumber = Number(input.value);
|
||||
@@ -2249,10 +2247,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
document.getElementById("locale_select").value = selected;
|
||||
};
|
||||
|
||||
const updateColoSchemeSelect = () => {
|
||||
const updateColoSchemeSelect = (colorScheme) => {
|
||||
const combobox = document.getElementById("colorSchemeSelect");
|
||||
const colorScheme = localPreferences.get("color_scheme");
|
||||
|
||||
if (colorScheme === "light")
|
||||
combobox.options[1].selected = true;
|
||||
else if (colorScheme === "dark")
|
||||
@@ -2264,20 +2260,31 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
const loadPreferences = () => {
|
||||
window.parent.qBittorrent.Cache.preferences.init()
|
||||
.then((pref) => {
|
||||
const clientData = window.parent.qBittorrent.ClientData;
|
||||
const colorScheme = clientData.get("color_scheme");
|
||||
const fullUrlTrackerColumn = clientData.get("full_url_tracker_column");
|
||||
const useVirtualList = clientData.get("use_virtual_list");
|
||||
const hideZeroStatusFilters = clientData.get("hide_zero_status_filters");
|
||||
const dblclickDownload = clientData.get("dblclick_download") ?? "1";
|
||||
const dblclickComplete = clientData.get("dblclick_complete") ?? "1";
|
||||
const dblclickFilter = clientData.get("dblclick_filter") ?? "1";
|
||||
const useAltRowColors = clientData.get("use_alt_row_colors");
|
||||
|
||||
// Behavior tab
|
||||
// Language
|
||||
updateWebuiLocaleSelect(pref.locale);
|
||||
updateColoSchemeSelect();
|
||||
updateColoSchemeSelect(colorScheme);
|
||||
|
||||
document.getElementById("statusBarExternalIP").checked = pref.status_bar_external_ip;
|
||||
document.getElementById("performanceWarning").checked = pref.performance_warning;
|
||||
document.getElementById("displayFullURLTrackerColumn").checked = (localPreferences.get("full_url_tracker_column", "false") === "true");
|
||||
document.getElementById("useVirtualList").checked = (localPreferences.get("use_virtual_list", "false") === "true");
|
||||
document.getElementById("hideZeroFiltersCheckbox").checked = (localPreferences.get("hide_zero_status_filters", "false") === "true");
|
||||
document.getElementById("dblclickDownloadSelect").value = localPreferences.get("dblclick_download", "1");
|
||||
document.getElementById("dblclickCompleteSelect").value = localPreferences.get("dblclick_complete", "1");
|
||||
document.getElementById("dblclickFiltersSelect").value = localPreferences.get("dblclick_filter", "1");
|
||||
document.getElementById("displayFullURLTrackerColumn").checked = fullUrlTrackerColumn === true;
|
||||
document.getElementById("useVirtualList").checked = useVirtualList === true;
|
||||
document.getElementById("hideZeroFiltersCheckbox").checked = hideZeroStatusFilters === true;
|
||||
document.getElementById("dblclickDownloadSelect").value = dblclickDownload;
|
||||
document.getElementById("dblclickCompleteSelect").value = dblclickComplete;
|
||||
document.getElementById("dblclickFiltersSelect").value = dblclickFilter;
|
||||
document.getElementById("confirmTorrentDeletion").checked = pref.confirm_torrent_deletion;
|
||||
document.getElementById("useAltRowColorsInput").checked = (localPreferences.get("use_alt_row_colors", "true") === "true");
|
||||
document.getElementById("useAltRowColorsInput").checked = useAltRowColors === true;
|
||||
document.getElementById("filelog_checkbox").checked = pref.file_log_enabled;
|
||||
document.getElementById("filelog_save_path_input").value = pref.file_log_path;
|
||||
document.getElementById("filelog_backup_checkbox").checked = pref.file_log_backup_enabled;
|
||||
@@ -2701,6 +2708,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
|
||||
const applyPreferences = () => {
|
||||
const settings = {};
|
||||
const clientData = {};
|
||||
// Validate form data
|
||||
|
||||
// Behavior tab
|
||||
@@ -2708,21 +2716,21 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
settings["locale"] = document.getElementById("locale_select").value;
|
||||
const colorScheme = Number(document.getElementById("colorSchemeSelect").value);
|
||||
if (colorScheme === 0)
|
||||
localPreferences.remove("color_scheme");
|
||||
clientData.color_scheme = null;
|
||||
else if (colorScheme === 1)
|
||||
localPreferences.set("color_scheme", "light");
|
||||
clientData.color_scheme = "light";
|
||||
else
|
||||
localPreferences.set("color_scheme", "dark");
|
||||
clientData.color_scheme = "dark";
|
||||
settings["status_bar_external_ip"] = document.getElementById("statusBarExternalIP").checked;
|
||||
settings["performance_warning"] = document.getElementById("performanceWarning").checked;
|
||||
localPreferences.set("full_url_tracker_column", document.getElementById("displayFullURLTrackerColumn").checked.toString());
|
||||
localPreferences.set("use_virtual_list", document.getElementById("useVirtualList").checked.toString());
|
||||
localPreferences.set("hide_zero_status_filters", document.getElementById("hideZeroFiltersCheckbox").checked.toString());
|
||||
localPreferences.set("dblclick_download", document.getElementById("dblclickDownloadSelect").value);
|
||||
localPreferences.set("dblclick_complete", document.getElementById("dblclickCompleteSelect").value);
|
||||
localPreferences.set("dblclick_filter", document.getElementById("dblclickFiltersSelect").value);
|
||||
clientData.full_url_tracker_column = document.getElementById("displayFullURLTrackerColumn").checked;
|
||||
clientData.use_virtual_list = document.getElementById("useVirtualList").checked;
|
||||
clientData.hide_zero_status_filters = document.getElementById("hideZeroFiltersCheckbox").checked;
|
||||
clientData.dblclick_download = document.getElementById("dblclickDownloadSelect").value;
|
||||
clientData.dblclick_complete = document.getElementById("dblclickCompleteSelect").value;
|
||||
clientData.dblclick_filter = document.getElementById("dblclickFiltersSelect").value;
|
||||
settings["confirm_torrent_deletion"] = document.getElementById("confirmTorrentDeletion").checked;
|
||||
localPreferences.set("use_alt_row_colors", document.getElementById("useAltRowColorsInput").checked.toString());
|
||||
clientData.use_alt_row_colors = document.getElementById("useAltRowColorsInput").checked;
|
||||
settings["file_log_enabled"] = document.getElementById("filelog_checkbox").checked;
|
||||
settings["file_log_path"] = document.getElementById("filelog_save_path_input").value;
|
||||
settings["file_log_backup_enabled"] = document.getElementById("filelog_backup_checkbox").checked;
|
||||
@@ -3212,15 +3220,19 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
settings["i2p_inbound_length"] = Number(document.getElementById("i2pInboundLength").value);
|
||||
settings["i2p_outbound_length"] = Number(document.getElementById("i2pOutboundLength").value);
|
||||
|
||||
// Send it to qBT
|
||||
// Send data to qBT
|
||||
Promise.allSettled([
|
||||
window.parent.qBittorrent.ClientData.set(clientData),
|
||||
window.parent.qBittorrent.Cache.preferences.set(settings)
|
||||
.then(() => {
|
||||
// Close window
|
||||
]).then((results) => {
|
||||
if (results.every((result) => result.status === "fulfilled")) {
|
||||
window.parent.location.reload();
|
||||
window.parent.qBittorrent.Client.closeWindow(document.getElementById("preferencesPage"));
|
||||
}).catch((error) => {
|
||||
}
|
||||
else {
|
||||
// keep window open so user can reattempt saving
|
||||
alert("QBT_TR(Unable to save program preferences, qBittorrent is probably unreachable.)QBT_TR[CONTEXT=HttpServer]");
|
||||
alert("QBT_TR(Unable to save preferences, qBittorrent is probably unreachable.)QBT_TR[CONTEXT=HttpServer]");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -390,6 +390,7 @@
|
||||
<file>private/scripts/addtorrent.js</file>
|
||||
<file>private/scripts/cache.js</file>
|
||||
<file>private/scripts/client.js</file>
|
||||
<file>private/scripts/client-data.js</file>
|
||||
<file>private/scripts/color-scheme.js</file>
|
||||
<file>private/scripts/contextmenu.js</file>
|
||||
<file>private/scripts/dynamicTable.js</file>
|
||||
|
||||
Reference in New Issue
Block a user