Change tooltip to id

This commit is contained in:
Clove 2026-06-26 02:39:48 +01:00
parent 063622b76f
commit 22774e2ab8
2 changed files with 43 additions and 4 deletions

View File

@ -1,3 +1,18 @@
/* =====================================================================
* discord/clientBadges.ts third-party client-mod badges.
*
* badges.equicord.org aggregates badges from Vencord, Equicord, Aliucord,
* and a bunch of other client mods (Nekocord, ReviewDB, BadgeVault, Aero,
* Raincord, Velocity, Enmity, Replugged, Paicord) into one "global badges"
* style response. We just hit the plain GET /:userId (no query params)
* that's already the combined view across every service and cache it,
* since none of this is ours to rate-limit.
*
* This is intentionally kept separate from `badges` (Discord's own
* flags/profile badges): different source, different trust level, and the
* caller asked for it to live at `data.clientBadges` instead.
* ===================================================================== */
import type { Env, UnifiedClientBadge } from "../types"; import type { Env, UnifiedClientBadge } from "../types";
const API_BASE = "https://badges.equicord.org"; const API_BASE = "https://badges.equicord.org";
@ -86,8 +101,29 @@ async function fetchClientBadges(id: string): Promise<UnifiedClientBadge[] | und
// `data.badges` via Discord's own flags, so drop them here to avoid // `data.badges` via Discord's own flags, so drop them here to avoid
// duplicating them under clientBadges. // duplicating them under clientBadges.
.filter((b) => !/\/public\/badges\/discord\//i.test(b.badge)) .filter((b) => !/\/public\/badges\/discord\//i.test(b.badge))
.map((b) => ({ .map((b) => {
tooltip: typeof b.tooltip === "string" ? b.tooltip : "", const tooltip = typeof b.tooltip === "string" ? b.tooltip : "";
return {
id: badgeId(tooltip, b.badge),
tooltip,
icon_url: b.badge, icon_url: b.badge,
})); };
});
}
/**
* Deterministic id for a badge the upstream API has no id field of its
* own (these are arbitrary per-user badges, not a fixed catalog), so we
* derive a stable short hash from tooltip+icon_url. Same badge -> same id
* every time, which is all that's needed for React keys / dedup / lookups.
*/
function badgeId(tooltip: string, iconUrl: string): string {
const input = `${tooltip}\u0000${iconUrl}`;
// FNV-1a 32-bit — fast, sync, good enough distribution for this purpose.
let hash = 0x811c9dc5;
for (let i = 0; i < input.length; i++) {
hash ^= input.charCodeAt(i);
hash = Math.imul(hash, 0x01000193);
}
return (hash >>> 0).toString(16).padStart(8, "0");
} }

View File

@ -60,6 +60,9 @@ export interface UnifiedBadge {
* unofficial third-party service. * unofficial third-party service.
*/ */
export interface UnifiedClientBadge { export interface UnifiedClientBadge {
/** Stable id derived from tooltip+icon_url (the upstream API has no id of
* its own these are arbitrary per-user badges, not a fixed catalog). */
id: string;
/** Tooltip text the client mod shows for this badge. */ /** Tooltip text the client mod shows for this badge. */
tooltip: string; tooltip: string;
/** Absolute URL to the badge icon (png/gif/webp/svg). */ /** Absolute URL to the badge icon (png/gif/webp/svg). */