diff options
-rw-r--r-- | src/components/Settings.tsx | 85 | ||||
-rw-r--r-- | src/utils/misc.tsx | 30 |
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; +} |