Skip to content

Commit

Permalink
feat(coreplugins): add badges
Browse files Browse the repository at this point in the history
  • Loading branch information
pylixonly committed Oct 9, 2024
1 parent ed52f33 commit e3df56d
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 2 deletions.
60 changes: 60 additions & 0 deletions src/core/plugins/badges/index.tsx
Original file line number Diff line number Diff line change
@@ -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",
});
});
});
}
});
3 changes: 2 additions & 1 deletion src/core/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
});

/**
Expand Down
2 changes: 1 addition & 1 deletion src/core/plugins/quickinstall/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()];
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -42,6 +43,7 @@ export default async () => {
patchLogHook(),
patchCommands(),
patchChatBackground(),
patchJSX(),
initVendettaObject(),
initFetchI18nStrings(),
initSettings(),
Expand Down
40 changes: 40 additions & 0 deletions src/lib/api/jsx/index.ts
Original file line number Diff line number Diff line change
@@ -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());
}

0 comments on commit e3df56d

Please sign in to comment.