const els = { body: document.body, menuBtn: document.getElementById("menuBtn"), sectionSelect: document.getElementById("sectionSelect"), sortSelect: document.getElementById("sortSelect"), searchBox: document.getElementById("searchBox"), postList: document.getElementById("postList"), viewer: document.getElementById("viewer"), content: document.getElementById("content") }; let indexData = null; let state = { section: "posts", sort: "newest", query: "", sidebarOpen: false }; async function init(){ indexData = await (await fetch("index.json")).json(); populateSections(); wireUI(); renderList(); handleHash(); window.addEventListener("hashchange", handleHash); } function populateSections(){ els.sectionSelect.innerHTML = ""; indexData.sections.forEach(s=>{ const opt = document.createElement("option"); opt.value = s; opt.textContent = s; els.sectionSelect.appendChild(opt); }); } function wireUI(){ els.menuBtn.addEventListener("click", ()=>{ state.sidebarOpen = !state.sidebarOpen; document.body.classList.toggle("sidebar-open", state.sidebarOpen); }); els.sectionSelect.addEventListener("change", ()=>renderList()); els.sortSelect.addEventListener("change", ()=>renderList()); els.searchBox.addEventListener("input", ()=>renderList()); els.content.addEventListener("click", ()=>{ if (window.matchMedia("(max-width:1024px)").matches && document.body.classList.contains("sidebar-open")){ document.body.classList.remove("sidebar-open"); state.sidebarOpen = false; } }); } function renderList(){ const section = els.sectionSelect.value; const sort = els.sortSelect.value; const query = els.searchBox.value.toLowerCase(); let posts = indexData.flat.filter(p=>p.path.startsWith(section)); if (query) posts = posts.filter(p=>p.title.toLowerCase().includes(query)); posts.sort((a,b)=> sort==="newest"? b.mtime-a.mtime : a.mtime-b.mtime); els.postList.innerHTML = ""; for (const p of posts){ const li = document.createElement("li"); li.innerHTML = `${p.title}
${new Date(p.mtime).toISOString().split("T")[0]}`; els.postList.appendChild(li); } } async function handleHash(){ const rel = location.hash.replace(/^#\//,""); if (!rel) return renderDefault(); const file = indexData.flat.find(f=>f.path===rel); if (!file) return; file.ext===".md"? await renderMarkdown(file.path) : renderHTML(file.path); } async function renderMarkdown(rel){ const src = await fetch(rel).then(r=>r.text()); const html = marked.parse(src); els.viewer.innerHTML = `
${html}
`; } function renderHTML(rel){ const iframe = document.createElement("iframe"); iframe.setAttribute("sandbox","allow-same-origin allow-scripts allow-forms"); iframe.loading = "eager"; iframe.src = "/" + rel; els.viewer.innerHTML = ""; els.viewer.appendChild(iframe); iframe.addEventListener("load", ()=>{ try{ const d = iframe.contentDocument || iframe.contentWindow.document; const s = d.createElement("style"); s.textContent = ` html,body{margin:0;padding:0;background:transparent;color:#e6e3d7;font:16px/1.6 Inter,ui-sans-serif;} main,article,section{max-width:720px;margin:auto;padding:2rem;} `; d.head.appendChild(s); }catch{} }); } function renderDefault(){ const latest = [...indexData.flat].sort((a,b)=>b.mtime-a.mtime)[0]; if (latest) location.hash = "#/" + latest.path; } init();