diff --git a/package.json b/package.json
index 9e3d97f..93321a0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "the-fold-within",
- "version": "3.2.0",
+ "version": "3.3.1",
"dependencies": {
"pdf-parse": "^1.1.1"
}
diff --git a/public/app.js b/public/app.js
index 829d184..b89a022 100755
--- a/public/app.js
+++ b/public/app.js
@@ -1,3 +1,9 @@
+/**
+ * app.js – v3.3.1 PREVIEW + PORTAL
+ * High-coherence, readable, maintainable.
+ * No hacks. No surgery. Only truth.
+ */
+
const els = {
menuBtn: document.getElementById("menuBtn"),
primaryNav: document.getElementById("primaryNav"),
@@ -17,12 +23,13 @@ const els = {
let indexData = null;
let sidebarOpen = false;
let currentParent = null;
-let indexFiles = null; // Cached
+let indexFiles = null; // Cached index files
+// === INITIALIZATION ===
async function init() {
try {
indexData = await (await fetch("index.json")).json();
- indexFiles = indexData.flat.filter(f => f.isIndex); // Cache
+ indexFiles = indexData.flat.filter(f => f.isIndex);
populateNav();
populateSections();
populateTags();
@@ -35,6 +42,7 @@ async function init() {
}
}
+// === NAVIGATION ===
function populateNav() {
els.primaryNav.innerHTML = 'Home';
const navSections = [...new Set(
@@ -55,11 +63,8 @@ function populateSections() {
els.sectionSelect.appendChild(opt);
});
- if (indexData.sections.includes("posts")) {
- els.sectionSelect.value = "posts";
- } else if (indexData.sections.length > 0) {
- els.sectionSelect.value = indexData.sections[0];
- }
+ const defaultSection = indexData.sections.includes("posts") ? "posts" : indexData.sections[0];
+ if (defaultSection) els.sectionSelect.value = defaultSection;
}
function populateTags() {
@@ -70,11 +75,7 @@ function populateTags() {
});
}
-function formatTimestamp(ms) {
- const d = new Date(ms);
- return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')} ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}`;
-}
-
+// === UI WIRING ===
function wireUI() {
els.menuBtn.addEventListener("click", () => {
sidebarOpen = !sidebarOpen;
@@ -95,6 +96,7 @@ function wireUI() {
[els.tagSelect, els.sortSelect, els.searchMode].forEach(el => el.addEventListener("change", renderList));
els.searchBox.addEventListener("input", renderList);
+ // Close sidebar on content click (mobile)
els.content.addEventListener("click", (e) => {
if (window.innerWidth < 1024 && document.body.classList.contains("sidebar-open")) {
if (!e.target.closest("#sidebar")) {
@@ -105,6 +107,7 @@ function wireUI() {
});
}
+// === LIST RENDERING ===
function renderList() {
const section = els.sectionSelect.value;
const tags = Array.from(els.tagSelect.selectedOptions).map(o => o.value.toLowerCase());
@@ -127,7 +130,7 @@ function renderList() {
posts.forEach(p => {
const li = document.createElement("li");
const pin = p.isPinned ? "Star " : "";
- const time = formatTimestamp(p.ctime);
+ const time = new Date(p.ctime).toLocaleDateString();
li.innerHTML = `${pin}${p.title}${time}`;
els.postList.appendChild(li);
});
@@ -143,7 +146,7 @@ function loadDefaultForSection(section) {
location.hash = `#/${pinned.path}`;
}
-// NESTED HORIZON: Deep-Aware Sub-Navigation
+// === SUBNAV (NESTED HORIZON) ===
function renderSubNav(parent) {
const subnav = els.subNav;
subnav.innerHTML = "";
@@ -159,16 +162,14 @@ function renderSubNav(parent) {
subnav.appendChild(link);
});
- requestAnimationFrame(() => {
- subnav.classList.add("visible");
- });
+ requestAnimationFrame(() => subnav.classList.add("visible"));
}
+// === HASH ROUTING ===
async function handleHash() {
els.viewer.innerHTML = "";
const rel = location.hash.replace(/^#\//, "");
const parts = rel.split("/").filter(Boolean);
-
const currentParentPath = parts.slice(0, -1).join("/") || parts[0] || null;
if (currentParentPath !== currentParent) {
@@ -186,41 +187,28 @@ async function handleHash() {
if (rel.endsWith('/')) {
const currentPath = parts.join("/");
-
const indexFile = indexFiles.find(f => {
const dir = f.path.split("/").slice(0, -1).join("/");
return dir === currentPath;
});
if (indexFile) {
- try {
- if (indexFile.ext === ".md") {
- const src = await fetch(indexFile.path).then(r => r.ok ? r.text() : "");
- const html = marked.parse(src || `# ${currentPath.split("/").pop()}\n\nNo content yet.`);
- els.viewer.innerHTML = `
No content yet.
`; + if (indexFile.ext === ".md") { + await renderMarkdown(indexFile.path); + } else { + await renderIframe("/" + indexFile.path); } } else { - if (topSection) { - els.sectionSelect.value = topSection; - renderList(); - loadDefaultForSection(topSection); - } else { - els.viewer.innerHTML = `No content yet.
`; - } + if (topSection) loadDefaultForSection(topSection); + else els.viewer.innerHTML = `No content yet.
`; } - } - else { + } else { const file = indexData.flat.find(f => f.path === rel); if (!file) { els.viewer.innerHTML = "Not found.
"; return; } - file.ext === ".md" ? await renderMarkdown(file.path) : renderIframe("/" + file.path); + file.ext === ".md" ? await renderMarkdown(file.path) : await renderIframe("/" + file.path); } } @@ -229,53 +217,61 @@ async function renderMarkdown(rel) { els.viewer.innerHTML = `No content yet.
-