diff --git a/README.md b/README.md
index 8fafe74f..18c8084d 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,6 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend
- PurgeMessages by bhop and nyx
- Quest Completer by HappyEnderman, SerStars, thororen
- QuestionMarkReplacement by nyx
-- Quoter by Samwich
- RepeatMessage by Tolgchu
- ReplyPingControl by ant0n and MrDiamond
- ScreenRecorder by AutumnVN
diff --git a/src/equicordplugins/quoter/components.tsx b/src/equicordplugins/quoter/components.tsx
deleted file mode 100644
index f7e350cd..00000000
--- a/src/equicordplugins/quoter/components.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-export function QuoteIcon() {
- return (
-
- );
-}
diff --git a/src/equicordplugins/quoter/index.tsx b/src/equicordplugins/quoter/index.tsx
deleted file mode 100644
index 66e7af11..00000000
--- a/src/equicordplugins/quoter/index.tsx
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
-import { definePluginSettings } from "@api/Settings";
-import { Devs } from "@utils/constants";
-import { getCurrentChannel } from "@utils/discord";
-import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
-import definePlugin, { OptionType } from "@utils/types";
-import { Button, Menu, Select, Switch, Text, TextInput, UploadHandler, useEffect, UserStore, useState } from "@webpack/common";
-import { Message } from "discord-types/general";
-
-import { QuoteIcon } from "./components";
-import { canvasToBlob, fetchImageAsBlob, FixUpQuote, wrapText } from "./utils";
-
-enum ImageStyle {
- inspirational
-}
-
-const messagePatch: NavContextMenuPatchCallback = (children, { message }) => {
- recentmessage = message;
- if (!message.content) return;
-
- const buttonElement =
-
{
- openModal(props => );
- }}
- />;
-
- const group = findGroupChildrenByChildId("copy-text", children);
- if (!group) {
- children.push(buttonElement);
- return;
- }
-
- group.splice(
- group.findIndex(c => c?.props?.id === "copy-text") + 1, 0, buttonElement
- );
-};
-
-let recentmessage: Message;
-let grayscale;
-let setStyle: ImageStyle = ImageStyle.inspirational;
-let customMessage: string = "";
-let customImage: string = "";
-let customName: string = "";
-let isUserCustomCapable = false;
-
-enum userIDOptions {
- usernameNormalized,
- userName,
- userId
-}
-const settings = definePluginSettings({
- userIdentifier:
- {
- type: OptionType.SELECT,
- description: "What the author's name should be displayed as",
- options: [
- { label: "Username Normalized", value: userIDOptions.usernameNormalized, default: true },
- { label: "Username", value: userIDOptions.userName },
- { label: "User ID", value: userIDOptions.userId }
- ]
- }
-});
-
-export default definePlugin({
- name: "Quoter",
- description: "Adds the ability to create an inspirational quote image from a message",
- authors: [Devs.Samwich],
- contextMenus: {
- "message": messagePatch
- },
- settings
-});
-
-function sizeUpgrade(url) {
- const u = new URL(url);
- u.searchParams.set("size", "512");
- return u.toString();
-}
-
-const preparingSentence: string[] = [];
-const lines: string[] = [];
-
-async function createQuoteImage(avatarUrl: string, quoteOld: string, grayScale: boolean): Promise {
- let name: string = "";
-
- switch (settings.store.userIdentifier) {
- case userIDOptions.usernameNormalized:
- const meow = recentmessage.author.usernameNormalized;
- if (meow) {
- name = meow;
- }
- else {
- name = recentmessage.author.username;
- }
- break;
- case userIDOptions.userName:
- name = recentmessage.author.username;
- break;
- case userIDOptions.userId:
- name = recentmessage.author.id;
- break;
- default:
- name = "MAN WTF HAPPENED";
- break;
- }
- let quote;
- if (isUserCustomCapable && customMessage.length > 0 && customImage.length > 0 && customName.length > 0) {
- quote = FixUpQuote(customMessage);
- avatarUrl = customImage;
- name = customName;
- } else if (isUserCustomCapable && customMessage.length > 0 && customImage.length > 0) {
- quote = FixUpQuote(customMessage);
- avatarUrl = customImage;
- } else if (isUserCustomCapable && customMessage.length > 0 && customName.length > 0) {
- quote = FixUpQuote(customMessage);
- name = customName;
- } else if (isUserCustomCapable && customImage.length > 0 && customName.length > 0) {
- avatarUrl = customImage;
- name = customName;
- } else if (isUserCustomCapable && customImage.length > 0) {
- avatarUrl = customImage;
- } else if (isUserCustomCapable && customName.length > 0) {
- name = customName;
- } else if (isUserCustomCapable && customMessage.length > 0) {
- quote = FixUpQuote(customMessage);
- } else {
- quote = FixUpQuote(quoteOld);
- }
- const canvas = document.createElement("canvas");
- const ctx = canvas.getContext("2d");
-
- if (!ctx) {
- throw new Error("Cant get 2d rendering context :(");
- }
-
- switch (setStyle) {
- case ImageStyle.inspirational:
-
- const cardWidth = 1200;
- const cardHeight = 600;
-
- canvas.width = cardWidth;
- canvas.height = cardHeight;
-
- ctx.fillStyle = "#000";
- ctx.fillRect(0, 0, canvas.width, canvas.height);
-
- const avatarBlob = await fetchImageAsBlob(avatarUrl);
- const fadeBlob = await fetchImageAsBlob("https://files.catbox.moe/54e96l.png");
-
- const avatar = new Image();
- const fade = new Image();
-
- const avatarPromise = new Promise(resolve => {
- avatar.onload = () => resolve();
- avatar.src = URL.createObjectURL(avatarBlob);
- });
-
- const fadePromise = new Promise(resolve => {
- fade.onload = () => resolve();
- fade.src = URL.createObjectURL(fadeBlob);
- });
-
- await Promise.all([avatarPromise, fadePromise]);
-
- ctx.drawImage(avatar, 0, 0, cardHeight, cardHeight);
-
- if (grayScale) {
- ctx.globalCompositeOperation = "saturation";
- ctx.fillStyle = "#fff";
- ctx.fillRect(0, 0, cardWidth, cardHeight);
- ctx.globalCompositeOperation = "source-over";
- }
-
- ctx.drawImage(fade, cardHeight - 400, 0, 400, cardHeight);
-
- ctx.fillStyle = "#fff";
- ctx.font = "italic 20px Georgia";
- const quoteWidth = cardWidth / 2 - 50;
- const quoteX = ((cardWidth - cardHeight));
- const quoteY = cardHeight / 2 - 10;
- wrapText(ctx, `"${quote}"`, quoteX, quoteY, quoteWidth, 20, preparingSentence, lines);
-
- const wrappedTextHeight = lines.length * 25;
-
- ctx.font = "bold 16px Georgia";
- const authorNameX = (cardHeight * 1.5) - (ctx.measureText(`- ${name}`).width / 2) - 30;
- const authorNameY = quoteY + wrappedTextHeight + 30;
-
- ctx.fillText(`- ${name}`, authorNameX, authorNameY);
- preparingSentence.length = 0;
- lines.length = 0;
- return await canvasToBlob(canvas);
- }
-}
-
-function registerStyleChange(style) {
- setStyle = style;
- GeneratePreview();
-}
-
-async function setIsUserCustomCapable() {
- const allowList: string[] = await fetch("https://raw.githubusercontent.com/Equicord/Ignore/main/quoterusers.json").then(e => e.json());
- isUserCustomCapable = allowList.includes(UserStore.getCurrentUser().id);
-}
-
-
-function QuoteModal(props: ModalProps) {
- setIsUserCustomCapable();
- const [gray, setGray] = useState(true);
- useEffect(() => {
- grayscale = gray;
- GeneratePreview();
- }, [gray]);
-
- const safeTextContent = recentmessage && recentmessage.content ? recentmessage.content : "";
- const safeAvatarContent = recentmessage && recentmessage.author.avatar ? recentmessage.author.avatar : "";
- const safeUsernameContent = recentmessage && recentmessage.author.username ? recentmessage.author.username : "";
-
- const [customText, setCustomText] = useState(safeTextContent);
- const [customAvatar, setCustomAvatar] = useState(safeAvatarContent);
- const [customUsername, setCustomUsername] = useState(safeUsernameContent);
- useEffect(() => {
- customMessage = customText;
- customImage = customAvatar;
- customName = customUsername;
- GeneratePreview();
- }, [customText]);
-
- return (
-
-
-
- Catch Them In 4K.
-
-
-
-
-
-
- {isUserCustomCapable &&
- (
- <>
-
-
-
-
-
-
- >
- )}
- Grayscale
-
-
-
-
-
-
-
- );
-}
-
-async function SendInChat(onClose) {
- const image = await createQuoteImage(sizeUpgrade(recentmessage.author.getAvatarURL()), recentmessage.content, grayscale);
- const imageName = `${new Date().toISOString()} - ${recentmessage.author.username}`;
- const file = new File([image], `${imageName}.png`, { type: "image/png" });
- UploadHandler.promptToUpload([file], getCurrentChannel(), 0);
- onClose();
-}
-
-async function Export() {
- const image = await createQuoteImage(sizeUpgrade(recentmessage.author.getAvatarURL()), recentmessage.content, grayscale);
- const link = document.createElement("a");
- link.href = URL.createObjectURL(image);
-
- const imageName = `${new Date().toISOString()} - ${recentmessage.author.username}`;
- link.download = `${imageName}.png`;
- link.click();
- link.remove();
-}
-
-async function GeneratePreview() {
- const image = await createQuoteImage(sizeUpgrade(recentmessage.author.getAvatarURL()), recentmessage.content, grayscale);
- document.getElementById("quoterPreview")?.setAttribute("src", URL.createObjectURL(image));
-}
diff --git a/src/equicordplugins/quoter/utils.tsx b/src/equicordplugins/quoter/utils.tsx
deleted file mode 100644
index bceaba91..00000000
--- a/src/equicordplugins/quoter/utils.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { UserStore } from "@webpack/common";
-
-export function canvasToBlob(canvas: HTMLCanvasElement): Promise {
- return new Promise(resolve => {
- canvas.toBlob(blob => {
- if (blob) {
- resolve(blob);
- } else {
- throw new Error("Failed to create Blob");
- }
- }, "image/png");
- });
-}
-
-export function wrapText(context: CanvasRenderingContext2D, text: string, x: number, y: number, maxWidth: number, lineHeight: number, preparingSentence: string[], lines: string[]) {
- const words = text.split(" ");
- for (let i = 0; i < words.length; i++) {
- const workSentence = preparingSentence.join(" ") + " " + words[i];
-
- if (context.measureText(workSentence).width > maxWidth) {
- lines.push(preparingSentence.join(" "));
- preparingSentence = [words[i]];
- } else {
- preparingSentence.push(words[i]);
- }
- }
-
- lines.push(preparingSentence.join(" "));
-
- lines.forEach(element => {
- const lineWidth = context.measureText(element).width;
- const xOffset = (maxWidth - lineWidth) / 2;
-
- y += lineHeight;
- context.fillText(element, x + xOffset, y);
- });
-}
-
-export async function fetchImageAsBlob(url: string): Promise {
- const response = await fetch(url);
- const blob = await response.blob();
- return blob;
-}
-
-export function FixUpQuote(quote) {
- const emojiRegex = //g;
- quote = quote.replace(emojiRegex, "");
-
-
- const mentionRegex = /<@(.*)>/;
- let result = quote;
-
- mentionRegex.exec(quote)?.forEach(match => {
- console.log(match);
- result = result.replace(match, `@${UserStore.getUser(match.replace("<@", "").replace(">", "")).username}`);
- });
-
- return result;
-}