/** * Avatar imager helpers. * * The public-facing imager URL is configured via NEXT_PUBLIC_IMAGER_URL env var. * Defaults to epicnabbo.nl imager with effect=14 and img_format=apng. */ export type { AvatarOptions } from "@/types/admin"; import type { AvatarOptions } from "@/types/admin"; const DEFAULT_IMAGER_URL = "https://epicnabbo.nl/imaging/avatarimage"; /** * Resolve the public-facing imager base URL from env. * Falls back to epicnabbo.nl if not configured. */ export function resolveImagerBase(): string { const fromEnv = process.env.NEXT_PUBLIC_IMAGER_URL?.trim(); if (!fromEnv) { return DEFAULT_IMAGER_URL; } return fromEnv.replace(/\/+$/, ""); } /** * Build an avatar image URL using the configured imager. * Uses effect=14 and img_format=apng by default for epicnabbo.nl compatibility. * Preserves the user's stored figure so the rendered avatar matches the account. * Omits default parameters (direction=2, head_direction=3, size=m) for cleaner URLs. */ export function getAvatarUrl( figure: string, options: AvatarOptions = {}, ): string { const { size = "m", direction = 2, headDirection = 3, headOnly = false, gesture, action, effect = 14, img_format = "apng", } = options; const params = new URLSearchParams({ figure, img_format, effect: String(effect), }); // Only add non-default params if (direction !== 2) params.set("direction", String(direction)); if (headDirection !== 3) params.set("head_direction", String(headDirection)); if (size !== "m") params.set("size", size); if (headOnly) params.set("headonly", "1"); if (gesture) params.set("gesture", gesture); if (action) params.set("action", action); const base = resolveImagerBase(); return `${base}?${params.toString()}`; }