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")} - /> -