Harden onion boot flow and deepen site surfaces

Add persistent onion key backup and restore, improve startup resilience, and flesh out the major site verticals with richer navigation, search coverage, and operator documentation.

Made-with: Cursor
This commit is contained in:
drjones
2026-04-07 21:35:52 -07:00
parent 52432dccfa
commit 78a071ba02
162 changed files with 21692 additions and 39 deletions

34
lib/userActivityStats.ts Normal file
View File

@@ -0,0 +1,34 @@
import { loadBarter } from "@/lib/barterState";
import { loadExchange } from "@/lib/exchangeState";
import { loadForum } from "@/lib/forumState";
/** Match forum / listings when the user types the same handle (case-insensitive). */
function matchesHandle(author: string, handles: string[]): boolean {
const a = author.trim().toLowerCase();
if (!a) return false;
const set = new Set(handles.map((h) => h.trim().toLowerCase()).filter(Boolean));
return set.has(a);
}
export type UserActivityStats = {
forumThreads: number;
forumReplies: number;
exchangeListings: number;
barterListings: number;
};
export function computeUserActivityStats(username: string, displayName: string): UserActivityStats {
const handles = [username, displayName];
const forum = loadForum();
let forumThreads = 0;
let forumReplies = 0;
for (const t of forum) {
if (matchesHandle(t.author, handles)) forumThreads++;
for (const r of t.replies) {
if (matchesHandle(r.author, handles)) forumReplies++;
}
}
const exchangeListings = loadExchange().filter((e) => matchesHandle(e.author, handles)).length;
const barterListings = loadBarter().filter((b) => matchesHandle(b.author, handles)).length;
return { forumThreads, forumReplies, exchangeListings, barterListings };
}