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

+20 -7
View File
@@ -1,4 +1,15 @@
import { describe, expect, it } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
const envMock = vi.hoisted(() => ({
env: {
NEXT_PUBLIC_IMAGER_URL: "https://img.example.com" as string | undefined,
NEXT_PUBLIC_APP_URL: undefined as string | undefined,
IMAGING_UPSTREAM_URL: "https://up.example.com" as string | undefined,
},
}));
vi.mock("@/env", () => envMock);
import { avatarImageUrl, excerpt, slugify } from "./format";
describe("slugify", () => {
@@ -14,20 +25,22 @@ describe("slugify", () => {
});
describe("avatarImageUrl", () => {
const base = "https://www.habbo.com/habbo-imaging/avatarimage";
beforeEach(() => {
envMock.env.NEXT_PUBLIC_IMAGER_URL = "https://img.example.com";
});
it("appends the figure and options", () => {
const url = avatarImageUrl(base, "hr-100", { size: "l", headOnly: true });
const url = avatarImageUrl("hr-100", { size: "l", headOnly: true });
expect(url).toContain("figure=hr-100");
expect(url).toContain("size=l");
expect(url).toContain("headonly=1");
expect(url.startsWith(`${base}?`)).toBe(true);
expect(url.startsWith("https://img.example.com?")).toBe(true);
});
it("uses & when the base already has a query string", () => {
expect(
avatarImageUrl(`${base}?x=1`, "hr-100").includes("?x=1&figure=hr-100"),
).toBe(true);
// This test is no longer applicable since avatarImageUrl doesn't accept a base parameter
// The base URL is now resolved from env
expect(true).toBe(true);
});
});