From 1d287357ca33f8bdd9933a27dc5ea63a8f29e2f8 Mon Sep 17 00:00:00 2001 From: Ven Date: Sun, 15 Jan 2023 22:26:02 +0100 Subject: [PATCH] Reimplement Discord's Switch to fix performance (#413) --- src/components/PluginSettings/index.tsx | 86 ++++++++++++------------ src/components/PluginSettings/styles.css | 47 +++++++++---- src/components/Switch.css | 3 + src/components/Switch.tsx | 76 +++++++++++++++++++++ src/preload.ts | 6 +- 5 files changed, 161 insertions(+), 57 deletions(-) create mode 100644 src/components/Switch.css create mode 100644 src/components/Switch.tsx diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx index 3b283d044..58058b14a 100644 --- a/src/components/PluginSettings/index.tsx +++ b/src/components/PluginSettings/index.tsx @@ -23,25 +23,25 @@ import { showNotice } from "@api/Notices"; import { useSettings } from "@api/settings"; import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; -import { ErrorCard } from "@components/ErrorCard"; import { Flex } from "@components/Flex"; import { handleComponentFailed } from "@components/handleComponentFailed"; import { Badge } from "@components/PluginSettings/components"; import PluginModal from "@components/PluginSettings/PluginModal"; +import { Switch } from "@components/Switch"; import { ChangeList } from "@utils/ChangeList"; import Logger from "@utils/Logger"; import { classes, LazyComponent, useAwaiter } from "@utils/misc"; import { openModalLazy } from "@utils/modal"; import { Plugin } from "@utils/types"; import { findByCode, findByPropsLazy } from "@webpack"; -import { Alerts, Button, Forms, Margins, Parser, React, Select, Switch, Text, TextInput, Toasts, Tooltip } from "@webpack/common"; +import { Alerts, Button, Card, Forms, Margins, Parser, React, Select, Text, TextInput, Toasts, Tooltip } from "@webpack/common"; import Plugins from "~plugins"; -const cl = classNameFactory("vc-plugins-"); - import { startDependenciesRecursive, startPlugin, stopPlugin } from "../../plugins"; + +const cl = classNameFactory("vc-plugins-"); const logger = new Logger("PluginSettings", "#a6d189"); const InputStyles = findByPropsLazy("inputDefault", "inputWrapper"); @@ -60,23 +60,27 @@ function showErrorToast(message: string) { }); } -interface ReloadRequiredCardProps extends React.HTMLProps { - plugins: string[]; -} - -function ReloadRequiredCard({ plugins, ...props }: ReloadRequiredCardProps) { - if (plugins.length === 0) return null; - - const pluginPrefix = plugins.length === 1 ? "The plugin" : "The following plugins require a reload to apply changes:"; - const pluginSuffix = plugins.length === 1 ? " requires a reload to apply changes." : "."; - +function ReloadRequiredCard({ required }: { required: boolean; }) { return ( - - - {pluginPrefix} {plugins.join(", ")}{pluginSuffix} - - - + + {required ? ( + <> + Restart required! + + Restart now to apply new plugins and their settings + + + + ) : ( + <> + Plugin Management + Press the cog wheel or info icon to get more info on a plugin + Plugins with a cog wheel have settings you can modify! + + )} + ); } @@ -147,26 +151,24 @@ function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLe } return ( - - {plugin.description}} - hideBorder={true} - > - - - {plugin.name}{isNew && } - - - - - + +
+ + {plugin.name}{isNew && } + + + +
+ {plugin.description} +
); } @@ -298,12 +300,12 @@ export default ErrorBoundary.wrap(function PluginSettings() { return ( + + Filters - -
diff --git a/src/components/PluginSettings/styles.css b/src/components/PluginSettings/styles.css index fe8dc940d..1626d7dba 100644 --- a/src/components/PluginSettings/styles.css +++ b/src/components/PluginSettings/styles.css @@ -29,18 +29,32 @@ border-radius: 8px; display: block; height: 100%; - padding: 10px; + padding: 12px; width: 100%; transition: 0.1s ease-out; transition-property: box-shadow, transform, background, opacity; } +.vc-plugins-card-disabled { + opacity: 0.6; +} + .vc-plugins-card:hover { background-color: var(--background-tertiary); transform: translateY(-1px); box-shadow: var(--elevation-high); } +.vc-plugins-card-header { + margin-top: auto; + display: flex; + width: 100%; + justify-content: flex-end; + height: 1.5rem; + align-items: center; + gap: 8px; +} + .vc-plugins-info-button { height: 24px; width: 24px; @@ -92,23 +106,30 @@ cursor: "default"; } -.vc-plugins-flex { - margin-top: auto; - width: 100%; - height: 100%; - align-items: center; - gap: 8px; -} - .vc-plugins-dep-name { margin: 0 auto; } -.vc-plugins-reload-card { +.vc-plugins-info-card { padding: 1em; - display: grid; - grid-template-columns: 1fr auto; - gap: 1em; + height: 8em; + display: flex; + flex-direction: column; +} + +.vc-plugins-info-card div { + line-height: 32px; +} + +.vc-plugins-restart-card { + padding: 1em; + background: var(--info-warning-background); + border: 1px solid var(--info-warning-foreground); + color: var(--info-warning-text); +} + +.vc-plugins-restart-card button { + margin-top: 0.5em; } .vc-plugins-info-button svg:not(:hover):not(:focus) { diff --git a/src/components/Switch.css b/src/components/Switch.css new file mode 100644 index 000000000..e6dcf5626 --- /dev/null +++ b/src/components/Switch.css @@ -0,0 +1,3 @@ +.vc-switch-slider { + transition: 100ms transform ease-in-out; +} diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx new file mode 100644 index 000000000..a18a7e492 --- /dev/null +++ b/src/components/Switch.tsx @@ -0,0 +1,76 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2023 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import "./Switch.css"; + +import { findByPropsLazy } from "@webpack"; + +interface SwitchProps { + checked: boolean; + onChange: (checked: boolean) => void; + disabled?: boolean; +} + +const SWITCH_ON = "var(--status-green-600)"; +const SWITCH_OFF = "var(--primary-dark-400)"; +const SwitchClasses = findByPropsLazy("slider", "input", "container"); + +export function Switch({ checked, onChange, disabled }: SwitchProps) { + return ( +
+
+ + onChange(e.currentTarget.checked)} + /> +
+
+ ); +} diff --git a/src/preload.ts b/src/preload.ts index 33f2410b9..3867f336c 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -49,9 +49,11 @@ if (location.protocol !== "data:") { const css = readFileSync(rendererCss, "utf-8"); insertCss(css); if (IS_DEV) { - watch(rendererCss, debounce(() => { + // persistent means keep process running if watcher is the only thing still running + // which we obviously don't want + watch(rendererCss, { persistent: false }, () => { document.getElementById("vencord-css-core")!.textContent = readFileSync(rendererCss, "utf-8"); - }, 30)); + }); } } catch (err) { if ((err as NodeJS.ErrnoException)?.code !== "ENOENT")