Add performance optimizations and component refactors
- Cache read-heavy public API routes via redisCache (leaderboard, values, shop, articles, photos, guilds, teams, staff, users, home, radio, badges) - Add single-flight and bounded-memory cache layer with unit tests - Parallelize independent DB queries on search, rares, shop, staff, polls and profile pages - Push radio points leaderboard aggregation to SQL with a LIMIT - Split studio-client and import-furni-client into focused modules - Clean up next.config.ts
This commit is contained in:
1 parent
54f2bc5e0c
commit
f285a7cd98
42 files changed
+1616
-1205
No files matched your search
@@ -0,0 +1,45 @@
|
||||
import type { SyntheticEvent } from "react";
|
||||
|
||||
export function getFurniImageUrl(classname: string, revision: number) {
|
||||
// Use official Habbo CDN for furniture icons
|
||||
const base = classname.includes("*")
|
||||
? classname.substring(0, classname.indexOf("*"))
|
||||
: classname;
|
||||
return `https://images.habbo.com/dcr/hof_furni/${revision}/${encodeURIComponent(base)}_icon.png`;
|
||||
}
|
||||
|
||||
export function getFurniIconUrl(classname: string, revision: number) {
|
||||
const iconName = classname.replace(/\*/g, "_");
|
||||
return `https://images.habbo.com/dcr/hof_furni/${revision}/${encodeURIComponent(iconName)}_icon.png`;
|
||||
}
|
||||
|
||||
export function handleImgError(
|
||||
e: SyntheticEvent<HTMLImageElement>,
|
||||
classname: string,
|
||||
revision: number,
|
||||
) {
|
||||
const img = e.target as HTMLImageElement;
|
||||
const iconName = classname.replace(/\*/g, "_");
|
||||
if (!img.dataset.fallback) {
|
||||
img.dataset.fallback = "1";
|
||||
img.src = getFurniIconUrl(classname, revision);
|
||||
} else if (img.dataset.fallback === "1") {
|
||||
img.dataset.fallback = "2";
|
||||
img.src = `/swf/dcr/hof_furni/icons/${encodeURIComponent(iconName)}_icon.png`;
|
||||
} else {
|
||||
// Show placeholder instead of invisible image
|
||||
img.style.opacity = "0.3";
|
||||
img.src =
|
||||
'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="%23666" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>';
|
||||
}
|
||||
}
|
||||
|
||||
export const STATUS_LABELS: Record<string, string> = {
|
||||
pending: "Pending",
|
||||
started: "Starting",
|
||||
downloading: "Downloading",
|
||||
converting: "Converting",
|
||||
writing_db: "Writing DB",
|
||||
done: "Done",
|
||||
failed: "Failed",
|
||||
};
|
||||
Reference in new issue
Block a user