Add manual target drag and drop

This commit is contained in:
DonVoo 2026-07-06 11:02:29 +02:00
parent ffa28f6182
commit a4eee37ab9
4 changed files with 229 additions and 35 deletions

View file

@ -1,6 +1,6 @@
(function () {
const key = "mail-graveyard-pane-widths";
const minWidths = [160, 220, 260, 260];
const key = "mail-graveyard-pane-widths-v2";
const minWidths = [160, 220, 300];
const handleWidth = 6;
function panes(container) {
@ -13,7 +13,7 @@
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 * 3, minWidths.reduce((a, b) => a + b, 0));
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;
@ -31,14 +31,14 @@
const total = container.getBoundingClientRect().width;
const w = clampWidths(widths, total);
container.style.gridTemplateColumns =
`${w[0]}px ${handleWidth}px ${w[1]}px ${handleWidth}px ${w[2]}px ${handleWidth}px ${w[3]}px`;
`${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 === 4) {
if (Array.isArray(saved) && saved.length === 3) {
applyWidths(container, saved);
}
} catch (_) {
@ -90,4 +90,79 @@
}
window.addEventListener("DOMContentLoaded", () => bind(document.querySelector(".four-pane")));
window.addEventListener("DOMContentLoaded", () => bind(document.querySelector(".three-pane")));
})();
(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;
});
})();