/** * browser.js * ---------- * Server-side directory browser modal. * * Fetches directory listings from /api/browse and renders them inside the * modal panel. The user navigates the server filesystem and selects a * directory to populate the scan path input. * * Exports * ------- * initBrowser() — attach all event listeners; call once at startup */ import { state, els, announce } from './state.js'; import { esc } from './utils.js'; // ─── Internal helpers ───────────────────────────────────────────────────────── async function loadBrowserPath(path) { els.browserList.innerHTML = '

Loading…

'; els.browserPath.textContent = path; try { const resp = await fetch(`/api/browse?path=${encodeURIComponent(path)}`); if (!resp.ok) throw new Error((await resp.json()).error || 'Error loading directory'); const data = await resp.json(); state.browserPath = data.current; els.browserPath.textContent = data.current; let html = ''; if (data.parent !== null) { html += ` `; } for (const entry of data.entries) { if (!entry.is_dir) continue; html += ` `; } if (!html) html = '

No subdirectories found.

'; els.browserList.innerHTML = html; els.browserList.querySelectorAll('.browser-item').forEach(btn => { btn.addEventListener('click', () => loadBrowserPath(btn.dataset.path)); btn.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); loadBrowserPath(btn.dataset.path); } }); }); } catch (err) { els.browserList.innerHTML = ``; } } function openBrowser() { els.browserModal.hidden = false; document.body.style.overflow = 'hidden'; loadBrowserPath(els.dirInput.value || '/'); els.closeBrowser.focus(); announce('Directory browser opened'); } function closeBrowser() { els.browserModal.hidden = true; document.body.style.overflow = ''; els.browseBtn.focus(); announce('Directory browser closed'); } // ─── Public init ───────────────────────────────────────────────────────────── /** * Attach all event listeners for the directory browser modal. * Call once during app initialisation. */ export function initBrowser() { els.browseBtn.addEventListener('click', openBrowser); els.closeBrowser.addEventListener('click', closeBrowser); els.browserCancel.addEventListener('click', closeBrowser); els.browserModal.addEventListener('click', e => { if (e.target === els.browserModal) closeBrowser(); }); els.browserSelect.addEventListener('click', () => { els.dirInput.value = state.browserPath; closeBrowser(); announce(`Directory selected: ${state.browserPath}`); }); document.addEventListener('keydown', e => { if (e.key === 'Escape' && !els.browserModal.hidden) closeBrowser(); }); }