/*
* 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 ErrorBoundary from "@components/ErrorBoundary";
import { useAwaiter } from "@utils/misc";
import { useIntersection } from "@utils/react";
import { hljs, React } from "@webpack/common";
import { resolveLang } from "../api/languages";
import { shiki } from "../api/shiki";
import { useShikiSettings } from "../hooks/useShikiSettings";
import { useTheme } from "../hooks/useTheme";
import { hex2Rgb } from "../utils/color";
import { cl, shouldUseHljs } from "../utils/misc";
import { ButtonRow } from "./ButtonRow";
import { Code } from "./Code";
import { Header } from "./Header";
export interface ThemeBase {
plainColor: string;
accentBgColor: string;
accentFgColor: string;
backgroundColor: string;
}
export interface HighlighterProps {
lang?: string;
content: string;
isPreview: boolean;
}
export const createHighlighter = (props: HighlighterProps) => (
);
export const Highlighter = ({
lang,
content,
isPreview,
}: HighlighterProps) => {
const { tryHljs, useDevIcon, bgOpacity } = useShikiSettings(["tryHljs", "useDevIcon", "bgOpacity"]);
const { id: currentThemeId, theme: currentTheme } = useTheme();
const shikiLang = lang ? resolveLang(lang) : null;
const useHljs = shouldUseHljs({ lang, tryHljs });
const [preRef, isIntersecting] = useIntersection(true);
const [tokens] = useAwaiter(async () => {
if (!shikiLang || useHljs || !isIntersecting) return null;
return await shiki.tokenizeCode(content, lang!);
}, {
fallbackValue: null,
deps: [lang, content, currentThemeId, isIntersecting],
});
const themeBase: ThemeBase = {
plainColor: currentTheme?.fg || "var(--text-normal)",
accentBgColor:
currentTheme?.colors?.["statusBar.background"] || (useHljs ? "#7289da" : "#007BC8"),
accentFgColor: currentTheme?.colors?.["statusBar.foreground"] || "#FFF",
backgroundColor:
currentTheme?.colors?.["editor.background"] || "var(--background-secondary)",
};
let langName;
if (lang) langName = useHljs ? hljs?.getLanguage?.(lang)?.name : shikiLang?.name;
const preClasses = [cl("root")];
if (!langName) preClasses.push(cl("plain"));
if (isPreview) preClasses.push(cl("preview"));
return (
{!isPreview && }
);
};