Add explorer icon view
This commit is contained in:
+29
-2
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user