(function () { const key = "mail-graveyard-pane-widths-v2"; const minWidths = [160, 220, 300]; const handleWidth = 6; function panes(container) { return Array.from(container.querySelectorAll(".pane")); } function widthsFromDOM(container) { return panes(container).map((pane) => Math.round(pane.getBoundingClientRect().width)); } function clampWidths(widths, total) { const next = widths.map((w, i) => Math.max(minWidths[i], Math.round(w || minWidths[i]))); const max = Math.max(total - handleWidth * (next.length - 1), minWidths.reduce((a, b) => a + b, 0)); const sum = next.reduce((a, b) => a + b, 0); if (sum > max) { let extra = sum - max; for (let i = next.length - 1; i >= 0 && extra > 0; i--) { const canTake = Math.max(0, next[i] - minWidths[i]); const take = Math.min(canTake, extra); next[i] -= take; extra -= take; } } return next; } function applyWidths(container, widths) { const total = container.getBoundingClientRect().width; const w = clampWidths(widths, total); container.style.gridTemplateColumns = `${w[0]}px ${handleWidth}px ${w[1]}px ${handleWidth}px minmax(${w[2]}px, 1fr)`; localStorage.setItem(key, JSON.stringify(w)); } function restore(container) { try { const saved = JSON.parse(localStorage.getItem(key) || "null"); if (Array.isArray(saved) && saved.length === 3) { applyWidths(container, saved); } } catch (_) { localStorage.removeItem(key); } } function bind(container) { if (!container || container.dataset.resizeBound === "1") return; container.dataset.resizeBound = "1"; restore(container); container.querySelectorAll(".pane-resizer").forEach((handle) => { handle.addEventListener("pointerdown", (event) => { if (window.matchMedia("(max-width: 820px)").matches) return; event.preventDefault(); handle.setPointerCapture(event.pointerId); handle.classList.add("dragging"); document.body.classList.add("resizing"); const index = Number(handle.dataset.resizeIndex || 0); const startX = event.clientX; const start = widthsFromDOM(container); function move(moveEvent) { const delta = moveEvent.clientX - startX; const next = start.slice(); const left = Math.max(minWidths[index], start[index] + delta); const used = left - start[index]; const right = Math.max(minWidths[index + 1], start[index + 1] - used); const actual = start[index + 1] - right; next[index] = start[index] + actual; next[index + 1] = right; applyWidths(container, next); } function up(upEvent) { handle.releasePointerCapture(upEvent.pointerId); handle.classList.remove("dragging"); document.body.classList.remove("resizing"); window.removeEventListener("pointermove", move); window.removeEventListener("pointerup", up); } window.addEventListener("pointermove", move); window.addEventListener("pointerup", up); }); }); } window.addEventListener("DOMContentLoaded", () => bind(document.querySelector(".four-pane"))); window.addEventListener("DOMContentLoaded", () => bind(document.querySelector(".three-pane"))); })(); (function () { function closeAll() { document.querySelectorAll(".ribbon-menu.open").forEach((menu) => { menu.classList.remove("open"); const button = menu.querySelector("[data-ribbon-menu-toggle]"); if (button) button.setAttribute("aria-expanded", "false"); }); } document.addEventListener("click", (event) => { const button = event.target.closest("[data-ribbon-menu-toggle]"); if (button) { const menu = button.closest(".ribbon-menu"); const willOpen = !menu.classList.contains("open"); closeAll(); menu.classList.toggle("open", willOpen); button.setAttribute("aria-expanded", willOpen ? "true" : "false"); return; } if (!event.target.closest(".ribbon-menu")) closeAll(); }); document.addEventListener("keydown", (event) => { if (event.key === "Escape") closeAll(); }); })(); (function () { function setOpen(open) { document.body.classList.toggle("backstage-open", open); document.querySelectorAll("[data-backstage-toggle]").forEach((button) => { button.setAttribute("aria-expanded", open ? "true" : "false"); }); } document.addEventListener("click", (event) => { const toggle = event.target.closest("[data-backstage-toggle]"); if (toggle) { setOpen(!document.body.classList.contains("backstage-open")); return; } if (event.target.closest("[data-backstage-close]")) { setOpen(false); } }); document.addEventListener("keydown", (event) => { if (event.key === "Escape") setOpen(false); }); })(); (function () { function rowPayload(row) { return { source: row.dataset.source || "", folder: row.dataset.folder || "", index: row.dataset.index || "" }; } document.addEventListener("dragstart", (event) => { const row = event.target.closest(".msg-row[draggable='true']"); if (!row || !event.dataTransfer) return; event.dataTransfer.effectAllowed = "copy"; event.dataTransfer.setData("application/json", JSON.stringify(rowPayload(row))); event.dataTransfer.setData("text/plain", `${row.dataset.source || ""}/${row.dataset.folder || ""}#${row.dataset.index || ""}`); row.classList.add("dragging"); }); document.addEventListener("dragend", (event) => { const row = event.target.closest(".msg-row"); if (row) row.classList.remove("dragging"); }); document.addEventListener("dragover", (event) => { const zone = event.target.closest("[data-drop-target='manual-copy']"); if (!zone) return; event.preventDefault(); zone.classList.add("drag-over"); if (event.dataTransfer) event.dataTransfer.dropEffect = "copy"; }); document.addEventListener("dragleave", (event) => { const zone = event.target.closest("[data-drop-target='manual-copy']"); if (zone) zone.classList.remove("drag-over"); }); document.addEventListener("drop", async (event) => { const zone = event.target.closest("[data-drop-target='manual-copy']"); if (!zone) return; event.preventDefault(); zone.classList.remove("drag-over"); let payload = {}; try { payload = JSON.parse(event.dataTransfer.getData("application/json") || "{}"); } catch (_) { payload = {}; } if (!payload.source) { payload = { source: zone.dataset.source || "", folder: zone.dataset.folder || "", index: zone.dataset.index || "" }; } const select = document.querySelector("#target-account-select"); const form = new URLSearchParams(); form.set("source", payload.source); form.set("folder", payload.folder); form.set("index", payload.index); form.set("target_account", select ? select.value : ""); zone.textContent = "Kopiere..."; const response = await fetch("/view/manual-copy", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" }, body: form.toString() }); const html = await response.text(); document.querySelector("#read").innerHTML = html; }); })();