diff --git a/public/app.js b/public/app.js index ee2f479..5dc1234 100755 --- a/public/app.js +++ b/public/app.js @@ -9,83 +9,118 @@ const els = { content: document.getElementById("content") }; -let indexData = null; -let state = { section: "posts", sort: "newest", query: "", sidebarOpen: false }; +const staticPages = new Set(["about", "contact", "legal"]); -async function init(){ - indexData = await (await fetch("index.json")).json(); - populateSections(); - wireUI(); - renderList(); - handleHash(); - window.addEventListener("hashchange", handleHash); +let indexData = null; +let sidebarOpen = false; + +async function init() { + try { + indexData = await (await fetch("index.json")).json(); + populateSections(); + wireUI(); + renderList(); + handleHash(); + window.addEventListener("hashchange", handleHash); + } catch (e) { + els.viewer.innerHTML = "
Failed to load site data. Please try refreshing.
"; + } } -function populateSections(){ +function populateSections() { els.sectionSelect.innerHTML = ""; - indexData.sections.forEach(s=>{ + indexData.sections.forEach(s => { const opt = document.createElement("option"); - opt.value = s; opt.textContent = s; + 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); +function wireUI() { + els.menuBtn.addEventListener("click", () => { + sidebarOpen = !sidebarOpen; + document.body.classList.toggle("sidebar-open", 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")){ + 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; + sidebarOpen = false; } }); } -function renderList(){ +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); + let posts = indexData.flat.filter(p => p.path.split('/')[0] === 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){ + for (const p of posts) { const li = document.createElement("li"); - li.innerHTML = `${p.title}No posts in this section yet.
`; + } else { + const latest = sectionPosts.sort((a, b) => b.mtime - a.mtime)[0]; + location.hash = '#/' + latest.path; // Triggers hashchange to load + } + } else { + els.viewer.innerHTML = 'Failed to load the file. Please try another.
'; + } + } } -async function renderMarkdown(rel){ - const src = await fetch(rel).then(r=>r.text()); +async function renderMarkdown(rel) { + const src = await fetch(rel).then(r => { if (!r.ok) throw new Error(); return r.text(); }); const html = marked.parse(src); els.viewer.innerHTML = `