diff --git a/bun.lock b/bun.lock
index f3d769c..18ea68d 100644
--- a/bun.lock
+++ b/bun.lock
@@ -16,6 +16,7 @@
"moment": "2.22.2",
"react-native": "0.78.0",
"react-native-reanimated": "^3.18.0",
+ "react-native-webview": "^13.16.0",
"spitroast": "^1.4.4",
"type-fest": "^4.41.0",
},
@@ -1407,6 +1408,8 @@
"react-native-reanimated": ["react-native-reanimated@3.19.0", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-class-properties": "^7.0.0-0", "@babel/plugin-transform-classes": "^7.0.0-0", "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", "@babel/plugin-transform-optional-chaining": "^7.0.0-0", "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", "@babel/plugin-transform-template-literals": "^7.0.0-0", "@babel/plugin-transform-unicode-regex": "^7.0.0-0", "@babel/preset-typescript": "^7.16.7", "convert-source-map": "^2.0.0", "invariant": "^2.2.4", "react-native-is-edge-to-edge": "1.1.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, "sha512-FNfqLuPuVHsW9KcsZtnJqIPlMQvuySnSFJXgSt9fVDPqptbSUkiAF6MthUwd4Mxt05hCRcbV+T65CENgVS5iCg=="],
+ "react-native-webview": ["react-native-webview@13.16.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0", "invariant": "2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-Nh13xKZWW35C0dbOskD7OX01nQQavOzHbCw9XoZmar4eXCo7AvrYJ0jlUfRVVIJzqINxHlpECYLdmAdFsl9xDA=="],
+
"react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="],
"read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="],
diff --git a/package.json b/package.json
index 15930e8..9473c83 100644
--- a/package.json
+++ b/package.json
@@ -48,6 +48,7 @@
"moment": "2.22.2",
"react-native": "0.78.0",
"react-native-reanimated": "^3.18.0",
+ "react-native-webview": "^13.16.0",
"spitroast": "^1.4.4",
"type-fest": "^4.41.0"
},
diff --git a/scripts/build.mjs b/scripts/build.mjs
index 5687fea..51d0948 100644
--- a/scripts/build.mjs
+++ b/scripts/build.mjs
@@ -44,6 +44,7 @@ const config = {
},
loader: {
".png": "dataurl",
+ ".html": "text",
},
define: {
window: "globalThis",
diff --git a/shims/depsModule.ts b/shims/depsModule.ts
index 63ef118..54c516c 100644
--- a/shims/depsModule.ts
+++ b/shims/depsModule.ts
@@ -6,6 +6,6 @@ module.exports = {
"util": findByPropsLazy("inspect", "isNullOrUndefined"),
"moment": findByPropsLazy("isMoment"),
"chroma-js": findByPropsLazy("brewer"),
- "lodash": findByPropsLazy("forEachRight")
-// "@shopify/react-native-skia": findByPropsLazy("useFont")
+ "lodash": findByPropsLazy("forEachRight"),
+ "react-native-webview": findByPropsLazy("WebView")
};
diff --git a/src/core/ui/settings/pages/Fonts/FontCard.tsx b/src/core/ui/settings/pages/Fonts/FontCard.tsx
index 339b90d..d2442a5 100644
--- a/src/core/ui/settings/pages/Fonts/FontCard.tsx
+++ b/src/core/ui/settings/pages/Fonts/FontCard.tsx
@@ -4,115 +4,141 @@ import { showConfirmationAlert } from "@core/vendetta/alerts";
import { useProxy } from "@core/vendetta/storage";
import { FontDefinition, fonts, selectFont } from "@lib/addons/fonts";
import { findAssetId } from "@lib/api/assets";
-import { BundleUpdaterManager } from "@lib/api/native/modules";
import { lazyDestructure } from "@lib/utils/lazy";
-import { findByProps } from "@metro";
+import { BundleUpdaterManager } from "@lib/api/native/modules";
+import { createStyles, TextStyleSheet } from "@lib/ui/styles";
import { NavigationNative, tokens } from "@metro/common";
-import { Button, Card, IconButton, Stack, Text } from "@metro/common/components";
-import * as Skia from "@shopify/react-native-skia";
-import { TextStyleSheet } from "@ui/styles";
-import { useMemo } from "react";
-import { View } from "react-native";
+import {
+ Button,
+ Card,
+ IconButton,
+ Stack,
+ Text,
+} from "@metro/common/components";
+import { findByProps } from "@metro";
+import { useMemo, useState } from "react";
+import { PixelRatio, View } from "react-native";
+import { WebView } from "react-native-webview";
+import previewHtml from "./preview.html";
import FontEditor from "./FontEditor";
const { useToken } = lazyDestructure(() => findByProps("useToken"));
-function FontPreview({ font }: { font: FontDefinition; }) {
- const TEXT_DEFAULT = useToken(tokens.colors.TEXT_DEFAULT);
- const { fontFamily: fontFamilyList, fontSize } = TextStyleSheet["text-md/medium"];
- const fontFamily = fontFamilyList!.split(/,/g)[0];
+const useStyles = createStyles({
+ full: {
+ position: "absolute",
+ inset: 0,
+ width: "100%",
+ height: "100%",
+ },
+});
- const typeface = Skia.useFont(font.main[fontFamily])?.getTypeface();
+function FontPreview({ font }: { font: FontDefinition }) {
+ const [loaded, setLoaded] = useState(false);
+ const styles = useStyles();
- const paragraph = useMemo(() => {
- if (!typeface) return null;
+ const TEXT_DEFAULT = useToken(tokens.colors.TEXT_DEFAULT);
+ const { fontFamily: fontFamilyList, fontSize } =
+ TextStyleSheet["text-md/medium"];
+ const fontFamily = fontFamilyList!.split(/,/g)[0];
- const fMgr = SkiaApi.TypefaceFontProvider.Make();
- fMgr.registerFont(typeface, fontFamily);
+ const props = useMemo(
+ () => ({
+ family: font.main[fontFamily],
+ size: fontSize! * PixelRatio.getFontScale(),
+ color: TEXT_DEFAULT,
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
+ }),
+ [font.main, fontFamily, fontSize, TEXT_DEFAULT],
+ );
-
- return SkiaApi.ParagraphBuilder.Make({}, fMgr)
- .pushStyle({
- color: SkiaApi.Color(TEXT_DEFAULT),
- fontFamilies: [fontFamily],
- fontSize,
- })
- .addText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
- .pop()
- .build();
- }, [typeface]);
-
- return (
- // This does not work, actually :woeis:
-
- {typeface
- ?
-
-
- :
-
- Loading...
-
- }
+ return (
+
+ setLoaded(true)}
+ source={{
+ html: previewHtml.replace("$$props", JSON.stringify(props)),
+ }}
+ javaScriptEnabled
+ scrollEnabled={false}
+ overScrollMode="never"
+ showsHorizontalScrollIndicator={false}
+ showsVerticalScrollIndicator={false}
+ pointerEvents="none"
+ style={[
+ styles.full,
+ { backgroundColor: "transparent", opacity: Number(loaded) },
+ ]}
+ />
+ {!loaded && (
+
+
+ Loading...
+
- );
+ )}
+
+ );
}
export default function FontCard({ item: font }: CardWrapper) {
- useProxy(fonts);
+ useProxy(fonts);
- const navigation = NavigationNative.useNavigation();
- const selected = fonts.__selected === font.name;
+ const navigation = NavigationNative.useNavigation();
+ const selected = fonts.__selected === font.name;
- return (
-
-
-
-
-
- {font.name}
-
- {/* TODO: Text wrapping doesn't work well */}
- {/*
+ return (
+
+
+
+
+ {font.name}
+ {/* TODO: Text wrapping doesn't work well */}
+ {/*
{font.description}
*/}
-
-
-
- {
- navigation.push("BUNNY_CUSTOM_PAGE", {
- title: "Edit Font",
- render: () =>
- });
- }}
- size="sm"
- variant="secondary"
- disabled={selected}
- icon={findAssetId("WrenchIcon")}
- />
-
-
-
-
+
+
+
+ {
+ navigation.push("BUNNY_CUSTOM_PAGE", {
+ title: "Edit Font",
+ render: () => ,
+ });
+ }}
+ size="sm"
+ variant="secondary"
+ disabled={selected}
+ icon={findAssetId("WrenchIcon")}
+ />
+
-
- );
-}
\ No newline at end of file
+
+
+
+
+
+ );
+}
diff --git a/src/core/ui/settings/pages/General/index.tsx b/src/core/ui/settings/pages/General/index.tsx
index 267c1ba..8a5bef0 100644
--- a/src/core/ui/settings/pages/General/index.tsx
+++ b/src/core/ui/settings/pages/General/index.tsx
@@ -79,7 +79,7 @@ export default function General() {
diff --git a/src/global.d.ts b/src/global.d.ts
index d8d38b4..f47e860 100644
--- a/src/global.d.ts
+++ b/src/global.d.ts
@@ -1,18 +1,17 @@
declare global {
- type React = typeof import("react");
- var SkiaApi: typeof import("@shopify/react-native-skia").Skia;
+ type React = typeof import("react");
- // ReactNative/Hermes globals
- var globalEvalWithSourceUrl: (script: string, sourceURL: string) => any;
- var nativePerformanceNow: typeof performance.now;
- var nativeModuleProxy: Record;
- var __turboModuleProxy: (name: string) => any;
+ // ReactNative/Hermes globals
+ var globalEvalWithSourceUrl: (script: string, sourceURL: string) => any;
+ var nativePerformanceNow: typeof performance.now;
+ var nativeModuleProxy: Record;
+ var __turboModuleProxy: (name: string) => any;
- interface Window {
- [key: string]: any;
- vendetta: any;
- bunny: typeof import("@lib");
- }
+ interface Window {
+ [key: string]: any;
+ vendetta: any;
+ bunny: typeof import("@lib");
+ }
}
export { };