Add preview next previous navigation

This commit is contained in:
Mikei386
2026-06-23 13:58:29 +02:00
parent 9f1119a72f
commit fa323e572e
6 changed files with 44 additions and 8 deletions
+29 -3
View File
@@ -120,7 +120,7 @@ function openProperties(entry = state.selectedEntry) {
});
}
function openPreview(entry) {
function openPreview(entry, sourceWindowId = state.focusedId) {
if (!entry || !isPreviewable(entry)) {
showError(new Error('Für diesen Dateityp ist keine Vorschau verfügbar.'));
return null;
@@ -129,6 +129,7 @@ function openPreview(entry) {
const existing = state.windows.find((item) => item.kind === 'preview');
if (existing) {
existing.data.entry = entry;
existing.data.sourceWindowId = sourceWindowId;
existing.data.content = '';
existing.data.loading = true;
existing.data.error = null;
@@ -145,6 +146,7 @@ function openPreview(entry) {
y: 110,
data: {
entry,
sourceWindowId,
content: '',
loading: true,
error: null
@@ -333,7 +335,7 @@ function renderExplorer(body, win) {
if (entry.type === 'directory') {
loadExplorer(win, entry.path);
} else if (isPreviewable(entry)) {
openPreview(entry);
openPreview(entry, win.id);
}
});
row.addEventListener('contextmenu', (event) => {
@@ -425,13 +427,20 @@ function renderPreview(body, win) {
return;
}
const entry = data.entry;
const navigation = previewNavigation(data);
body.innerHTML = `
<div class="preview-meta">
<div class="preview-nav">
<button class="icon" data-action="preview-prev" title="Vorherige Datei" aria-label="Vorherige Datei" ${navigation.previous ? '' : 'disabled'}>←</button>
<button class="icon" data-action="preview-next" title="Nächste Datei" aria-label="Nächste Datei" ${navigation.next ? '' : 'disabled'}>→</button>
</div>
<strong>${escapeHtml(entry?.name || data.name || 'Vorschau')}</strong>
<span>${escapeHtml(formatBytes(data.size || entry?.size || 0))}</span>
</div>
${renderPreviewContent(data)}
`;
body.querySelector('[data-action="preview-prev"]')?.addEventListener('click', () => openPreview(navigation.previous, data.sourceWindowId));
body.querySelector('[data-action="preview-next"]')?.addEventListener('click', () => openPreview(navigation.next, data.sourceWindowId));
}
function renderPreviewContent(data) {
@@ -456,6 +465,22 @@ function renderPreviewContent(data) {
return `<pre class="preview-text">${escapeHtml(data.content || '')}</pre>`;
}
function previewNavigation(data) {
const source = state.windows.find((win) => win.id === data.sourceWindowId && win.kind === 'explorer');
const entries = (source?.data.entries || []).filter(isPreviewable);
if (entries.length < 2) {
return { previous: null, next: null };
}
const index = entries.findIndex((entry) => entry.path === data.entry?.path);
if (index < 0) {
return { previous: null, next: null };
}
return {
previous: entries[(index - 1 + entries.length) % entries.length],
next: entries[(index + 1) % entries.length]
};
}
async function loadPreview(win, entry) {
win.data.loading = true;
win.data.error = null;
@@ -463,6 +488,7 @@ async function loadPreview(win, entry) {
try {
const result = await api(apiUrl(`preview.php?path=${encodeURIComponent(entry.path)}`));
win.data.entry = entry;
win.data.sourceWindowId = win.data.sourceWindowId || state.focusedId;
win.data.name = result.name;
win.data.size = result.size;
win.data.type = result.type;
@@ -1000,7 +1026,7 @@ function renderContextMenu() {
if (entry.type === 'directory') {
actions.push(['Öffnen', () => loadExplorer(win, entry.path)]);
} else if (isPreviewable(entry)) {
actions.push(['Vorschau', () => openPreview(entry)]);
actions.push(['Vorschau', () => openPreview(entry, win.id)]);
}
actions.push(['Eigenschaften', () => showPropertiesForEntry(win, entry)]);
if (!isReadOnly()) {