diff --git a/src/equicordplugins/stickerBlocker/index.tsx b/src/equicordplugins/stickerBlocker/index.tsx new file mode 100644 index 000000000..50402c87a --- /dev/null +++ b/src/equicordplugins/stickerBlocker/index.tsx @@ -0,0 +1,131 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu"; +import { DataStore } from "@api/index"; +import { definePluginSettings } from "@api/Settings"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { Devs } from "@utils/constants"; +import definePlugin, { OptionType } from "@utils/types"; +import { Button, Menu } from "@webpack/common"; +import React, { ReactNode } from "react"; + +const settings = definePluginSettings({ + showGif: { + type: OptionType.BOOLEAN, + description: "Whether to show a snazzy cat gif", + default: true, + restartNeeded: true + }, + showMessage: { + type: OptionType.BOOLEAN, + description: "Whether to show a message detailing which id was blocked", + default: false, + restartNeeded: true + }, + showButton: { + type: OptionType.BOOLEAN, + description: "Whether to show a button to unblock the gif", + default: true, + restartNeeded: true + }, + blockedStickers: { + type: OptionType.STRING, + description: "The list of blocked sticker IDs (don't edit unless you know what you're doing)", + default: "" + } +}); + +export default definePlugin({ + name: "StickerBlocker", + description: "Allows you to block stickers from being displayed.", + authors: [Devs.Samwich], + patches: [ + { + find: "l.Z.STICKER_MESSAGE", + replacement: { + match: /}\),\(null!=\i\?\i:(\i)\)\.name]}\);/, + replace: "$& if(Vencord.Settings.plugins.StickerBlocker.blockedStickers.split(\", \").includes($1.id)) { return($self.blockedComponent($1)) }" + } + } + ], + start() { + addContextMenuPatch("message", messageContextMenuPatch); + DataStore.createStore("StickerBlocker", "data"); + }, + stop() { + removeContextMenuPatch("message", messageContextMenuPatch); + }, + blockedComponent: ErrorBoundary.wrap(blockedComponentRender, { fallback: () =>

Failed to render :(

}), + settings, +}); + +function blockedComponentRender(sticker) { + const { showGif, showMessage, showButton } = settings.store; + const elements = [] as ReactNode[]; + + if (showGif) { + elements.push( + + ); + } + + if (showMessage) { + elements.push( +
Blocked Sticker. ID: {sticker.id}, NAME: {sticker.name}
+ ); + } + + if (showButton) { + elements.push( + + ); + } + + return <>{elements}; +} + + +const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => () => { + const { favoriteableType, favoriteableId } = props ?? {}; + if (favoriteableType !== "sticker") { return; } + if (favoriteableId === null) { return; } + const group = findGroupChildrenByChildId("reply", children); + if (!group) return; + + group.splice(group.findIndex(c => c?.props?.id === "reply") + 1, 0, buttonThingy(favoriteableId)); +}; + +function buttonThingy(name) { + return ( + toggleBlock(name)} + /> + ); +} + +function toggleBlock(name) { + if (settings.store.blockedStickers === undefined || settings.store.blockedStickers == null) { + return; + } + const excepted = isStickerBlocked(name); + if (excepted) { + settings.store.blockedStickers = settings.store.blockedStickers.split(", ").filter(item => item !== name).join(", "); + } else { + settings.store.blockedStickers = settings.store.blockedStickers.split(", ").concat(name).join(", "); + } +} + + +function isStickerBlocked(name) { + if (settings.store.blockedStickers === undefined || settings.store.blockedStickers == null) { + return; + } + return settings.store.blockedStickers.split(", ").includes(name); +}