/* * 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 "./styles.css"; import { get, set } from "@api/DataStore"; import { updateMessage } from "@api/MessageUpdater"; import { migratePluginSettings } from "@api/Settings"; import { ImageInvisible, ImageVisible } from "@components/Icons"; import { Devs } from "@utils/constants"; import { classes } from "@utils/misc"; import definePlugin from "@utils/types"; import { Message } from "@vencord/discord-types"; import { ChannelStore } from "@webpack/common"; const KEY = "HideMedia_HiddenIds"; let hiddenMessages = new Set(); async function getHiddenMessages() { const stored = await get(KEY); hiddenMessages = new Set(stored ?? []); return hiddenMessages; } const saveHiddenMessages = (ids: Set) => set(KEY, [...ids]); migratePluginSettings("HideMedia", "HideAttachments"); const hasMedia = (msg: Message) => msg.attachments.length > 0 || msg.embeds.length > 0 || msg.stickerItems.length > 0 || msg.components.length > 0; async function toggleHide(channelId: string, messageId: string) { const ids = await getHiddenMessages(); if (!ids.delete(messageId)) ids.add(messageId); await saveHiddenMessages(ids); updateMessage(channelId, messageId); } export default definePlugin({ name: "HideMedia", description: "Hide attachments and embeds for individual messages via hover button", tags: ["Chat", "Appearance"], authors: [Devs.Ven], dependencies: ["MessageUpdaterAPI", "MessageAccessoriesAPI", "MessagePopoverAPI"], patches: [{ find: "this.renderAttachments(", replacement: { match: /(?<=\i=)this\.render(?:Attachments|Embeds|StickersAccessories|ComponentAccessories)\((\i)\)/g, replace: "$self.shouldHide($1?.id)?null:$&" } }], messagePopoverButton: { icon: ImageInvisible, render(msg) { if (!hasMedia(msg) && !msg.messageSnapshots.some(s => hasMedia(s.message))) return null; const isHidden = hiddenMessages.has(msg.id); return { label: isHidden ? "Show Media" : "Hide Media", icon: isHidden ? ImageVisible : ImageInvisible, message: msg, channel: ChannelStore.getChannel(msg.channel_id), onClick: () => toggleHide(msg.channel_id, msg.id) }; }, }, renderMessageAccessory({ message }) { if (!this.shouldHide(message.id)) return null; return ( Media Hidden ); }, async start() { await getHiddenMessages(); }, stop() { hiddenMessages.clear(); }, shouldHide(messageId: string) { return hiddenMessages.has(messageId); }, });