diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx index b51615f55..4389fe640 100644 --- a/src/components/PluginSettings/index.tsx +++ b/src/components/PluginSettings/index.tsx @@ -198,7 +198,13 @@ function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLe ); } -export default ErrorBoundary.wrap(function Settings() { +enum SearchStatus { + ALL, + ENABLED, + DISABLED +} + +export default ErrorBoundary.wrap(function PluginSettings() { const settings = useSettings(); const changes = React.useMemo(() => new ChangeList(), []); @@ -239,21 +245,19 @@ export default ErrorBoundary.wrap(function Settings() { const sortedPlugins = React.useMemo(() => Object.values(Plugins) .sort((a, b) => a.name.localeCompare(b.name)), []); - const [searchValue, setSearchValue] = React.useState({ value: "", status: "all" }); + const [searchValue, setSearchValue] = React.useState({ value: "", status: SearchStatus.ALL }); const onSearch = (query: string) => setSearchValue(prev => ({ ...prev, value: query })); - const onStatusChange = (status: string) => setSearchValue(prev => ({ ...prev, status })); + const onStatusChange = (status: SearchStatus) => setSearchValue(prev => ({ ...prev, status })); const pluginFilter = (plugin: typeof Plugins[keyof typeof Plugins]) => { - const showEnabled = searchValue.status === "enabled" || searchValue.status === "all"; - const showDisabled = searchValue.status === "disabled" || searchValue.status === "all"; const enabled = settings.plugins[plugin.name]?.enabled || plugin.started; + if (enabled && searchValue.status === SearchStatus.DISABLED) return false; + if (!enabled && searchValue.status === SearchStatus.ENABLED) return false; + if (!searchValue.value.length) return true; return ( - ((showEnabled && enabled) || (showDisabled && !enabled)) && - ( - plugin.name.toLowerCase().includes(searchValue.value.toLowerCase()) || - plugin.description.toLowerCase().includes(searchValue.value.toLowerCase()) - ) + plugin.name.toLowerCase().includes(searchValue.value.toLowerCase()) || + plugin.description.toLowerCase().includes(searchValue.value.toLowerCase()) ); }; @@ -274,6 +278,52 @@ export default ErrorBoundary.wrap(function Settings() { return window._.isEqual(newPlugins, sortedPluginNames) ? [] : newPlugins; })); + type P = JSX.Element | JSX.Element[]; + let plugins: P, requiredPlugins: P; + if (sortedPlugins?.length) { + plugins = []; + requiredPlugins = []; + + for (const p of sortedPlugins) { + if (!pluginFilter(p)) continue; + + const isRequired = p.required || depMap[p.name]?.some(d => Settings.plugins[d].enabled); + + if (isRequired) { + const tooltipText = p.required + ? "This plugin is required for Vencord to function." + : makeDependencyList(depMap[p.name]?.filter(d => settings.plugins[d].enabled)); + + requiredPlugins.push( + + {({ onMouseLeave, onMouseEnter }) => ( + changes.handleChange(name)} + disabled={true} + plugin={p} + /> + )} + + ); + } else { + plugins.push( + changes.handleChange(name)} + disabled={false} + plugin={p} + isNew={newPlugins?.includes(p.name)} + key={p.name} + /> + ); + } + + } + } else { + plugins = requiredPlugins = No plugins meet search criteria.; + } + return ( @@ -288,9 +338,9 @@ export default ErrorBoundary.wrap(function Settings() {