2025-11-08 15:35:37 -06:00
|
|
|
async function handleHash() {
|
2025-11-08 15:48:53 -06:00
|
|
|
els.viewer.innerHTML = "";
|
2025-11-08 15:35:37 -06:00
|
|
|
const rel = location.hash.replace(/^#\//, "");
|
2025-11-08 15:26:01 -06:00
|
|
|
if (!rel) return renderDefault();
|
2025-11-08 15:35:37 -06:00
|
|
|
|
|
|
|
|
if (rel.endsWith('/')) {
|
2025-11-08 18:23:47 -06:00
|
|
|
const section = rel.slice(0, -1);
|
2025-11-08 19:30:28 -06:00
|
|
|
const indexFile = indexData.flat.find(f =>
|
|
|
|
|
f.path.startsWith(section + "/") && f.isIndex
|
|
|
|
|
);
|
|
|
|
|
|
2025-11-08 18:10:27 -06:00
|
|
|
if (indexFile) {
|
2025-11-08 19:30:28 -06:00
|
|
|
// ALWAYS render the index file — never show file name
|
|
|
|
|
try {
|
|
|
|
|
if (indexFile.ext === ".md") {
|
|
|
|
|
const src = await fetch(indexFile.path).then(r => r.ok ? r.text() : "");
|
|
|
|
|
const html = marked.parse(src || "# " + section);
|
|
|
|
|
els.viewer.innerHTML = `<article class="markdown">${html}</article>`;
|
|
|
|
|
} else {
|
|
|
|
|
renderIframe(indexFile.path);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
// If fetch fails, show clean message
|
|
|
|
|
els.viewer.innerHTML = `<h1>${section}</h1><p>No content yet.</p>`;
|
|
|
|
|
}
|
2025-11-08 15:35:37 -06:00
|
|
|
} else {
|
2025-11-08 19:30:28 -06:00
|
|
|
// No index file → show posts
|
2025-11-08 18:10:27 -06:00
|
|
|
els.sectionSelect.value = section;
|
|
|
|
|
renderList();
|
|
|
|
|
loadDefaultForSection(section);
|
2025-11-08 15:35:37 -06:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const file = indexData.flat.find(f => f.path === rel);
|
|
|
|
|
if (!file) {
|
2025-11-08 18:23:47 -06:00
|
|
|
els.viewer.innerHTML = "<h1>404</h1><p>Not found.</p>";
|
2025-11-08 15:35:37 -06:00
|
|
|
return;
|
|
|
|
|
}
|
2025-11-08 18:23:47 -06:00
|
|
|
file.ext === ".md" ? await renderMarkdown(file.path) : renderIframe(file.path);
|
2025-11-08 15:35:37 -06:00
|
|
|
}
|
2025-11-08 19:30:28 -06:00
|
|
|
}
|