diff --git a/src/components/PluginSettings/PluginModal.tsx b/src/components/PluginSettings/PluginModal.tsx index 43558ef1..b96a5ea9 100644 --- a/src/components/PluginSettings/PluginModal.tsx +++ b/src/components/PluginSettings/PluginModal.tsx @@ -30,7 +30,7 @@ import { classes, isObjectEmpty } from "@utils/misc"; import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { OptionType, Plugin } from "@utils/types"; import { findByPropsLazy, findComponentByCodeLazy } from "@webpack"; -import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from "@webpack/common"; +import { Button, Clickable, FluxDispatcher, Forms, React, Text, Toasts, Tooltip, UserStore, UserUtils } from "@webpack/common"; import { User } from "discord-types/general"; import { Constructor } from "type-fest"; @@ -139,6 +139,10 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti onClose(); } + function handleResetClick() { + openWarningModal(plugin, { onClose, transitionState }, onRestartNeeded); + } + function renderSettings() { if (!hasSettings || !plugin.options) { return There are no settings for this plugin.; @@ -279,29 +283,45 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti {hasSettings && - - - Cancel - - + + {({ onMouseEnter, onMouseLeave }) => ( - Save & Close + Reset )} + + + Cancel + + + {({ onMouseEnter, onMouseLeave }) => ( + + Save & Close + + )} + + {saveError && Error while saving: {saveError}} @@ -319,3 +339,125 @@ export function openPluginModal(plugin: Plugin, onRestartNeeded?: (pluginName: s /> )); } + +function resetSettings(plugin: Plugin, warningModalProps?: ModalProps, pluginModalProps?: ModalProps, onRestartNeeded?: (pluginName: string) => void) { + const defaultSettings = plugin.settings?.def; + const pluginName = plugin.name; + + if (!defaultSettings) { + console.error(`No default settings found for ${pluginName}`); + return; + } + + const newSettings: Record = {}; + let restartNeeded = false; + + for (const key in defaultSettings) { + if (key === "enabled") continue; + + const setting = defaultSettings[key]; + setting.type = setting.type ?? OptionType.STRING; + + if (setting.type === OptionType.STRING) { + newSettings[key] = setting.default !== undefined && setting.default !== "" ? setting.default : ""; + } else if ("default" in setting && setting.default !== undefined) { + newSettings[key] = setting.default; + } + + if (setting?.restartNeeded) { + restartNeeded = true; + } + } + + + const currentSettings = plugin.settings?.store; + if (currentSettings) { + Object.assign(currentSettings, newSettings); + } + + if (plugin.afterSave) { + plugin.afterSave(); + } + + if (restartNeeded) { + onRestartNeeded?.(plugin.name); + } + + Toasts.show({ + message: `Settings for ${pluginName} have been reset.`, + id: Toasts.genId(), + type: Toasts.Type.SUCCESS, + options: { + position: Toasts.Position.TOP + } + }); + + warningModalProps?.onClose(); + pluginModalProps?.onClose(); +} + +export function openWarningModal(plugin: Plugin, pluginModalProps: ModalProps, onRestartNeeded?: (pluginName: string) => void) { + openModal(warningModalProps => ( + + + Warning: Dangerous Action + + + + + + + + You are about to reset all settings for {plugin.name} to their default values. + + + This action is irreversible. + + + If you are certain you want to proceed, click Confirm Reset. Otherwise, click Cancel. + + + + + + + + + Cancel + + + {({ onMouseEnter, onMouseLeave }) => ( + { + resetSettings(plugin, warningModalProps, pluginModalProps, onRestartNeeded); + }} + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave} + style={{ marginLeft: "10px", backgroundColor: "var(--button-danger-background)" }} + > + Confirm Reset + + )} + + + + + + )); +} diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx index eac7bcbc..4114e42b 100644 --- a/src/components/PluginSettings/index.tsx +++ b/src/components/PluginSettings/index.tsx @@ -386,6 +386,76 @@ export default function PluginSettings() { Plugins + {enabledPlugins.length > 0 && ( + { + return Alerts.show({ + title: "Disable All Plugins", + body: ( + <> + + + WARNING: You are about to disable {enabledPlugins.length} plugins! + + + Are you absolutely sure you want to proceed? You can always enable them back later. + + > + ), + confirmText: "Disable All", + cancelText: "Cancel", + onConfirm: () => { + let restartNeeded = false; + + for (const plugin of enabledPlugins) { + const pluginSettings = settings.plugins[plugin]; + + if (Plugins[plugin].patches?.length) { + pluginSettings.enabled = false; + changes.handleChange(plugin); + restartNeeded = true; + continue; + } + + const result = stopPlugin(Plugins[plugin]); + + if (!result) { + logger.error(`Error while stopping plugin ${plugin}`); + showErrorToast(`Error while stopping plugin ${plugin}`); + continue; + } + + pluginSettings.enabled = false; + } + + if (restartNeeded) { + Alerts.show({ + title: "Restart Required", + body: ( + <> + Some plugins require a restart to fully disable. + Would you like to restart now? + > + ), + confirmText: "Restart Now", + cancelText: "Later", + onConfirm: () => location.reload() + }); + } + } + }); + }} + > + Disable All Plugins + + )} + {plugins.length || requiredPlugins.length ? (
+ WARNING: You are about to disable {enabledPlugins.length} plugins! +
+ Are you absolutely sure you want to proceed? You can always enable them back later. +
Some plugins require a restart to fully disable.
Would you like to restart now?