// Fetch and render directory tree const treeContainer = document.getElementById('tree'); const contentContainer = document.getElementById('content'); function fetchTree(relPath = '') { fetch(`/api/tree?path=${encodeURIComponent(relPath)}`) .then(r => r.json()) .then(data => renderTree(data, relPath)) .catch(err => console.error('Tree error', err)); } function renderTree(items, parentPath) { const ul = document.createElement('ul'); items.forEach(item => { const li = document.createElement('li'); li.dataset.path = item.path; const span = document.createElement('span'); span.textContent = item.name; li.appendChild(span); if (item.type === 'dir') { li.classList.add('dir'); span.onclick = () => { // Toggle expansion if (li.dataset.loaded) { const child = li.querySelector('ul'); if (child) child.style.display = child.style.display === 'none' ? 'block' : 'none'; } else { fetchTree(item.path); li.dataset.loaded = 'true'; } }; } else if (item.type === 'file') { li.classList.add('file'); span.onclick = () => loadMarkdown(item.path); } ul.appendChild(li); }); // Append under the correct parent node const parentLi = treeContainer.querySelector(`li[data-path="${parentPath.replace(/"/g,'\\"')}"]`); if (parentLi) { // If already has a child ul, replace it const existing = parentLi.querySelector('ul'); if (existing) parentLi.replaceChild(ul, existing); else parentLi.appendChild(ul); } else { // Root level treeContainer.innerHTML = ''; treeContainer.appendChild(ul); } } function loadMarkdown(relPath) { fetch(`/api/md?path=${encodeURIComponent(relPath)}`) .then(r => r.json()) .then(data => { contentContainer.innerHTML = data.html; }) .catch(err => console.error('MD load error', err)); } // Initial load of root directory fetchTree();