Refactor badge data structure and fetching logic

This commit is contained in:
OTKUSteyler 2026-07-01 15:59:43 +02:00 • committed by GitHub
parent 60f9e9e872
commit 6c68f5b5d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,7 +1,6 @@
import { after } from "@lib/api/patcher"; import { after } from "@lib/api/patcher";
import { onJsxCreate } from "@lib/api/react/jsx"; import { onJsxCreate } from "@lib/api/react/jsx";
import { findByName, findByNameLazy } from "@metro"; import { findByNameLazy } from "@metro";
import { useEffect, useState } from "react";
import { defineCorePlugin } from ".."; import { defineCorePlugin } from "..";
import { FluxDispatcher } from "@metro/common"; import { FluxDispatcher } from "@metro/common";
@ -10,14 +9,9 @@ interface Badge {
url: string; url: string;
} }
interface CustomBadge {
label: string;
url: string;
}
interface UserBadgeData { interface UserBadgeData {
roles?: string[]; roles?: string[];
custom?: CustomBadge[]; custom?: Badge[];
} }
interface BadgeData { interface BadgeData {
@ -45,20 +39,20 @@ const badgeProps = new Map<string, Record<string, any>>();
const pendingRequests = new Set<string>(); const pendingRequests = new Set<string>();
export default defineCorePlugin({ export default defineCorePlugin({
manifest: { manifest: {
id: "bunny.badges", id: "bunny.badges",
version: "1.2.0", version: "1.2.0",
type: "plugin", type: "plugin",
spec: 3, spec: 3,
main: "", main: "",
display: { display: {
name: "Badges", name: "Badges",
description: "Adds badges to user's profile", description: "Adds badges to user's profile",
authors: [{ name: "cocobo1" }, { name: "pylixonly" }], authors: [{ name: "cocobo1" }, { name: "pylixonly" }],
},
}, },
},
start() { start() {
onJsxCreate("ProfileBadge", (component, ret) => { onJsxCreate("ProfileBadge", (component, ret) => {
if (ret.props.id?.startsWith("rain-")) { if (ret.props.id?.startsWith("rain-")) {
const cachedProps = badgeProps.get(ret.props.id); const cachedProps = badgeProps.get(ret.props.id);
@ -79,23 +73,36 @@ export default defineCorePlugin({
} }
}); });
// Small helper so one failing/optional source can't take down the others.
const safeFetchJson = async <T,>(url: string, fallback: T): Promise<T> => {
try {
const res = await fetch(url);
if (!res.ok) return fallback;
return (await res.json()) as T;
} catch {
return fallback;
}
};
const fetchAndProcessBadges = async (userId: string) => { const fetchAndProcessBadges = async (userId: string) => {
if (pendingRequests.has(userId)) return; if (pendingRequests.has(userId)) return;
pendingRequests.add(userId); pendingRequests.add(userId);
try { try {
const [badgesRes, rolesRes, equicordRes] = await Promise.all([ const [badgesData, rolesData, equicordData] = await Promise.all([
fetch("https://codeberg.org/chocomint-chan/GoonCord_Badges/raw/branch/main/badges.json"), safeFetchJson<BadgeData>(
fetch("https://codeberg.org/chocomint-chan/GoonCord_Badges/raw/branch/main/assets/roles/roles.json"), "https://codeberg.org/chocomint-chan/GoonCord_Badges/raw/branch/main/badges.json",
fetch("https://badge.equicord.org/badges.json"), {}
fetch("https://badges.vencord.dev/badges/"), ),
fetch("https://codeberg.org/raincord/badges/raw/branch/main/badges.json"), safeFetchJson<RolesData>(
fetch("https://codeberg.org/raincord/badges/raw/branch/main/assets/roles/roles.json"), "https://codeberg.org/chocomint-chan/GoonCord_Badges/raw/branch/main/assets/roles/roles.json",
]); {}
),
const badgesData: BadgeData = await badgesRes.json(); safeFetchJson<Record<string, EquicordBadge[]>>(
const rolesData: RolesData = await rolesRes.json(); "https://badge.equicord.org/badges.json",
const equicordData: Record<string, EquicordBadge[]> = equicordRes.ok ? await equicordRes.json() : {}; {}
),
]);
const userBadgeData = badgesData[userId] || { roles: [], custom: [] }; const userBadgeData = badgesData[userId] || { roles: [], custom: [] };
@ -138,12 +145,14 @@ export default defineCorePlugin({
}); });
FluxDispatcher.dispatch({ type: "USER_UPDATE", user: { id: userId } }); FluxDispatcher.dispatch({ type: "USER_UPDATE", user: { id: userId } });
} catch (err) {
console.error("[bunny.badges] Failed to fetch/process badges:", err);
} finally { } finally {
pendingRequests.delete(userId); pendingRequests.delete(userId);
} }
}; };
after("default", useBadgesModule, ([user], result) => { return after("default", useBadgesModule, ([user], result) => {
if (!user) return; if (!user) return;
const userId = user.userId; const userId = user.userId;