โ back to Ventura Corridor
iter 150: /magazine.html ๐ since-last filter โ localStorage stamp + unseen-count badge
6dc50d07622d4cba1434d288edd8f6c0dfd3cc01 ยท 2026-05-06 19:17:59 -0700 ยท SteveStudio2
Files touched
Diff
commit 6dc50d07622d4cba1434d288edd8f6c0dfd3cc01
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 6 19:17:59 2026 -0700
iter 150: /magazine.html ๐ since-last filter โ localStorage stamp + unseen-count badge
---
public/magazine.html | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/public/magazine.html b/public/magazine.html
index 26e4c1d..55306d5 100644
--- a/public/magazine.html
+++ b/public/magazine.html
@@ -251,6 +251,7 @@
<button onclick="toggleView()" id="view-btn">๐ Table of contents</button>
<button onclick="reviewDrafts()" style="border:1px solid var(--metal);color:var(--metal)">โโโ Review drafts</button>
<button onclick="publishReviewed()" style="border:1px solid var(--metal-glow);color:var(--metal-glow)">โ
Publish reviewed</button>
+ <button id="since-last-btn" onclick="toggleSinceLast()" title="Show only features generated since you last opened this page">๐ since last</button>
<a href="/issue" target="_blank" style="display:inline-block;background:transparent;border:1px solid var(--accent);color:var(--accent);font-size:9px;letter-spacing:.22em;text-transform:uppercase;padding:5px 12px;text-decoration:none;font-family:var(--sans)">โ Public issue</a>
</div>
@@ -265,6 +266,12 @@ let currentCat = 'all';
let adsOnly = false;
let searchTerm = '';
let viewMode = 'cards'; // 'cards' | 'toc'
+let sinceLast = false;
+const SINCE_LAST_KEY = 'corridor-magazine-last-seen';
+const SINCE_LAST_MARK_AT = Date.now();
+const _lastSeenAt = (() => { try { return parseInt(localStorage.getItem(SINCE_LAST_KEY) || '0', 10); } catch { return 0; } })();
+// Stamp current visit at end-of-load so "since last" filters anything older than the PREVIOUS visit.
+function stampSeen() { try { localStorage.setItem(SINCE_LAST_KEY, String(SINCE_LAST_MARK_AT)); } catch {} }
let _searchT;
function onSearch() {
clearTimeout(_searchT);
@@ -281,6 +288,12 @@ function toggleAdsOnly() {
btn.classList.toggle('active', adsOnly);
load();
}
+function toggleSinceLast() {
+ sinceLast = !sinceLast;
+ const btn = document.getElementById('since-last-btn');
+ btn.classList.toggle('active', sinceLast);
+ load();
+}
const CATS = [
{ id: 'all', label: 'All' },
@@ -317,6 +330,9 @@ async function load() {
const data = await fetch(url).then(r => r.json());
let rows = data.rows || [];
if (adsOnly) rows = rows.filter(r => Number(r.paid_ads_count || 0) > 0);
+ if (sinceLast && _lastSeenAt) {
+ rows = rows.filter(r => new Date(r.generated_at).getTime() > _lastSeenAt);
+ }
if (searchTerm) {
rows = rows.filter(r => {
const hay = ((r.name || '') + ' ' + (r.headline || '') + ' ' + (r.editorial || '') + ' ' + (r.address || '') + ' ' + (r.city || '') + ' ' + (r.naics || '')).toLowerCase();
@@ -407,6 +423,16 @@ async function load() {
</footer>
</article>`;
}).join('');
+ // Mark seen AFTER first successful render so the badge reflects truly-new gen on next visit.
+ if (!window._stamped) { stampSeen(); window._stamped = true; }
+ // Update the "since last" button label with the unseen count
+ const sinceBtn = document.getElementById('since-last-btn');
+ if (sinceBtn && _lastSeenAt) {
+ const newCount = (data.rows || []).filter(r => new Date(r.generated_at).getTime() > _lastSeenAt).length;
+ sinceBtn.textContent = newCount > 0 ? `๐ since last (${newCount})` : '๐ since last';
+ sinceBtn.style.color = newCount > 0 ? 'var(--metal-glow)' : '';
+ sinceBtn.style.borderColor = newCount > 0 ? 'var(--metal-glow)' : '';
+ }
} catch (e) {
document.getElementById('spread').innerHTML = `<div class="empty">load failed: ${e.message}</div>`;
}
โ f050969 iter 149: per-feature editor margin notes โ collapsible "add
ยท
back to Ventura Corridor
ยท
iter 151: /quotes โ typographic 3-col wall of every editoria 0c9c392 โ