diff --git a/src/plugins/messageLinkEmbeds/index.tsx b/src/plugins/messageLinkEmbeds/index.tsx index 9fd677389..d86cac53a 100644 --- a/src/plugins/messageLinkEmbeds/index.tsx +++ b/src/plugins/messageLinkEmbeds/index.tsx @@ -22,6 +22,7 @@ import { definePluginSettings } from "@api/Settings"; import { getUserSettingLazy } from "@api/UserSettings"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants.js"; +import { getIntlMessage } from "@utils/discord"; import { classes } from "@utils/misc"; import { Queue } from "@utils/Queue"; import definePlugin, { OptionType } from "@utils/types"; @@ -31,6 +32,7 @@ import { ChannelStore, Constants, GuildStore, + Icons, IconUtils, MessageStore, Parser, @@ -38,7 +40,8 @@ import { PermissionStore, RestAPI, Text, - UserStore + UserStore, + useState } from "@webpack/common"; import { Channel, Message } from "discord-types/general"; @@ -53,6 +56,8 @@ const ChannelMessage = findComponentByCodeLazy("childrenExecutedCommand:", ".hid const SearchResultClasses = findByPropsLazy("message", "searchResult"); const EmbedClasses = findByPropsLazy("embedAuthorIcon", "embedAuthor", "embedAuthor"); +const SpoilerClasses = findByPropsLazy("explicitContentWarning", "explicitContentWarningText", "spoilerContent"); +const MosaicClasses = findByPropsLazy("obscured", "hiddenMosaicItem", "hiddenExplicit"); const MessageDisplayCompact = getUserSettingLazy("textAndImages", "messageDisplayCompact")!; @@ -97,6 +102,11 @@ const settings = definePluginSettings({ } ] }, + blurNsfw: { + description: "Blur embeds from age restricted channels", + type: OptionType.BOOLEAN, + default: true + }, listMode: { description: "Whether to use ID list as blacklist or whitelist", type: OptionType.SELECT, @@ -283,6 +293,55 @@ function getChannelLabelAndIconUrl(channel: Channel) { return ["Server", IconUtils.getGuildIconURL(GuildStore.getGuild(channel.guild_id))]; } +function Spoiler(props: { children: JSX.Element }) : JSX.Element { + const [visible, setVisible] = useState(false); + const { + explicitContentWarning, + explicitContentWarningText, + spoilerContent, + spoilerContainer, + hidden, + spoilerInnerContainer, + obscureButtonContainer, + obscureHoverButton + } = SpoilerClasses; + const { obscured, hiddenMosaicItem, hiddenExplicit } = MosaicClasses; + + return ( +
+ {!visible && +
+ + + {getIntlMessage("EXPLICIT_CONTENT_WARNING")} + +
+ } +
+ {props.children} +
+
+ setVisible(!visible)} + aria-label={getIntlMessage("EXPLICIT_CONTENT_BUTTON_TOOLTIP")} + className={obscureHoverButton}> + {visible ? : + } + +
+
+ ); +} + function ChannelMessageEmbedAccessory({ message, channel }: MessageEmbedProps): JSX.Element | null { const compact = MessageDisplayCompact.useSetting(); @@ -314,6 +373,7 @@ function ChannelMessageEmbedAccessory({ message, channel }: MessageEmbedProps): /> )} + {...(settings.store.blurNsfw && channel.isNSFW() && { obscureReason: "explicit_content" })} /> ); } @@ -326,7 +386,7 @@ function AutomodEmbedAccessory(props: MessageEmbedProps): JSX.Element | null { const [channelLabel, iconUrl] = getChannelLabelAndIconUrl(channel); - return @@ -361,6 +421,12 @@ function AutomodEmbedAccessory(props: MessageEmbedProps): JSX.Element | null { message={message} _messageEmbed="automod" />; + + if (settings.store.blurNsfw && channel.isNSFW()) { + return {embed}; + } + + return embed; } export default definePlugin({