// ── Plugin Settings UI ── // Renders the list of installed plugins with on/off toggles in the // settings overlay. Disabled plugins are skipped at PHP render time; // toggling requires a reload to take effect (page must re-fetch the // new script/css/html tag set). import { $, esc, api } from './util.js'; let pluginsCache = null; let dirtyAfterToggle = false; async function fetchPlugins() { const res = await fetch('api/plugins'); if (!res.ok) throw new Error('failed to load plugins'); pluginsCache = await res.json(); return pluginsCache; } function render(list) { const container = $('plugins-list'); if (!container) return; if (!list.length) { container.innerHTML = '

No plugins installed. Drop a plugin folder into public/plugins/ to add one.

'; return; } container.innerHTML = list.map(p => `
${esc(p.name)} v${esc(p.version || '?')} ${p.hasBackend ? 'php' : ''}
${p.description ? `
${esc(p.description)}
` : ''}
`).join(''); container.querySelectorAll('.plugin-toggle').forEach(input => { input.addEventListener('change', onToggle); }); } async function onToggle(e) { const input = e.currentTarget; const name = input.dataset.name; const enabled = input.checked; input.disabled = true; try { const res = await api('api/plugins/toggle', { method: 'POST', body: { name, enabled }, }); if (res.error) throw new Error(res.error); pluginsCache = res.plugins; dirtyAfterToggle = true; $('plugins-reload-notice')?.classList.remove('hidden'); } catch (err) { // Revert UI on failure input.checked = !enabled; console.error('[plugins] toggle failed:', err); } finally { input.disabled = false; } } export async function openPluginSettings() { const container = $('plugins-list'); if (!container) return; container.innerHTML = '

Loading...

'; if (!dirtyAfterToggle) { $('plugins-reload-notice')?.classList.add('hidden'); } try { const list = await fetchPlugins(); render(list); } catch (err) { container.innerHTML = `

Failed to load plugins: ${esc(err.message)}

`; } } // Wire reload button once at module load document.addEventListener('DOMContentLoaded', () => { $('plugins-reload-btn')?.addEventListener('click', () => location.reload()); }, { once: true }); // In case DOMContentLoaded already fired (modules are deferred but safe to retry) $('plugins-reload-btn')?.addEventListener('click', () => location.reload());