Frontend: Kacheln per Drag-and-drop umsortieren (Reihenfolge in localStorage)
This commit is contained in:
1 parent
a7a6f17d0e
commit
0b2837f0c3
1 file changed
+52
-1
+52
-1
@@ -57,6 +57,10 @@ main{padding:22px;max-width:1800px;margin:0 auto}
|
|||||||
.btn.ok:hover{box-shadow:0 4px 16px rgba(34,197,94,.45)}
|
.btn.ok:hover{box-shadow:0 4px 16px rgba(34,197,94,.45)}
|
||||||
.btn.alt{background:#222a3a;box-shadow:none;color:var(--fg);border:1px solid var(--line)}
|
.btn.alt{background:#222a3a;box-shadow:none;color:var(--fg);border:1px solid var(--line)}
|
||||||
.btn.alt:hover{border-color:var(--accent);color:var(--accent)}
|
.btn.alt:hover{border-color:var(--accent);color:var(--accent)}
|
||||||
|
.grid .cap{cursor:grab}
|
||||||
|
.grid .cap .btn{cursor:pointer}
|
||||||
|
.tile.dragging{opacity:.4}
|
||||||
|
.tile.dragover{border-color:var(--accent)}
|
||||||
.focus .tile.big .view{aspect-ratio:auto;height:min(75vh,56.25vw)}
|
.focus .tile.big .view{aspect-ratio:auto;height:min(75vh,56.25vw)}
|
||||||
.strip{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px;margin-top:20px}
|
.strip{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px;margin-top:20px}
|
||||||
.strip .cap{padding:8px 12px;font-size:13px}
|
.strip .cap{padding:8px 12px;font-size:13px}
|
||||||
@@ -232,6 +236,52 @@ function stopTile(o) {
|
|||||||
function reloadTile(o) { stopTile(o); setTimeout(() => startTile(o), 300); }
|
function reloadTile(o) { stopTile(o); setTimeout(() => startTile(o), 300); }
|
||||||
const liveTiles = () => Object.values(tiles).filter(o => o.mode === "live");
|
const liveTiles = () => Object.values(tiles).filter(o => o.mode === "live");
|
||||||
|
|
||||||
|
const ORDER_KEY = "webcam-order";
|
||||||
|
function savedOrder() {
|
||||||
|
try { return JSON.parse(localStorage.getItem(ORDER_KEY)) || []; } catch (e) { return []; }
|
||||||
|
}
|
||||||
|
function sortBySaved(names) {
|
||||||
|
const saved = savedOrder();
|
||||||
|
const rank = n => { const i = saved.indexOf(n); return i < 0 ? saved.length : i; };
|
||||||
|
return names.map((n, i) => [n, i]).sort((a, b) => rank(a[0]) - rank(b[0]) || a[1] - b[1]).map(x => x[0]);
|
||||||
|
}
|
||||||
|
// Kacheln per Drag-and-drop an der Beschriftungsleiste umsortieren
|
||||||
|
function enableReorder(grid) {
|
||||||
|
let dragged = null;
|
||||||
|
grid.querySelectorAll(".tile").forEach(t => {
|
||||||
|
const cap = t.querySelector(".cap");
|
||||||
|
cap.draggable = true;
|
||||||
|
cap.addEventListener("dragstart", e => {
|
||||||
|
dragged = t;
|
||||||
|
t.classList.add("dragging");
|
||||||
|
e.dataTransfer.effectAllowed = "move";
|
||||||
|
e.dataTransfer.setData("text/plain", t.querySelector(".name").textContent);
|
||||||
|
e.dataTransfer.setDragImage(t, 20, 20);
|
||||||
|
});
|
||||||
|
cap.addEventListener("dragend", () => {
|
||||||
|
t.classList.remove("dragging");
|
||||||
|
grid.querySelectorAll(".dragover").forEach(x => x.classList.remove("dragover"));
|
||||||
|
dragged = null;
|
||||||
|
});
|
||||||
|
t.addEventListener("dragover", e => {
|
||||||
|
if (!dragged || dragged === t) return;
|
||||||
|
e.preventDefault();
|
||||||
|
t.classList.add("dragover");
|
||||||
|
});
|
||||||
|
t.addEventListener("dragleave", () => t.classList.remove("dragover"));
|
||||||
|
t.addEventListener("drop", e => {
|
||||||
|
e.preventDefault();
|
||||||
|
t.classList.remove("dragover");
|
||||||
|
if (!dragged || dragged === t) return;
|
||||||
|
const kids = [...grid.children];
|
||||||
|
grid.insertBefore(dragged, kids.indexOf(dragged) < kids.indexOf(t) ? t.nextSibling : t);
|
||||||
|
try {
|
||||||
|
localStorage.setItem(ORDER_KEY, JSON.stringify([...grid.children].map(c => c.querySelector(".name").textContent)));
|
||||||
|
} catch (err) {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function build(cams) {
|
function build(cams) {
|
||||||
const names = cams.map(c => c.name);
|
const names = cams.map(c => c.name);
|
||||||
const setupOf = n => cams.find(c => c.name === n).setup;
|
const setupOf = n => cams.find(c => c.name === n).setup;
|
||||||
@@ -247,8 +297,9 @@ function build(cams) {
|
|||||||
if (strip.children.length) app.append(strip);
|
if (strip.children.length) app.append(strip);
|
||||||
} else {
|
} else {
|
||||||
const grid = el("div", "grid");
|
const grid = el("div", "grid");
|
||||||
names.forEach(n => grid.append(makeTile(n, "live", setupOf(n))));
|
sortBySaved(names).forEach(n => grid.append(makeTile(n, "live", setupOf(n))));
|
||||||
app.append(grid);
|
app.append(grid);
|
||||||
|
enableReorder(grid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user