mirror of
https://github.com/infinition/Bjorn.git
synced 2025-12-13 16:14:57 +00:00
feat: Add small badge styles and enhance content loader with persistent local storage caching and TTL.
This commit is contained in:
70
index.html
70
index.html
@@ -393,6 +393,21 @@
|
|||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badge-sm {
|
||||||
|
transform: scale(.75);
|
||||||
|
transform-origin: top left;
|
||||||
|
margin-bottom: calc(-6px * .75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-sm:hover {
|
||||||
|
transform: scale(.80);
|
||||||
|
transition: transform .15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: linear-gradient(180deg, var(--accent-green), var(--border-color));
|
||||||
|
}
|
||||||
|
|
||||||
/* --- PRINT STYLESHEET --- */
|
/* --- PRINT STYLESHEET --- */
|
||||||
@media print {
|
@media print {
|
||||||
body {
|
body {
|
||||||
@@ -584,29 +599,35 @@
|
|||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<strong class="text-gray-500 text-sm block mb-3 font-mono tracking-wide">:: JOIN US ::</strong>
|
<strong class="text-gray-500 text-sm block mb-3 font-mono tracking-wide">:: JOIN US ::</strong>
|
||||||
<div class="flex flex-col gap-2.5">
|
<div class="flex flex-col gap-2.5">
|
||||||
|
|
||||||
<a href="https://discord.gg/B3ZH9taVfT" target="_blank"
|
<a href="https://discord.gg/B3ZH9taVfT" target="_blank"
|
||||||
class="hover:opacity-80 transition-opacity block">
|
class="hover:opacity-80 transition-opacity block">
|
||||||
<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fdiscord.com%2Fapi%2Finvites%2FB3ZH9taVfT%3Fwith_counts%3Dtrue&query=%24.approximate_member_count&logo=discord&logoColor=white&style=for-the-badge&label=BJORN&color=5865F2&labelColor=2A2E35"
|
<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fdiscord.com%2Fapi%2Finvites%2FB3ZH9taVfT%3Fwith_counts%3Dtrue&query=%24.approximate_member_count&logo=discord&logoColor=white&style=for-the-badge&label=BJORN&color=5865F2&labelColor=2A2E35"
|
||||||
alt="Discord BJORN" class="w-full" />
|
alt="Discord BJORN" class="w-full badge-sm" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="https://www.reddit.com/r/Bjorn_CyberViking/" target="_blank"
|
<a href="https://www.reddit.com/r/Bjorn_CyberViking/" target="_blank"
|
||||||
class="hover:opacity-80 transition-opacity block">
|
class="hover:opacity-80 transition-opacity block">
|
||||||
<img src="https://img.shields.io/reddit/subreddit-subscribers/Bjorn_CyberViking?style=for-the-badge&logo=reddit&label=r/Bjorn&color=FF4500&labelColor=2A2E35&logoColor=white"
|
<img src="https://img.shields.io/reddit/subreddit-subscribers/Bjorn_CyberViking?style=for-the-badge&logo=reddit&label=r/Bjorn&color=FF4500&labelColor=2A2E35&logoColor=white"
|
||||||
alt="Reddit" class="w-full" />
|
alt="Reddit" class="w-full badge-sm" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="https://github.com/infinition/Bjorn" target="_blank"
|
<a href="https://github.com/infinition/Bjorn" target="_blank"
|
||||||
class="hover:opacity-80 transition-opacity block">
|
class="hover:opacity-80 transition-opacity block">
|
||||||
<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.github.com%2Frepos%2Finfinition%2FBjorn&query=%24.stargazers_count&style=for-the-badge&logo=github&color=0B0C0E&labelColor=2A2E35&label=BJORN&logoColor=white"
|
<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.github.com%2Frepos%2Finfinition%2FBjorn&query=%24.stargazers_count&style=for-the-badge&logo=github&color=0B0C0E&labelColor=2A2E35&label=BJORN&logoColor=white"
|
||||||
alt="GitHub BJORN" class="w-full" />
|
alt="GitHub BJORN" class="w-full badge-sm" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="https://buymeacoffee.com/infinition" target="_blank"
|
<a href="https://buymeacoffee.com/infinition" target="_blank"
|
||||||
class="hover:opacity-80 transition-opacity block pt-2 border-t border-hack-border/30 mt-1">
|
class="hover:opacity-80 transition-opacity block pt-2 border-t border-hack-border/30 mt-1">
|
||||||
<img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black"
|
<img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black"
|
||||||
alt="Buy Me A Coffee" class="w-full" />
|
alt="Buy Me A Coffee" class="w-full badge-sm" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<!-- Mobile Sidebar (Right - TOC) -->
|
<!-- Mobile Sidebar (Right - TOC) -->
|
||||||
@@ -891,7 +912,7 @@
|
|||||||
hljs.highlightAll();
|
hljs.highlightAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 5. CONTENT LOADER ---
|
// --- 5. CONTENT LOADER (PERSISTENT CACHE OPTIMIZED) ---
|
||||||
async function loadContent(folder, title, filename, pushHistory = true) {
|
async function loadContent(folder, title, filename, pushHistory = true) {
|
||||||
const viewer = document.getElementById('markdown-viewer');
|
const viewer = document.getElementById('markdown-viewer');
|
||||||
const pageNav = document.getElementById('page-nav');
|
const pageNav = document.getElementById('page-nav');
|
||||||
@@ -903,6 +924,7 @@
|
|||||||
<span>${cleanFolder}</span> <span>/</span> <span class="text-hack-green font-bold">${title}</span>
|
<span>${cleanFolder}</span> <span>/</span> <span class="text-hack-green font-bold">${title}</span>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// Only show loader if not in RAM cache
|
||||||
if (!STATE.contentCache[`${folder}/${filename}`]) {
|
if (!STATE.contentCache[`${folder}/${filename}`]) {
|
||||||
viewer.innerHTML = `<div class="animate-pulse space-y-4 pt-10"><div class="h-8 bg-gray-800 rounded w-1/3 mb-6"></div><div class="h-4 bg-gray-800 rounded w-full"></div><div class="h-4 bg-gray-800 rounded w-5/6"></div><div class="h-4 bg-gray-800 rounded w-4/6"></div></div>`;
|
viewer.innerHTML = `<div class="animate-pulse space-y-4 pt-10"><div class="h-8 bg-gray-800 rounded w-1/3 mb-6"></div><div class="h-4 bg-gray-800 rounded w-full"></div><div class="h-4 bg-gray-800 rounded w-5/6"></div><div class="h-4 bg-gray-800 rounded w-4/6"></div></div>`;
|
||||||
}
|
}
|
||||||
@@ -913,10 +935,30 @@
|
|||||||
try {
|
try {
|
||||||
let text;
|
let text;
|
||||||
const cacheKey = `${folder}/${filename}`;
|
const cacheKey = `${folder}/${filename}`;
|
||||||
|
const storageKey = `bjorn_content_${cacheKey}`;
|
||||||
|
const now = Date.now();
|
||||||
|
const TTL = 3600 * 1000 * 24; // 24 Hours Cache
|
||||||
|
|
||||||
|
// 1. Check RAM (Fastest)
|
||||||
if (STATE.contentCache[cacheKey]) {
|
if (STATE.contentCache[cacheKey]) {
|
||||||
text = STATE.contentCache[cacheKey];
|
text = STATE.contentCache[cacheKey];
|
||||||
} else {
|
}
|
||||||
|
// 2. Check LocalStorage (Persistence)
|
||||||
|
else {
|
||||||
|
const stored = localStorage.getItem(storageKey);
|
||||||
|
if (stored) {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(stored);
|
||||||
|
if (now - data.ts < TTL) {
|
||||||
|
text = data.content;
|
||||||
|
STATE.contentCache[cacheKey] = text; // Restore to RAM
|
||||||
|
}
|
||||||
|
} catch (e) { localStorage.removeItem(storageKey); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Network Fetch (Fallback)
|
||||||
|
if (!text) {
|
||||||
try {
|
try {
|
||||||
const path1 = `./wiki/${folder}/${filename}`;
|
const path1 = `./wiki/${folder}/${filename}`;
|
||||||
const res = await fetch(path1);
|
const res = await fetch(path1);
|
||||||
@@ -934,7 +976,15 @@
|
|||||||
throw new Error(`Content not found.`);
|
throw new Error(`Content not found.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save to caches
|
||||||
STATE.contentCache[cacheKey] = text;
|
STATE.contentCache[cacheKey] = text;
|
||||||
|
try {
|
||||||
|
localStorage.setItem(storageKey, JSON.stringify({
|
||||||
|
ts: now,
|
||||||
|
content: text
|
||||||
|
}));
|
||||||
|
} catch (e) { console.warn("LocalStorage full"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleanHTML = DOMPurify.sanitize(marked.parse(text));
|
const cleanHTML = DOMPurify.sanitize(marked.parse(text));
|
||||||
@@ -1018,8 +1068,14 @@
|
|||||||
[idx - 1, idx + 1].forEach(i => {
|
[idx - 1, idx + 1].forEach(i => {
|
||||||
if (flatList[i]) {
|
if (flatList[i]) {
|
||||||
const url = `./wiki/${flatList[i].folder}/${flatList[i].file}`;
|
const url = `./wiki/${flatList[i].folder}/${flatList[i].file}`;
|
||||||
|
const cacheKey = `${flatList[i].folder}/${flatList[i].file}`;
|
||||||
|
|
||||||
|
// Check persistent cache first to avoid fetch
|
||||||
|
const storageKey = `bjorn_content_${cacheKey}`;
|
||||||
|
if (localStorage.getItem(storageKey)) return;
|
||||||
|
|
||||||
fetch(url).then(r => r.text()).then(t => {
|
fetch(url).then(r => r.text()).then(t => {
|
||||||
STATE.contentCache[`${flatList[i].folder}/${flatList[i].file}`] = t;
|
STATE.contentCache[cacheKey] = t;
|
||||||
}).catch(() => { });
|
}).catch(() => { });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user