From 0dbec8d0cd3554ec66030ed6fe2649f90308d950 Mon Sep 17 00:00:00 2001 From: rushii <33725716+DiamondMiner88@users.noreply.github.com> Date: Sun, 13 Nov 2022 14:13:32 -0800 Subject: feat: message logger plugin (#49) Co-authored-by: Ven --- src/plugins/EmoteYoink.tsx | 243 --------------------------------------------- 1 file changed, 243 deletions(-) delete mode 100644 src/plugins/EmoteYoink.tsx (limited to 'src/plugins/EmoteYoink.tsx') diff --git a/src/plugins/EmoteYoink.tsx b/src/plugins/EmoteYoink.tsx deleted file mode 100644 index 405f383..0000000 --- a/src/plugins/EmoteYoink.tsx +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 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 { Settings } from "../api/settings"; -import { CheckedTextInput } from "../components/CheckedTextInput"; -import { Devs } from "../utils/constants"; -import { lazyWebpack, makeLazy } from "../utils/misc"; -import { ModalContent, ModalHeader, ModalRoot, openModal } from "../utils/modal"; -import definePlugin from "../utils/types"; -import { filters } from "../webpack"; -import { Forms, GuildStore, Margins, Menu, PermissionStore, React, Toasts, Tooltip, UserStore } from "../webpack/common"; - -const MANAGE_EMOJIS_AND_STICKERS = 1n << 30n; - -const GuildEmojiStore = lazyWebpack(filters.byProps("getGuilds", "getGuildEmoji")); -const uploadEmoji = lazyWebpack(filters.byCode('"EMOJI_UPLOAD_START"', "GUILD_EMOJIS(")); - -function getGuildCandidates(isAnimated: boolean) { - const meId = UserStore.getCurrentUser().id; - - return Object.values(GuildStore.getGuilds()).filter(g => { - const canCreate = g.ownerId === meId || - BigInt(PermissionStore.getGuildPermissions({ id: g.id }) & MANAGE_EMOJIS_AND_STICKERS) === MANAGE_EMOJIS_AND_STICKERS; - if (!canCreate) return false; - - const emojiSlots = g.getMaxEmojiSlots(); - const { emojis } = GuildEmojiStore.getGuilds()[g.id]; - - let count = 0; - for (const emoji of emojis) - if (emoji.animated === isAnimated) count++; - return count < emojiSlots; - }).sort((a, b) => a.name.localeCompare(b.name)); -} - -async function doClone(guildId: string, id: string, name: string, isAnimated: boolean) { - const data = await fetch(`https://cdn.discordapp.com/emojis/${id}.${isAnimated ? "gif" : "png"}`) - .then(r => r.blob()); - const reader = new FileReader(); - - reader.onload = () => { - uploadEmoji({ - guildId, - name, - image: reader.result - }).then(() => { - Toasts.show({ - message: `Successfully yoinked ${name}!`, - type: Toasts.Type.SUCCESS, - id: Toasts.genId() - }); - }).catch(e => { - console.error("[EmoteYoink] Failed to upload emoji", e); - Toasts.show({ - message: "Oopsie something went wrong :( Check console!!!", - type: Toasts.Type.FAILURE, - id: Toasts.genId() - }); - }); - }; - - reader.readAsDataURL(data); -} - -const getFontSize = (s: string) => { - // [18, 18, 16, 16, 14, 12, 10] - const sizes = [20, 20, 18, 18, 16, 14, 12]; - return sizes[s.length] ?? 4; -}; - -const nameValidator = /^\w+$/i; - -function CloneModal({ id, name: emojiName, isAnimated }: { id: string; name: string; isAnimated: boolean; }) { - const [isCloning, setIsCloning] = React.useState(false); - const [name, setName] = React.useState(emojiName); - - const [x, invalidateMemo] = React.useReducer(x => x + 1, 0); - - const guilds = React.useMemo(() => getGuildCandidates(isAnimated), [isAnimated, x]); - - return ( - <> - Custom Name - - (v.length > 1 && v.length < 32 && nameValidator.test(v)) - || "Name must be between 2 and 32 characters and only contain alphanumeric characters" - } - /> -
- {guilds.map(g => ( - - {({ onMouseLeave, onMouseEnter }) => ( -
{ - setIsCloning(true); - doClone(g.id, id, name, isAnimated).finally(() => { - invalidateMemo(); - setIsCloning(false); - }); - }} - > - {g.icon ? ( - {g.name} - ) : ( - - {g.acronym} - - )} -
- )} -
- ))} -
- - ); -} - -export default definePlugin({ - name: "EmoteYoink", - description: "Clone emotes to your own server", - authors: [Devs.Ven], - dependencies: ["MenuItemDeobfuscatorApi"], - - patches: [{ - // Literally copy pasted from ReverseImageSearch lol - find: "open-native-link", - replacement: { - match: /id:"open-native-link".{0,200}\(\{href:(.{0,3}),.{0,200}\},"open-native-link"\)/, - replace: "$&,Vencord.Plugins.plugins.EmoteYoink.makeMenu(arguments[2])" - }, - - }, - // Also copy pasted from Reverse Image Search - { - // pass the target to the open link menu so we can grab its data - find: "REMOVE_ALL_REACTIONS_CONFIRM_BODY,", - predicate: makeLazy(() => !Settings.plugins.ReverseImageSearch.enabled), - replacement: { - match: /(?.).onHeightUpdate.{0,200}(.)=(.)=.\.url;.+?\(null!=\3\?\3:\2[^)]+/, - replace: "$&,$.target" - } - }], - - makeMenu(htmlElement: HTMLImageElement) { - if (htmlElement?.dataset.type !== "emoji") - return null; - - const { id } = htmlElement.dataset; - const name = htmlElement.alt.match(/:(.*)(?:~\d+)?:/)?.[1]; - - if (!name || !id) - return null; - - const isAnimated = new URL(htmlElement.src).pathname.endsWith(".gif"); - - return - openModal(modalProps => ( - - - - Clone {name} - - - - - - )) - } - > - ; - }, -}); -- cgit