diff --git a/src/plusplugins/pingControl/index.tsx b/src/plusplugins/pingControl/index.tsx new file mode 100644 index 00000000000..6a7f8330f59 --- /dev/null +++ b/src/plusplugins/pingControl/index.tsx @@ -0,0 +1,274 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { openNotificationLogModal } from "@api/Notifications/notificationLog"; +import { Settings, useSettings, definePluginSettings } from "@api/Settings"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { Devs } from "@utils/constants"; +import definePlugin, { OptionType } from "@utils/types"; +import { findExportedComponentLazy } from "@webpack"; +import { Menu, Popout, useState } from "@webpack/common"; +import type { ReactNode } from "react"; +import { DeleteIcon } from "@components/Icons"; +import { findByProps } from "@webpack"; + +import { addContextMenuPatch, removeContextMenuPatch } from "@api/ContextMenu"; + +const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider"); + +let inbox = [] + +function lol() { + window.open("https://dis.gd/notifications-technical-details", "_blank"); +} + +function clear() { + inbox = [] +} + +function jumpTo(e) { + findByProps("jumpToMessage").jumpToMessage({ + channelId: e.channelId, + messageId: e.message, + flash: !0 +}) + + +} + +function VencordPopout(onClose: () => void) { + let entries = [] as ReactNode[]; + + inbox.forEach(item => { + if (item.guild) { + entries.push( + jumpTo(item)} + /> + ) + } else { +entries.push( + jumpTo(item)} + /> + )} + }) + + if (entries.length === 0) { + entries.push( + + ) + } else { +entries.push( + + ) + } + + return ( + + {...entries} + + ); +} + +function VencordPopoutIcon(isShown: boolean) { + return ( + + + + + + + + + + + + + + + + + + + + + ); +} + +function VencordPopoutButton() { + const [show, setShow] = useState(false); + + return ( + setShow(false)} + renderPopout={() => VencordPopout(() => setShow(false))} + > + {(_, { isShown }) => ( + setShow(v => !v)} + tooltip={isShown ? null : "Blocked Ping Inbox"} + icon={() => VencordPopoutIcon(isShown)} + selected={isShown} + showBadge={settings.store.showBadge&&inbox[0]&&true||false} + /> + )} + + ); +} + +function ToolboxFragmentWrapper({ children }: { children: ReactNode[]; }) { + children.splice( + children.length - 1, 0, + + + + ); + + return <>{children}; +} + +interface UserContextProps { + channel: Channel; + guildId?: string; + user: User; +} + +function t(id) { + if (settings.store.userList.search(id.id) !== -1) { + settings.store.userList = settings.store.userList.replace(`${id.id}`, "") + + findByProps("showToast").showToast( + findByProps("createToast").createToast(`Pings from ${id.globalName || id.username} are no longer blocked`, 1, { + duration: 4000 + }) + ) + } else { + settings.store.userList = `${settings.store.userList},${id.id}` + + findByProps("showToast").showToast( + findByProps("createToast").createToast(`Pings from ${id.globalName || id.username} are now blocked`, 1, { + duration: 4000 + }) + ) + } +} + +function a(id) { + if (settings.store.userList.search(id) === -1) { + return false + } else { + return true + } +} + +const UserContextMenuPatch: NavContextMenuPatchCallback = (children, { user, guildId }: UserContextProps) => { + if (!user) return; + + const isBlocked = a(user.id) + + children.push( + t(user)} + /> + ); +}; + +const settings = definePluginSettings({ + userList: { + description: + "List of blocked ping users (separated by commas)", + type: OptionType.STRING, + default: "" + }, + showBadge: { + type: OptionType.BOOLEAN, + description: "Show a badge when there is one message in the inbox", + default: true + }, +}); + +export default definePlugin({ + name: "PingControl", + description: "Allows you to block incoming pings from certain users", + authors: [Devs.HumanCat222], + settings, + + patches: [ + { + find: "toolbar:function", + replacement: { + match: /(?<=toolbar:function.{0,100}\()\i.Fragment,/, + replace: "$self.ToolboxFragmentWrapper," + } + } + ], + + contextMenus: { + "user-context": UserContextMenuPatch + }, + + ToolboxFragmentWrapper: ErrorBoundary.wrap(ToolboxFragmentWrapper, { + fallback: () =>

Failed to render :(

+ }), + + start() { + +const currentUserId = findByProps("getCurrentUser", "getUser").getCurrentUser().id; + + findByProps("addInterceptor").addInterceptor((e: { type: string; message: { mentions: any[]; content: string; }; }) => { + if (e.type === "MESSAGE_CREATE") { + e.message.mentions.forEach(mention => { + if (mention.id === currentUserId && settings.store.userList.search(e.message.author.id) !== -1) { + e.message.mentions = []; + e.message.content = "󠁰󠁩󠁮󠁧󠀠󠁢󠁬󠁯󠁣󠁫󠁥󠁤<:PingBlocked:1221214625899479081> " + e.message.content; + + let guilds = Object.values(findByProps("getGuilds").getGuilds()) + let channel = findByProps("getChannel").getChannel(e.channelId) + let guild = null + + guilds.forEach(g => { + if (g.id === e.guildId) { + guild = g + } + }) + + inbox.push({ + author: e.message.author.global_name || e.message.author.username || "???", + channel: channel && channel.name, + channelId: channel && channel.id, + message: e.message.id, + guild: guild && guild.name + }) + } + }); + } + }); + } +});