fix: conserver plein ecran et panneau metadonnees dans la visionneuse d'images (sidebar droite) + lanceur E2E Windows BUG-072
This commit is contained in:
+48
-15
@@ -548,6 +548,13 @@ const IMAGE_EXTS = new Set([".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".
|
||||
const IMAGE_ZOOM_MIN = 0.1;
|
||||
const IMAGE_ZOOM_MAX = 8;
|
||||
let _imageViewerCleanup = null;
|
||||
// BUG-072 — the lightbox and metadata panel states must survive the re-render
|
||||
// triggered by ←/→ navigation (openFile → renderFile → renderImageViewer).
|
||||
// Reset as soon as a non-image file is rendered.
|
||||
const _imageViewerState = { lightbox: false, meta: false };
|
||||
// Set right before an image→image navigation (←/→ / filmstrip click) so
|
||||
// renderFile knows the state above must be carried over instead of reset.
|
||||
let _imageViewerNavPending = false;
|
||||
|
||||
/** Clamp a zoom factor into the supported [0.1, 8] range. */
|
||||
export function clampImageZoom(value) {
|
||||
@@ -614,27 +621,29 @@ export function renderImageViewer(area, data) {
|
||||
const nextBtn = mkBtn("chevron-right", t("viewer.image_next"));
|
||||
const originalBtn = mkBtn("external-link", t("viewer.image_open_original"));
|
||||
const downloadBtn = mkBtn("download", t("viewer.download"));
|
||||
const metaBtn = mkBtn("info", t("viewer.image_metadata"));
|
||||
const lightboxBtn = mkBtn("maximize", t("viewer.image_fullscreen"));
|
||||
const metaBtn = mkBtn("info", t("viewer.image_metadata"), "image-btn-metadata");
|
||||
const lightboxBtn = mkBtn("maximize", t("viewer.image_fullscreen"), "image-btn-lightbox");
|
||||
[prevBtn, nextBtn, zoomOutBtn, zoomInBtn, zoomResetBtn, metaBtn, originalBtn, downloadBtn, lightboxBtn]
|
||||
.forEach((b) => toolbar.appendChild(b));
|
||||
container.appendChild(toolbar);
|
||||
|
||||
// ── Stage (image + pan/zoom) ───────────────────────────────────────────
|
||||
// ── Body: image stage + metadata sidebar (right) ───────────────────────
|
||||
const body = el("div", { class: "image-viewer-body" });
|
||||
const stage = el("div", { class: "image-stage" });
|
||||
const img = el("img", { class: "image-main", src: imgUrl, alt: data.title || fileName, draggable: "false" });
|
||||
stage.appendChild(img);
|
||||
container.appendChild(stage);
|
||||
body.appendChild(stage);
|
||||
|
||||
// ── Metadata sidebar (kept open across ←/→ navigation) ─────────────────
|
||||
const metaPanel = el("div", { class: "image-meta-panel" });
|
||||
metaPanel.hidden = !_imageViewerState.meta;
|
||||
body.appendChild(metaPanel);
|
||||
container.appendChild(body);
|
||||
|
||||
// ── Thumbnail filmstrip (navigation) ───────────────────────────────────
|
||||
const strip = el("div", { class: "image-nav-strip", hidden: true });
|
||||
container.appendChild(strip);
|
||||
|
||||
// ── Metadata panel ─────────────────────────────────────────────────────
|
||||
const metaPanel = el("div", { class: "image-meta-panel" });
|
||||
metaPanel.hidden = true;
|
||||
container.appendChild(metaPanel);
|
||||
|
||||
let scale = 1;
|
||||
let tx = 0;
|
||||
let ty = 0;
|
||||
@@ -674,6 +683,7 @@ export function renderImageViewer(area, data) {
|
||||
const go = (delta) => {
|
||||
if (siblings.length < 2 || currentIndex < 0) return;
|
||||
const next = (currentIndex + delta + siblings.length) % siblings.length;
|
||||
_imageViewerNavPending = true;
|
||||
openFile(vault, siblings[next].path);
|
||||
};
|
||||
|
||||
@@ -689,7 +699,11 @@ export function renderImageViewer(area, data) {
|
||||
title: s.name,
|
||||
loading: "lazy",
|
||||
});
|
||||
thumb.addEventListener("click", () => { if (s.path !== path) openFile(vault, s.path); });
|
||||
thumb.addEventListener("click", () => {
|
||||
if (s.path === path) return;
|
||||
_imageViewerNavPending = true;
|
||||
openFile(vault, s.path);
|
||||
});
|
||||
strip.appendChild(thumb);
|
||||
});
|
||||
};
|
||||
@@ -751,13 +765,21 @@ export function renderImageViewer(area, data) {
|
||||
const dlUrl = `/api/file/${encodeURIComponent(vault)}/download?path=${encodeURIComponent(path)}`;
|
||||
window.open(dlUrl, "_blank");
|
||||
});
|
||||
metaBtn.setAttribute("aria-pressed", _imageViewerState.meta ? "true" : "false");
|
||||
metaBtn.addEventListener("click", () => {
|
||||
metaPanel.hidden = !metaPanel.hidden;
|
||||
if (!metaPanel.hidden) renderMeta();
|
||||
_imageViewerState.meta = !_imageViewerState.meta;
|
||||
metaPanel.hidden = !_imageViewerState.meta;
|
||||
metaBtn.setAttribute("aria-pressed", _imageViewerState.meta ? "true" : "false");
|
||||
if (_imageViewerState.meta) renderMeta();
|
||||
});
|
||||
const syncLightbox = () => {
|
||||
container.classList.toggle("lightbox", _imageViewerState.lightbox);
|
||||
lightboxBtn.setAttribute("aria-pressed", _imageViewerState.lightbox ? "true" : "false");
|
||||
};
|
||||
syncLightbox();
|
||||
lightboxBtn.addEventListener("click", () => {
|
||||
container.classList.toggle("lightbox");
|
||||
lightboxBtn.setAttribute("aria-pressed", container.classList.contains("lightbox") ? "true" : "false");
|
||||
_imageViewerState.lightbox = !_imageViewerState.lightbox;
|
||||
syncLightbox();
|
||||
});
|
||||
|
||||
img.addEventListener("load", () => { if (!metaPanel.hidden) renderMeta(); });
|
||||
@@ -772,7 +794,10 @@ export function renderImageViewer(area, data) {
|
||||
else if (e.key === "+" || e.key === "=") { e.preventDefault(); setZoom(scale * 1.25); }
|
||||
else if (e.key === "-") { e.preventDefault(); setZoom(scale / 1.25); }
|
||||
else if (e.key === "0") { e.preventDefault(); resetView(); }
|
||||
else if (e.key === "Escape") { container.classList.remove("lightbox"); }
|
||||
else if (e.key === "Escape") {
|
||||
_imageViewerState.lightbox = false;
|
||||
syncLightbox();
|
||||
}
|
||||
};
|
||||
document.addEventListener("keydown", onKey);
|
||||
_imageViewerCleanup = () => document.removeEventListener("keydown", onKey);
|
||||
@@ -780,6 +805,7 @@ export function renderImageViewer(area, data) {
|
||||
area.appendChild(container);
|
||||
safeCreateIcons();
|
||||
applyTransform();
|
||||
if (_imageViewerState.meta) renderMeta();
|
||||
try { container.focus({ preventScroll: true }); } catch (_) { /* non-fatal */ }
|
||||
}
|
||||
|
||||
@@ -810,6 +836,13 @@ export function renderFile(data) {
|
||||
// #108 — release the image viewer's document-level shortcuts before swapping
|
||||
// the content area (otherwise they leak on every re-render).
|
||||
if (_imageViewerCleanup) { _imageViewerCleanup(); _imageViewerCleanup = null; }
|
||||
// BUG-072 — carry the lightbox / metadata-panel state over an image→image
|
||||
// navigation; any other render starts from a clean viewer.
|
||||
if (!data.is_image || !_imageViewerNavPending) {
|
||||
_imageViewerState.lightbox = false;
|
||||
_imageViewerState.meta = false;
|
||||
}
|
||||
_imageViewerNavPending = false;
|
||||
const area = getContentArea();
|
||||
// #110 — if this render is about to replace the surface that currently hosts
|
||||
// the shared media element, hand it back to the persistent dock first.
|
||||
|
||||
+11
-4
@@ -9673,6 +9673,11 @@ body.desktop-mode .editor-container {
|
||||
min-width: 46px;
|
||||
text-align: center;
|
||||
}
|
||||
.image-viewer-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
}
|
||||
.image-stage {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
@@ -9680,7 +9685,7 @@ body.desktop-mode .editor-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 60vh;
|
||||
min-width: 0;
|
||||
background: var(--surface2);
|
||||
cursor: grab;
|
||||
touch-action: none;
|
||||
@@ -9731,9 +9736,12 @@ body.desktop-mode .editor-container {
|
||||
opacity: 1;
|
||||
}
|
||||
.image-meta-panel {
|
||||
width: 280px;
|
||||
max-width: 40%;
|
||||
overflow-y: auto;
|
||||
padding: 10px 16px;
|
||||
background: var(--surface);
|
||||
border-top: 1px solid var(--border);
|
||||
border-left: 1px solid var(--border);
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-secondary);
|
||||
flex-shrink: 0;
|
||||
@@ -9761,8 +9769,7 @@ body.desktop-mode .editor-container {
|
||||
z-index: 2000;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
.image-viewer-container.lightbox .image-nav-strip,
|
||||
.image-viewer-container.lightbox .image-meta-panel {
|
||||
.image-viewer-container.lightbox .image-nav-strip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user