From a0d0823deff7268f514616bd75d4b0a2c35cc84b Mon Sep 17 00:00:00 2001
From: vMohammad <62218284+vMohammad24@users.noreply.github.com>
Date: Wed, 12 Feb 2025 22:18:51 +0300
Subject: [PATCH] feat(refactor): fontLoader (#148)
---
src/equicordplugins/FontLoader/index.tsx | 96 +++++++++---------------
1 file changed, 34 insertions(+), 62 deletions(-)
diff --git a/src/equicordplugins/FontLoader/index.tsx b/src/equicordplugins/FontLoader/index.tsx
index a934acfb..283b9adf 100644
--- a/src/equicordplugins/FontLoader/index.tsx
+++ b/src/equicordplugins/FontLoader/index.tsx
@@ -13,6 +13,7 @@ import { Margins } from "@utils/margins";
import { classes } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import { Card, Forms, React, TextInput } from "@webpack/common";
+
interface GoogleFontMetadata {
family: string;
displayName: string;
@@ -27,7 +28,15 @@ interface GoogleFontMetadata {
}>;
}>;
}
-const userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome / 128.0.0.0 Safari / 537.36";
+
+const createGoogleFontUrl = (family: string, options = "") =>
+ `https://fonts.googleapis.com/css2?family=${encodeURIComponent(family)}${options}&display=swap`;
+
+const loadFontStyle = (url: string) => {
+ document.head.insertAdjacentHTML("beforeend", ``);
+ return document.createElement("style");
+};
+
async function searchGoogleFonts(query: string) {
try {
const response = await fetch("https://fonts.google.com/$rpc/fonts.fe.catalog.actions.metadata.MetadataService/FontSearch", {
@@ -36,14 +45,12 @@ async function searchGoogleFonts(query: string) {
"content-type": "application/json+protobuf",
"x-user-agent": "grpc-web-javascript/0.1"
},
- // the nulls are optional filters
body: JSON.stringify([[query, null, null, null, null, null, 1], [5], null, 16])
});
const data = await response.json();
if (!data?.[1]) return [];
- // god please help me
- const fonts = data[1].map(([_, fontData]: [string, any[]]) => ({
+ return data[1].map(([_, fontData]: [string, any[]]) => ({
family: fontData[0],
displayName: fontData[1],
authors: fontData[2],
@@ -54,81 +61,52 @@ async function searchGoogleFonts(query: string) {
}))
}))
}));
- return fonts;
- // LETS GO IT FUCKING WORKSSSSSSSSSSSS
} catch (err) {
console.error("Failed to fetch fonts:", err);
return [];
}
}
-async function preloadFont(family: string) {
- // https://developers.google.com/fonts/docs/css2
- const url = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(family)}&text=The quick brown fox jumps over the lazy dog&display=swap`;
- const css = await fetch(url, {
- headers: {
- "User-Agent": userAgent
- }
- }).then(r => r.text());
+const preloadFont = (family: string) =>
+ loadFontStyle(createGoogleFontUrl(family, "&text=The quick brown fox jumps over the lazy dog"));
- const style = document.createElement("style");
- style.textContent = css;
- document.head.appendChild(style);
- return style;
-}
+let styleElement: HTMLStyleElement | null = null;
-async function applyFont(fontFamily: string) {
+const applyFont = async (fontFamily: string) => {
if (!fontFamily) {
- if (styleElement) {
- styleElement.remove();
- styleElement = null;
- }
+ styleElement?.remove();
+ styleElement = null;
return;
}
try {
- const response = await fetch(
- `https://fonts.googleapis.com/css2?family=${encodeURIComponent(fontFamily)}:wght@300;400;500;600;700&display=swap`,
- {
- headers: {
- "User-Agent": userAgent
- }
- }
- );
- const css = await response.text();
-
if (!styleElement) {
styleElement = document.createElement("style");
document.head.appendChild(styleElement);
}
+ loadFontStyle(createGoogleFontUrl(fontFamily, ":wght@300;400;500;600;700"));
styleElement.textContent = `
- ${css}
- * {
- --font-primary: '${fontFamily}', sans-serif !important;
- --font-display: '${fontFamily}', sans-serif !important;
- --font-headline: '${fontFamily}', sans-serif !important;
- --font-code: '${fontFamily}', monospace !important;
- }
- `;
+ * {
+ --font-primary: '${fontFamily}', sans-serif !important;
+ --font-display: '${fontFamily}', sans-serif !important;
+ --font-headline: '${fontFamily}', sans-serif !important;
+ --font-code: '${fontFamily}', monospace !important;
+ }
+ `;
} catch (err) {
console.error("Failed to load font:", err);
}
-}
+};
function GoogleFontSearch({ onSelect }: { onSelect: (font: GoogleFontMetadata) => void; }) {
const [query, setQuery] = React.useState("");
const [results, setResults] = React.useState([]);
const [loading, setLoading] = React.useState(false);
-
-
const previewStyles = React.useRef([]);
-
- React.useEffect(() => {
- return () => {
- previewStyles.current.forEach(style => style.remove());
- };
+ React.useEffect(() => () => {
+ previewStyles.current.forEach(style => style.remove());
}, []);
const debouncedSearch = debounce(async (value: string) => {
@@ -138,22 +116,18 @@ function GoogleFontSearch({ onSelect }: { onSelect: (font: GoogleFontMetadata) =
setLoading(false);
return;
}
+
const fonts = await searchGoogleFonts(value);
-
previewStyles.current.forEach(style => style.remove());
- previewStyles.current = [];
-
- const styles = await Promise.all(fonts.map(f => preloadFont(f.family)));
- previewStyles.current = styles;
-
+ previewStyles.current = await Promise.all(fonts.map(f => preloadFont(f.family)));
setResults(fonts);
setLoading(false);
}, 300);
- const handleSearch = React.useCallback((value: string) => {
- setQuery(value);
- debouncedSearch(value);
- }, []);
+ const handleSearch = (e: string) => {
+ setQuery(e);
+ debouncedSearch(e);
+ };
return (
@@ -193,8 +167,6 @@ function GoogleFontSearch({ onSelect }: { onSelect: (font: GoogleFontMetadata) =
);
}
-let styleElement: HTMLStyleElement | null = null;
-
const settings = definePluginSettings({
selectedFont: {
type: OptionType.STRING,