Reorganize repo layout
This commit is contained in:
121
web/public/assets/ui.js
Normal file
121
web/public/assets/ui.js
Normal file
@@ -0,0 +1,121 @@
|
||||
(function(){
|
||||
const host = document.getElementById("toastHost");
|
||||
|
||||
function iconFor(type){
|
||||
if(type === "success") return "✅";
|
||||
if(type === "error") return "⛔";
|
||||
if(type === "info") return "🛰️";
|
||||
return "🔔";
|
||||
}
|
||||
|
||||
window.toast = function(type="info", title="Notice", message="", ttl=3200){
|
||||
if(!host) return;
|
||||
|
||||
const el = document.createElement("div");
|
||||
el.className = `toast toast-${type}`;
|
||||
el.innerHTML = `
|
||||
<div class="toast-icon">${iconFor(type)}</div>
|
||||
<div class="toast-body">
|
||||
<div class="toast-title">${escapeHtml(title)}</div>
|
||||
<div class="toast-msg">${escapeHtml(message)}</div>
|
||||
</div>
|
||||
<button class="toast-x" aria-label="Close">✕</button>
|
||||
`;
|
||||
|
||||
const remove = () => {
|
||||
el.classList.add("out");
|
||||
el.addEventListener("animationend", () => el.remove(), { once:true });
|
||||
};
|
||||
|
||||
el.querySelector(".toast-x").addEventListener("click", remove);
|
||||
host.appendChild(el);
|
||||
if (ttl > 0) setTimeout(remove, ttl);
|
||||
};
|
||||
|
||||
function escapeHtml(s){
|
||||
return String(s ?? "")
|
||||
.replaceAll("&","&")
|
||||
.replaceAll("<","<")
|
||||
.replaceAll(">",">")
|
||||
.replaceAll('"',""")
|
||||
.replaceAll("'","'");
|
||||
}
|
||||
|
||||
// Notifications dropdown (tiny JS)
|
||||
const notif = document.getElementById("notifPanel");
|
||||
window.toggleNotif = function(){
|
||||
if(!notif) return;
|
||||
const isHidden = notif.hasAttribute("hidden");
|
||||
if(isHidden) notif.removeAttribute("hidden");
|
||||
else notif.setAttribute("hidden","");
|
||||
};
|
||||
document.addEventListener("click", (e)=>{
|
||||
if(!notif) return;
|
||||
const btn = e.target.closest(".iconbtn");
|
||||
const inside = e.target.closest("#notifPanel");
|
||||
if(inside || btn) return;
|
||||
notif.setAttribute("hidden","");
|
||||
});
|
||||
|
||||
// Settings helpers: perf + alertpulse (no cookies)
|
||||
function setStorage(key, val, remember){
|
||||
try{
|
||||
if (remember) {
|
||||
localStorage.setItem(key, val);
|
||||
sessionStorage.removeItem(key);
|
||||
} else {
|
||||
sessionStorage.setItem(key, val);
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}catch(e){}
|
||||
}
|
||||
function applyDataset(key, val){
|
||||
document.documentElement.dataset[key] = val;
|
||||
if (key === "perf") {
|
||||
const label = document.getElementById("perfLabel");
|
||||
if(label) label.textContent = val.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
window.applyPerfFromUI = function(){
|
||||
const chosen = document.querySelector(".seg-btn.is-selected[data-perf]")?.dataset.perf;
|
||||
const remember = document.getElementById("rememberPerf")?.checked;
|
||||
const val = chosen || "auto";
|
||||
setStorage("perf", val, remember);
|
||||
applyDataset("perf", val);
|
||||
toast("success","Performance", `Profil: ${val.toUpperCase()}`, 2200);
|
||||
if (val === "low") toast("info","Hint","Low deaktiviert Starfield", 1800);
|
||||
};
|
||||
|
||||
window.applyPulseFromUI = function(){
|
||||
const chosen = document.querySelector(".seg-btn.is-selected[data-alertpulse]")?.dataset.alertpulse;
|
||||
const remember = document.getElementById("rememberPulse")?.checked;
|
||||
const val = chosen || "burst";
|
||||
setStorage("alertpulse", val, remember);
|
||||
applyDataset("alertpulse", val);
|
||||
toast("success","Alerts", `Pulse: ${val.toUpperCase()}`, 2200);
|
||||
};
|
||||
|
||||
// Segment button selection behavior
|
||||
document.addEventListener("click", (e)=>{
|
||||
const b = e.target.closest(".seg-btn");
|
||||
if(!b) return;
|
||||
const parent = b.closest(".seg");
|
||||
if(parent){
|
||||
parent.querySelectorAll(".seg-btn").forEach(x=>x.classList.remove("is-selected"));
|
||||
b.classList.add("is-selected");
|
||||
}
|
||||
});
|
||||
|
||||
// Pre-select in settings pages
|
||||
document.addEventListener("DOMContentLoaded", ()=>{
|
||||
const perf = document.documentElement.dataset.perf || "auto";
|
||||
document.querySelectorAll('.seg-btn[data-perf]').forEach(b=>{
|
||||
if(b.dataset.perf === perf) b.classList.add("is-selected");
|
||||
});
|
||||
const pulse = document.documentElement.dataset.alertpulse || "burst";
|
||||
document.querySelectorAll('.seg-btn[data-alertpulse]').forEach(b=>{
|
||||
if(b.dataset.alertpulse === pulse) b.classList.add("is-selected");
|
||||
});
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user