Refactor badge data structure and fetching logic
This commit is contained in:
parent
60f9e9e872
commit
6c68f5b5d6
1 changed files with 42 additions and 33 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue