/* * Vencord, a Discord client mod * Copyright (c) 2023 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import "./styles.css"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import { Logger } from "@utils/Logger"; import definePlugin from "@utils/types"; import { Tooltip } from "@webpack/common"; import type { Component } from "react"; interface Props { embed: { rawTitle: string; provider?: { name: string; }; thumbnail: { proxyURL: string; }; video: { url: string; }; dearrow: { enabled: boolean; oldTitle?: string; oldThumb?: string; }; }; } const embedUrlRe = /https:\/\/www\.youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/; async function embedDidMount(this: Component) { try { const { embed } = this.props; if (!embed || embed.dearrow || embed.provider?.name !== "YouTube" || !embed.video?.url) return; const videoId = embedUrlRe.exec(embed.video.url)?.[1]; if (!videoId) return; const res = await fetch(`https://sponsor.ajay.app/api/branding?videoID=${videoId}`); if (!res.ok) return; const { titles, thumbnails } = await res.json(); const hasTitle = titles[0]?.votes >= 0; const hasThumb = thumbnails[0]?.votes >= 0 && !thumbnails[0].original; if (!hasTitle && !hasThumb) return; embed.dearrow = { enabled: true }; if (hasTitle) { embed.dearrow.oldTitle = embed.rawTitle; embed.rawTitle = titles[0].title.replace(/ >(\S)/g, " $1"); } if (hasThumb) { embed.dearrow.oldThumb = embed.thumbnail.proxyURL; embed.thumbnail.proxyURL = `https://dearrow-thumb.ajay.app/api/v1/getThumbnail?videoID=${videoId}&time=${thumbnails[0].timestamp}`; } this.forceUpdate(); } catch (err) { new Logger("Dearrow").error("Failed to dearrow embed", err); } } function DearrowButton({ component }: { component: Component; }) { const { embed } = component.props; if (!embed?.dearrow) return null; return ( {({ onMouseEnter, onMouseLeave }) => ( )} ); } export default definePlugin({ name: "Dearrow", description: "Makes YouTube embed titles and thumbnails less sensationalist, powered by Dearrow", authors: [Devs.Ven], embedDidMount, renderButton(component: Component) { return ( ); }, patches: [{ find: "this.renderInlineMediaEmbed", replacement: [ // patch componentDidMount to replace embed thumbnail and title { match: /render\(\)\{.{0,30}let\{embed:/, replace: "componentDidMount=$self.embedDidMount;$&" }, // add dearrow button { match: /children:\[(?=null!=\i\?\i\.renderSuppressButton)/, replace: "children:[$self.renderButton(this)," } ] }], });