image file info toegevoegd bij CMD+ENTER
This commit is contained in:
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user