feat: Lightroom-style workspace UI #2

Merged
iu merged 18 commits from feature/lightroom-workspace-ui into develop 2026-10-10 19:56:23 +00:00
Showing only changes of commit 642e3bcf8a - Show all commits
+7 -77
View File
@@ -37,12 +37,7 @@
let showBottom = $state(false);
let showLeft = $state(false);
let showRight = $state(false);
const EDGE = 8;
let hideTopTimer: ReturnType<typeof setTimeout> | undefined;
let hideBottomTimer: ReturnType<typeof setTimeout> | undefined;
let hideLeftTimer: ReturnType<typeof setTimeout> | undefined;
let hideRightTimer: ReturnType<typeof setTimeout> | undefined;
let dragging = false;
let startX = 0;
@@ -99,13 +94,7 @@
resetBars();
};
document.addEventListener('fullscreenchange', onFs);
return () => {
document.removeEventListener('fullscreenchange', onFs);
clearTimeout(hideTopTimer);
clearTimeout(hideBottomTimer);
clearTimeout(hideLeftTimer);
clearTimeout(hideRightTimer);
};
return () => document.removeEventListener('fullscreenchange', onFs);
});
const topClass = $derived(
@@ -132,14 +121,6 @@
);
function resetBars() {
clearTimeout(hideTopTimer);
clearTimeout(hideBottomTimer);
clearTimeout(hideLeftTimer);
clearTimeout(hideRightTimer);
hideTopTimer = undefined;
hideBottomTimer = undefined;
hideLeftTimer = undefined;
hideRightTimer = undefined;
showTop = false;
showBottom = false;
showLeft = false;
@@ -152,70 +133,19 @@
return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;
}
function scheduleTop(shouldShow: boolean) {
if (shouldShow) {
clearTimeout(hideTopTimer);
hideTopTimer = undefined;
showTop = true;
} else if (showTop && !hideTopTimer) {
hideTopTimer = setTimeout(() => {
showTop = false;
hideTopTimer = undefined;
}, 1000);
}
}
function scheduleBottom(shouldShow: boolean) {
if (shouldShow) {
clearTimeout(hideBottomTimer);
hideBottomTimer = undefined;
showBottom = true;
} else if (showBottom && !hideBottomTimer) {
hideBottomTimer = setTimeout(() => {
showBottom = false;
hideBottomTimer = undefined;
}, 1000);
}
}
function scheduleLeft(shouldShow: boolean) {
if (shouldShow) {
clearTimeout(hideLeftTimer);
hideLeftTimer = undefined;
showLeft = true;
} else if (showLeft && !hideLeftTimer) {
hideLeftTimer = setTimeout(() => {
showLeft = false;
hideLeftTimer = undefined;
}, 300);
}
}
function scheduleRight(shouldShow: boolean) {
if (shouldShow) {
clearTimeout(hideRightTimer);
hideRightTimer = undefined;
showRight = true;
} else if (showRight && !hideRightTimer) {
hideRightTimer = setTimeout(() => {
showRight = false;
hideRightTimer = undefined;
}, 300);
}
}
function onWinMouseMove(e: MouseEvent) {
const r = viewerEl?.getBoundingClientRect();
if (r) {
const zoneX = r.width / 6;
scheduleLeft(!zoomed && e.clientX <= r.left + zoneX);
scheduleRight(!zoomed && e.clientX >= r.right - zoneX);
const insideY = e.clientY >= r.top && e.clientY <= r.bottom;
showLeft = !zoomed && insideY && e.clientX >= r.left && e.clientX <= r.left + zoneX;
showRight = !zoomed && insideY && e.clientX <= r.right && e.clientX >= r.right - zoneX;
}
if (!isFullscreen) return;
const nearTop = e.clientY <= EDGE;
const nearBottom = e.clientY >= window.innerHeight - EDGE;
scheduleTop(nearTop || inRect(topEl, e.clientX, e.clientY));
scheduleBottom(nearBottom || inRect(bottomEl, e.clientX, e.clientY));
showTop = nearTop || inRect(topEl, e.clientX, e.clientY);
showBottom = nearBottom || inRect(bottomEl, e.clientX, e.clientY);
}
function baseWidth(): number {
@@ -313,7 +243,7 @@
async function toggleViewerFullscreen() {
if (!viewerEl) return;
try {
if (document.fullscreenElement) await document.exitFullscreen();
if (document.fullscreenElement === viewerEl) await document.exitFullscreen();
else await viewerEl.requestFullscreen();
} catch {
/* недоступно */