fix PronounDB crash with new profile in dms, force start dependencies
This commit is contained in:
parent
b48c8d8a4a
commit
81edc14070
8 changed files with 80 additions and 24 deletions
|
@ -22,8 +22,13 @@ import { Margins, React } from "../webpack/common";
|
||||||
import { ErrorCard } from "./ErrorCard";
|
import { ErrorCard } from "./ErrorCard";
|
||||||
|
|
||||||
interface Props {
|
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; }>>;
|
fallback?: React.ComponentType<React.PropsWithChildren<{ error: any; message: string; stack: string; }>>;
|
||||||
|
/** called when an error occurs */
|
||||||
onError?(error: Error, errorInfo: React.ErrorInfo): void;
|
onError?(error: Error, errorInfo: React.ErrorInfo): void;
|
||||||
|
/** Custom error message */
|
||||||
message?: string;
|
message?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +72,8 @@ const ErrorBoundary = LazyComponent(() => {
|
||||||
render() {
|
render() {
|
||||||
if (this.state.error === NO_ERROR) return this.props.children;
|
if (this.state.error === NO_ERROR) return this.props.children;
|
||||||
|
|
||||||
|
if (this.props.noop) return null;
|
||||||
|
|
||||||
if (this.props.fallback)
|
if (this.props.fallback)
|
||||||
return <this.props.fallback
|
return <this.props.fallback
|
||||||
children={this.props.children}
|
children={this.props.children}
|
||||||
|
|
|
@ -37,6 +37,7 @@ export default definePlugin({
|
||||||
wreq: Vencord.Webpack.wreq,
|
wreq: Vencord.Webpack.wreq,
|
||||||
wpsearch: Vencord.Webpack.search,
|
wpsearch: Vencord.Webpack.search,
|
||||||
wpex: Vencord.Webpack.extract,
|
wpex: Vencord.Webpack.extract,
|
||||||
|
wpexs: (code: string) => Vencord.Webpack.extract(Vencord.Webpack.findModuleId(code)!),
|
||||||
findByProps: Vencord.Webpack.findByProps,
|
findByProps: Vencord.Webpack.findByProps,
|
||||||
find: Vencord.Webpack.find,
|
find: Vencord.Webpack.find,
|
||||||
Plugins: Vencord.Plugins,
|
Plugins: Vencord.Plugins,
|
||||||
|
|
|
@ -30,11 +30,36 @@ export const PMLogger = logger;
|
||||||
export const plugins = Plugins;
|
export const plugins = Plugins;
|
||||||
export const patches = [] as Patch[];
|
export const patches = [] as Patch[];
|
||||||
|
|
||||||
|
const settings = Settings.plugins;
|
||||||
|
|
||||||
export function isPluginEnabled(p: string) {
|
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)) {
|
if (p.patches && isPluginEnabled(p.name)) {
|
||||||
for (const patch of p.patches) {
|
for (const patch of p.patches) {
|
||||||
patch.plugin = p.name;
|
patch.plugin = p.name;
|
||||||
|
|
|
@ -27,12 +27,18 @@ import { PronounMapping } from "../types";
|
||||||
|
|
||||||
const styles: Record<string, string> = lazyWebpack(filters.byProps("timestampInline"));
|
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
|
// 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
|
// 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(
|
const [result, , isPending] = useAwaiter(
|
||||||
() => fetchPronouns(message.author.id),
|
() => fetchPronouns(message.author.id),
|
||||||
null,
|
null,
|
||||||
|
@ -47,6 +53,6 @@ export default function PronounsChatComponent({ message }: { message: Message; }
|
||||||
>• {formatPronouns(result)}</span>
|
>• {formatPronouns(result)}</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Otherwise, return null so nothing else is rendered
|
|
||||||
else return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,22 @@ export default function PronounsProfileWrapper(PronounsComponent: React.ElementT
|
||||||
if (!Settings.plugins.PronounDB.showSelf && user.id === UserStore.getCurrentUser().id)
|
if (!Settings.plugins.PronounDB.showSelf && user.id === UserStore.getCurrentUser().id)
|
||||||
return null;
|
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(
|
const [result, , isPending] = useAwaiter(
|
||||||
() => fetchPronouns(user.id),
|
() => fetchPronouns(userId),
|
||||||
null,
|
null,
|
||||||
e => console.error("Fetching pronouns failed: ", e)
|
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 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]) {
|
if (!isPending && result && result !== "unspecified" && PronounMapping[result]) {
|
||||||
// First child is the header, second is a div with the actual text
|
// First child is the header, second is a div with the actual text
|
||||||
props.currentPronouns ||= formatPronouns(result);
|
leProps.currentPronouns ||= formatPronouns(result);
|
||||||
return <PronounsComponent {...props} />;
|
return <Component {...leProps} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -21,7 +21,7 @@ import type { Guild } from "discord-types/general";
|
||||||
import { Devs } from "../utils/constants";
|
import { Devs } from "../utils/constants";
|
||||||
import { LazyComponent, lazyWebpack } from "../utils/misc";
|
import { LazyComponent, lazyWebpack } from "../utils/misc";
|
||||||
import { ModalRoot, ModalSize, openModal } from "../utils/modal";
|
import { ModalRoot, ModalSize, openModal } from "../utils/modal";
|
||||||
import definePlugin from "../utils/types";
|
import { PluginDef } from "../utils/types";
|
||||||
import { filters, find } from "../webpack";
|
import { filters, find } from "../webpack";
|
||||||
import { Menu } from "../webpack/common";
|
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 GuildBannerStore = lazyWebpack(filters.byProps("getGuildBannerURL"));
|
||||||
|
|
||||||
const OPEN_URL = "Vencord.Plugins.plugins.ViewIcons.openImage(";
|
const OPEN_URL = "Vencord.Plugins.plugins.ViewIcons.openImage(";
|
||||||
export default definePlugin({
|
export default new class ViewIcons implements PluginDef {
|
||||||
name: "ViewIcons",
|
name = "ViewIcons";
|
||||||
authors: [Devs.Ven],
|
authors = [Devs.Ven];
|
||||||
description: "Makes Avatars/Banners in user profiles clickable, and adds Guild Context Menu Entries to View Banner/Icon.",
|
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) {
|
openImage(url: string) {
|
||||||
const u = new URL(url);
|
const u = new URL(url);
|
||||||
|
@ -53,9 +53,9 @@ export default definePlugin({
|
||||||
/>
|
/>
|
||||||
</ModalRoot>
|
</ModalRoot>
|
||||||
));
|
));
|
||||||
},
|
}
|
||||||
|
|
||||||
patches: [
|
patches = [
|
||||||
{
|
{
|
||||||
find: "onAddFriend:",
|
find: "onAddFriend:",
|
||||||
replacement: {
|
replacement: {
|
||||||
|
@ -84,7 +84,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
];
|
||||||
|
|
||||||
buildGuildContextMenuEntries(guild: Guild) {
|
buildGuildContextMenuEntries(guild: Guild) {
|
||||||
return (
|
return (
|
||||||
|
@ -108,4 +108,4 @@ export default definePlugin({
|
||||||
</Menu.MenuGroup>
|
</Menu.MenuGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
|
@ -49,9 +49,10 @@ export interface PluginAuthor {
|
||||||
export interface Plugin extends PluginDef {
|
export interface Plugin extends PluginDef {
|
||||||
patches?: Patch[];
|
patches?: Patch[];
|
||||||
started: boolean;
|
started: boolean;
|
||||||
|
isDependency?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PluginDef {
|
export interface PluginDef {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
authors: PluginAuthor[];
|
authors: PluginAuthor[];
|
||||||
|
|
|
@ -228,9 +228,11 @@ export const Menu = proxyLazy(() => {
|
||||||
|
|
||||||
if (!hasDeobfuscator) {
|
if (!hasDeobfuscator) {
|
||||||
for (const m of menuItems)
|
for (const m of menuItems)
|
||||||
map[m] = () => {
|
Object.defineProperty(map, m, {
|
||||||
throw new Error(`Your plugin needs to depend on MenuItemDeobfuscatorApi to use ${m}`);
|
get() {
|
||||||
};
|
throw new Error("MenuItemDeobfuscator must be enabled to use this.");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
|
Loading…
Reference in a new issue