fix PronounDB crash with new profile in dms, force start dependencies

This commit is contained in:
Vendicated 2022-11-12 15:09:02 +01:00
parent b48c8d8a4a
commit 81edc14070
No known key found for this signature in database
GPG Key ID: EC781ADFB93EFFA3
8 changed files with 80 additions and 24 deletions

View File

@ -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}

View File

@ -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,

View File

@ -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;
}
for (const p of Object.values(Plugins))
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 pluginsValues)
if (p.patches && isPluginEnabled(p.name)) {
for (const patch of p.patches) {
patch.plugin = p.name;

View File

@ -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;
}

View File

@ -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;

View File

@ -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>
);
}
});
};

View File

@ -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[];

View File

@ -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;