aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/ErrorBoundary.tsx7
-rw-r--r--src/plugins/consoleShortcuts.ts1
-rw-r--r--src/plugins/index.ts29
-rw-r--r--src/plugins/pronoundb/components/PronounsChatComponent.tsx16
-rw-r--r--src/plugins/pronoundb/components/PronounsProfileWrapper.tsx20
-rw-r--r--src/plugins/viewIcons.tsx20
-rw-r--r--src/utils/types.ts3
-rw-r--r--src/webpack/common.tsx8
8 files changed, 80 insertions, 24 deletions
diff --git a/src/components/ErrorBoundary.tsx b/src/components/ErrorBoundary.tsx
index 4c2725d..870371e 100644
--- a/src/components/ErrorBoundary.tsx
+++ b/src/components/ErrorBoundary.tsx
@@ -22,8 +22,13 @@ import { Margins, React } from "../webpack/common";
import { ErrorCard } from "./ErrorCard";
interface Props {
+ /** Render nothing if an error occurs */
+ noop?: boolean;
+ /** Fallback component to render if an error occurs */
fallback?: React.ComponentType<React.PropsWithChildren<{ error: any; message: string; stack: string; }>>;
+ /** called when an error occurs */
onError?(error: Error, errorInfo: React.ErrorInfo): void;
+ /** Custom error message */
message?: string;
}
@@ -67,6 +72,8 @@ const ErrorBoundary = LazyComponent(() => {
render() {
if (this.state.error === NO_ERROR) return this.props.children;
+ if (this.props.noop) return null;
+
if (this.props.fallback)
return <this.props.fallback
children={this.props.children}
diff --git a/src/plugins/consoleShortcuts.ts b/src/plugins/consoleShortcuts.ts
index 6cfa357..eeb5d8d 100644
--- a/src/plugins/consoleShortcuts.ts
+++ b/src/plugins/consoleShortcuts.ts
@@ -37,6 +37,7 @@ export default definePlugin({
wreq: Vencord.Webpack.wreq,
wpsearch: Vencord.Webpack.search,
wpex: Vencord.Webpack.extract,
+ wpexs: (code: string) => Vencord.Webpack.extract(Vencord.Webpack.findModuleId(code)!),
findByProps: Vencord.Webpack.findByProps,
find: Vencord.Webpack.find,
Plugins: Vencord.Plugins,
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index d3842aa..268e200 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -30,11 +30,36 @@ export const PMLogger = logger;
export const plugins = Plugins;
export const patches = [] as Patch[];
+const settings = Settings.plugins;
+
export function isPluginEnabled(p: string) {
- return (Settings.plugins[p]?.enabled || Plugins[p]?.required) ?? false;
+ return (
+ Plugins[p]?.required ||
+ Plugins[p]?.isDependency ||
+ settings[p]?.enabled
+ ) ?? false;
+}
+
+const pluginsValues = Object.values(Plugins);
+
+// First roundtrip to mark and force enable dependencies
+for (const p of pluginsValues) {
+ p.dependencies?.forEach(d => {
+ const dep = Plugins[d];
+ if (dep) {
+ settings[d].enabled = true;
+ dep.isDependency = true;
+ }
+ else {
+ const error = new Error(`Plugin ${p.name} has unresolved dependency ${d}`);
+ if (IS_DEV)
+ throw error;
+ logger.warn(error);
+ }
+ });
}
-for (const p of Object.values(Plugins))
+for (const p of pluginsValues)
if (p.patches && isPluginEnabled(p.name)) {
for (const patch of p.patches) {
patch.plugin = p.name;
diff --git a/src/plugins/pronoundb/components/PronounsChatComponent.tsx b/src/plugins/pronoundb/components/PronounsChatComponent.tsx
index 78cee48..57033cc 100644
--- a/src/plugins/pronoundb/components/PronounsChatComponent.tsx
+++ b/src/plugins/pronoundb/components/PronounsChatComponent.tsx
@@ -27,12 +27,18 @@ import { PronounMapping } from "../types";
const styles: Record<string, string> = lazyWebpack(filters.byProps("timestampInline"));
-export default function PronounsChatComponent({ message }: { message: Message; }) {
+export default function PronounsChatComponentWrapper({ message }: { message: Message; }) {
// Don't bother fetching bot or system users
- if (message.author.bot || message.author.system) return null;
+ if (message.author.bot || message.author.system)
+ return null;
// Respect showSelf options
- if (!Settings.plugins.PronounDB.showSelf && message.author.id === UserStore.getCurrentUser().id) return null;
+ if (!Settings.plugins.PronounDB.showSelf && message.author.id === UserStore.getCurrentUser().id)
+ return null;
+ return <PronounsChatComponent message={message} />;
+}
+
+function PronounsChatComponent({ message }: { message: Message; }) {
const [result, , isPending] = useAwaiter(
() => fetchPronouns(message.author.id),
null,
@@ -47,6 +53,6 @@ export default function PronounsChatComponent({ message }: { message: Message; }
>• {formatPronouns(result)}</span>
);
}
- // Otherwise, return null so nothing else is rendered
- else return null;
+
+ return null;
}
diff --git a/src/plugins/pronoundb/components/PronounsProfileWrapper.tsx b/src/plugins/pronoundb/components/PronounsProfileWrapper.tsx
index 139fb8a..b39f4ed 100644
--- a/src/plugins/pronoundb/components/PronounsProfileWrapper.tsx
+++ b/src/plugins/pronoundb/components/PronounsProfileWrapper.tsx
@@ -30,8 +30,22 @@ export default function PronounsProfileWrapper(PronounsComponent: React.ElementT
if (!Settings.plugins.PronounDB.showSelf && user.id === UserStore.getCurrentUser().id)
return null;
+ return <ProfilePronouns
+ userId={profileProps.userId}
+ Component={PronounsComponent}
+ leProps={props}
+ />;
+}
+
+function ProfilePronouns(
+ { userId, Component, leProps }: {
+ userId: string;
+ Component: React.ElementType<UserProfilePronounsProps>;
+ leProps: UserProfilePronounsProps;
+ }
+) {
const [result, , isPending] = useAwaiter(
- () => fetchPronouns(user.id),
+ () => fetchPronouns(userId),
null,
e => console.error("Fetching pronouns failed: ", e)
);
@@ -39,8 +53,8 @@ export default function PronounsProfileWrapper(PronounsComponent: React.ElementT
// If the promise completed, the result was not "unspecified", and there is a mapping for the code, then render
if (!isPending && result && result !== "unspecified" && PronounMapping[result]) {
// First child is the header, second is a div with the actual text
- props.currentPronouns ||= formatPronouns(result);
- return <PronounsComponent {...props} />;
+ leProps.currentPronouns ||= formatPronouns(result);
+ return <Component {...leProps} />;
}
return null;
diff --git a/src/plugins/viewIcons.tsx b/src/plugins/viewIcons.tsx
index afffdff..671b197 100644
--- a/src/plugins/viewIcons.tsx
+++ b/src/plugins/viewIcons.tsx
@@ -21,7 +21,7 @@ import type { Guild } from "discord-types/general";
import { Devs } from "../utils/constants";
import { LazyComponent, lazyWebpack } from "../utils/misc";
import { ModalRoot, ModalSize, openModal } from "../utils/modal";
-import definePlugin from "../utils/types";
+import { PluginDef } from "../utils/types";
import { filters, find } from "../webpack";
import { Menu } from "../webpack/common";
@@ -31,12 +31,12 @@ const MaskedLink = LazyComponent(() => find(m => m.type?.toString().includes("MA
const GuildBannerStore = lazyWebpack(filters.byProps("getGuildBannerURL"));
const OPEN_URL = "Vencord.Plugins.plugins.ViewIcons.openImage(";
-export default definePlugin({
- name: "ViewIcons",
- authors: [Devs.Ven],
- description: "Makes Avatars/Banners in user profiles clickable, and adds Guild Context Menu Entries to View Banner/Icon.",
+export default new class ViewIcons implements PluginDef {
+ name = "ViewIcons";
+ authors = [Devs.Ven];
+ description = "Makes Avatars/Banners in user profiles clickable, and adds Guild Context Menu Entries to View Banner/Icon.";
- dependencies: ["MenuItemDeobfuscatorApi"],
+ dependencies = ["MenuItemDeobfuscatorApi"];
openImage(url: string) {
const u = new URL(url);
@@ -53,9 +53,9 @@ export default definePlugin({
/>
</ModalRoot>
));
- },
+ }
- patches: [
+ patches = [
{
find: "onAddFriend:",
replacement: {
@@ -84,7 +84,7 @@ export default definePlugin({
}
]
}
- ],
+ ];
buildGuildContextMenuEntries(guild: Guild) {
return (
@@ -108,4 +108,4 @@ export default definePlugin({
</Menu.MenuGroup>
);
}
-});
+};
diff --git a/src/utils/types.ts b/src/utils/types.ts
index dd0a9c5..30c603f 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -49,9 +49,10 @@ export interface PluginAuthor {
export interface Plugin extends PluginDef {
patches?: Patch[];
started: boolean;
+ isDependency?: boolean;
}
-interface PluginDef {
+export interface PluginDef {
name: string;
description: string;
authors: PluginAuthor[];
diff --git a/src/webpack/common.tsx b/src/webpack/common.tsx
index 8c77506..497dfe4 100644
--- a/src/webpack/common.tsx
+++ b/src/webpack/common.tsx
@@ -228,9 +228,11 @@ export const Menu = proxyLazy(() => {
if (!hasDeobfuscator) {
for (const m of menuItems)
- map[m] = () => {
- throw new Error(`Your plugin needs to depend on MenuItemDeobfuscatorApi to use ${m}`);
- };
+ Object.defineProperty(map, m, {
+ get() {
+ throw new Error("MenuItemDeobfuscator must be enabled to use this.");
+ }
+ });
}
return map;