diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx index c3b6e9082..1a895d3de 100644 --- a/src/components/PluginSettings/index.tsx +++ b/src/components/PluginSettings/index.tsx @@ -19,7 +19,6 @@ import "./styles.css"; import * as DataStore from "@api/DataStore"; -import { showNotice } from "@api/Notices"; import { Settings, useSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; import { CogWheel, InfoIcon } from "@components/Icons"; @@ -27,38 +26,24 @@ import { openPluginModal } from "@components/PluginSettings/PluginModal"; import { AddonCard } from "@components/VencordSettings/AddonCard"; import { SettingsTab } from "@components/VencordSettings/shared"; import { ChangeList } from "@utils/ChangeList"; -import { proxyLazy } from "@utils/lazy"; -import { Logger } from "@utils/Logger"; import { Margins } from "@utils/margins"; import { classes, isObjectEmpty } from "@utils/misc"; import { useAwaiter } from "@utils/react"; import { Plugin } from "@utils/types"; import { findByPropsLazy } from "@webpack"; -import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip, useMemo } from "@webpack/common"; +import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Tooltip, useMemo } from "@webpack/common"; import Plugins, { ExcludedPlugins } from "~plugins"; -// Avoid circular dependency -const { startDependenciesRecursive, startPlugin, stopPlugin } = proxyLazy(() => require("../../plugins")); +import { ExcludedReasons, togglePluginEnabled } from "./utils"; + const cl = classNameFactory("vc-plugins-"); -const logger = new Logger("PluginSettings", "#a6d189"); const InputStyles = findByPropsLazy("inputWrapper", "inputDefault", "error"); const ButtonClasses = findByPropsLazy("button", "disabled", "enabled"); -function showErrorToast(message: string) { - Toasts.show({ - message, - type: Toasts.Type.FAILURE, - id: Toasts.genId(), - options: { - position: Toasts.Position.BOTTOM - } - }); -} - function ReloadRequiredCard({ required }: { required: boolean; }) { return ( @@ -91,54 +76,9 @@ interface PluginCardProps extends React.HTMLProps { } export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLeave, isNew }: PluginCardProps) { - const settings = Settings.plugins[plugin.name]; + const isEnabled = () => Settings.plugins[plugin.name].enabled ?? false; - const isEnabled = () => settings.enabled ?? false; - - function toggleEnabled() { - const wasEnabled = isEnabled(); - - // If we're enabling a plugin, make sure all deps are enabled recursively. - if (!wasEnabled) { - const { restartNeeded, failures } = startDependenciesRecursive(plugin); - if (failures.length) { - logger.error(`Failed to start dependencies for ${plugin.name}: ${failures.join(", ")}`); - showNotice("Failed to start dependencies: " + failures.join(", "), "Close", () => null); - return; - } else if (restartNeeded) { - // If any dependencies have patches, don't start the plugin yet. - settings.enabled = true; - onRestartNeeded(plugin.name); - return; - } - } - - // if the plugin has patches, dont use stopPlugin/startPlugin. Wait for restart to apply changes. - if (plugin.patches?.length) { - settings.enabled = !wasEnabled; - onRestartNeeded(plugin.name); - return; - } - - // If the plugin is enabled, but hasn't been started, then we can just toggle it off. - if (wasEnabled && !plugin.started) { - settings.enabled = !wasEnabled; - return; - } - - const result = wasEnabled ? stopPlugin(plugin) : startPlugin(plugin); - - if (!result) { - settings.enabled = false; - - const msg = `Error while ${wasEnabled ? "stopping" : "starting"} plugin ${plugin.name}`; - logger.error(msg); - showErrorToast(msg); - return; - } - - settings.enabled = !wasEnabled; - } + const togglePlugin = () => togglePluginEnabled(isEnabled(), plugin, onRestartNeeded); return ( name.toLowerCase().includes(search)); - const ExcludedReasons: Record<"web" | "discordDesktop" | "vencordDesktop" | "desktop" | "dev", string> = { - desktop: "Discord Desktop app or Vesktop", - discordDesktop: "Discord Desktop app", - vencordDesktop: "Vesktop app", - web: "Vesktop app and the Web version of Discord", - dev: "Developer version of Vencord" - }; - return ( {matchingExcludedPlugins.length diff --git a/src/components/PluginSettings/utils.ts b/src/components/PluginSettings/utils.ts new file mode 100644 index 000000000..b53765385 --- /dev/null +++ b/src/components/PluginSettings/utils.ts @@ -0,0 +1,83 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { showNotice } from "@api/Notices"; +import { Settings } from "@api/Settings"; +import { proxyLazy } from "@utils/lazy"; +import { Logger } from "@utils/Logger"; +import { Plugin } from "@utils/types"; +import { Toasts } from "@webpack/common"; + +// Avoid circular dependency +const { startDependenciesRecursive, startPlugin, stopPlugin } = proxyLazy(() => require("../../plugins")); + + +const logger = new Logger("PluginSettings", "#a6d189"); + +function showErrorToast(message: string) { + Toasts.show({ + message, + type: Toasts.Type.FAILURE, + id: Toasts.genId(), + options: { + position: Toasts.Position.BOTTOM + } + }); +} + +export function togglePluginEnabled(isEnabled: boolean, plugin: Plugin,onRestartNeeded: (pluginName: string) => void) { + const settings = Settings.plugins[plugin.name]; + const wasEnabled = isEnabled; + + // If we're enabling a plugin, make sure all deps are enabled recursively. + if (!wasEnabled) { + const { restartNeeded, failures } = startDependenciesRecursive(plugin); + if (failures.length) { + logger.error(`Failed to start dependencies for ${plugin.name}: ${failures.join(", ")}`); + showNotice("Failed to start dependencies: " + failures.join(", "), "Close", () => null); + return; + } else if (restartNeeded) { + // If any dependencies have patches, don't start the plugin yet. + settings.enabled = true; + onRestartNeeded(plugin.name); + return; + } + } + + // if the plugin has patches, dont use stopPlugin/startPlugin. Wait for restart to apply changes. + if (plugin.patches?.length) { + settings.enabled = !wasEnabled; + onRestartNeeded(plugin.name); + return; + } + + // If the plugin is enabled, but hasn't been started, then we can just toggle it off. + if (wasEnabled && !plugin.started) { + settings.enabled = !wasEnabled; + return; + } + + const result = wasEnabled ? stopPlugin(plugin) : startPlugin(plugin); + + if (!result) { + settings.enabled = false; + + const msg = `Error while ${wasEnabled ? "stopping" : "starting"} plugin ${plugin.name}`; + logger.error(msg); + showErrorToast(msg); + return; + } + + settings.enabled = !wasEnabled; +} + +export const ExcludedReasons: Record<"web" | "discordDesktop" | "vencordDesktop" | "desktop" | "dev", string> = { + desktop: "Discord Desktop app or Vesktop", + discordDesktop: "Discord Desktop app", + vencordDesktop: "Vesktop app", + web: "Vesktop app and the Web version of Discord", + dev: "Developer version of Vencord" +}; diff --git a/src/plugins/_core/supportHelper.tsx b/src/plugins/_core/supportHelper.tsx index 432896fc7..6b657a7c0 100644 --- a/src/plugins/_core/supportHelper.tsx +++ b/src/plugins/_core/supportHelper.tsx @@ -22,12 +22,14 @@ import { getUserSettingLazy } from "@api/UserSettings"; import ErrorBoundary from "@components/ErrorBoundary"; import { Flex } from "@components/Flex"; import { Link } from "@components/Link"; +import { openPluginModal } from "@components/PluginSettings/PluginModal"; +import { ExcludedReasons, togglePluginEnabled } from "@components/PluginSettings/utils"; import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab"; import { Devs, SUPPORT_CHANNEL_ID } from "@utils/constants"; import { sendMessage } from "@utils/discord"; import { Logger } from "@utils/Logger"; import { Margins } from "@utils/margins"; -import { isPluginDev, tryOrElse } from "@utils/misc"; +import { isObjectEmpty, isPluginDev, tryOrElse } from "@utils/misc"; import { relaunch } from "@utils/native"; import { onlyOnce } from "@utils/onlyOnce"; import { makeCodeblock } from "@utils/text"; @@ -36,7 +38,7 @@ import { checkForUpdates, isOutdated, update } from "@utils/updater"; import { Alerts, Button, Card, ChannelStore, Forms, GuildMemberStore, Parser, RelationshipStore, showToast, Text, Toasts, UserStore } from "@webpack/common"; import gitHash from "~git-hash"; -import plugins, { PluginMeta } from "~plugins"; +import plugins, { ExcludedPlugins, PluginMeta } from "~plugins"; import SettingsPlugin from "./settings"; @@ -321,6 +323,55 @@ export default definePlugin({ ); } + if (props.message.embeds[0]?.url?.includes("/plugins/")) { + const pluginName = props.message.embeds[0].rawTitle; + const excludedPlugin = ExcludedPlugins[pluginName]; + if (excludedPlugin) { + buttons.push( + + ); + // button really wide, good ideas? + } else { + const isEnabled = Vencord.Plugins.isPluginEnabled(pluginName); + const toggle = isEnabled ? "Disable" : "Enable"; + const plugin = plugins[pluginName]; + const onRestartNeeded = () => showToast("Restart to apply changes!"); + const togglePlugin = () => togglePluginEnabled(isEnabled, plugin, onRestartNeeded); + if (plugin.required) { + buttons.push( + + ); + } else { + buttons.push( + + ); + } + if (plugin.options && !isObjectEmpty(plugin.options)) { + buttons.push( + + ); + } + } + } } }