Change tooltip to id
This commit is contained in:
parent
063622b76f
commit
22774e2ab8
|
|
@ -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 : "";
|
||||||
icon_url: b.badge,
|
return {
|
||||||
}));
|
id: badgeId(tooltip, b.badge),
|
||||||
|
tooltip,
|
||||||
|
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");
|
||||||
}
|
}
|
||||||
|
|
@ -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). */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue