Initial DDC release
This commit is contained in:
commit
434f6441da
57 files changed
+4606
No files matched your search
@@ -0,0 +1,104 @@
|
||||
import { api } from "./api.js";
|
||||
import { element } from "./dom.js";
|
||||
|
||||
const themeStorageKey = "ddc-theme";
|
||||
|
||||
const fields = {
|
||||
dialog: document.getElementById("settings-dialog"),
|
||||
form: document.getElementById("settings-form"),
|
||||
closeButton: document.getElementById("settings-close"),
|
||||
cancelButton: document.getElementById("settings-cancel"),
|
||||
error: document.getElementById("settings-error"),
|
||||
concurrent: document.getElementById("setting-concurrent"),
|
||||
minFree: document.getElementById("setting-min-free"),
|
||||
ports: document.getElementById("setting-ports"),
|
||||
autoExtract: document.getElementById("setting-auto-extract"),
|
||||
cleanup: document.getElementById("setting-cleanup"),
|
||||
theme: document.getElementById("setting-theme"),
|
||||
downloadDir: document.getElementById("info-download-dir"),
|
||||
roots: document.getElementById("info-roots"),
|
||||
};
|
||||
|
||||
export function setupSettings(onSaved) {
|
||||
fields.closeButton.addEventListener("click", () => fields.dialog.close());
|
||||
fields.cancelButton.addEventListener("click", () => fields.dialog.close());
|
||||
fields.form.addEventListener("submit", (event) => saveSettings(event, onSaved));
|
||||
fields.theme.addEventListener("change", () => applyTheme(fields.theme.value));
|
||||
fields.dialog.addEventListener("close", () => applyTheme(readTheme()));
|
||||
}
|
||||
|
||||
export async function loadSettings() {
|
||||
const data = await api.settings();
|
||||
return data.settings;
|
||||
}
|
||||
|
||||
export async function openSettings() {
|
||||
fields.error.textContent = "";
|
||||
const data = await api.settings();
|
||||
fillForm(data);
|
||||
fields.dialog.showModal();
|
||||
}
|
||||
|
||||
function fillForm(data) {
|
||||
const settings = data.settings;
|
||||
fields.concurrent.value = settings.maxConcurrentDownloads;
|
||||
fields.minFree.value = settings.minFreeGB;
|
||||
fields.ports.value = settings.allowedPorts.length > 0 ? settings.allowedPorts.join(", ") : "*";
|
||||
fields.autoExtract.checked = settings.autoExtract;
|
||||
fields.cleanup.checked = settings.cleanupAfterMove;
|
||||
fields.theme.value = readTheme();
|
||||
fields.downloadDir.textContent = data.downloadDir;
|
||||
fields.roots.replaceChildren(...data.libraryRoots.map((root) => element("div", "mono", root)));
|
||||
}
|
||||
|
||||
async function saveSettings(event, onSaved) {
|
||||
event.preventDefault();
|
||||
fields.error.textContent = "";
|
||||
try {
|
||||
const payload = {
|
||||
maxConcurrentDownloads: Number(fields.concurrent.value),
|
||||
minFreeGB: Number(fields.minFree.value),
|
||||
allowedPorts: parsePorts(fields.ports.value),
|
||||
autoExtract: fields.autoExtract.checked,
|
||||
cleanupAfterMove: fields.cleanup.checked,
|
||||
};
|
||||
const data = await api.saveSettings(payload);
|
||||
storeTheme(fields.theme.value);
|
||||
fields.dialog.close();
|
||||
onSaved(data.settings);
|
||||
} catch (error) {
|
||||
fields.error.textContent = error.message;
|
||||
}
|
||||
}
|
||||
|
||||
function parsePorts(text) {
|
||||
const trimmed = text.trim();
|
||||
if (trimmed === "*") return [];
|
||||
const ports = trimmed.split(/[\s,]+/).filter(Boolean).map(Number);
|
||||
const invalid = ports.length === 0 || ports.some((port) => !Number.isInteger(port) || port < 1 || port > 65535);
|
||||
if (invalid) throw new Error("Allowed ports must be numbers between 1 and 65535, or * for any port.");
|
||||
return ports;
|
||||
}
|
||||
|
||||
function readTheme() {
|
||||
try {
|
||||
return localStorage.getItem(themeStorageKey) || "system";
|
||||
} catch {
|
||||
return "system";
|
||||
}
|
||||
}
|
||||
|
||||
function storeTheme(theme) {
|
||||
try {
|
||||
localStorage.setItem(themeStorageKey, theme);
|
||||
} catch {
|
||||
return;
|
||||
} finally {
|
||||
applyTheme(theme);
|
||||
}
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
if (theme === "light" || theme === "dark") document.documentElement.dataset.theme = theme;
|
||||
else delete document.documentElement.dataset.theme;
|
||||
}
|
||||
Reference in new issue
Block a user