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 = {
|
const els = {
|
||||||
body: document.body,
|
body: document.body,
|
||||||
menuBtn: document.getElementById("menuBtn"),
|
menuBtn: document.getElementById("menuBtn"),
|
||||||
|
primaryNav: document.getElementById("primaryNav"),
|
||||||
sectionSelect: document.getElementById("sectionSelect"),
|
sectionSelect: document.getElementById("sectionSelect"),
|
||||||
sortSelect: document.getElementById("sortSelect"),
|
sortSelect: document.getElementById("sortSelect"),
|
||||||
searchBox: document.getElementById("searchBox"),
|
searchBox: document.getElementById("searchBox"),
|
||||||
|
|
@ -10,6 +11,11 @@ const els = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const staticPages = new Set(["about", "contact", "legal"]);
|
const staticPages = new Set(["about", "contact", "legal"]);
|
||||||
|
const sectionIcons = { // Optional: Add icons per section (e.g., 'essays': '✍️')
|
||||||
|
essays: '✍️',
|
||||||
|
fieldnotes: '📓',
|
||||||
|
pinned: '📌'
|
||||||
|
};
|
||||||
|
|
||||||
let indexData = null;
|
let indexData = null;
|
||||||
let sidebarOpen = false;
|
let sidebarOpen = false;
|
||||||
|
|
@ -17,22 +23,34 @@ let sidebarOpen = false;
|
||||||
async function init() {
|
async function init() {
|
||||||
try {
|
try {
|
||||||
indexData = await (await fetch("index.json")).json();
|
indexData = await (await fetch("index.json")).json();
|
||||||
|
populateNav();
|
||||||
populateSections();
|
populateSections();
|
||||||
wireUI();
|
wireUI();
|
||||||
renderList();
|
renderList();
|
||||||
handleHash();
|
handleHash();
|
||||||
window.addEventListener("hashchange", handleHash);
|
window.addEventListener("hashchange", handleHash);
|
||||||
} catch (e) {
|
} 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() {
|
function populateSections() {
|
||||||
els.sectionSelect.innerHTML = "";
|
els.sectionSelect.innerHTML = "";
|
||||||
indexData.sections.forEach(s => {
|
indexData.sections.forEach(s => {
|
||||||
|
const icon = sectionIcons[s] ? `${sectionIcons[s]} ` : '';
|
||||||
const opt = document.createElement("option");
|
const opt = document.createElement("option");
|
||||||
opt.value = s;
|
opt.value = s;
|
||||||
opt.textContent = s;
|
opt.textContent = `${icon}${s}`;
|
||||||
els.sectionSelect.appendChild(opt);
|
els.sectionSelect.appendChild(opt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -72,54 +90,59 @@ function renderList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleHash() {
|
async function handleHash() {
|
||||||
els.viewer.innerHTML = ""; // Clear viewer to avoid stale content
|
els.viewer.innerHTML = "";
|
||||||
const rel = location.hash.replace(/^#\//, "");
|
const rel = location.hash.replace(/^#\//, "");
|
||||||
if (!rel) return renderDefault();
|
if (!rel) return renderDefault();
|
||||||
|
|
||||||
if (rel.endsWith('/')) {
|
if (rel.endsWith('/')) {
|
||||||
const section = rel.replace(/\/$/, '');
|
const section = rel.replace(/\/$/, '');
|
||||||
if (staticPages.has(section)) {
|
if (staticPages.has(section)) {
|
||||||
renderHTML(section + '/index.html');
|
renderIframe(`${section}/index.html`);
|
||||||
} else if (indexData.sections.includes(section)) {
|
} else if (indexData.sections.includes(section)) {
|
||||||
els.sectionSelect.value = section;
|
els.sectionSelect.value = section;
|
||||||
renderList();
|
renderList();
|
||||||
const sectionPosts = indexData.flat.filter(p => p.path.split('/')[0] === section);
|
const sectionPosts = indexData.flat.filter(p => p.path.split('/')[0] === section);
|
||||||
if (sectionPosts.length === 0) {
|
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 {
|
} else {
|
||||||
const latest = sectionPosts.sort((a, b) => b.mtime - a.mtime)[0];
|
const latest = sectionPosts.sort((a, b) => b.mtime - a.mtime)[0];
|
||||||
location.hash = '#/' + latest.path; // Triggers hashchange to load
|
location.hash = '#/' + latest.path;
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
const file = indexData.flat.find(f => f.path === rel);
|
const file = indexData.flat.find(f => f.path === rel);
|
||||||
if (!file) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
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) {
|
} 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) {
|
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);
|
const html = marked.parse(src);
|
||||||
els.viewer.innerHTML = `<article>${html}</article>`;
|
els.viewer.innerHTML = `<article>${html}</article>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderHTML(rel) {
|
function renderIframe(rel) {
|
||||||
const iframe = document.createElement("iframe");
|
const iframe = document.createElement("iframe");
|
||||||
iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms");
|
iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms");
|
||||||
iframe.loading = "eager";
|
iframe.loading = "eager";
|
||||||
iframe.src = "/" + rel;
|
iframe.src = "/" + rel;
|
||||||
els.viewer.appendChild(iframe);
|
els.viewer.appendChild(iframe);
|
||||||
iframe.addEventListener("load", () => {
|
iframe.addEventListener("load", () => {
|
||||||
|
if (rel.endsWith('.pdf')) return;
|
||||||
try {
|
try {
|
||||||
const d = iframe.contentDocument || iframe.contentWindow.document;
|
const d = iframe.contentDocument || iframe.contentWindow.document;
|
||||||
const s = d.createElement("style");
|
const s = d.createElement("style");
|
||||||
|
|
@ -134,7 +157,11 @@ function renderHTML(rel) {
|
||||||
|
|
||||||
function renderDefault() {
|
function renderDefault() {
|
||||||
const latest = [...indexData.flat].sort((a, b) => b.mtime - a.mtime)[0];
|
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();
|
init();
|
||||||
Loading…
Add table
Add a link
Reference in a new issue