fix: make badges work again
This commit is contained in:
parent
cb6a242fe8
commit
1cf2787f3a
1 changed files with 105 additions and 43 deletions
|
|
@ -1,15 +1,43 @@
|
|||
import { after } from "@lib/api/patcher";
|
||||
import { onJsxCreate } from "@lib/api/react/jsx";
|
||||
import { findByName } from "@metro";
|
||||
import { findByName, findByNameLazy } from "@metro";
|
||||
import { useEffect, useState } from "react";
|
||||
import { defineCorePlugin } from "..";
|
||||
import { FluxDispatcher } from "@metro/common";
|
||||
|
||||
interface BunnyBadge {
|
||||
interface Badge {
|
||||
label: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const useBadgesModule = findByName("useBadges", false);
|
||||
interface CustomBadge {
|
||||
label: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface UserBadgeData {
|
||||
roles?: string[];
|
||||
custom?: CustomBadge[];
|
||||
}
|
||||
|
||||
interface BadgeData {
|
||||
[userId: string]: UserBadgeData;
|
||||
}
|
||||
|
||||
interface RoleData {
|
||||
label: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface RolesData {
|
||||
[roleName: string]: RoleData;
|
||||
}
|
||||
|
||||
const useBadgesModule = findByNameLazy("useBadges", false);
|
||||
|
||||
const badgesCache = new Map<string, Badge[]>();
|
||||
const badgeProps = new Map<string, Record<string, any>>();
|
||||
const pendingRequests = new Set<string>();
|
||||
|
||||
export default defineCorePlugin({
|
||||
manifest: {
|
||||
|
|
@ -26,12 +54,9 @@ export default defineCorePlugin({
|
|||
},
|
||||
|
||||
start() {
|
||||
let allBadges: { [x: string]: any; } | null = null;
|
||||
const badgeProps = {} as Record<string, any>;
|
||||
|
||||
onJsxCreate("ProfileBadge", (component, ret) => {
|
||||
if (ret.props.id?.startsWith("bunny-")) {
|
||||
const cachedProps = badgeProps[ret.props.id];
|
||||
if (ret.props.id?.startsWith("rain-")) {
|
||||
const cachedProps = badgeProps.get(ret.props.id);
|
||||
if (cachedProps) {
|
||||
ret.props.source = cachedProps.source;
|
||||
ret.props.label = cachedProps.label;
|
||||
|
|
@ -39,54 +64,91 @@ export default defineCorePlugin({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
onJsxCreate("RenderedBadge", (component, ret) => {
|
||||
if (ret.props.id?.startsWith("bunny-")) {
|
||||
const cachedProps = badgeProps[ret.props.id];
|
||||
if (ret.props.id?.startsWith("rain-")) {
|
||||
const cachedProps = badgeProps.get(ret.props.id);
|
||||
if (cachedProps) {
|
||||
Object.assign(ret.props, cachedProps);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
after("default", useBadgesModule, ([user], result) => {
|
||||
const [badges, setBadges] = useState<BunnyBadge[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
|
||||
if (!allBadges) {
|
||||
fetch("https://codeberg.org/raincord/badges/raw/branch/main/badges.json")
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
allBadges = data;
|
||||
//@ts-expect-error
|
||||
setBadges(allBadges[user.userId] || []);
|
||||
})
|
||||
} else {
|
||||
//user has no badges, but maybe they should get some by contributing
|
||||
setBadges(allBadges[user.userId] || []);
|
||||
|
||||
const fetchAndProcessBadges = async (userId: string) => {
|
||||
if (pendingRequests.has(userId)) return;
|
||||
pendingRequests.add(userId);
|
||||
|
||||
try {
|
||||
const [badgesRes, rolesRes] = await Promise.all([
|
||||
fetch("https://codeberg.org/raincord/badges/raw/branch/main/badges.json"),
|
||||
fetch("https://codeberg.org/raincord/badges/raw/branch/main/assets/roles/roles.json"),
|
||||
]);
|
||||
|
||||
const badgesData: BadgeData = await badgesRes.json();
|
||||
const rolesData: RolesData = await rolesRes.json();
|
||||
|
||||
const userBadgeData = badgesData[userId] || { roles: [], custom: [] };
|
||||
|
||||
const allBadges: Badge[] = [];
|
||||
|
||||
// process role badges
|
||||
if (userBadgeData.roles) {
|
||||
userBadgeData.roles.forEach(roleName => {
|
||||
const roleData = rolesData[roleName];
|
||||
if (roleData) {
|
||||
allBadges.push({
|
||||
label: roleData.label,
|
||||
url: roleData.url,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [user?.userId]);
|
||||
|
||||
if (user && badges.length > 0) {
|
||||
badges.forEach((badge, i) => {
|
||||
const badgeId = `bunny-${user.userId}-${i}`;
|
||||
|
||||
badgeProps[badgeId] = {
|
||||
|
||||
// process custom badges
|
||||
if (userBadgeData.custom) {
|
||||
allBadges.push(...userBadgeData.custom);
|
||||
}
|
||||
|
||||
badgesCache.set(userId, allBadges);
|
||||
|
||||
allBadges.forEach((badge, i) => {
|
||||
const badgeId = `rain-${userId}-${i}`;
|
||||
badgeProps.set(badgeId, {
|
||||
id: badgeId,
|
||||
source: { uri: badge.url },
|
||||
label: badge.label,
|
||||
userId: user.userId,
|
||||
};
|
||||
|
||||
result.push({
|
||||
id: badgeId,
|
||||
description: badge.label,
|
||||
icon: " _",
|
||||
userId,
|
||||
});
|
||||
});
|
||||
|
||||
FluxDispatcher.dispatch({ type: "USER_UPDATE", user: { id: userId } });
|
||||
} finally {
|
||||
pendingRequests.delete(userId);
|
||||
}
|
||||
};
|
||||
|
||||
after("default", useBadgesModule, ([user], result) => {
|
||||
if (!user) return;
|
||||
|
||||
const userId = user.userId;
|
||||
const cached = badgesCache.get(userId);
|
||||
|
||||
if (!cached) {
|
||||
if (!pendingRequests.has(userId)) {
|
||||
fetchAndProcessBadges(userId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cached.forEach((badge, i) => {
|
||||
const badgeId = `rain-${userId}-${i}`;
|
||||
|
||||
result.unshift({
|
||||
id: badgeId,
|
||||
description: badge.label,
|
||||
icon: " _",
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue