aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/Settings.tsx85
-rw-r--r--src/utils/misc.tsx30
2 files changed, 85 insertions, 30 deletions
diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx
index c274366..dfea116 100644
--- a/src/components/Settings.tsx
+++ b/src/components/Settings.tsx
@@ -1,9 +1,9 @@
-import { useAwaiter } from "../utils/misc";
+import { humanFriendlyJoin, useAwaiter } from "../utils/misc";
import Plugins from 'plugins';
import { useSettings } from "../api/settings";
import IpcEvents from "../utils/IpcEvents";
-import { Button, ButtonProps, Flex, Switch, Forms } from "../webpack/common";
+import { Button, ButtonProps, Flex, Switch, Forms, React } from "../webpack/common";
import ErrorBoundary from "./ErrorBoundary";
import { startPlugin } from "../plugins";
import { stopPlugin } from '../plugins/index';
@@ -12,6 +12,22 @@ export default ErrorBoundary.wrap(function Settings(props) {
const [settingsDir, , settingsDirPending] = useAwaiter(() => VencordNative.ipc.invoke<string>(IpcEvents.GET_SETTINGS_DIR), "Loading...");
const settings = useSettings();
+ const depMap = React.useMemo(() => {
+ const o = {} as Record<string, string[]>;
+ for (const plugin in Plugins) {
+ const deps = Plugins[plugin].dependencies;
+ if (deps) {
+ for (const dep of deps) {
+ o[dep] ??= [];
+ o[dep].push(plugin);
+ }
+ }
+ }
+ return o;
+ }, []);
+
+ console.log(depMap);
+
return (
<Forms.FormSection tag="h1" title="Vencord">
<Forms.FormText>SettingsDir: {settingsDir}</Forms.FormText>
@@ -45,39 +61,50 @@ export default ErrorBoundary.wrap(function Settings(props) {
</Switch>
<Forms.FormDivider />
<Forms.FormTitle tag="h5">Plugins</Forms.FormTitle>
- {Object.values(Plugins).map(p => (
- <Switch
- disabled={p.required === true}
- key={p.name}
- value={settings.plugins[p.name].enabled}
- onChange={v => {
- settings.plugins[p.name].enabled = v;
- if (v) {
- p.dependencies?.forEach(d => {
- settings.plugins[d].enabled = true;
- if (!Plugins[d].started && !stopPlugin) {
+ {Object.values(Plugins).map(p => {
+ const enabledDependants = depMap[p.name]?.filter(d => settings.plugins[d].enabled);
+ const dependency = enabledDependants?.length;
+
+ return (
+ <Switch
+ disabled={p.required || dependency}
+ key={p.name}
+ value={settings.plugins[p.name].enabled || p.required || dependency}
+ onChange={v => {
+ settings.plugins[p.name].enabled = v;
+ if (v) {
+ p.dependencies?.forEach(d => {
+ settings.plugins[d].enabled = true;
+ if (!Plugins[d].started && !stopPlugin) {
+ // TODO show notification
+ settings.plugins[p.name].enabled = false;
+ }
+ });
+ if (!p.started && !startPlugin(p)) {
+ // TODO show notification
+ }
+ } else {
+ if (p.started && !stopPlugin(p)) {
// TODO show notification
- settings.plugins[p.name].enabled = false;
}
- });
- if (!p.started && !startPlugin(p)) {
- // TODO show notification
}
- } else {
- if (p.started && !stopPlugin(p)) {
+ if (p.patches) {
// TODO show notification
}
+ }}
+ note={p.description}
+ tooltipNote={
+ p.required ?
+ "This plugin is required. Thus you cannot disable it."
+ : dependency ?
+ `${humanFriendlyJoin(enabledDependants)} ${enabledDependants.length === 1 ? "depends" : "depend"} on this plugin. Thus you cannot disable it.`
+ : ""
}
- if (p.patches) {
- // TODO show notification
- }
- }}
- note={p.description}
- tooltipNote={p.required ? "This plugin is required. Thus you cannot disable it." : undefined}
- >
- {p.name}
- </Switch>
- ))
+ >
+ {p.name}
+ </Switch>
+ );
+ })
}
</Forms.FormSection >
);
diff --git a/src/utils/misc.tsx b/src/utils/misc.tsx
index aca7661..9d4c001 100644
--- a/src/utils/misc.tsx
+++ b/src/utils/misc.tsx
@@ -69,4 +69,32 @@ export function mergeDefaults<T>(obj: T, defaults: T): T {
}
}
return obj;
-} \ No newline at end of file
+}
+
+
+/**
+ * Join an array of strings in a human readable way (1, 2 and 3)
+ * @param elements Elements
+ */
+export function humanFriendlyJoin(elements: string[]): string;
+/**
+ * Join an array of strings in a human readable way (1, 2 and 3)
+ * @param elements Elements
+ * @param mapper Function that converts elements to a string
+ */
+export function humanFriendlyJoin<T>(elements: T[], mapper: (e: T) => string): string;
+export function humanFriendlyJoin(elements: any[], mapper: (e: any) => string = s => s): string {
+ const { length } = elements;
+ if (length === 0) return "";
+ if (length === 1) return mapper(elements[0]);
+
+ let s = "";
+
+ for (let i = 0; i < length; i++) {
+ s += mapper(elements[i]);
+ if (length - i > 2) s += ", ";
+ else if (length - i > 1) s += " and ";
+ }
+
+ return s;
+}