diff --git a/package.json b/package.json index 70ba619..a6b1648 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "license": "BSD-3-Clause", "devDependencies": { "@react-native-clipboard/clipboard": "1.10.0", + "@shopify/react-native-skia": "^1.3.0", "@swc/core": "^1.4.17", "@swc/helpers": "^0.5.11", "@types/chroma-js": "~2.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e7b1ed..1d64cfa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,6 +19,9 @@ devDependencies: '@react-native-clipboard/clipboard': specifier: 1.10.0 version: 1.10.0 + '@shopify/react-native-skia': + specifier: ^1.3.0 + version: 1.3.0 '@swc/core': specifier: ^1.4.17 version: 1.4.17(@swc/helpers@0.5.11) @@ -436,6 +439,25 @@ packages: nullthrows: 1.1.1 dev: true + /@shopify/react-native-skia@1.3.0: + resolution: {integrity: sha512-TsQM6e9Cb8V2dukFwdjVurpynb1Avw3mxl6DZCLqDugGaVOCoWIkcJWPQEW62uXN/qumJ0dFOCKaXudo+Y4Z4A==} + hasBin: true + peerDependencies: + react: '>=18.0' + react-native: '>=0.64' + react-native-reanimated: '>=2.0.0' + peerDependenciesMeta: + react: + optional: true + react-native: + optional: true + react-native-reanimated: + optional: true + dependencies: + canvaskit-wasm: 0.39.1 + react-reconciler: 0.27.0 + dev: true + /@swc/core-darwin-arm64@1.4.17: resolution: {integrity: sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw==} engines: {node: '>=10'} @@ -753,6 +775,10 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true + /@webgpu/types@0.1.21: + resolution: {integrity: sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==} + dev: true + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -933,6 +959,12 @@ packages: engines: {node: '>=6'} dev: true + /canvaskit-wasm@0.39.1: + resolution: {integrity: sha512-Gy3lCmhUdKq+8bvDrs9t8+qf7RvcjuQn+we7vTVVyqgOVO1UVfHpsnBxkTZw+R4ApEJ3D5fKySl9TU11hmjl/A==} + dependencies: + '@webgpu/types': 0.1.21 + dev: true + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -2033,6 +2065,19 @@ packages: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true + /react-reconciler@0.27.0: + resolution: {integrity: sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==} + engines: {node: '>=0.10.0'} + peerDependencies: + react: ^18.0.0 + peerDependenciesMeta: + react: + optional: true + dependencies: + loose-envify: 1.4.0 + scheduler: 0.21.0 + dev: true + /reflect.getprototypeof@1.0.5: resolution: {integrity: sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==} engines: {node: '>= 0.4'} @@ -2107,6 +2152,12 @@ packages: is-regex: 1.1.4 dev: true + /scheduler@0.21.0: + resolution: {integrity: sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==} + dependencies: + loose-envify: 1.4.0 + dev: true + /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true diff --git a/src/core/ui/settings/pages/Fonts/FontCard.tsx b/src/core/ui/settings/pages/Fonts/FontCard.tsx index e1b4f3e..bc5a4d9 100644 --- a/src/core/ui/settings/pages/Fonts/FontCard.tsx +++ b/src/core/ui/settings/pages/Fonts/FontCard.tsx @@ -1,39 +1,117 @@ import { Strings } from "@core/i18n"; import { CardWrapper } from "@core/ui/components/AddonCard"; -import { RemoveModeContext } from "@core/ui/components/AddonPage"; import { requireAssetIndex } from "@lib/api/assets"; +import { BundleUpdaterManager } from "@lib/api/native/modules"; import { useProxy } from "@lib/api/storage"; -import { FontDefinition, fonts, removeFont, selectFont } from "@lib/managers/fonts"; -import { FormCheckbox, IconButton, TableRow, TableRowGroup } from "@metro/common/components"; -import { showToast } from "@ui/toasts"; -import { useContext } from "react"; -import { Pressable, View } from "react-native"; +import { FontDefinition, fonts, selectFont } from "@lib/managers/fonts"; +import { showConfirmationAlert } from "@lib/ui/alerts"; +import { TextStyleSheet } from "@lib/ui/styles"; +import { lazyDestructure } from "@lib/utils/lazy"; +import { ButtonColors } from "@lib/utils/types"; +import { findByProps } from "@metro"; +import { NavigationNative, Skia, tokens } from "@metro/common"; +import { Button, Card, IconButton, Stack, Text } from "@metro/common/components"; +import { useMemo } from "react"; +import { View } from "react-native"; -export default function FontCard({ item: font, index }: CardWrapper) { +import FontEditor from "./FontEditor"; + +const { useToken } = lazyDestructure(() => findByProps("useToken")); + +function FontPreview({ font }: { font: FontDefinition; }) { + const TEXT_NORMAL = useToken(tokens.colors.TEXT_NORMAL); + const { fontFamily: fontFamilyList, fontSize } = TextStyleSheet["text-md/medium"]; + const fontFamily = fontFamilyList!.split(/,/g)[0]; + const typeface = Skia.useFont(font.main[fontFamily])?.getTypeface(); + + const paragraph = useMemo(() => { + if (!typeface) return null; + + const fMgr = SkiaApi.TypefaceFontProvider.Make(); + fMgr.registerFont(typeface, fontFamily); + + + return SkiaApi.ParagraphBuilder.Make({}, fMgr) + .pushStyle({ + color: SkiaApi.Color(TEXT_NORMAL), + 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... + + } + + ); +} + +export default function FontCard({ item: font }: CardWrapper) { useProxy(fonts); - const removeMode = useContext(RemoveModeContext); + const navigation = NavigationNative.useNavigation(); const selected = fonts.__selected === font.name; - return - - { - selectFont(selected ? null : font.name).then(() => { - showToast(Strings.RESTART_REQUIRED_TO_TAKE_EFFECT, requireAssetIndex("WarningIcon")); - }); - }}> - {!removeMode ? : removeFont(font.name)} - />} - - } - /> - - ; + return ( + + + + + + {font.name} + + {/* TODO: Text wrapping doesn't work well */} + {/* + {font.description} + */} + + + + { + navigation.push("VendettaCustomPage", { + title: "Edit Font", + render: () => + }); + }} + size="sm" + variant="secondary" + disabled={selected} + icon={requireAssetIndex("PencilIcon")} + /> +