From cdeccda3df8ce0751bdb4da565384534c814b71b Mon Sep 17 00:00:00 2001 From: Rayanzay Date: Tue, 3 Jun 2025 18:03:42 +1000 Subject: [PATCH] Remove deprecated plugins: UnitConverter, UwUifier, WhitelistedEmojis, WigglyText, and WriteUpperCase --- src/equicordplugins/moyai/index.ts | 17 +- .../unitConverter/ConverterAccessory.tsx | 66 -- .../unitConverter/converter.ts | 166 ----- src/equicordplugins/unitConverter/index.tsx | 77 --- src/equicordplugins/unitConverter/style.css | 24 - src/equicordplugins/uwuifier/index.ts | 206 ------ .../whitelistedEmojis/index.tsx | 636 ------------------ .../whitelistedEmojis/style.css | 105 --- src/equicordplugins/wigglyText/index.tsx | 200 ------ .../ui/components/ExampleWiggle.tsx | 20 - src/equicordplugins/writeUpperCase/index.ts | 47 -- 11 files changed, 12 insertions(+), 1552 deletions(-) delete mode 100644 src/equicordplugins/unitConverter/ConverterAccessory.tsx delete mode 100644 src/equicordplugins/unitConverter/converter.ts delete mode 100644 src/equicordplugins/unitConverter/index.tsx delete mode 100644 src/equicordplugins/unitConverter/style.css delete mode 100644 src/equicordplugins/uwuifier/index.ts delete mode 100644 src/equicordplugins/whitelistedEmojis/index.tsx delete mode 100644 src/equicordplugins/whitelistedEmojis/style.css delete mode 100644 src/equicordplugins/wigglyText/index.tsx delete mode 100644 src/equicordplugins/wigglyText/ui/components/ExampleWiggle.tsx delete mode 100644 src/equicordplugins/writeUpperCase/index.ts diff --git a/src/equicordplugins/moyai/index.ts b/src/equicordplugins/moyai/index.ts index a0f76b01..f6c558bb 100644 --- a/src/equicordplugins/moyai/index.ts +++ b/src/equicordplugins/moyai/index.ts @@ -54,6 +54,8 @@ interface IVoiceChannelEffectSendEvent { const MOYAI = "🗿"; const MOYAI_URL = "https://github.com/Equicord/Equibored/raw/main/sounds/moyai/moyai.mp3"; const MOYAI_URL_HD = "https://github.com/Equicord/Equibored/raw/main/sounds/moyai/moyai.wav"; +const MOYAI_URL_ULTRA = "https://pub-e77fd37d275f481896833bda931f1d70.r2.dev/moyai.WAV"; +const MOYAI_URL_ULTRA_HD = "https://pub-e77fd37d275f481896833bda931f1d70.r2.dev/moyai.WAV"; const settings = definePluginSettings({ volume: { @@ -76,6 +78,11 @@ const settings = definePluginSettings({ type: OptionType.BOOLEAN, default: true }, + ultraMode: { + description: "ryncord's special 🗿 feature!!", + type: OptionType.BOOLEAN, + default: true + }, ignoreBots: { description: "Ignore bots", type: OptionType.BOOLEAN, @@ -90,8 +97,8 @@ const settings = definePluginSettings({ export default definePlugin({ name: "Moyai", - authors: [Devs.Megu, Devs.Nuckyz], - description: "🗿🗿🗿🗿🗿🗿🗿🗿", + authors: [Devs.Megu, Devs.Nuckyz, Devs.rayanzay], + description: "🗿 but with something else inside the settings...", settings, flux: { @@ -166,9 +173,9 @@ function boom() { if (!settings.store.triggerWhenUnfocused && !document.hasFocus()) return; const audioElement = document.createElement("audio"); - audioElement.src = settings.store.quality === "HD" - ? MOYAI_URL_HD - : MOYAI_URL; + audioElement.src = settings.store.ultraMode + ? (settings.store.quality === "HD" ? MOYAI_URL_ULTRA_HD : MOYAI_URL_ULTRA) + : (settings.store.quality === "HD" ? MOYAI_URL_HD : MOYAI_URL); audioElement.volume = settings.store.volume; audioElement.play(); diff --git a/src/equicordplugins/unitConverter/ConverterAccessory.tsx b/src/equicordplugins/unitConverter/ConverterAccessory.tsx deleted file mode 100644 index 940c89d1..00000000 --- a/src/equicordplugins/unitConverter/ConverterAccessory.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2023 Vendicated and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -import { classNameFactory } from "@api/Styles"; -import { useState } from "@webpack/common"; -import { Message } from "discord-types/general"; - -export const conversions = new Map void>(); -const cl = classNameFactory("vc-converter-"); -function Dismiss({ onDismiss }: { onDismiss: () => void; }) { - return ( - - ); -} -// thanks <@408047304864432139> -export function ConvertIcon({ height = 24, width = 24, className }: { - height?: number, - width?: number, - className?: string; -}) { - return ( - - - - ); -} -export function ConverterAccessory({ message }: { message: Message; }) { - const [conversion, setConversion] = useState(""); - conversions.set(message.id, setConversion); - if (!conversion) return null; - return ( - - - {conversion} - {" - "} - setConversion("")} /> - - ); -} diff --git a/src/equicordplugins/unitConverter/converter.ts b/src/equicordplugins/unitConverter/converter.ts deleted file mode 100644 index 70e5f4e5..00000000 --- a/src/equicordplugins/unitConverter/converter.ts +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { settings } from "."; - -interface regexes { - imperial: { - [key: string]: { - regex: RegExp, - convert: (...groups: string[]) => string; - }; - }; - metric: { - [key: string]: { - regex: RegExp, - convert: (...groups: string[]) => string; - }; - }; -} -// TODO: add grams, kilograms, ounces, and pounds -const regexes: regexes = { - // matches imperial units, converts them to metric - imperial: { - farenheight: { - regex: /(-?\d+(?:\.\d+)?)°?(f)(?!\w)/ig, - convert(...groups) { - const c = ((parseFloat(groups[1]) - 32) * (5 / 9)).toFixed(2); - return `${c}°C`; - }, - }, - feetInchesMark: { - regex: /(\d+)(') ?(\d+(?:\.\d+)?)("|'')?/g, - convert(...groups) { - let ftin = parseFloat(groups[1]) / 3.281; - ftin += parseFloat(groups[3]) / 39.37; - return `${ftin.toFixed(2)}m`; - }, - }, - feetWord: { - regex: /(\d+(?:\.\d+)?) *(f(ee)?t)(?! *\d)/ig, - convert(...groups) { - const ft = (parseFloat(groups[1]) / 3.281).toFixed(2); - return `${ft}m`; - }, - }, - inchesWord: { - regex: /(?. -*/ - -import "./style.css"; - -import { addMessageAccessory } from "@api/MessageAccessories"; -import { addMessagePopoverButton } from "@api/MessagePopover"; -import { definePluginSettings } from "@api/Settings"; -import { Devs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; -import { ChannelStore } from "@webpack/common"; - -import { convert } from "./converter"; -import { conversions, ConverterAccessory, ConvertIcon } from "./ConverterAccessory"; - - -export const settings = definePluginSettings({ - myUnits: { - type: OptionType.SELECT, - description: "the units you use and want things converted to. defaults to imperial", - options: [ - { - default: true, - label: "Imperial", - value: "imperial", - }, - { - label: "Metric", - value: "metric" - } - ] - }, - // invert: { - // type: OptionType.BOOLEAN, - // default: false, - // // is there a better way to word this? - // description: "If this option is set, ignore the units you set and invert every conversion." - // } -}); -export default definePlugin({ - name: "UnitConverter", - description: "Converts metric units to Imperal units and vice versa", - authors: [Devs.sadan], - start() { - addMessageAccessory("vc-converter", props => ); - addMessagePopoverButton("vc-converter", message => { - if (!message.content) return null; - return { - label: "Convert Units", - icon: ConvertIcon, - message, - channel: ChannelStore.getChannel(message.channel_id), - onClick: async () => { - const setConversion = conversions.get(message.id); - if (!setConversion) return; - setConversion(convert(message.content)); - } - }; - }); - }, - settings, -}); diff --git a/src/equicordplugins/unitConverter/style.css b/src/equicordplugins/unitConverter/style.css deleted file mode 100644 index 1815b2c2..00000000 --- a/src/equicordplugins/unitConverter/style.css +++ /dev/null @@ -1,24 +0,0 @@ -.vc-converter-dismiss { - all: unset; - cursor: pointer; - color: var(--text-link); -} - -.vc-converter-dismiss:is(:hover, :focus) { - text-decoration: underline; -} - -.vc-converter-accessory { - color: var(--text-muted); - margin-top: 0.5em; - font-style: italic; - font-weight: 400; -} - -.vc-converter-accessory svg { - margin-right: 0.25em; -} - -.vc-converter-chat-button { - scale: 1.085; -} diff --git a/src/equicordplugins/uwuifier/index.ts b/src/equicordplugins/uwuifier/index.ts deleted file mode 100644 index 99631fde..00000000 --- a/src/equicordplugins/uwuifier/index.ts +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 exhq - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -import { findOption, RequiredMessageOption } from "@api/Commands"; -import { addMessagePreEditListener, addMessagePreSendListener, MessageObject, removeMessagePreEditListener, removeMessagePreSendListener } from "@api/MessageEvents"; -import { definePluginSettings } from "@api/Settings"; -import { Devs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; - -const endings = [ - "rawr x3", - "OwO", - "UwU", - "o.O", - "-.-", - ">w<", - "(⑅˘꒳˘)", - "(ꈍᴗꈍ)", - "(˘ω˘)", - "(U ᵕ U❁)", - "σωσ", - "òωó", - "(///ˬ///✿)", - "(U ﹏ U)", - "( ͡o ω ͡o )", - "ʘwʘ", - ":3", - ":3", // important enough to have twice - ":3", // important enough to have thrice - "XD", - "nyaa~~", - "mya", - ">_<", - "😳", - "🥺", - "😳😳😳", - "rawr", - "^^", - "^^;;", - "(ˆ ﻌ ˆ)♡", - "^•ﻌ•^", - "/(^•ω•^)", - "(✿oωo)" -]; - -const replacements = [ - ["small", "smol"], - ["cute", "kawaii"], - ["fluff", "floof"], - ["love", "luv"], - ["stupid", "baka"], - ["what", "nani"], - ["meow", "nya"], - ["hello", "hewwo"], -]; - -const settings = definePluginSettings({ - uwuEveryMessage: { - description: "Make every single message uwuified", - type: OptionType.BOOLEAN, - default: false, - restartNeeded: false - }, - uwuEverything: { - description: "Makes *all* text uwuified - really bad idea", - type: OptionType.BOOLEAN, - default: false, - restartNeeded: true - } -}); - -function selectRandomElement(arr) { - // generate a random index based on the length of the array - const randomIndex = Math.floor(Math.random() * arr.length); - - // return the element at the randomly generated index - return arr[randomIndex]; -} -const isOneCharacterString = (str: string): boolean => { - return str.split("").every((char: string) => char === str[0]); -}; - -function replaceString(inputString) { - let replaced = false; - for (const replacement of replacements) { - const regex = new RegExp(`\\b${replacement[0]}\\b`, "gi"); - if (regex.test(inputString)) { - inputString = inputString.replace(regex, replacement[1]); - replaced = true; - } - } - return replaced ? inputString : false; -} - -function uwuify(message: string): string { - const rule = /\S+|\s+/g; - const words: string[] | null = message.match(rule); - let answer = ""; - - if (words === null) return ""; - - for (let i = 0; i < words.length; i++) { - if (isOneCharacterString(words[i]) || words[i].startsWith("https://")) { - answer += words[i]; - continue; - } - - if (!replaceString(words[i])) { - answer += words[i] - .replace(/n(?=[aeo])/g, "ny") - .replace(/l|r/g, "w"); - } else answer += replaceString(words[i]); - - } - - answer += " " + selectRandomElement(endings); - return answer; -} - -function uwuifyArray(arr) { - const newArr = [...arr]; - - newArr.forEach((item, index) => { - if (Array.isArray(item)) { - newArr[index] = uwuifyArray(item); - } else if (typeof item === "string") { - newArr[index] = uwuify(item); - } - }); - - return newArr; -} - - -// actual command declaration -export default definePlugin({ - name: "UwUifier", - description: "Make everything uwu", - authors: [Devs.echo], - dependencies: ["MessageEventsAPI"], - settings, - - commands: [ - { - name: "uwuify", - description: "uwuifies your messages", - options: [RequiredMessageOption], - - execute: opts => ({ - content: uwuify(findOption(opts, "message", "")), - }), - }, - ], - - patches: [ - { - find: ".isPureReactComponent=!0;", - predicate: () => settings.store.uwuEverything, - replacement: { - match: /(?<=.defaultProps\)void 0.{0,60})(\i)\)/, - replace: "$self.uwuifyProps($1))" - } - } - ], - - uwuifyProps(props: any) { - if (!props.children) return props; - if (typeof props.children === "string") props.children = uwuify(props.children); - else if (Array.isArray(props.children)) props.children = uwuifyArray(props.children); - return props; - }, - - onSend(msg: MessageObject) { - // Only run when it's enabled - if (settings.store.uwuEveryMessage) { - msg.content = uwuify(msg.content); - } - }, - - start() { - this.preSend = addMessagePreSendListener((_, msg) => this.onSend(msg)); - this.preEdit = addMessagePreEditListener((_cid, _mid, msg) => - this.onSend(msg) - ); - }, - - stop() { - removeMessagePreSendListener(this.preSend); - removeMessagePreEditListener(this.preEdit); - }, -}); diff --git a/src/equicordplugins/whitelistedEmojis/index.tsx b/src/equicordplugins/whitelistedEmojis/index.tsx deleted file mode 100644 index 4c0677cf..00000000 --- a/src/equicordplugins/whitelistedEmojis/index.tsx +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import "./style.css"; - -import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu"; -import { DataStore } from "@api/index"; -import { definePluginSettings, migratePluginSettings } from "@api/Settings"; -import { EquicordDevs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; -import { Alerts, Button, EmojiStore, GuildStore, Menu, Toasts, useEffect, useState } from "@webpack/common"; -import { CustomEmoji, UnicodeEmoji } from "@webpack/types"; -import { JSX } from "react"; - -interface ContextMenuEmoji { - type: string; - id: string; - name: string; - surrogates?: string; -} - -interface Target { - dataset: ContextMenuEmoji; - firstChild: HTMLImageElement; -} - -interface customSaveEmoji { - type: string; - id: string; - guildId?: string; - name: string; - surrogates?: string; - url?: string; - animated?: boolean; -} - -const DATA_COLLECTION_NAME = "whitelisted-emojis"; - -let cache_allowedList: ContextMenuEmoji[] = []; -const getAllowedList = async (): Promise => (await DataStore.get(DATA_COLLECTION_NAME)) ?? []; - -function isItemAllowed(item: (CustomEmoji | UnicodeEmoji)) { - if ("uniqueName" in item) { - return cache_allowedList.some(emoji => emoji.name === item.uniqueName); - } - return cache_allowedList.some(emoji => emoji.name === item.name); -} - - -function itemAlreadyInList(item: ContextMenuEmoji) { - return cache_allowedList.some(emoji => emoji.name === item.name); -} - -async function addBulkToAllowedList(items: ContextMenuEmoji[]) { - const itemsToAdd = await Promise.all(items.map(async item => { - if (!itemAlreadyInList(item)) { - let emojiData: CustomEmoji | null = null; - - if (!item.surrogates) { - emojiData = EmojiStore.getCustomEmojiById(item.id); - } - - const saveData: customSaveEmoji = { - type: "emoji", - id: item.id, - name: item.name, - surrogates: item.surrogates, - }; - - if (emojiData && emojiData.guildId) { - saveData.url = `https://cdn.discordapp.com/emojis/${emojiData.id}.${emojiData.animated ? "gif" : "png"}`; - saveData.guildId = emojiData.guildId; - saveData.animated = emojiData.animated; - } - - return saveData; - } - return null; - })); - - const validItemsToAdd = itemsToAdd.filter(item => item !== null); - await DataStore.set(DATA_COLLECTION_NAME, [...cache_allowedList, ...validItemsToAdd]); - - if (!settings.store.disableToasts) { - Toasts.show({ - message: `Added ${validItemsToAdd.length} emojis to the list, ${items.length - validItemsToAdd.length} already in the list`, - type: Toasts.Type.SUCCESS, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - - cache_allowedList = await getAllowedList(); -} - -async function removeBulkFromAllowedList(items: ContextMenuEmoji[]) { - const itemsToRemove = items.filter(item => itemAlreadyInList(item)); - await DataStore.set(DATA_COLLECTION_NAME, cache_allowedList.filter(emoji => { - return !itemsToRemove.some(item => item.name === emoji.name); - })); - - if (!settings.store.disableToasts) { - Toasts.show({ - message: `Removed ${itemsToRemove.length} emojis from the list`, - type: Toasts.Type.SUCCESS, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - - cache_allowedList = await getAllowedList(); -} - -async function addToAllowedList(item: ContextMenuEmoji) { - if (!itemAlreadyInList(item)) { - let emojiData: CustomEmoji | null = null; - - if (!item.surrogates) { - emojiData = EmojiStore.getCustomEmojiById(item.id); - } - - const saveData: customSaveEmoji = { - type: "emoji", - id: item.id, - name: item.name, - surrogates: item.surrogates, - }; - - if (emojiData && emojiData.guildId) { - saveData.url = `https://cdn.discordapp.com/emojis/${emojiData.id}.${emojiData.animated ? "gif" : "png"}`; - saveData.guildId = emojiData.guildId; - saveData.animated = emojiData.animated; - } - - await DataStore.set(DATA_COLLECTION_NAME, [...cache_allowedList, { ...saveData }]); - - if (!settings.store.disableToasts) { - Toasts.show({ - message: `Added "${item.name}" to the list`, - type: Toasts.Type.SUCCESS, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - } else { - if (!settings.store.disableToasts) { - Toasts.show({ - message: `"${item.name}" is already in the list`, - type: Toasts.Type.FAILURE, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - } - - cache_allowedList = await getAllowedList(); -} - -async function removeFromAllowedList(item: ContextMenuEmoji) { - if (itemAlreadyInList(item)) { - await DataStore.set(DATA_COLLECTION_NAME, cache_allowedList.filter(emoji => { - return emoji.name !== item.name; - })); - - if (!settings.store.disableToasts) { - Toasts.show({ - message: `Removed "${item.name}" from the list`, - type: Toasts.Type.SUCCESS, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - } else { - if (!settings.store.disableToasts) { - Toasts.show({ - message: `"${item.name}" is not in the list`, - type: Toasts.Type.FAILURE, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - } - - cache_allowedList = await getAllowedList(); -} - -const expressionPickerPatch: NavContextMenuPatchCallback = (children, { target }: { target: Target; }) => { - const { dataset } = target; - - if (!dataset) return; - if (dataset.type !== "emoji") return; - - const emoji = dataset as ContextMenuEmoji; - - if ("name" in emoji) { - children.push(buildMenuItems(emoji)); - } -}; - -const guildContextPatch: NavContextMenuPatchCallback = (children, { guild }: { guild: { id: string; name: string; }; }) => { - children.push(buildGuildContextPatch(guild)); -}; - -const buildGuildContextPatch = (guild: { id: string; name: string; }) => { - return ( - - { - const { id, name } = guild; - const emojis = EmojiStore.getGuildEmoji(id); - addBulkToAllowedList(emojis.map(emoji => ({ - type: "emoji", - id: emoji.id, - name: emoji.name - }))); - }} - /> - { - const { id, name } = guild; - const emojis = EmojiStore.getGuildEmoji(id); - removeBulkFromAllowedList(emojis.map(emoji => ({ - type: "emoji", - id: emoji.id, - name: emoji.name - }))); - }} - /> - - ); -}; - -function buildMenuItems(emoji: ContextMenuEmoji) { - const typeString = itemAlreadyInList(emoji) ? "Remove" : "Add"; - return ( - <> - - { - if (typeString === "Add") { - addToAllowedList(emoji); - } else { - removeFromAllowedList(emoji); - } - }} - /> - - ); -} - -const WhiteListedEmojisComponent = (): JSX.Element => { - const [whitelistedEmojis, setWhitelistedEmojis] = useState([]); - const [collapsedGroups, setCollapsedGroups] = useState>({}); - - useEffect(() => { - const fetchAllowedList = async () => { - const allowedList = await getAllowedList() as customSaveEmoji[]; - setWhitelistedEmojis(allowedList); - }; - fetchAllowedList(); - }, []); - - const handleRemoveEmoji = async (emoji: customSaveEmoji) => { - await removeFromAllowedList(emoji); - setWhitelistedEmojis(await getAllowedList() as customSaveEmoji[]); - }; - - const handleRemoveAllEmojis = async (guildId: string) => { - const emojisToRemove = whitelistedEmojis.filter(emoji => emoji.guildId === guildId || (guildId === "default" && !emoji.guildId)); - for (const emoji of emojisToRemove) { - await removeFromAllowedList(emoji); - } - setWhitelistedEmojis(await getAllowedList() as customSaveEmoji[]); - }; - - const toggleGroupCollapse = (guildId: string) => { - setCollapsedGroups(prev => ({ - ...prev, - [guildId]: !prev[guildId] - })); - }; - - const groupedEmojis = whitelistedEmojis.reduce((groups, emoji) => { - const groupKey = emoji.guildId || "default"; - if (!groups[groupKey]) { - groups[groupKey] = []; - } - groups[groupKey].push(emoji); - return groups; - }, {} as Record); - - return ( -
- {Object.entries(groupedEmojis).map(([guildId, emojis]) => ( -
-
-

toggleGroupCollapse(guildId)}> - {guildId === "default" ? "Default Emojis" : `${GuildStore.getGuild(guildId)?.name || `Guild ${guildId}`} Emojis`} -

- -
- {!collapsedGroups[guildId] && ( -
- {emojis.map(emoji => ( -
- {emoji.name} - {emoji.surrogates ? ( - {emoji.surrogates} - ) : ( - {emoji.name} - )} - -
- ))} -
- )} -
- ))} - {whitelistedEmojis.length === 0 && ( - No emojis in the whitelist. - )} -
- ); -}; - -const exportEmojis = async () => { - const fileName = "whitelisted-emojis.json"; - const exportData = await exportEmojisToJson(); - const data = new TextEncoder().encode(exportData); - - if (IS_WEB || IS_EQUIBOP || IS_VESKTOP) { - const file = new File([data], fileName, { type: "application/json" }); - const a = document.createElement("a"); - a.href = URL.createObjectURL(file); - a.download = fileName; - - document.body.appendChild(a); - a.click(); - setImmediate(() => { - URL.revokeObjectURL(a.href); - document.body.removeChild(a); - }); - } else { - DiscordNative.fileManager.saveWithDialog(data, fileName); - } - - if (!settings.store.disableToasts) { - Toasts.show({ - message: "Successfully exported emojis", - type: Toasts.Type.SUCCESS, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } -}; - -async function exportEmojisToJson() { - const emojis = await getAllowedList(); - return JSON.stringify({ emojis }, null, 4); -} - -const uploadEmojis = async () => { - if (IS_WEB || IS_EQUIBOP || IS_VESKTOP) { - const input = document.createElement("input"); - input.type = "file"; - input.style.display = "none"; - input.accept = "application/json"; - input.onchange = async () => { - const file = input.files?.[0]; - if (!file) return; - - const reader = new FileReader(); - reader.onload = async () => { - const data = reader.result as string; - await importEmojis(data); - }; - - reader.readAsText(file); - }; - - document.body.appendChild(input); - input.click(); - setImmediate(() => { - document.body.removeChild(input); - }); - } else { - const [file] = await DiscordNative.fileManager.openFiles({ - filters: [ - { name: "Whitelisted Emojis", extensions: ["json"] }, - { name: "all", extensions: ["*"] } - ] - }); - - if (file) { - try { - await importEmojis(new TextDecoder().decode(file.data)); - } catch (err) { - console.error(err); - if (!settings.store.disableToasts) { - Toasts.show({ - message: `Failed to import emojis: ${err}`, - type: Toasts.Type.FAILURE, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - } - } - } -}; - -const importEmojis = async (data: string) => { - try { - const parsed = JSON.parse(data); - if (parsed && typeof parsed === "object" && Array.isArray(parsed.emojis)) { - await DataStore.set(DATA_COLLECTION_NAME, parsed.emojis); - cache_allowedList = await getAllowedList(); - - if (!settings.store.disableToasts) { - Toasts.show({ - message: "Successfully imported emojis", - type: Toasts.Type.SUCCESS, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - } else { - if (!settings.store.disableToasts) { - Toasts.show({ - message: "Invalid JSON data", - type: Toasts.Type.FAILURE, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - } - } catch (err) { - if (!settings.store.disableToasts) { - Toasts.show({ - message: `Failed to import emojis: ${err}`, - type: Toasts.Type.FAILURE, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } - } -}; - -const resetEmojis = async () => { - await DataStore.set(DATA_COLLECTION_NAME, []); - cache_allowedList = await getAllowedList(); - - if (!settings.store.disableToasts) { - Toasts.show({ - message: "Reset emojis", - type: Toasts.Type.SUCCESS, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - } -}; - -const settings = definePluginSettings({ - defaultEmojis: { - type: OptionType.BOOLEAN, - description: "Hide default emojis", - default: true - }, - serverEmojis: { - type: OptionType.BOOLEAN, - description: "Hide server emojis", - default: true - }, - disableToasts: { - type: OptionType.BOOLEAN, - description: "Disable toasts", - default: false - }, - whiteListedEmojis: { - type: OptionType.COMPONENT, - description: "Whitelisted Emojis", - component: WhiteListedEmojisComponent - }, - exportEmojis: { - type: OptionType.COMPONENT, - description: "Export Emojis", - component: () => ( - - ) - }, - importEmojis: { - type: OptionType.COMPONENT, - description: "Import Emojis", - component: () => ( - - ) - }, - resetEmojis: { - type: OptionType.COMPONENT, - description: "Reset Emojis", - component: () => ( - - ) - } -}); - -migratePluginSettings("WhitelistedEmojis", "NoDefaultEmojis"); -export default definePlugin({ - name: "WhitelistedEmojis", - description: "Adds the ability to disable all message emojis except for a whitelisted set.", - authors: [EquicordDevs.creations], - patches: [ - { - find: "#{intl::EMOJI_MATCHING}", - replacement: { - match: /renderResults\((\i)\){/, - replace: "$&$1.results.emojis=$self.filterEmojis($1);if($1.results.emojis.length===0)return;" - } - } - ], - settings: settings, - async start() { - cache_allowedList = await getAllowedList(); - addContextMenuPatch("expression-picker", expressionPickerPatch); - addContextMenuPatch("guild-context", guildContextPatch); - }, - stop() { - removeContextMenuPatch("expression-picker", expressionPickerPatch); - removeContextMenuPatch("guild-context", guildContextPatch); - }, - filterEmojis: (data: { results: { emojis: (CustomEmoji | UnicodeEmoji)[]; }; }) => { - const { emojis } = data.results; - let modifiedEmojis = emojis; - - if (settings.store.defaultEmojis) { - modifiedEmojis = modifiedEmojis.filter(emoji => !("uniqueName" in emoji) || isItemAllowed(emoji)); - } - - if (settings.store.serverEmojis) { - modifiedEmojis = modifiedEmojis.filter(emoji => "uniqueName" in emoji || isItemAllowed(emoji)); - } - - return modifiedEmojis; - } -}); diff --git a/src/equicordplugins/whitelistedEmojis/style.css b/src/equicordplugins/whitelistedEmojis/style.css deleted file mode 100644 index 457eae74..00000000 --- a/src/equicordplugins/whitelistedEmojis/style.css +++ /dev/null @@ -1,105 +0,0 @@ -.emoji-container { - display: grid; - gap: 10px; - background-color: var(--background-secondary); - max-height: 300px; - overflow-y: auto; -} - -.guild-section { - border: 1px solid var(--background-tertiary); - border-radius: 4px; - overflow: hidden; -} - -.guild-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px; - background-color: var(--background-tertiary); - cursor: pointer; -} - -.guild-name { - font-size: 18px; - font-weight: bold; - color: var(--white-500); - margin: 0; -} - -.remove-all-button { - cursor: pointer; - background-color: var(--button-danger-background); - color: var(--white-500); - transition: background-color 0.2s ease; -} - -.remove-all-button:hover { - filter: saturate(75%); -} - -.guild-emojis { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); - gap: 10px; - padding: 10px; -} - -.emoji-item { - display: flex; - flex-direction: column; - align-items: center; - padding: 8px; - background-color: var(--background-secondary-alt); - border-radius: 4px; -} - -.emoji-image { - max-height: 32px; - width: auto; - height: auto; -} - -.emoji-surrogate { - font-size: 32px; -} - -.emoji-name { - font-weight: bold; - color: var(--white-500); - margin-bottom: 10px; - text-align: center; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 100%; -} - -.remove-button { - cursor: pointer; - background-color: var(--button-danger-background); - color: var(--white-500); - transition: background-color 0.2s ease; - margin-top: 10px; -} - -.remove-button:hover { - filter: saturate(75%); -} - -.emoji-container::-webkit-scrollbar { - background-color: #fff1; - width: 10px; -} - -.emoji-container::-webkit-scrollbar-thumb { - background-color: #fff3; -} - -.no-emoji-message { - font-size: 25px; - color: var(--white-500); - text-align: center; - margin: 20px; -} diff --git a/src/equicordplugins/wigglyText/index.tsx b/src/equicordplugins/wigglyText/index.tsx deleted file mode 100644 index df261230..00000000 --- a/src/equicordplugins/wigglyText/index.tsx +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { definePluginSettings } from "@api/Settings"; -import { makeRange } from "@components/PluginSettings/components"; -import { EquicordDevs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; -import { Text } from "@webpack/common"; -import { ReactNode } from "react"; - -import ExampleWiggle from "./ui/components/ExampleWiggle"; - -const settings = definePluginSettings({ - intensity: { - type: OptionType.SLIDER, - description: "Animation intensity in px", - markers: makeRange(1, 10, 1), - default: 4, - stickToMarkers: true, - onChange: () => updateStyles() - } -}); - -const dirMap = { - x: "0.6s wiggle-wavy-x alternate ease-in-out infinite", - y: "1.2s wiggle-wavy-y linear infinite" -}; - -const classMap = [ - { - chars: ["<", ">"], - className: "wiggle-inner-x", - }, - { - chars: ["^", "^"], - className: "wiggle-inner-y", - }, - { - chars: [")", "("], - className: "wiggle-inner-xy" - } -]; - -let styles: HTMLStyleElement; -const updateStyles = () => { - const inten = Vencord.Settings.plugins.WigglyText.intensity + "px"; - styles.textContent = ` -.wiggle-example { - list-style-type: disc; - list-style-position: outside; - margin: 4px 0 0 16px; -} - -.wiggle-example li { - white-space: break-spaces; - margin-bottom: 4px; -} - -.wiggle-inner { - position: relative; - top: 0; - left: 0; - - &.wiggle-inner-x { - animation: ${dirMap.x}; - } - - &.wiggle-inner-y { - animation: ${dirMap.y}; - } - - &.wiggle-inner-xy { - animation: ${dirMap.x}, ${dirMap.y}; - } -} - -@keyframes wiggle-wavy-x { - from { - left: -${inten}; - } - - to { - left: ${inten}; - } -} - -@keyframes wiggle-wavy-y { - 0% { - top: 0; - animation-timing-function: ease-out; - } - - 25% { - top: -${inten}; - animation-timing-function: ease-in; - } - - 50% { - top: 0; - animation-timing-function: ease-out; - } - - 75% { - top: ${inten}; - animation-timing-function: ease-in; - } -}`; -}; - -export default definePlugin({ - name: "WigglyText", - description: "Adds a new markdown formatting that makes text wiggly.", - authors: [EquicordDevs.nexpid], - settings, - settingsAboutComponent: () => ( - - You can make text wiggle with the following:
-
    -
  • left and right by typing <~text~>
  • -
  • up and down by typing ^~text~^
  • -
  • in a circle by typing )~text~(
  • -
-
- ), - - patches: [ - { - find: "parseToAST:", - replacement: { - match: /(parse[\w]*):(.*?)\((\i)\),/g, - replace: "$1:$2({...$3,wiggly:$self.wigglyRule}),", - }, - }, - ], - - wigglyRule: { - order: 24, - match: (source: string) => classMap.map(({ chars }) => source.match(new RegExp(`^(\\${chars[0]})~([\\s\\S]+?)~(\\${chars[1]})(?!_)`))).find(x => x !== null), - parse: ( - capture: RegExpMatchArray, - transform: (...args: any[]) => any, - state: any - ) => { - const className = classMap.find(({ chars }) => chars[0] === capture[1] && chars[1] === capture[3])?.className ?? ""; - - return { - content: transform(capture[2], state), - className - }; - }, - react: ( - data: { content: any[]; className: string; }, - output: (...args: any[]) => ReactNode[] - ) => { - let offset = 0; - const traverse = (raw: any) => { - const children = !Array.isArray(raw) ? [raw] : raw; - let modified = false; - - let j = -1; - for (const child of children) { - j++; - if (typeof child === "string") { - modified = true; - children[j] = child.split("").map((x, i) => ( - - - {x} - - - )); - } else if (child?.props?.children) - child.props.children = traverse(child.props.children); - } - - return modified ? children : raw; - }; - - return traverse(output(data.content)); - }, - }, - - start: () => { - styles = document.createElement("style"); - styles.id = "WigglyText"; - document.head.appendChild(styles); - - updateStyles(); - }, - - stop: () => styles.remove() -}); diff --git a/src/equicordplugins/wigglyText/ui/components/ExampleWiggle.tsx b/src/equicordplugins/wigglyText/ui/components/ExampleWiggle.tsx deleted file mode 100644 index 1f6e709a..00000000 --- a/src/equicordplugins/wigglyText/ui/components/ExampleWiggle.tsx +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -export default function ExampleWiggle({ wiggle, children }: { wiggle: "x" | "y" | "xy", children: string; }) { - return children.split("").map((x, i) => ( - - - {x} - - - )); -} diff --git a/src/equicordplugins/writeUpperCase/index.ts b/src/equicordplugins/writeUpperCase/index.ts deleted file mode 100644 index a19e9c9c..00000000 --- a/src/equicordplugins/writeUpperCase/index.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { addMessagePreSendListener, MessageSendListener, removeMessagePreSendListener } from "@api/MessageEvents"; -import { definePluginSettings } from "@api/Settings"; -import { Devs, EquicordDevs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; - -const settings = definePluginSettings( - { - blockedWords: { - type: OptionType.STRING, - description: "Strings not to capitilise (seperate with a comma)", - default: "http, https, ok" - } - } -); - -const presendObject: MessageSendListener = (_, msg) => { - const sentences = msg.content.split(/(?<=\w\.)\s/); - const blockedWordsArray: string[] = settings.store.blockedWords.split(", "); - - msg.content = sentences.map(element => { - if (!blockedWordsArray.some(word => element.toLowerCase().startsWith(word.toLocaleLowerCase()))) { - return element.charAt(0).toUpperCase() + element.slice(1); - } else { - return element; - } - }).join(" "); -}; - -export default definePlugin({ - name: "WriteUpperCase", - description: "Changes the first Letter of each Sentence in Message Inputs to Uppercase", - authors: [Devs.Samwich, EquicordDevs.KrystalSkull], - settings, - - start() { - addMessagePreSendListener(presendObject); - }, - stop() { - removeMessagePreSendListener(presendObject); - } -});