mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-18 10:57:04 -04:00
Settings API: add support for custom objects / arrays (#3154)
This commit is contained in:
parent
317121fc08
commit
5c8ba6e542
13 changed files with 420 additions and 355 deletions
|
@ -22,7 +22,6 @@ import { Flex } from "@components/Flex";
|
|||
import { DeleteIcon } from "@components/Icons";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { useForceUpdater } from "@utils/react";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { Button, Forms, React, TextInput, useState } from "@webpack/common";
|
||||
|
||||
|
@ -34,8 +33,6 @@ type Rule = Record<"find" | "replace" | "onlyIfIncludes", string>;
|
|||
interface TextReplaceProps {
|
||||
title: string;
|
||||
rulesArray: Rule[];
|
||||
rulesKey: string;
|
||||
update: () => void;
|
||||
}
|
||||
|
||||
const makeEmptyRule: () => Rule = () => ({
|
||||
|
@ -45,34 +42,36 @@ const makeEmptyRule: () => Rule = () => ({
|
|||
});
|
||||
const makeEmptyRuleArray = () => [makeEmptyRule()];
|
||||
|
||||
let stringRules = makeEmptyRuleArray();
|
||||
let regexRules = makeEmptyRuleArray();
|
||||
|
||||
const settings = definePluginSettings({
|
||||
replace: {
|
||||
type: OptionType.COMPONENT,
|
||||
description: "",
|
||||
component: () => {
|
||||
const update = useForceUpdater();
|
||||
const { stringRules, regexRules } = settings.use(["stringRules", "regexRules"]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TextReplace
|
||||
title="Using String"
|
||||
rulesArray={stringRules}
|
||||
rulesKey={STRING_RULES_KEY}
|
||||
update={update}
|
||||
/>
|
||||
<TextReplace
|
||||
title="Using Regex"
|
||||
rulesArray={regexRules}
|
||||
rulesKey={REGEX_RULES_KEY}
|
||||
update={update}
|
||||
/>
|
||||
<TextReplaceTesting />
|
||||
</>
|
||||
);
|
||||
}
|
||||
},
|
||||
stringRules: {
|
||||
type: OptionType.CUSTOM,
|
||||
default: makeEmptyRuleArray(),
|
||||
},
|
||||
regexRules: {
|
||||
type: OptionType.CUSTOM,
|
||||
default: makeEmptyRuleArray(),
|
||||
}
|
||||
});
|
||||
|
||||
function stringToRegex(str: string) {
|
||||
|
@ -119,28 +118,24 @@ function Input({ initialValue, onChange, placeholder }: {
|
|||
);
|
||||
}
|
||||
|
||||
function TextReplace({ title, rulesArray, rulesKey, update }: TextReplaceProps) {
|
||||
function TextReplace({ title, rulesArray }: TextReplaceProps) {
|
||||
const isRegexRules = title === "Using Regex";
|
||||
|
||||
async function onClickRemove(index: number) {
|
||||
if (index === rulesArray.length - 1) return;
|
||||
rulesArray.splice(index, 1);
|
||||
|
||||
await DataStore.set(rulesKey, rulesArray);
|
||||
update();
|
||||
}
|
||||
|
||||
async function onChange(e: string, index: number, key: string) {
|
||||
if (index === rulesArray.length - 1)
|
||||
if (index === rulesArray.length - 1) {
|
||||
rulesArray.push(makeEmptyRule());
|
||||
}
|
||||
|
||||
rulesArray[index][key] = e;
|
||||
|
||||
if (rulesArray[index].find === "" && rulesArray[index].replace === "" && rulesArray[index].onlyIfIncludes === "" && index !== rulesArray.length - 1)
|
||||
if (rulesArray[index].find === "" && rulesArray[index].replace === "" && rulesArray[index].onlyIfIncludes === "" && index !== rulesArray.length - 1) {
|
||||
rulesArray.splice(index, 1);
|
||||
|
||||
await DataStore.set(rulesKey, rulesArray);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -207,29 +202,26 @@ function TextReplaceTesting() {
|
|||
}
|
||||
|
||||
function applyRules(content: string): string {
|
||||
if (content.length === 0)
|
||||
if (content.length === 0) {
|
||||
return content;
|
||||
|
||||
if (stringRules) {
|
||||
for (const rule of stringRules) {
|
||||
if (!rule.find) continue;
|
||||
if (rule.onlyIfIncludes && !content.includes(rule.onlyIfIncludes)) continue;
|
||||
|
||||
content = ` ${content} `.replaceAll(rule.find, rule.replace.replaceAll("\\n", "\n")).replace(/^\s|\s$/g, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (regexRules) {
|
||||
for (const rule of regexRules) {
|
||||
if (!rule.find) continue;
|
||||
if (rule.onlyIfIncludes && !content.includes(rule.onlyIfIncludes)) continue;
|
||||
for (const rule of settings.store.stringRules) {
|
||||
if (!rule.find) continue;
|
||||
if (rule.onlyIfIncludes && !content.includes(rule.onlyIfIncludes)) continue;
|
||||
|
||||
try {
|
||||
const regex = stringToRegex(rule.find);
|
||||
content = content.replace(regex, rule.replace.replaceAll("\\n", "\n"));
|
||||
} catch (e) {
|
||||
new Logger("TextReplace").error(`Invalid regex: ${rule.find}`);
|
||||
}
|
||||
content = ` ${content} `.replaceAll(rule.find, rule.replace.replaceAll("\\n", "\n")).replace(/^\s|\s$/g, "");
|
||||
}
|
||||
|
||||
for (const rule of settings.store.regexRules) {
|
||||
if (!rule.find) continue;
|
||||
if (rule.onlyIfIncludes && !content.includes(rule.onlyIfIncludes)) continue;
|
||||
|
||||
try {
|
||||
const regex = stringToRegex(rule.find);
|
||||
content = content.replace(regex, rule.replace.replaceAll("\\n", "\n"));
|
||||
} catch (e) {
|
||||
new Logger("TextReplace").error(`Invalid regex: ${rule.find}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,7 +245,17 @@ export default definePlugin({
|
|||
},
|
||||
|
||||
async start() {
|
||||
stringRules = await DataStore.get(STRING_RULES_KEY) ?? makeEmptyRuleArray();
|
||||
regexRules = await DataStore.get(REGEX_RULES_KEY) ?? makeEmptyRuleArray();
|
||||
// TODO: Remove DataStore rules migrations once enough time has passed
|
||||
const oldStringRules = await DataStore.get<Rule[]>(STRING_RULES_KEY);
|
||||
if (oldStringRules != null) {
|
||||
settings.store.stringRules = oldStringRules;
|
||||
await DataStore.del(STRING_RULES_KEY);
|
||||
}
|
||||
|
||||
const oldRegexRules = await DataStore.get<Rule[]>(REGEX_RULES_KEY);
|
||||
if (oldRegexRules != null) {
|
||||
settings.store.regexRules = oldRegexRules;
|
||||
await DataStore.del(REGEX_RULES_KEY);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue