Files
antisocial/src/render/layout.ts
T
thatguygriffandClaude Opus 5 899b6e38d8
CI / Typecheck, test, build (pull_request) Successful in 26s
No browser chosen, no "Open on" button
The plain address is the one thing that button must not offer -- followed
in the browser the rewrite rules are installed in, it comes straight back
here -- so there is nothing to show until there is a browser to hand it to.
The copy button and the selectable URL were always the part carrying the
weight; the open link now ships hidden and the script reveals it along with
the scheme.

That also settles what the button should say. It went back to "Open on
<platform>": the browser's name was there to explain a tap that went
nowhere, and a button that is not shown until it works needs no such
explanation.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01KF5YF3iZVKbezwALap8LYd
2026-08-29 19:40:39 -03:00

62 lines
2.5 KiB
TypeScript

import { html, type Raw } from './html.ts';
export function layout(title: string, body: Raw): string {
return `<!doctype html>
${html`<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="robots" content="noindex, nofollow">
<meta name="referrer" content="no-referrer">
<meta name="color-scheme" content="light dark">
<title>${title}</title>
<link rel="stylesheet" href="/static/app.css">
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
</head>
<body>
<main>${body}</main>
<script src="/static/app.js" type="module"></script>
</body>
</html>`}`;
}
/**
* Indicative brand accents. The written label is what actually identifies
* the platform; the colour is only there to make it recognisable at a
* glance.
*/
const ACCENT: Record<string, { color: string; monogram: string }> = {
x: { color: '#0f1419', monogram: '✕' },
threads: { color: '#3b3b3b', monogram: '@' },
instagram: { color: '#c13584', monogram: 'IG' },
tiktok: { color: '#fe2c55', monogram: '♪' },
bluesky: { color: '#0085ff', monogram: 'B' },
reddit: { color: '#ff4500', monogram: 'r' },
};
export function badge(platform: string, label: string): Raw {
const accent = ACCENT[platform] ?? { color: '#666', monogram: '?' };
return html`<span class="badge" style="--accent: ${accent.color}">
<span class="badge__mark" aria-hidden="true">${accent.monogram}</span>
<span class="badge__label">${label}</span>
</span>`;
}
/** The copy control, plus the URL itself so it is always selectable even if
* the clipboard API is unavailable.
*
* The open link ships hidden: followed in the browser the rewrite rules are
* installed in, it redirects straight back here, so it is only worth showing
* once a browser has been picked to hand it to. The script reveals it, and
* the href in the markup is the plain address it starts from. */
export function originalUrlBlock(originalUrl: string, platformLabel: string): Raw {
return html`<div class="original">
<button type="button" class="copy" data-url="${originalUrl}">
<span class="copy__idle">Copy original link</span>
<span class="copy__done" hidden>Copied</span>
</button>
<a class="original__open" href="${originalUrl}" rel="noopener noreferrer nofollow" target="_blank" hidden>Open on ${platformLabel}</a>
<p class="original__url"><code>${originalUrl}</code></p>
</div>`;
}