mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-12 08:03:06 -04:00
feat(settings): reset plugins & settings options(#57)
* start of channelbadges * update badges * give in and add colors to settings page, refactor * change from styles.css to style.css * update for linter * forgot to remove dm css no need for them * Fixes * update PluginModal.tsx and src/components/PluginSettings/index.tsx adds options to disable all plugins and a option to reset a plugins settings to the default state * Update warning image and image size in PluginModal and PluginSettings --------- Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com>
This commit is contained in:
parent
2cb70a7cb8
commit
70c15730b7
2 changed files with 226 additions and 14 deletions
|
@ -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 <Forms.FormText>There are no settings for this plugin.</Forms.FormText>;
|
||||
|
@ -279,6 +283,21 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
|
|||
</ModalContent>
|
||||
{hasSettings && <ModalFooter>
|
||||
<Flex flexDirection="column" style={{ width: "100%" }}>
|
||||
<Flex style={{ justifyContent: "space-between" }}>
|
||||
<Tooltip text="Reset to default settings" shouldShow={!isObjectEmpty(tempSettings)}>
|
||||
{({ onMouseEnter, onMouseLeave }) => (
|
||||
<Button
|
||||
size={Button.Sizes.SMALL}
|
||||
color={Button.Colors.BRAND}
|
||||
onClick={handleResetClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
style={{ backgroundColor: "var(--button-danger-background)" }}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
)}
|
||||
</Tooltip>
|
||||
<Flex style={{ marginLeft: "auto" }}>
|
||||
<Button
|
||||
onClick={onClose}
|
||||
|
@ -303,6 +322,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
|
|||
)}
|
||||
</Tooltip>
|
||||
</Flex>
|
||||
</Flex>
|
||||
{saveError && <Text variant="text-md/semibold" style={{ color: "var(--text-danger)" }}>Error while saving: {saveError}</Text>}
|
||||
</Flex>
|
||||
</ModalFooter>}
|
||||
|
@ -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<string, any> = {};
|
||||
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 => (
|
||||
<ModalRoot
|
||||
{...warningModalProps}
|
||||
size={ModalSize.SMALL}
|
||||
className="vc-text-selectable"
|
||||
transitionState={warningModalProps.transitionState}
|
||||
>
|
||||
<ModalHeader separator={false}>
|
||||
<Text style={{ flexGrow: 1, color: "var(--text-danger)", fontSize: "1.4rem", fontWeight: "bold" }}>Warning: Dangerous Action</Text>
|
||||
<ModalCloseButton onClick={warningModalProps.onClose} />
|
||||
</ModalHeader>
|
||||
<ModalContent>
|
||||
<Forms.FormSection>
|
||||
<Flex className="vc-warning-info" style={{ gap: "15px", flexDirection: "column", userSelect: "none" }}>
|
||||
<img
|
||||
src="https://media.tenor.com/Y6DXKZiBCs8AAAAi/stavario-josefbenes.gif"
|
||||
alt="Warning"
|
||||
style={{ width: "60%", height: "auto", marginBottom: "10px", display: "block", margin: "auto" }}
|
||||
/>
|
||||
<Text style={{ fontSize: "1.2rem", color: "var(--text-normal)" }}>
|
||||
You are about to reset all settings for <strong>{plugin.name}</strong> to their default values.
|
||||
</Text>
|
||||
<Text style={{ fontSize: "1.2rem", color: "var(--text-danger)", fontWeight: "bold" }}>
|
||||
This action is irreversible.
|
||||
</Text>
|
||||
<Text style={{ fontSize: "1.2rem", color: "var(--text-normal)", marginBottom: "10px" }}>
|
||||
If you are certain you want to proceed, click <strong>Confirm Reset</strong>. Otherwise, click <strong>Cancel</strong>.
|
||||
</Text>
|
||||
</Flex>
|
||||
</Forms.FormSection>
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<Flex flexDirection="column" style={{ width: "100%" }}>
|
||||
<Flex style={{ justifyContent: "space-between" }}>
|
||||
<Button
|
||||
size={Button.Sizes.SMALL}
|
||||
color={Button.Colors.PRIMARY}
|
||||
onClick={warningModalProps.onClose}
|
||||
look={Button.Looks.LINK}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Tooltip text="This action cannot be undone. Are you sure?" shouldShow={true}>
|
||||
{({ onMouseEnter, onMouseLeave }) => (
|
||||
<Button
|
||||
size={Button.Sizes.SMALL}
|
||||
color={Button.Colors.BRAND}
|
||||
onClick={() => {
|
||||
resetSettings(plugin, warningModalProps, pluginModalProps, onRestartNeeded);
|
||||
}}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
style={{ marginLeft: "10px", backgroundColor: "var(--button-danger-background)" }}
|
||||
>
|
||||
Confirm Reset
|
||||
</Button>
|
||||
)}
|
||||
</Tooltip>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</ModalFooter>
|
||||
</ModalRoot>
|
||||
));
|
||||
}
|
||||
|
|
|
@ -386,6 +386,76 @@ export default function PluginSettings() {
|
|||
</div>
|
||||
|
||||
<Forms.FormTitle className={Margins.top20}>Plugins</Forms.FormTitle>
|
||||
{enabledPlugins.length > 0 && (
|
||||
<Button
|
||||
size={Button.Sizes.SMALL}
|
||||
style={{ backgroundColor: "var(--button-danger-background)", margin: "20px 0" }}
|
||||
onClick={() => {
|
||||
return Alerts.show({
|
||||
title: "Disable All Plugins",
|
||||
body: (
|
||||
<>
|
||||
<img
|
||||
src="https://media.tenor.com/Y6DXKZiBCs8AAAAi/stavario-josefbenes.gif"
|
||||
alt="Warning"
|
||||
style={{ width: "60%", height: "auto", marginBottom: "10px", display: "block", margin: "auto" }}
|
||||
/>
|
||||
<p style={{ fontSize: "1.2rem", color: "var(--text-danger)", fontWeight: "bold" }}>
|
||||
WARNING: You are about to disable <span style={{ textDecoration: "underline" }}>{enabledPlugins.length}</span> plugins!
|
||||
</p>
|
||||
<p style={{ fontSize: "1rem" }}>
|
||||
Are you absolutely sure you want to proceed? You can always enable them back later.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
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: (
|
||||
<>
|
||||
<p>Some plugins require a restart to fully disable.</p>
|
||||
<p>Would you like to restart now?</p>
|
||||
</>
|
||||
),
|
||||
confirmText: "Restart Now",
|
||||
cancelText: "Later",
|
||||
onConfirm: () => location.reload()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
Disable All Plugins
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
||||
{plugins.length || requiredPlugins.length
|
||||
? (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue