Add resizable viewer panes
This commit is contained in:
parent
a4ea4c120e
commit
2bdf622257
3 changed files with 110 additions and 7 deletions
93
frontend-js/dist/app.js
vendored
Normal file
93
frontend-js/dist/app.js
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
(function () {
|
||||
const key = "mail-graveyard-pane-widths";
|
||||
const minWidths = [160, 220, 260, 260];
|
||||
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 * 3, 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 ${w[2]}px ${handleWidth}px ${w[3]}px`;
|
||||
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) {
|
||||
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")));
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue