Add preview next previous navigation
This commit is contained in:
+29
-3
@@ -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()) {
|
||||
|
||||
@@ -704,12 +704,22 @@
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--line);
|
||||
color: var(--muted);
|
||||
display: flex;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
justify-content: space-between;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.u-nav .preview-nav {
|
||||
display: inline-flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.u-nav .preview-nav button:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.42;
|
||||
}
|
||||
|
||||
.u-nav .preview-meta strong {
|
||||
color: var(--text);
|
||||
min-width: 0;
|
||||
|
||||
Reference in New Issue
Block a user