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 { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import { OptionType, Plugin } from "@utils/types";
|
import { OptionType, Plugin } from "@utils/types";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
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 { User } from "discord-types/general";
|
||||||
import { Constructor } from "type-fest";
|
import { Constructor } from "type-fest";
|
||||||
|
|
||||||
|
@ -139,6 +139,10 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleResetClick() {
|
||||||
|
openWarningModal(plugin, { onClose, transitionState }, onRestartNeeded);
|
||||||
|
}
|
||||||
|
|
||||||
function renderSettings() {
|
function renderSettings() {
|
||||||
if (!hasSettings || !plugin.options) {
|
if (!hasSettings || !plugin.options) {
|
||||||
return <Forms.FormText>There are no settings for this plugin.</Forms.FormText>;
|
return <Forms.FormText>There are no settings for this plugin.</Forms.FormText>;
|
||||||
|
@ -279,29 +283,45 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
{hasSettings && <ModalFooter>
|
{hasSettings && <ModalFooter>
|
||||||
<Flex flexDirection="column" style={{ width: "100%" }}>
|
<Flex flexDirection="column" style={{ width: "100%" }}>
|
||||||
<Flex style={{ marginLeft: "auto" }}>
|
<Flex style={{ justifyContent: "space-between" }}>
|
||||||
<Button
|
<Tooltip text="Reset to default settings" shouldShow={!isObjectEmpty(tempSettings)}>
|
||||||
onClick={onClose}
|
|
||||||
size={Button.Sizes.SMALL}
|
|
||||||
color={Button.Colors.PRIMARY}
|
|
||||||
look={Button.Looks.LINK}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<Tooltip text="You must fix all errors before saving" shouldShow={!canSubmit()}>
|
|
||||||
{({ onMouseEnter, onMouseLeave }) => (
|
{({ onMouseEnter, onMouseLeave }) => (
|
||||||
<Button
|
<Button
|
||||||
size={Button.Sizes.SMALL}
|
size={Button.Sizes.SMALL}
|
||||||
color={Button.Colors.BRAND}
|
color={Button.Colors.BRAND}
|
||||||
onClick={saveAndClose}
|
onClick={handleResetClick}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
disabled={!canSubmit()}
|
style={{ backgroundColor: "var(--button-danger-background)" }}
|
||||||
>
|
>
|
||||||
Save & Close
|
Reset
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Flex style={{ marginLeft: "auto" }}>
|
||||||
|
<Button
|
||||||
|
onClick={onClose}
|
||||||
|
size={Button.Sizes.SMALL}
|
||||||
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.LINK}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Tooltip text="You must fix all errors before saving" shouldShow={!canSubmit()}>
|
||||||
|
{({ onMouseEnter, onMouseLeave }) => (
|
||||||
|
<Button
|
||||||
|
size={Button.Sizes.SMALL}
|
||||||
|
color={Button.Colors.BRAND}
|
||||||
|
onClick={saveAndClose}
|
||||||
|
onMouseEnter={onMouseEnter}
|
||||||
|
onMouseLeave={onMouseLeave}
|
||||||
|
disabled={!canSubmit()}
|
||||||
|
>
|
||||||
|
Save & Close
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
{saveError && <Text variant="text-md/semibold" style={{ color: "var(--text-danger)" }}>Error while saving: {saveError}</Text>}
|
{saveError && <Text variant="text-md/semibold" style={{ color: "var(--text-danger)" }}>Error while saving: {saveError}</Text>}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -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>
|
</div>
|
||||||
|
|
||||||
<Forms.FormTitle className={Margins.top20}>Plugins</Forms.FormTitle>
|
<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
|
{plugins.length || requiredPlugins.length
|
||||||
? (
|
? (
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue