diff --git a/src/plugins/contentWarning/index.tsx b/src/plugins/contentWarning/index.tsx new file mode 100644 index 000000000..359a00573 --- /dev/null +++ b/src/plugins/contentWarning/index.tsx @@ -0,0 +1,151 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated, camila314, and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import definePlugin, { OptionType } from "@utils/types"; +import { Button, Forms, useState, TextInput } from "@webpack/common"; +import { DataStore } from "@api/index"; +import { definePluginSettings } from "@api/Settings"; +import { DeleteIcon } from "@components/Icons"; +import { Devs } from "@utils/constants"; +import { Flex } from "@components/Flex"; +import { useForceUpdater } from "@utils/react"; + +const WORDS_KEY = "ContentWarning_words"; + +let triggerWords = [""]; + +function safeMatchesRegex(s: string, r: string) { + if (r == "") return false; + try { + return s.match(new RegExp(r.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))); + } catch { + return false; + } +} + +function TriggerContainer({ child }) { + const [visible, setVisible] = useState(false); + + if (visible) { + return child; + } else { + return (
setVisible(true)}> +
+ {child} +
+
); + } +} + +function FlaggedInput({ index, forceUpdate }) { + let [value, setValue] = useState(triggerWords[index]); + + if (value != triggerWords[index]) { + setValue(triggerWords[index]); + } + + let isLast = index == triggerWords.length - 1; + + const updateValue = (v) => { + triggerWords[index] = v; + setValue(v); + + if (isLast) { + triggerWords.push(""); + forceUpdate(); + } + }; + + const removeSelf = () => { + if (triggerWords.length == 1) { + return; + } + triggerWords = triggerWords.slice(0, index).concat(triggerWords.slice(index + 1)); + forceUpdate(); + }; + + return ( +
+ +
+ + +
); +} + +function FlaggedWords() { + const forceUpdate = useForceUpdater(); + + let inputs = triggerWords.map((_, idx) => { + return ( + + ); + }) + + return (<> + Flagged Words + {inputs} + ); +} + +const settings = definePluginSettings({ + flagged: { + type: OptionType.COMPONENT, + component: () => , + } +}); + +export default definePlugin({ + name: "ContentWarning", + authors: [Devs.camila314], + description: "Allows you to specify certain trigger words that will be blurred by default. Clicking on the blurred content will reveal it.", + settings, + patches: [ + { + find: ".VOICE_HANGOUT_INVITE?", + replacement: { + match: /(contentRef:\i}=(\i).+?)\(0,(.+]}\)]}\))/, + replace: "$1 $self.modify($2, (0, $3)" + } + } + ], + + beforeSave() { + DataStore.set(WORDS_KEY, triggerWords); + return true; + }, + + modify(e, c) { + if (triggerWords.some(w => safeMatchesRegex(e.message.content, w))) { + return + } else { + return c; + } + }, + + async start() { + triggerWords = await DataStore.get(WORDS_KEY) ?? [""]; + } +}); diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 6653e6307..1da18ed38 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -375,6 +375,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({ name: "ProffDea", id: 609329952180928513n }, + camila314: { + name: "camila314", + id: 738592270617542716n + }, UlyssesZhan: { name: "UlyssesZhan", id: 586808226058862623n