embedParams.ts (3789B)
1 import { 2 type EmbedFontId, 3 type EmbedPresetId, 4 type EmbedThemeOverrides, 5 hexForQueryParam, 6 parseEmbedFont, 7 parseEmbedPreset, 8 parseEmbedRadius, 9 parseHexColor, 10 } from "./embedTheme"; 11 12 export type EmbedTheme = "default" | "compact"; 13 14 export type EmbedParams = { 15 autoplay: boolean; 16 theme: EmbedTheme; 17 startId: string | null; 18 showBrand: boolean; 19 startMuted: boolean; 20 themeOverrides: EmbedThemeOverrides; 21 }; 22 23 function parseBool(raw: string | null, defaultValue: boolean): boolean { 24 if (raw === null || raw === "") return defaultValue; 25 return raw === "1" || raw === "true" || raw === "yes"; 26 } 27 28 function parseThemeOverrides(p: URLSearchParams): EmbedThemeOverrides { 29 const preset = parseEmbedPreset(p.get("preset")); 30 const font = parseEmbedFont(p.get("font")); 31 const radius = parseEmbedRadius(p.get("radius")); 32 const accent = parseHexColor(p.get("accent")); 33 const bg = parseHexColor(p.get("bg")); 34 const panel = parseHexColor(p.get("panel")); 35 const text = parseHexColor(p.get("text")); 36 const fgMuted = parseHexColor(p.get("fgMuted") ?? p.get("textMuted")); 37 38 const overrides: EmbedThemeOverrides = {}; 39 if (preset) overrides.preset = preset; 40 if (font) overrides.font = font; 41 if (radius !== null) overrides.radius = radius; 42 if (accent) overrides.accent = accent; 43 if (bg) overrides.bg = bg; 44 if (panel) overrides.panel = panel; 45 if (text) overrides.text = text; 46 if (fgMuted) overrides.fgMuted = fgMuted; 47 return overrides; 48 } 49 50 export function parseEmbedParams(search: string): EmbedParams { 51 const p = new URLSearchParams(search); 52 const themeRaw = p.get("theme")?.trim().toLowerCase(); 53 return { 54 autoplay: parseBool(p.get("autoplay"), true), 55 theme: themeRaw === "compact" ? "compact" : "default", 56 startId: p.get("start")?.trim() || null, 57 showBrand: parseBool(p.get("brand"), true), 58 startMuted: parseBool(p.get("muted"), false), 59 themeOverrides: parseThemeOverrides(p), 60 }; 61 } 62 63 export function buildEmbedSearchParams( 64 opts: Partial< 65 EmbedParams & { 66 themeOverrides?: EmbedThemeOverrides; 67 preset?: EmbedPresetId; 68 accent?: string; 69 bg?: string; 70 panel?: string; 71 text?: string; 72 fgMuted?: string; 73 radius?: number; 74 font?: EmbedFontId; 75 } 76 >, 77 ): string { 78 const p = new URLSearchParams(); 79 if (opts.autoplay === false) p.set("autoplay", "0"); 80 if (opts.theme === "compact") p.set("theme", "compact"); 81 if (opts.startId) p.set("start", opts.startId); 82 if (opts.showBrand === false) p.set("brand", "0"); 83 if (opts.startMuted) p.set("muted", "1"); 84 85 const theme = { ...opts.themeOverrides }; 86 if (opts.preset) theme.preset = opts.preset; 87 if (opts.accent) theme.accent = opts.accent; 88 if (opts.bg) theme.bg = opts.bg; 89 if (opts.panel) theme.panel = opts.panel; 90 if (opts.text) theme.text = opts.text; 91 if (opts.fgMuted) theme.fgMuted = opts.fgMuted; 92 if (opts.radius !== undefined && opts.radius !== null) theme.radius = opts.radius; 93 if (opts.font) theme.font = opts.font; 94 95 if (theme.preset && theme.preset !== "default") p.set("preset", theme.preset); 96 const accentQ = hexForQueryParam(theme.accent ?? null); 97 if (accentQ) p.set("accent", accentQ); 98 const bgQ = hexForQueryParam(theme.bg ?? null); 99 if (bgQ) p.set("bg", bgQ); 100 const panelQ = hexForQueryParam(theme.panel ?? null); 101 if (panelQ) p.set("panel", panelQ); 102 const textQ = hexForQueryParam(theme.text ?? null); 103 if (textQ) p.set("text", textQ); 104 const fgMutedQ = hexForQueryParam(theme.fgMuted ?? null); 105 if (fgMutedQ) p.set("fgMuted", fgMutedQ); 106 if (theme.radius !== undefined && theme.radius !== null) p.set("radius", String(theme.radius)); 107 if (theme.font && theme.font !== "sans") p.set("font", theme.font); 108 109 const s = p.toString(); 110 return s ? `?${s}` : ""; 111 }