123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 | // Settings window: bar-level settings (height, padding, accent, font)
// plus a hand-off button to the bar's in-place layout editor — widget
// arrangement and per-widget settings live on the bar itself (drag in
// edit mode, right-click a widget). Every change saves and applies to
// the real bar immediately.
import { BAR_SETTINGS } from "./lib/bar-config.js";
import { renderSettingsRows } from "./lib/settings-form.js";
let state = { widgets: [] };
let invoke = null;
const statusEl = document.getElementById("status");
const sectionsEl = document.getElementById("sections");
// --- Status + persistence --------------------------------------------------
let statusTimer = null;
function setStatus(text, kind = "") {
statusEl.textContent = text;
statusEl.className = kind;
statusEl.style.opacity = "1";
if (statusTimer) clearTimeout(statusTimer);
if (kind === "ok") {
statusTimer = setTimeout(() => (statusEl.style.opacity = "0"), 1500);
}
}
let saveTimer = null;
function scheduleSave() {
if (saveTimer) clearTimeout(saveTimer);
saveTimer = setTimeout(async () => {
try {
await invoke("save_config", { config: state });
setStatus("Saved ✓", "ok");
} catch (err) {
setStatus(`Save failed: ${err}`, "error");
}
}, 250);
}
// --- Helpers ---------------------------------------------------------------
function el(tag, className, text) {
const node = document.createElement(tag);
if (className) node.className = className;
if (text != null) node.textContent = text;
return node;
}
// --- Sections --------------------------------------------------------------
function barSection() {
const section = el("section");
section.append(el("h2", "", "Bar"));
const panel = el("div", "panel");
const options = (state.bar ??= {});
renderSettingsRows(panel, {
schemas: BAR_SETTINGS,
options,
invoke,
onChange(key, value) {
options[key] = value;
scheduleSave();
},
});
section.append(panel);
return section;
}
function widgetsSection() {
const section = el("section");
section.append(el("h2", "", "Widgets"));
const panel = el("div", "panel");
panel.append(
el(
"p",
"hint",
"Widgets are arranged on the bar itself: edit mode lets you drag " +
"them around, add, and remove; right-click any widget to change " +
"its settings.",
),
);
const btn = el("button", "", "Edit bar layout…");
btn.addEventListener("click", async () => {
try {
await window.__TAURI__.event.emit("divebar://edit-layout");
await invoke("close_settings");
} catch (err) {
setStatus(`Edit layout failed: ${err}`, "error");
}
});
panel.append(btn);
section.append(panel);
return section;
}
// --- Render + init ---------------------------------------------------------
function render() {
sectionsEl.replaceChildren(barSection(), widgetsSection());
}
document.getElementById("close").addEventListener("click", () => {
window.__TAURI__?.core
?.invoke("close_settings")
.catch((err) => setStatus(`Close failed: ${err}`, "error"));
});
document.getElementById("reset").addEventListener("click", async () => {
try {
state = await invoke("get_default_config");
render();
scheduleSave();
setStatus("Reset to defaults");
} catch (err) {
setStatus(`Reset failed: ${err}`, "error");
}
});
async function init() {
if (!window.__TAURI__?.core) {
throw new Error("Tauri API not available in this window");
}
invoke = window.__TAURI__.core.invoke;
state = await invoke("get_config");
state.widgets ??= [];
state.bar ??= {};
// The bar window saves configs too (layout editor, right-click widget
// settings). Adopt its widget changes so a later save from here
// doesn't clobber them; bar-level settings are only edited here.
window.__TAURI__.event.listen("divebar://config", (event) => {
if (event.payload?.widgets) state.widgets = event.payload.widgets;
});
render();
}
init().catch((err) => {
console.error("divebar settings: init failed", err);
render();
setStatus(`Failed to load settings: ${err}`, "error");
});
window.addEventListener("unhandledrejection", (e) =>
setStatus(`Error: ${e.reason}`, "error"),
);
window.addEventListener("error", (e) => setStatus(`Error: ${e.message}`, "error"));
|