Update index.html
This commit is contained in:
parent
2c6058d661
commit
be8ac0d1d3
1 changed files with 55 additions and 134 deletions
|
|
@ -1,153 +1,74 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" />
|
||||||
<meta name="theme-color" content="#0b0c10" />
|
|
||||||
<title>The Fold Within</title>
|
<title>The Fold Within</title>
|
||||||
|
<meta name="color-scheme" content="dark light" />
|
||||||
<!-- Styles -->
|
<link rel="preload" href="/styles.css" as="style" />
|
||||||
<link rel="stylesheet" href="./styles.css" />
|
<link rel="stylesheet" href="/styles.css" />
|
||||||
|
|
||||||
<!-- Markdown + Sanitizer -->
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.1.6/dist/purify.min.js"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Minimal fade-in startup */
|
|
||||||
body { opacity: 0; transition: opacity 0.6s ease-in; }
|
|
||||||
body.ready { opacity: 1; }
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- ============================================================
|
<!-- Global Shell -->
|
||||||
TOPBAR NAVIGATION
|
<header class="topbar" role="banner" aria-label="Primary">
|
||||||
============================================================ -->
|
<button class="icon-btn" id="navToggle" aria-controls="sidebar" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<header class="topbar">
|
☰
|
||||||
<button id="navToggle" title="Toggle Navigation">☰</button>
|
</button>
|
||||||
<a href="#=" class="brand">The Fold Within</a>
|
|
||||||
<nav>
|
<nav class="primary-nav" aria-label="Main">
|
||||||
<a href="#=index.html">Home</a>
|
<a class="brand" href="#/">Home</a>
|
||||||
<a href="#=about.html">About</a>
|
<a href="#/about">About</a>
|
||||||
<a href="#=essays/index.html">Essays</a>
|
<a href="#/essays">Essays</a>
|
||||||
<a href="#=fieldnotes/index.html">Fieldnotes</a>
|
<a href="#/fieldnotes">Fieldnotes</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="view-controls" aria-hidden="true">
|
||||||
|
<span id="routeHint"></span>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- ============================================================
|
<div id="appLayout">
|
||||||
LAYOUT WRAPPER
|
|
||||||
============================================================ -->
|
|
||||||
<div class="page">
|
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
<aside class="sidebar">
|
<aside id="sidebar" class="sidebar" aria-label="Content navigation">
|
||||||
<div class="controls">
|
<div class="side-head">
|
||||||
<select id="sortOrder">
|
<div class="filters">
|
||||||
<option value="newest">Newest</option>
|
<label class="visually-hidden" for="filterSection">Section</label>
|
||||||
<option value="oldest">Oldest</option>
|
<select id="filterSection">
|
||||||
</select>
|
<option value="all">All</option>
|
||||||
<input id="search" placeholder="Search titles..." />
|
</select>
|
||||||
</div>
|
|
||||||
<div id="fileTree">
|
<label class="visually-hidden" for="sortOrder">Sort</label>
|
||||||
<!-- auto-generated file tree will appear here -->
|
<select id="sortOrder">
|
||||||
|
<option value="newest">Newest</option>
|
||||||
|
<option value="oldest">Oldest</option>
|
||||||
|
<option value="title">Title</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="search">
|
||||||
|
<input id="searchBox" type="search" placeholder="Search titles…" aria-label="Search titles" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<nav id="tree" class="tree" aria-label="Posts"></nav>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<!-- Overlay for mobile -->
|
<!-- Main viewer -->
|
||||||
<div class="overlay"></div>
|
<main id="content" class="content" role="main">
|
||||||
|
<article id="viewer" class="viewer" aria-live="polite">
|
||||||
<!-- Content Area -->
|
<div class="empty">
|
||||||
<main class="content">
|
<h1>The Fold Within</h1>
|
||||||
<!-- Markdown View -->
|
<p>Select a note on the left, or open a direct link.</p>
|
||||||
<article id="mdView" class="viewer fade-in"></article>
|
</div>
|
||||||
|
</article>
|
||||||
<!-- HTML View (iframe for dynamic HTML files) -->
|
|
||||||
<iframe id="htmlView" class="viewer fade-in" style="display:none;"></iframe>
|
|
||||||
|
|
||||||
<div class="pager">
|
|
||||||
<button id="prev">← Prev</button>
|
|
||||||
<button id="next">Next →</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ============================================================
|
<!-- Local, vendored libs (more reliable than CDN) -->
|
||||||
SCRIPTS
|
<script src="/lib/marked.min.js"></script>
|
||||||
============================================================ -->
|
<script src="/lib/purify.min.js"></script>
|
||||||
<script src="./app.js"></script>
|
|
||||||
|
|
||||||
<script>
|
<script src="/app.js" type="module"></script>
|
||||||
// ============================================================
|
|
||||||
// FILE TREE INDEXER (CLIENT-SIDE DIRECTORY READER SIMULATION)
|
|
||||||
// ============================================================
|
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
|
||||||
const treeEl = document.getElementById("fileTree");
|
|
||||||
|
|
||||||
// simple directory crawl using pre-generated /index.json if available
|
|
||||||
let indexData;
|
|
||||||
try {
|
|
||||||
const res = await fetch("./index.json");
|
|
||||||
indexData = res.ok ? await res.json() : null;
|
|
||||||
} catch (e) {
|
|
||||||
indexData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indexData) {
|
|
||||||
treeEl.innerHTML = renderTree(indexData);
|
|
||||||
attachTreeHandlers();
|
|
||||||
} else {
|
|
||||||
// fallback: manual message
|
|
||||||
treeEl.innerHTML = `
|
|
||||||
<div class="md-warn">
|
|
||||||
<strong>File index not found.</strong><br>
|
|
||||||
Deploy a JSON index at <code>/index.json</code> or statically list your files.
|
|
||||||
</div>`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Recursive tree renderer
|
|
||||||
function renderTree(node, depth = 0) {
|
|
||||||
if (!node) return "";
|
|
||||||
if (node.type === "file") {
|
|
||||||
const icon = node.name.endsWith(".md")
|
|
||||||
? "📄"
|
|
||||||
: node.name.endsWith(".html")
|
|
||||||
? "🧩"
|
|
||||||
: "📁";
|
|
||||||
return `<div class="file" data-path="${node.path}" style="margin-left:${depth *
|
|
||||||
10}px">${icon} ${node.name}</div>`;
|
|
||||||
}
|
|
||||||
if (node.type === "dir") {
|
|
||||||
return `
|
|
||||||
<div class="dir" style="margin-left:${depth * 10}px">
|
|
||||||
<div class="label">${node.name}</div>
|
|
||||||
<div class="children">
|
|
||||||
${(node.children || [])
|
|
||||||
.map((child) => renderTree(child, depth + 1))
|
|
||||||
.join("")}
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expand/Collapse folders and attach file click
|
|
||||||
function attachTreeHandlers() {
|
|
||||||
document.querySelectorAll(".dir .label").forEach((label) => {
|
|
||||||
label.addEventListener("click", () => {
|
|
||||||
label.parentElement.classList.toggle("open");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll(".file").forEach((file) => {
|
|
||||||
file.addEventListener("click", () => {
|
|
||||||
const path = file.dataset.path;
|
|
||||||
if (path) window.location.hash = `#=${path}`;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fade-in after DOM ready
|
|
||||||
window.addEventListener("load", () => document.body.classList.add("ready"));
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue