feat: switch avatar imager to epicnabbo.nl with figure conversion

- Update imager to use epicnabbo.nl by default with effect=14 and img_format=apng
- Add figure string converter (old Habbo format -> epicnabbo.nl short format)
- Update avatarImageUrl to auto-convert figure strings
- Update online-users-widget to use new avatarImageUrl
- Add tests for imager and figure conversion
This commit is contained in:
openhands committed 2026-08-09 19:38:04 +02:00
1 parent 703c29bc83
commit fc7e6ca248
10 files changed
+270 -114

No files matched your search

+3 -1
View File
@@ -1,7 +1,7 @@
import { type NextRequest, NextResponse } from "next/server";
import { resolveUpstreamBase } from "@/lib/imager";
const FIGURE_RE = /^[a-z]{2}-\d+/i;
const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i;
const FIGURE_MAX_LEN = 512;
const FIGURE_MAX_PARTS = 24;
const UPSTREAM_TIMEOUT_MS = 10_000;
@@ -49,6 +49,7 @@ export async function GET(request: NextRequest) {
searchParams.get("headOnly") === "1";
const gesture = searchParams.get("gesture") ?? undefined;
const action = searchParams.get("action") ?? undefined;
const effect = searchParams.get("effect") ?? undefined;
const params = new URLSearchParams({
figure,
@@ -60,6 +61,7 @@ export async function GET(request: NextRequest) {
if (headOnly) params.set("headonly", "1");
if (gesture) params.set("gesture", gesture);
if (action) params.set("action", action);
if (effect) params.set("effect", effect);
const imgFormat = searchParams.get("img_format");
if (imgFormat) params.set("img_format", imgFormat);
+3 -1
View File
@@ -1,7 +1,7 @@
import { type NextRequest, NextResponse } from "next/server";
import { resolveUpstreamBase } from "@/lib/imager";
const FIGURE_RE = /^[a-z]{2}-\d+/i;
const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i;
const FIGURE_MAX_LEN = 512;
const FIGURE_MAX_PARTS = 24;
const UPSTREAM_TIMEOUT_MS = 10_000;
@@ -49,6 +49,7 @@ export async function GET(request: NextRequest) {
searchParams.get("headOnly") === "1";
const gesture = searchParams.get("gesture") ?? undefined;
const action = searchParams.get("action") ?? undefined;
const effect = searchParams.get("effect") ?? undefined;
const params = new URLSearchParams({
figure,
@@ -60,6 +61,7 @@ export async function GET(request: NextRequest) {
if (headOnly) params.set("headonly", "1");
if (gesture) params.set("gesture", gesture);
if (action) params.set("action", action);
if (effect) params.set("effect", effect);
const imgFormat = searchParams.get("img_format");
if (imgFormat) params.set("img_format", imgFormat);