image file info toegevoegd bij CMD+ENTER

This commit is contained in:
kodi
2026-03-13 11:37:27 +01:00
parent 05569576a7
commit 018c3dcd94
18 changed files with 726 additions and 0 deletions
+146
View File
@@ -51,6 +51,12 @@ let batchMoveState = {
destinationBase: "",
count: 0,
};
let imageViewerState = {
scale: 1,
fitScale: 1,
path: null,
resizeHandler: null,
};
let settingsState = {
activeTab: "general",
logsLoaded: false,
@@ -203,6 +209,22 @@ function pdfElements() {
};
}
function imageElements() {
return {
overlay: document.getElementById("image-modal"),
title: document.getElementById("image-title"),
fileName: document.getElementById("image-file-name"),
filePath: document.getElementById("image-file-path"),
error: document.getElementById("image-error"),
viewport: document.getElementById("image-viewport"),
image: document.getElementById("image-viewer-img"),
closeButton: document.getElementById("image-close-btn"),
zoomInButton: document.getElementById("image-zoom-in-btn"),
zoomOutButton: document.getElementById("image-zoom-out-btn"),
resetButton: document.getElementById("image-reset-btn"),
};
}
function moveElements() {
return {
overlay: document.getElementById("move-popup"),
@@ -655,6 +677,32 @@ function isPdfSelection(item) {
return (item.name || "").toLowerCase().endsWith(".pdf");
}
function isImageSelection(item) {
if (!item || item.kind !== "file") {
return false;
}
const lower = (item.name || "").toLowerCase();
return [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp", ".avif"].some((suffix) => lower.endsWith(suffix));
}
function currentImageScale() {
return Number.isFinite(imageViewerState.scale) ? imageViewerState.scale : 1;
}
function applyImageScale() {
const image = imageElements().image;
image.style.transform = `scale(${currentImageScale()})`;
}
function resetImageViewerState() {
imageViewerState = {
scale: 1,
fitScale: 1,
path: null,
resizeHandler: null,
};
}
function currentParentPath(path) {
const normalized = (path || "").trim();
if (!normalized) {
@@ -1771,6 +1819,55 @@ function closePdfViewer() {
pdf.frame.removeAttribute("src");
}
function isImageOpen() {
return !imageElements().overlay.classList.contains("hidden");
}
function fitImageToViewport() {
const image = imageElements().image;
const viewport = imageElements().viewport;
if (!image.naturalWidth || !image.naturalHeight) {
return;
}
const widthScale = viewport.clientWidth / image.naturalWidth;
const heightScale = viewport.clientHeight / image.naturalHeight;
imageViewerState.fitScale = Math.min(widthScale, heightScale, 1);
imageViewerState.scale = imageViewerState.fitScale;
applyImageScale();
}
function adjustImageZoom(multiplier) {
if (!isImageOpen()) {
return;
}
const minScale = Math.max(imageViewerState.fitScale * 0.5, 0.1);
const maxScale = Math.max(imageViewerState.fitScale * 6, 1.5);
imageViewerState.scale = Math.min(maxScale, Math.max(minScale, currentImageScale() * multiplier));
applyImageScale();
}
function resetImageZoom() {
if (!isImageOpen()) {
return;
}
imageViewerState.scale = imageViewerState.fitScale;
applyImageScale();
}
function closeImageViewer() {
const image = imageElements();
image.overlay.classList.add("hidden");
image.error.textContent = "";
image.image.removeAttribute("src");
image.image.removeAttribute("alt");
image.image.onload = null;
image.image.onerror = null;
if (imageViewerState.resizeHandler) {
window.removeEventListener("resize", imageViewerState.resizeHandler);
}
resetImageViewerState();
}
function isInfoOpen() {
return !infoElements().overlay.classList.contains("hidden");
}
@@ -1815,6 +1912,8 @@ async function openInfo() {
renderInfoField("Content type", data.content_type);
renderInfoField("Owner", data.owner);
renderInfoField("Group", data.group);
renderInfoField("Width", data.width);
renderInfoField("Height", data.height);
} catch (err) {
elements.error.textContent = err.message;
}
@@ -2116,6 +2215,36 @@ async function openPdfViewer() {
pdf.frame.src = pdfUrl;
}
async function openImageViewer() {
const selectedItems = activePaneState().selectedItems;
if (selectedItems.length !== 1 || !isImageSelection(selectedItems[0])) {
return;
}
const selected = selectedItems[0];
const image = imageElements();
const imageUrl = `/api/files/image?${new URLSearchParams({ path: selected.path }).toString()}`;
closeImageViewer();
image.overlay.classList.remove("hidden");
image.title.textContent = "Image";
image.fileName.textContent = selected.name;
image.filePath.textContent = selected.path;
image.error.textContent = "";
image.image.alt = selected.name;
image.image.onload = () => {
fitImageToViewport();
image.image.onload = null;
};
image.image.onerror = () => {
image.error.textContent = "Image could not be displayed in this browser.";
image.image.onerror = null;
};
imageViewerState.path = selected.path;
imageViewerState.resizeHandler = () => fitImageToViewport();
window.addEventListener("resize", imageViewerState.resizeHandler);
image.image.src = imageUrl;
}
function videoPlaybackMessage(item) {
const lower = (item.name || "").toLowerCase();
if (lower.endsWith(".mkv")) {
@@ -2179,6 +2308,10 @@ function openViewer() {
return;
}
const selected = selectedItems[0];
if (isImageSelection(selected)) {
openImageViewer();
return;
}
if (isVideoSelection(selected)) {
openVideoViewer();
return;
@@ -2369,6 +2502,13 @@ function handleKeyboardShortcuts(event) {
}
return;
}
if (isImageOpen()) {
if (event.key === "Escape") {
event.preventDefault();
closeImageViewer();
}
return;
}
if (isVideoOpen()) {
if (event.key === "Escape") {
event.preventDefault();
@@ -2553,6 +2693,12 @@ function setupEvents() {
}
};
const image = imageElements();
image.closeButton.onclick = closeImageViewer;
image.zoomInButton.onclick = () => adjustImageZoom(1.2);
image.zoomOutButton.onclick = () => adjustImageZoom(1 / 1.2);
image.resetButton.onclick = resetImageZoom;
const search = searchElements();
search.closeButton.onclick = closeSearch;
search.overlay.onclick = (event) => {