// app.js — bootstrap. Runs after every other module's IIFE has // registered its functions on window.app.modules. (function () { 'use strict'; var state = window.app.state; var loader = window.app.modules.loader; var tree = window.app.modules.tree; var events = window.app.modules.events; // Virtual canonical folder injection used to live here (browse // appended archive/working/staging/reviewing entries at a project // root when missing). zddc-server now emits them in the listing // directly so the .zddc `display:` map can override their labels // the same as real entries. This pass-through stub keeps the // events.js rescope contract intact without doing any merging. function passThroughEntries(entries) { return entries; } // Expose for events.js's client-side rescope on dblclick. window.app.modules.augmentRoot = passThroughEntries; async function bootstrap() { events.init(); // Try server auto-detect. If this page is served by zddc-server // (or any server with a Caddy-shaped JSON listing), load the // current directory automatically. Otherwise show the empty // state with the "Select Directory" button. var detected = await loader.autoDetectServerMode(); if (detected) { tree.setRoot(detected.entries); events.showBrowseRoot(); tree.render(); events.statusInfo('Loaded ' + detected.entries.length + ' item' + (detected.entries.length === 1 ? '' : 's') + ' from ' + detected.path); } // Else: empty state stays visible; user can click Select Directory. // Browser back / forward: client-side rescope when the URL // changes via popstate. We can't tell server-vs-fs mode from // popstate alone, so only honor it in server mode. window.addEventListener('popstate', async function () { if (window.app.state.source !== 'server') return; var path = location.pathname; if (!path.endsWith('/')) path += '/'; try { var es = await loader.fetchServerChildren(path); window.app.state.currentPath = path; window.app.state.selectedId = null; window.app.state.lastPreviewedNodeId = null; tree.setRoot(es); tree.render(); var previewBody = document.getElementById('previewBody'); if (previewBody) previewBody.innerHTML = ''; var previewTitle = document.getElementById('previewTitle'); if (previewTitle) previewTitle.textContent = 'No file selected'; } catch (_e) { /* swallow — leave the tree as-is */ } }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', bootstrap); } else { bootstrap(); } })();