feat(coreplugins): add badges
This commit is contained in:
parent
ed52f332da
commit
e3df56dc58
5 changed files with 105 additions and 2 deletions
60
src/core/plugins/badges/index.tsx
Normal file
60
src/core/plugins/badges/index.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import { addJSXCallback } from "@lib/api/jsx";
|
||||
import { after } from "@lib/api/patcher";
|
||||
import { findByName } from "@metro";
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { ImageSourcePropType, ViewStyle } from "react-native";
|
||||
|
||||
import { defineCorePlugin } from "..";
|
||||
|
||||
interface BunnyBadge {
|
||||
label: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const useBadgesModule = findByName("useBadges", false);
|
||||
|
||||
export default defineCorePlugin({
|
||||
manifest: {
|
||||
id: "bunny.badges",
|
||||
name: "Badges",
|
||||
version: "1.0.0",
|
||||
description: "Adds badges to user's profile",
|
||||
authors: [{ name: "pylixonly" }]
|
||||
},
|
||||
start() {
|
||||
const propHolder = {} as Record<string, any>;
|
||||
const badgeCache = {} as Record<string, BunnyBadge[]>;
|
||||
|
||||
addJSXCallback("RenderedBadge", (_, ret) => {
|
||||
if (ret.props.id.match(/bunny-\d+-\d+/)) {
|
||||
Object.assign(ret.props, propHolder[ret.props.id]);
|
||||
}
|
||||
});
|
||||
|
||||
after("default", useBadgesModule, ([user], r) => {
|
||||
const [badges, setBadges] = useState<BunnyBadge[]>(user ? badgeCache[user.userId] ??= [] : []);
|
||||
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
fetch(`https://raw.githubusercontent.com/pyoncord/badges/refs/heads/main/${user.userId}.json`)
|
||||
.then(r => r.json())
|
||||
.then(badges => setBadges(badgeCache[user.userId] = badges));
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
badges.forEach((badges, i) => {
|
||||
propHolder[`bunny-${user.userId}-${i}`] = {
|
||||
source: { uri: badges.url },
|
||||
id: `bunny-${i}`,
|
||||
label: badges.label
|
||||
};
|
||||
|
||||
r.push({
|
||||
id: `bunny-${user.userId}-${i}`,
|
||||
description: badges.label,
|
||||
icon: "2ba85e8026a8614b640c2837bcdfe21b",
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -7,7 +7,8 @@ interface CorePlugin {
|
|||
|
||||
// Called from @lib/plugins
|
||||
export const getCorePlugins = (): Record<string, CorePlugin> => ({
|
||||
"bunny.quickinstall": require("./quickinstall")
|
||||
"bunny.quickinstall": require("./quickinstall"),
|
||||
"bunny.badges": require("./badges")
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export default defineCorePlugin({
|
|||
name: "QuickInstall",
|
||||
version: "1.0.0",
|
||||
description: "Quickly install Vendetta plugins and themes",
|
||||
authors: ["pyoncord"]
|
||||
authors: [{ name: "Vendetta Team" }]
|
||||
},
|
||||
start() {
|
||||
patches = [patchForumPost(), patchUrl()];
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { VdPluginManager } from "@core/vendetta/plugins";
|
|||
import { patchCommands } from "@lib/api/commands";
|
||||
import { patchLogHook } from "@lib/api/debug";
|
||||
import { injectFluxInterceptor } from "@lib/api/flux";
|
||||
import { patchJSX } from "@lib/api/jsx";
|
||||
import { removeFile, writeFile } from "@lib/api/native/fs";
|
||||
import { isPyonLoader, isThemeSupported } from "@lib/api/native/loader";
|
||||
import { FileManager } from "@lib/api/native/modules";
|
||||
|
|
@ -42,6 +43,7 @@ export default async () => {
|
|||
patchLogHook(),
|
||||
patchCommands(),
|
||||
patchChatBackground(),
|
||||
patchJSX(),
|
||||
initVendettaObject(),
|
||||
initFetchI18nStrings(),
|
||||
initSettings(),
|
||||
|
|
|
|||
40
src/lib/api/jsx/index.ts
Normal file
40
src/lib/api/jsx/index.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { after } from "@lib/api/patcher";
|
||||
import { findByPropsLazy } from "@metro";
|
||||
|
||||
type Callback = (Component: any, ret: JSX.Element) => void;
|
||||
const callbacks = new Map<string, Callback[]>();
|
||||
|
||||
const jsxRuntime = findByPropsLazy("jsx", "jsxs");
|
||||
|
||||
export function addJSXCallback(Component: string, callback: Callback) {
|
||||
if (!callbacks.has(Component)) callbacks.set(Component, []);
|
||||
callbacks.get(Component)!.push(callback);
|
||||
}
|
||||
|
||||
export function removeJSXCallback(Component: string, callback: Callback) {
|
||||
if (!callbacks.has(Component)) return;
|
||||
const cbs = callbacks.get(Component)!;
|
||||
cbs.splice(cbs.indexOf(callback), 1);
|
||||
if (cbs.length === 0) callbacks.delete(Component);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function patchJSX() {
|
||||
// Only a simple name check for now
|
||||
const callback = ([Component, props]: any[], ret: any) => {
|
||||
if (typeof Component === "function" && callbacks.has(Component.name)) {
|
||||
const cbs = callbacks.get(Component.name)!;
|
||||
for (const cb of cbs) ret = cb(Component, ret);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
const patches = [
|
||||
after("jsx", jsxRuntime, callback),
|
||||
after("jsxs", jsxRuntime, callback)
|
||||
];
|
||||
|
||||
return () => patches.forEach(unpatch => unpatch());
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue