Add explorer icon view

This commit is contained in:
Mikei386
2026-06-23 08:48:15 +02:00
parent 55d7a8989a
commit dde4236a91
6 changed files with 131 additions and 6 deletions
+29 -2
View File
@@ -73,6 +73,7 @@ function openExplorer(initialPath = state.config?.roots?.[0]?.path) {
path: initialPath,
entries: [],
selectedPath: null,
view: 'list',
loading: false,
error: null
}
@@ -202,10 +203,14 @@ function renderExplorer(body, win) {
<input value="${escapeAttr(data.path || '')}" aria-label="Pfad">
<button data-action="go">Öffnen</button>
<button data-action="refresh">Neu laden</button>
<div class="view-toggle" aria-label="Ansicht">
<button class="${data.view !== 'icons' ? 'active' : ''}" data-action="view-list" title="Listenansicht">Liste</button>
<button class="${data.view === 'icons' ? 'active' : ''}" data-action="view-icons" title="Symbolansicht">Symbole</button>
</div>
</div>
<div class="drop-zone ${data.dragOver ? 'drag-over' : ''}">
${data.error ? `<p class="muted">${escapeHtml(data.error)}</p>` : ''}
${data.loading ? '<p class="muted">Lade...</p>' : renderFileTable(data.entries || [])}
${data.loading ? '<p class="muted">Lade...</p>' : renderFileEntries(data.entries || [], data.view || 'list')}
</div>
`;
@@ -213,6 +218,8 @@ function renderExplorer(body, win) {
body.querySelector('[data-action="go"]').addEventListener('click', () => loadExplorer(win, input.value));
body.querySelector('[data-action="refresh"]').addEventListener('click', () => loadExplorer(win, data.path));
body.querySelector('[data-action="up"]').addEventListener('click', () => loadExplorer(win, parentPath(data.path)));
body.querySelector('[data-action="view-list"]').addEventListener('click', () => setExplorerView(win, 'list'));
body.querySelector('[data-action="view-icons"]').addEventListener('click', () => setExplorerView(win, 'icons'));
const dropZone = body.querySelector('.drop-zone');
dropZone.addEventListener('dragenter', (event) => {
@@ -273,11 +280,14 @@ function renderExplorer(body, win) {
}
}
function renderFileTable(entries) {
function renderFileEntries(entries, view) {
if (!entries.length) {
return '<p class="muted">Dieser Ordner ist leer. Dateien können hier abgelegt werden.</p>';
}
return view === 'icons' ? renderFileIcons(entries) : renderFileTable(entries);
}
function renderFileTable(entries) {
const rows = entries.map((entry) => `
<tr class="file-row ${entry.path === state.selectedEntry?.path ? 'selected' : ''}" data-path="${escapeAttr(entry.path)}" data-type="${escapeAttr(entry.type)}">
<td><span class="name-cell"><span class="badge">${icons[entry.type] || 'Item'}</span>${escapeHtml(entry.name)}</span></td>
@@ -295,6 +305,23 @@ function renderFileTable(entries) {
`;
}
function renderFileIcons(entries) {
const items = entries.map((entry) => `
<button type="button" class="file-row icon-item ${entry.path === state.selectedEntry?.path ? 'selected' : ''}" data-path="${escapeAttr(entry.path)}" data-type="${escapeAttr(entry.type)}">
<span class="file-icon ${escapeAttr(entry.type)}">${icons[entry.type] || 'Item'}</span>
<span class="icon-name">${escapeHtml(entry.name)}</span>
<span class="icon-meta">${entry.type === 'file' ? formatBytes(entry.size) : entry.type}</span>
</button>
`).join('');
return `<div class="icon-grid">${items}</div>`;
}
function setExplorerView(win, view) {
win.data.view = view;
render();
}
function renderProperties(body) {
const entry = state.selectedEntry;
if (!entry) {