diff --git a/bun.lock b/bun.lock index a025da9..1822cc9 100644 --- a/bun.lock +++ b/bun.lock @@ -7,7 +7,6 @@ "dependencies": { "@profullstack/auth-system": "^0.8.3", "@profullstack/emailer": "^1.0.3", - "@profullstack/footer": "latest", "@profullstack/hqtui": "^0.10.3", "@profullstack/player": "^0.14.0", "jsonwebtoken": "^9.0.2", @@ -81,8 +80,6 @@ "@profullstack/emailer": ["@profullstack/emailer@1.0.3", "", {}, "sha512-VyAtCcfnSI6LOwJvWogCr3ZNmEsaZw+iuWrqnosLsdcKsbRyCrCmXigMNZJZEjlgYlR+lK//PwNPG+xtCFvWAw=="], - "@profullstack/footer": ["@profullstack/footer@0.2.1", "", { "peerDependencies": { "react": ">=18" }, "optionalPeers": ["react"], "bin": { "profullstack-footer": "bin/profullstack-footer.js" } }, "sha512-KHmKVwrlzCBrSAAJ4zobNFCxTg8VF0gvNMeAut00dX3+gbWCtk6eOwIR2AaqEC7smj6Aio6cIexzt/dUnv1McA=="], - "@profullstack/hqtui": ["@profullstack/hqtui@0.10.3", "", { "bin": { "hqtui": "bin/hqtui.mjs" } }, "sha512-Z2jaDqmiaGyrMy4JXOoPGCyEkei8l3tHoCbmT3/1gAWDl72ynPvMuHcUj+U97KgsF/CFIpZzzBYnYqcOq5e46g=="], "@profullstack/player": ["@profullstack/player@0.14.0", "", { "dependencies": { "hls.js": "^1.7.1", "mpegts.js": "^1.8.2" }, "peerDependencies": { "react": ">=18" }, "optionalPeers": ["react"] }, "sha512-HBDNkb17jGhZrkpksCp1iB07yWjfKIeDQq8LarhA04bKBZdX+vkRRTN1gsxXiAM3T4t0Zxj+99dpTA0uPtKofw=="], diff --git a/package.json b/package.json index 7ab6170..722cd06 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,6 @@ "dependencies": { "@profullstack/auth-system": "^0.8.3", "@profullstack/emailer": "^1.0.3", - "@profullstack/footer": "latest", "@profullstack/hqtui": "^0.10.3", "@profullstack/player": "^0.14.0", "jsonwebtoken": "^9.0.2", diff --git a/src/server/footer.js b/src/server/footer.js index 06a2072..a4d92df 100644 --- a/src/server/footer.js +++ b/src/server/footer.js @@ -1,19 +1,39 @@ -// The shared Profullstack footer (@profullstack/footer), rendered into the -// markers of index.html from the @latest template on jsDelivr -// (cached an hour by the package; the bundled template if the CDN is down), so a -// footer release needs no redeploy and the ring's verifier sees it in the HTML. -import { footerHtml } from '@profullstack/footer'; +// The pit.world network footer, fetched server side from +// https://pit.world/snippets/footer.html and rendered into the +// markers of index.html on every page load. It refetches at +// most hourly with a 3-second timeout; on failure it keeps the last good copy, +// or renders nothing, so pit.world being down never breaks the page. +const URL_ = 'https://pit.world/snippets/footer.html?site=hdtilt.com'; +const TTL = 60 * 60 * 1000; +const REGION = /[\s\S]*?/; -const OPTIONS = { site: 'https://hdtilt.com/' }; -const REGION = /[\s\S]*?/; +let cached = ''; +let fetchedAt = 0; +/** @type {Promise | null} */ +let inflight = null; + +function refresh() { + if (Date.now() - fetchedAt < TTL) return Promise.resolve(); + inflight ??= (async () => { + try { + const res = await fetch(URL_, { signal: AbortSignal.timeout(3000) }); + if (res.ok) { + const html = await res.text(); + if (html.includes('data-pit-footer')) cached = html; + } + } catch { + // Keep the last good footer. + } finally { + fetchedAt = Date.now(); + inflight = null; + } + })(); + return inflight; +} /** @param {string} html */ export async function withFooter(html) { if (!REGION.test(html)) return html; - try { - const footer = await footerHtml(OPTIONS); - return html.replace(REGION, () => `${footer}`); - } catch { - return html; - } + await refresh(); + return html.replace(REGION, () => `${cached}`); } diff --git a/web/public/app.css b/web/public/app.css index 9a9d83c..a382d62 100644 --- a/web/public/app.css +++ b/web/public/app.css @@ -1085,7 +1085,8 @@ body.gated .nav-items button:not(#nav-account) { min-width: 0; } -/* @profullstack/footer: only while the sheet is up, docked under it. */ +/* Footer (own copyright row + the pit.world network footer): only while the + sheet is up, docked under it. */ .ring-dock { display: none; } @@ -1101,6 +1102,27 @@ body.gated .nav-items button:not(#nav-account) { display: block; color: var(--text); } +.site-foot { + margin: 0; + padding: 0.75rem 1rem 0; + text-align: center; + font-size: 0.85rem; + color: var(--dim); +} +.site-foot a { + color: inherit; +} +/* The pit.world snippet is styled for light pages; this app is always dark. */ +.ring-dock .pit-foot { + color: var(--dim); +} +.ring-dock .pit-foot b { + color: var(--text); +} +.ring-dock .pit-foot-links > a, +.ring-dock .pit-foot-links > button { + color: var(--accent); +} /* CrawlProof ad unit, docked at the top of the sheet (under the nav): zero height until ad.js fills it, and never on the sign-in / account screens. Filled only from mountAd() in app.js, the first time a home or settings @@ -1136,10 +1158,6 @@ body.nav-on #sheet:not([hidden]) ~ .ad-dock { #sheet:not([hidden]):not([data-screen="account"]):has(~ .ad-dock .cp-ad[data-cp-filled]) { padding-top: 4rem; } -.ring-dock .pfs-footer { - --pfs-footer-muted: var(--dim); - border-top: 0; -} /* ---- Movies & Shows ---------------------------------------------------------- */ .list.vod { diff --git a/web/public/index.html b/web/public/index.html index a08d39a..8c1791d 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -84,10 +84,9 @@ the footer, never over the picture or on sign-in). -->
- -
+ +

© 2026 Profullstack, Inc. · Source