/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { addMessageAccessory, removeMessageAccessory } from "@api/MessageAccessories";
import { definePluginSettings } from "@api/Settings";
import { getUserSettingLazy } from "@api/UserSettings";
import ErrorBoundary from "@components/ErrorBoundary";
import definePlugin, { OptionType } from "@utils/types";
import { Message } from "@vencord/discord-types";
import { React, Text } from "@webpack/common";
import { knownHosts } from "./knownHosts";
import { knownVideoIds } from "./knownVideoIDs";
const MessageDisplayCompact = getUserSettingLazy(
"textAndImages",
"messageDisplayCompact"
)!;
const settings = definePluginSettings({
customLinks: {
description: "Custom links to check for (separated by commas)",
type: OptionType.STRING,
default: "",
restartNeeded: true,
},
customVideoIds: {
description:
"Custom YouTube video IDs to check for (separated by commas)",
type: OptionType.STRING,
default: "",
restartNeeded: true,
},
});
function isPotentialRickroll(url: string): boolean {
try {
const parsedUrl = new URL(url);
const hostname = parsedUrl.hostname.replace("www.", "");
const customLinks = settings.store.customLinks
.split(",")
.map(s => s.trim())
.filter(Boolean);
const customVideoIDs = settings.store.customVideoIds
.split(",")
.map(s => s.trim())
.filter(Boolean);
if (customLinks.some(link => parsedUrl.href.includes(link))) {
return true;
}
if (hostname === "youtube.com" || hostname === "youtu.be") {
let videoID = "";
if (hostname === "youtube.com") {
videoID =
parsedUrl.searchParams.get("v") ||
parsedUrl.searchParams.get("V") ||
"";
} else if (hostname === "youtu.be") {
videoID = parsedUrl.pathname.slice(1);
}
const knownVideoIDs = [...knownVideoIds, ...customVideoIDs];
if (knownVideoIDs.includes(videoID)) {
return true;
}
}
if (knownHosts.includes(hostname)) {
return true;
}
} catch (e) {
// Invalid URL, ignore :trolley:
}
return false;
}
function extractUrls(content: string): string[] {
const urls: string[] = [];
const markdownLinkRegex = /\[.*?\]\((<)?(https?:\/\/[^\s>]+)(>)?\)/g;
const urlRegex = /https?:\/\/[^\s<]+/g;
const maskedUrlRegex = /<(https?:\/\/[^\s>]+)>/g;
let match: RegExpExecArray | null;
while ((match = markdownLinkRegex.exec(content)) !== null) {
urls.push(match[2]);
}
while ((match = urlRegex.exec(content)) !== null) {
urls.push(match[0]);
}
while ((match = maskedUrlRegex.exec(content)) !== null) {
urls.push(match[1]);
}
return urls;
}
function RickrollWarningAccessory({ message }: { message: Message; }) {
const urls = extractUrls(message.content);
if (urls.length === 0) return null;
for (const url of urls) {
const isCustom = isCustomRickroll(url);
if (isPotentialRickroll(url) || isCustom) {
return (