Update app.js
This commit is contained in:
parent
a43055f3b8
commit
42af773c98
1 changed files with 40 additions and 13 deletions
|
|
@ -1,6 +1,7 @@
|
|||
const els = {
|
||||
body: document.body,
|
||||
menuBtn: document.getElementById("menuBtn"),
|
||||
primaryNav: document.getElementById("primaryNav"),
|
||||
sectionSelect: document.getElementById("sectionSelect"),
|
||||
sortSelect: document.getElementById("sortSelect"),
|
||||
searchBox: document.getElementById("searchBox"),
|
||||
|
|
@ -10,6 +11,11 @@ const els = {
|
|||
};
|
||||
|
||||
const staticPages = new Set(["about", "contact", "legal"]);
|
||||
const sectionIcons = { // Optional: Add icons per section (e.g., 'essays': '✍️')
|
||||
essays: '✍️',
|
||||
fieldnotes: '📓',
|
||||
pinned: '📌'
|
||||
};
|
||||
|
||||
let indexData = null;
|
||||
let sidebarOpen = false;
|
||||
|
|
@ -17,22 +23,34 @@ let sidebarOpen = false;
|
|||
async function init() {
|
||||
try {
|
||||
indexData = await (await fetch("index.json")).json();
|
||||
populateNav();
|
||||
populateSections();
|
||||
wireUI();
|
||||
renderList();
|
||||
handleHash();
|
||||
window.addEventListener("hashchange", handleHash);
|
||||
} catch (e) {
|
||||
els.viewer.innerHTML = "<h1>Error Loading Index</h1><p>Failed to load site data. Please try refreshing.</p>";
|
||||
els.viewer.innerHTML = "<h1>Error Loading Site</h1><p>Failed to load index data. Please refresh or check connection.</p>";
|
||||
}
|
||||
}
|
||||
|
||||
function populateNav() {
|
||||
els.primaryNav.innerHTML = '<a href="#/">Home</a>';
|
||||
staticPages.forEach(p => {
|
||||
els.primaryNav.innerHTML += `<a href="#/${p}/">${p.charAt(0).toUpperCase() + p.slice(1)}</a>`;
|
||||
});
|
||||
indexData.sections.forEach(s => {
|
||||
els.primaryNav.innerHTML += `<a href="#/${s}/">${s.charAt(0).toUpperCase() + s.slice(1)}</a>`;
|
||||
});
|
||||
}
|
||||
|
||||
function populateSections() {
|
||||
els.sectionSelect.innerHTML = "";
|
||||
indexData.sections.forEach(s => {
|
||||
const icon = sectionIcons[s] ? `${sectionIcons[s]} ` : '';
|
||||
const opt = document.createElement("option");
|
||||
opt.value = s;
|
||||
opt.textContent = s;
|
||||
opt.textContent = `${icon}${s}`;
|
||||
els.sectionSelect.appendChild(opt);
|
||||
});
|
||||
}
|
||||
|
|
@ -72,54 +90,59 @@ function renderList() {
|
|||
}
|
||||
|
||||
async function handleHash() {
|
||||
els.viewer.innerHTML = ""; // Clear viewer to avoid stale content
|
||||
els.viewer.innerHTML = "";
|
||||
const rel = location.hash.replace(/^#\//, "");
|
||||
if (!rel) return renderDefault();
|
||||
|
||||
if (rel.endsWith('/')) {
|
||||
const section = rel.replace(/\/$/, '');
|
||||
if (staticPages.has(section)) {
|
||||
renderHTML(section + '/index.html');
|
||||
renderIframe(`${section}/index.html`);
|
||||
} else if (indexData.sections.includes(section)) {
|
||||
els.sectionSelect.value = section;
|
||||
renderList();
|
||||
const sectionPosts = indexData.flat.filter(p => p.path.split('/')[0] === section);
|
||||
if (sectionPosts.length === 0) {
|
||||
els.viewer.innerHTML = `<h1>${section.charAt(0).toUpperCase() + section.slice(1)}</h1><p>No posts in this section yet.</p>`;
|
||||
els.viewer.innerHTML = `<h1>${section.charAt(0).toUpperCase() + section.slice(1)}</h1><p>No content in this section yet. Check back soon!</p>`;
|
||||
} else {
|
||||
const latest = sectionPosts.sort((a, b) => b.mtime - a.mtime)[0];
|
||||
location.hash = '#/' + latest.path; // Triggers hashchange to load
|
||||
location.hash = '#/' + latest.path;
|
||||
}
|
||||
} else {
|
||||
els.viewer.innerHTML = '<h1>404 Not Found</h1>';
|
||||
els.viewer.innerHTML = '<h1>404: Section Not Found</h1><p>The requested section does not exist.</p>';
|
||||
}
|
||||
} else {
|
||||
const file = indexData.flat.find(f => f.path === rel);
|
||||
if (!file) {
|
||||
els.viewer.innerHTML = '<h1>404 Not Found</h1>';
|
||||
els.viewer.innerHTML = '<h1>404: File Not Found</h1><p>The requested file could not be located.</p>';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
file.ext === ".md" ? await renderMarkdown(file.path) : renderHTML(file.path);
|
||||
if (file.ext === ".md") {
|
||||
await renderMarkdown(file.path);
|
||||
} else {
|
||||
renderIframe(file.path);
|
||||
}
|
||||
} catch (e) {
|
||||
els.viewer.innerHTML = '<h1>Error Loading Content</h1><p>Failed to load the file. Please try another.</p>';
|
||||
els.viewer.innerHTML = '<h1>Error Loading Content</h1><p>Unable to load the file. It may be corrupted or inaccessible.</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function renderMarkdown(rel) {
|
||||
const src = await fetch(rel).then(r => { if (!r.ok) throw new Error(); return r.text(); });
|
||||
const src = await fetch(rel).then(r => { if (!r.ok) throw new Error('Fetch failed'); return r.text(); });
|
||||
const html = marked.parse(src);
|
||||
els.viewer.innerHTML = `<article>${html}</article>`;
|
||||
}
|
||||
|
||||
function renderHTML(rel) {
|
||||
function renderIframe(rel) {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms");
|
||||
iframe.loading = "eager";
|
||||
iframe.src = "/" + rel;
|
||||
els.viewer.appendChild(iframe);
|
||||
iframe.addEventListener("load", () => {
|
||||
if (rel.endsWith('.pdf')) return;
|
||||
try {
|
||||
const d = iframe.contentDocument || iframe.contentWindow.document;
|
||||
const s = d.createElement("style");
|
||||
|
|
@ -134,7 +157,11 @@ function renderHTML(rel) {
|
|||
|
||||
function renderDefault() {
|
||||
const latest = [...indexData.flat].sort((a, b) => b.mtime - a.mtime)[0];
|
||||
if (latest) location.hash = "#/" + latest.path;
|
||||
if (latest) {
|
||||
location.hash = "#/" + latest.path;
|
||||
} else {
|
||||
els.viewer.innerHTML = '<h1>Welcome</h1><p>No content yet. Add files to sections and redeploy!</p>';
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
Loading…
Add table
Add a link
Reference in a new issue