SPB Git forge
15commits 1branches 0releases
29.7 MBsize
maindefault branch
10 days agolast push
TypeScript 36.3% Python 31.8% Go 18% JavaScript 9.8% Shell 1.9% SQL 1.4% CSS 0.5%
4.4 KB · 63 lines tsx
Raw Blame History
1import { ImageResponse } from 'next/og';2import { fmt, fmtDelta } from '@/lib/format';3import { levelById, pressureColor } from '@/lib/pressure';4import { TAGLINE } from '@/lib/site';5import type { GlobalPressure } from '@/lib/types';67export const runtime = 'nodejs';8export const dynamic = 'force-dynamic';9export const alt = 'Global Internet Pressure right now';10export const size = { width: 1200, height: 630 };11export const contentType = 'image/png';1213/** OG image rendered from the live index (real API data, never a fixture). Falls back to an unknown state. */14/** The brand dial (same geometry as scripts/brand.py / public/brand/mark.svg). */15function Dial({ SZ, OP }: { SZ: number; OP: number }) {16  return (17    <svg viewBox="0 0 64 64" width={SZ} height={SZ} style={{ opacity: OP }}><path d="M11.22 44.00 A24.0 24.0 0 0 1 8.01 31.28" stroke="#4CC9F0" strokeWidth={6.5} strokeLinecap="round" fill="none" /><path d="M8.08 30.03 A24.0 24.0 0 0 1 12.69 17.75" stroke="#7FB77E" strokeWidth={6.5} strokeLinecap="round" fill="none" /><path d="M13.46 16.76 A24.0 24.0 0 0 1 24.24 9.29" stroke="#E9C46A" strokeWidth={6.5} strokeLinecap="round" fill="none" /><path d="M25.44 8.91 A24.0 24.0 0 0 1 38.56 8.91" stroke="#F4A261" strokeWidth={6.5} strokeLinecap="round" fill="none" /><path d="M39.76 9.29 A24.0 24.0 0 0 1 50.54 16.76" stroke="#E76F51" strokeWidth={6.5} strokeLinecap="round" fill="none" /><path d="M51.31 17.75 A24.0 24.0 0 0 1 55.92 30.03" stroke="#D62828" strokeWidth={6.5} strokeLinecap="round" fill="none" /><path d="M55.99 31.28 A24.0 24.0 0 0 1 52.78 44.00" stroke="#F72585" strokeWidth={6.5} strokeLinecap="round" fill="none" /><polygon points="34.11,31.36 29.89,32.64 27.09,15.73" fill="#E6EDF3" /><circle cx="32" cy="32" r="4.2" fill="#E6EDF3" /><circle cx="32" cy="32" r="1.6" fill="#070A0F" /></svg>18  );19}2021export default async function OpenGraphImage() {22  let g: GlobalPressure | null = null;23  try {24    const res = await fetch((process.env.API_URL_INTERNAL ?? process.env.API_URL ?? 'http://127.0.0.1:8352') + '/api/v1/pressure/global', { cache: 'no-store' });25    if (res.ok) g = (await res.json()) as GlobalPressure;26  } catch {27    g = null;28  }29  const color = g ? pressureColor(g.level) : '#8B98A5';30  const degraded = !g || g.internal_status !== 'ok' || g.stale;31  return new ImageResponse(32    (33      <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: '56px 72px', background: '#070A0F', color: '#E6EDF3', fontFamily: 'sans-serif', position: 'relative' }}>34        <div style={{ position: 'absolute', right: -40, top: 60, display: 'flex' }}>35          <Dial SZ={560} OP={0.22} />36        </div>37        <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>38          <Dial SZ={52} OP={1} />39          <div style={{ display: 'flex', fontSize: 30, letterSpacing: -0.5 }}>40            InternetPressure<span style={{ color: '#5B6875' }}>.io</span>41          </div>42        </div>43        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>44          <div style={{ fontSize: 20, letterSpacing: 4, color: '#8B98A5', display: 'flex' }}>GLOBAL INTERNET PRESSURE</div>45          <div style={{ display: 'flex', alignItems: 'baseline', gap: 36 }}>46            <div style={{ fontSize: 220, fontWeight: 600, letterSpacing: -10, lineHeight: 1, color: degraded ? '#8B98A5' : '#E6EDF3', display: 'flex' }}>{g ? fmt(g.pressure) : '—'}</div>47            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>48              <div style={{ fontSize: 44, letterSpacing: 6, color, display: 'flex' }}>{g ? (levelById(g.level)?.short ?? g.level).toUpperCase() : 'UNAVAILABLE'}</div>49              {g && <div style={{ fontSize: 30, color: '#8B98A5', display: 'flex' }}>{`${g.trend === 'rising' ? '↑' : g.trend === 'falling' ? '↓' : '→'} ${fmtDelta(g.delta_1h)} / 1h`}</div>}50              {degraded && <div style={{ fontSize: 22, color: '#E9C46A', display: 'flex' }}>Instrument degraded — score frozen</div>}51            </div>52          </div>53        </div>54        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 20, color: '#8B98A5' }}>55          <div style={{ display: 'flex' }}>{TAGLINE}</div>56          {g && <div style={{ display: 'flex' }}>{`${g.coverage.probes_active} probes · ${g.coverage.probe_regions} regions · ${g.coverage.targets} targets · confidence ${Math.round(g.confidence * 100)} %`}</div>}57        </div>58      </div>59    ),60    { ...size },61  );62}63