code.pablomurad.com

mymusics

Retro web player for random tracks from the Myspace Dragon Hoard

src/lib/embedParams.ts raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import {
  type EmbedFontId,
  type EmbedPresetId,
  type EmbedThemeOverrides,
  hexForQueryParam,
  parseEmbedFont,
  parseEmbedPreset,
  parseEmbedRadius,
  parseHexColor,
} from "./embedTheme";

export type EmbedTheme = "default" | "compact";

export type EmbedParams = {
  autoplay: boolean;
  theme: EmbedTheme;
  startId: string | null;
  showBrand: boolean;
  startMuted: boolean;
  themeOverrides: EmbedThemeOverrides;
};

function parseBool(raw: string | null, defaultValue: boolean): boolean {
  if (raw === null || raw === "") return defaultValue;
  return raw === "1" || raw === "true" || raw === "yes";
}

function parseThemeOverrides(p: URLSearchParams): EmbedThemeOverrides {
  const preset = parseEmbedPreset(p.get("preset"));
  const font = parseEmbedFont(p.get("font"));
  const radius = parseEmbedRadius(p.get("radius"));
  const accent = parseHexColor(p.get("accent"));
  const bg = parseHexColor(p.get("bg"));
  const panel = parseHexColor(p.get("panel"));
  const text = parseHexColor(p.get("text"));
  const fgMuted = parseHexColor(p.get("fgMuted") ?? p.get("textMuted"));

  const overrides: EmbedThemeOverrides = {};
  if (preset) overrides.preset = preset;
  if (font) overrides.font = font;
  if (radius !== null) overrides.radius = radius;
  if (accent) overrides.accent = accent;
  if (bg) overrides.bg = bg;
  if (panel) overrides.panel = panel;
  if (text) overrides.text = text;
  if (fgMuted) overrides.fgMuted = fgMuted;
  return overrides;
}

export function parseEmbedParams(search: string): EmbedParams {
  const p = new URLSearchParams(search);
  const themeRaw = p.get("theme")?.trim().toLowerCase();
  return {
    autoplay: parseBool(p.get("autoplay"), true),
    theme: themeRaw === "compact" ? "compact" : "default",
    startId: p.get("start")?.trim() || null,
    showBrand: parseBool(p.get("brand"), true),
    startMuted: parseBool(p.get("muted"), false),
    themeOverrides: parseThemeOverrides(p),
  };
}

export function buildEmbedSearchParams(
  opts: Partial<
    EmbedParams & {
      themeOverrides?: EmbedThemeOverrides;
      preset?: EmbedPresetId;
      accent?: string;
      bg?: string;
      panel?: string;
      text?: string;
      fgMuted?: string;
      radius?: number;
      font?: EmbedFontId;
    }
  >,
): string {
  const p = new URLSearchParams();
  if (opts.autoplay === false) p.set("autoplay", "0");
  if (opts.theme === "compact") p.set("theme", "compact");
  if (opts.startId) p.set("start", opts.startId);
  if (opts.showBrand === false) p.set("brand", "0");
  if (opts.startMuted) p.set("muted", "1");

  const theme = { ...opts.themeOverrides };
  if (opts.preset) theme.preset = opts.preset;
  if (opts.accent) theme.accent = opts.accent;
  if (opts.bg) theme.bg = opts.bg;
  if (opts.panel) theme.panel = opts.panel;
  if (opts.text) theme.text = opts.text;
  if (opts.fgMuted) theme.fgMuted = opts.fgMuted;
  if (opts.radius !== undefined && opts.radius !== null) theme.radius = opts.radius;
  if (opts.font) theme.font = opts.font;

  if (theme.preset && theme.preset !== "default") p.set("preset", theme.preset);
  const accentQ = hexForQueryParam(theme.accent ?? null);
  if (accentQ) p.set("accent", accentQ);
  const bgQ = hexForQueryParam(theme.bg ?? null);
  if (bgQ) p.set("bg", bgQ);
  const panelQ = hexForQueryParam(theme.panel ?? null);
  if (panelQ) p.set("panel", panelQ);
  const textQ = hexForQueryParam(theme.text ?? null);
  if (textQ) p.set("text", textQ);
  const fgMutedQ = hexForQueryParam(theme.fgMuted ?? null);
  if (fgMutedQ) p.set("fgMuted", fgMutedQ);
  if (theme.radius !== undefined && theme.radius !== null) p.set("radius", String(theme.radius));
  if (theme.font && theme.font !== "sans") p.set("font", theme.font);

  const s = p.toString();
  return s ? `?${s}` : "";
}