hopefully fix iOS crash??

I guess no, but eh
This commit is contained in:
kmmiio99o 2025-12-26 18:55:53 +01:00
parent c8bd5a4303
commit 2ee516b5fd
No known key found for this signature in database
GPG key ID: 163FE39F7772D2EC
5 changed files with 40 additions and 177 deletions

View file

@ -1,7 +1,3 @@
{ {
"languages": { "format_on_save": "off",
"TypeScript": {
"format_on_save": "off"
}
}
} }

View file

@ -17,6 +17,7 @@
"react-devtools": "^7.0.1", "react-devtools": "^7.0.1",
"react-native": "0.83.1", "react-native": "0.83.1",
"react-native-reanimated": "^4.2.1", "react-native-reanimated": "^4.2.1",
"react-native-webview": "^13.16.0",
"spitroast": "^2.1.6", "spitroast": "^2.1.6",
"type-fest": "^5.3.1", "type-fest": "^5.3.1",
}, },
@ -1366,6 +1367,8 @@
"react-native-reanimated": ["react-native-reanimated@4.2.1", "", { "dependencies": { "react-native-is-edge-to-edge": "1.2.1", "semver": "7.7.3" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-worklets": ">=0.7.0" } }, "sha512-/NcHnZMyOvsD/wYXug/YqSKw90P9edN0kEPL5lP4PFf1aQ4F1V7MKe/E0tvfkXKIajy3Qocp5EiEnlcrK/+BZg=="], "react-native-reanimated": ["react-native-reanimated@4.2.1", "", { "dependencies": { "react-native-is-edge-to-edge": "1.2.1", "semver": "7.7.3" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-worklets": ">=0.7.0" } }, "sha512-/NcHnZMyOvsD/wYXug/YqSKw90P9edN0kEPL5lP4PFf1aQ4F1V7MKe/E0tvfkXKIajy3Qocp5EiEnlcrK/+BZg=="],
"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-native-worklets": ["react-native-worklets@0.6.1", "", { "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", "semver": "7.7.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, ""], "react-native-worklets": ["react-native-worklets@0.6.1", "", { "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", "semver": "7.7.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, ""],
"react-refresh": ["react-refresh@0.14.2", "", {}, ""], "react-refresh": ["react-refresh@0.14.2", "", {}, ""],
@ -1708,7 +1711,7 @@
"@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], "@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="],
"@electron/get/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@electron/get/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, ""],
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, ""], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, ""],
@ -1832,6 +1835,8 @@
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, ""], "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, ""],
"fdir/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
"finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, ""], "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, ""],
"finalhandler/encodeurl": ["encodeurl@1.0.2", "", {}, ""], "finalhandler/encodeurl": ["encodeurl@1.0.2", "", {}, ""],
@ -2256,7 +2261,7 @@
"send/statuses": ["statuses@2.0.1", "", {}, ""], "send/statuses": ["statuses@2.0.1", "", {}, ""],
"signale/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, ""], "signale/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
"signale/figures": ["figures@2.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, ""], "signale/figures": ["figures@2.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, ""],
@ -2504,8 +2509,6 @@
"react-devtools/cross-spawn/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": "bin/which" }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="], "react-devtools/cross-spawn/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": "bin/which" }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="],
"react-native/react-devtools-core/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, ""],
"react-native/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, ""], "react-native/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, ""],
"react-native/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, ""], "react-native/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, ""],
@ -2534,13 +2537,13 @@
"send/debug/ms": ["ms@2.0.0", "", {}, ""], "send/debug/ms": ["ms@2.0.0", "", {}, ""],
"signale/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, ""], "signale/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
"signale/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, ""], "signale/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
"signale/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, ""], "signale/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
"signale/figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, ""], "signale/figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
"term-size/execa/cross-spawn": ["cross-spawn@5.1.0", "", { "dependencies": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A=="], "term-size/execa/cross-spawn": ["cross-spawn@5.1.0", "", { "dependencies": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A=="],
@ -2720,9 +2723,9 @@
"semantic-release/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, ""], "semantic-release/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, ""],
"signale/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, ""], "signale/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
"signale/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, ""], "signale/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
"term-size/execa/cross-spawn/lru-cache": ["lru-cache@4.1.5", "", { "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="], "term-size/execa/cross-spawn/lru-cache": ["lru-cache@4.1.5", "", { "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="],
@ -2806,9 +2809,7 @@
"read-pkg-up/read-pkg/normalize-package-data/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, ""], "read-pkg-up/read-pkg/normalize-package-data/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, ""],
"signale/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, ""], "signale/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
"term-size/execa/cross-spawn/lru-cache/yallist": ["yallist@2.1.2", "", {}, "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="],
"term-size/execa/cross-spawn/shebang-command/shebang-regex": ["shebang-regex@1.0.0", "", {}, "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="], "term-size/execa/cross-spawn/shebang-command/shebang-regex": ["shebang-regex@1.0.0", "", {}, "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="],
@ -2826,10 +2827,6 @@
"@saithodev/semantic-release-backmerge/semantic-release/@semantic-release/github/@octokit/plugin-throttling/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@20.0.0", "", {}, ""], "@saithodev/semantic-release-backmerge/semantic-release/@semantic-release/github/@octokit/plugin-throttling/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@20.0.0", "", {}, ""],
"@saithodev/semantic-release-backmerge/semantic-release/@semantic-release/npm/read-pkg/normalize-package-data/hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, ""],
"@semantic-release/release-notes-generator/read-package-up/read-pkg/normalize-package-data/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, ""], "@semantic-release/release-notes-generator/read-package-up/read-pkg/normalize-package-data/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, ""],
"@saithodev/semantic-release-backmerge/semantic-release/@semantic-release/npm/read-pkg/normalize-package-data/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, ""],
} }
} }

View file

@ -49,6 +49,7 @@
"react-devtools": "^7.0.1", "react-devtools": "^7.0.1",
"react-native": "0.83.1", "react-native": "0.83.1",
"react-native-reanimated": "^4.2.1", "react-native-reanimated": "^4.2.1",
"react-native-webview": "^13.16.0",
"spitroast": "^2.1.6", "spitroast": "^2.1.6",
"type-fest": "^5.3.1" "type-fest": "^5.3.1"
}, },

View file

@ -22,14 +22,13 @@ import {
} from "@metro/common/components"; } from "@metro/common/components";
import { ErrorBoundary, Search } from "@ui/components"; import { ErrorBoundary, Search } from "@ui/components";
import { isNotNil } from "es-toolkit"; import { isNotNil } from "es-toolkit";
import fuzzysort from "fuzzysort";
import { import {
ComponentType, ComponentType,
ReactNode, ReactNode,
useCallback, useCallback,
useEffect, useEffect,
useMemo, useMemo,
useRef,
useState,
} from "react"; } from "react";
import { Image, ScrollView, View } from "react-native"; import { Image, ScrollView, View } from "react-native";
@ -199,27 +198,6 @@ export default function AddonPage<T extends object>({
} }
}, [navigation]); }, [navigation]);
const fuzzysortRef = useRef<any>(null);
const [fuzzLoaded, setFuzzLoaded] = useState(false);
useEffect(() => {
let cancelled = false;
if (!fuzzysortRef.current) {
import("fuzzysort")
.then((m) => {
if (cancelled) return;
fuzzysortRef.current = m.default || m;
setFuzzLoaded(true);
})
.catch(() => {
// ignore dynamic import failures; we'll fallback to simple filtering
});
}
return () => {
cancelled = true;
};
}, []);
const results = useMemo(() => { const results = useMemo(() => {
let values = props.items; let values = props.items;
if (props.resolveItem) if (props.resolveItem)
@ -227,84 +205,11 @@ export default function AddonPage<T extends object>({
const items = values.filter((i) => isNotNil(i) && typeof i === "object"); const items = values.filter((i) => isNotNil(i) && typeof i === "object");
if (!search && sortFn) items.sort(sortFn); if (!search && sortFn) items.sort(sortFn);
// Prefer fuzzysort when loaded and a search query exists return fuzzysort.go(search, items, {
if (fuzzysortRef.current && search) { keys: props.searchKeywords,
try { all: true,
return fuzzysortRef.current.go(search, items, {
keys: props.searchKeywords,
all: true,
});
} catch {
// If fuzzysort throws for some reason, fall back to the simple filter below
}
}
// If there is no search query, return items shaped similarly to fuzzysort results
const makeFallbackResult = (obj: any, keys: any[]) => {
const r: any = { obj };
// current search query in the outer scope; only highlight when there's an active query
const q = String(search ?? "")
.toLowerCase()
.trim();
for (let k = 0; k < keys.length; k++) {
const key = keys[k];
let text = "";
try {
text =
typeof key === "string" ? String(obj[key] ?? "") : String(key(obj));
} catch {
text = "";
}
r[k] = {
target: text,
highlight: (cb: any) => {
// Do not highlight anything when there is no active search.
if (!q) return [];
const lower = text.toLowerCase();
const idx = lower.indexOf(q);
if (idx === -1) return [];
// Split into before/match/after and invoke the callback for each segment so
// consumers can render matched substring(s) with highlight styling while
// preserving surrounding context.
const parts: any[] = [];
let i = 0;
const before = text.slice(0, idx);
const match = text.slice(idx, idx + q.length);
const after = text.slice(idx + q.length);
if (before) parts.push(cb(before, i++));
parts.push(cb(match, i++));
if (after) parts.push(cb(after, i++));
return parts;
},
};
}
return r;
};
if (!search) {
return items.map((obj: any) =>
makeFallbackResult(obj, props.searchKeywords),
);
}
// Basic fallback: case-insensitive substring match across configured keys
const q = String(search).toLowerCase();
const filtered = items.filter((it: any) => {
for (const key of props.searchKeywords) {
try {
const text =
typeof key === "string" ? String(it[key] ?? "") : String(key(it));
if (text.toLowerCase().includes(q)) return true;
} catch {
// ignore any accessor errors and continue
}
}
return false;
}); });
}, [props.items, sortFn, search]);
return filtered.map((obj: any) =>
makeFallbackResult(obj, props.searchKeywords),
);
}, [props.items, sortFn, search, fuzzLoaded]);
const onInstallPress = useCallback(() => { const onInstallPress = useCallback(() => {
if (!props.installAction) return () => {}; if (!props.installAction) return () => {};

View file

@ -16,8 +16,9 @@ import {
Text, Text,
} from "@metro/common/components"; } from "@metro/common/components";
import { findByProps } from "@metro"; import { findByProps } from "@metro";
import { useMemo, useState, useEffect } from "react"; import { useMemo, useState } from "react";
import { PixelRatio, View } from "react-native"; import { PixelRatio, View } from "react-native";
import { WebView } from "react-native-webview";
import previewHtml from "./preview.html"; import previewHtml from "./preview.html";
import FontEditor from "./FontEditor"; import FontEditor from "./FontEditor";
@ -35,7 +36,6 @@ const useStyles = createStyles({
function FontPreview({ font }: { font: FontDefinition }) { function FontPreview({ font }: { font: FontDefinition }) {
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
const [WebViewComponent, setWebViewComponent] = useState<any>(null);
const styles = useStyles(); const styles = useStyles();
const TEXT_DEFAULT = useToken(tokens.colors.TEXT_DEFAULT); const TEXT_DEFAULT = useToken(tokens.colors.TEXT_DEFAULT);
@ -53,61 +53,25 @@ function FontPreview({ font }: { font: FontDefinition }) {
[font.main, fontFamily, fontSize, TEXT_DEFAULT], [font.main, fontFamily, fontSize, TEXT_DEFAULT],
); );
// Memoize generated HTML to avoid string replacement on every render
const html = useMemo(
() => previewHtml.replace("$$props", JSON.stringify(props)),
[props],
);
// Lazy-load the WebView implementation so it's not included in the main bundle
useEffect(() => {
let cancelled = false;
import("react-native-webview")
.then((m) => {
if (cancelled) return;
// support both default export and named WebView export
setWebViewComponent(m.WebView || m.default || m);
})
.catch(() => {
// ignore dynamic import failures; component will show placeholder
});
return () => {
cancelled = true;
};
}, []);
return ( return (
<View style={{ width: "100%", height: 64 }}> <View style={{ width: "100%", height: 64 }}>
{WebViewComponent ? ( <WebView
<> onMessage={() => setLoaded(true)}
<WebViewComponent source={{
onMessage={() => setLoaded(true)} html: previewHtml.replace("$$props", JSON.stringify(props)),
source={{ html }} }}
javaScriptEnabled javaScriptEnabled
scrollEnabled={false} scrollEnabled={false}
overScrollMode="never" overScrollMode="never"
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
pointerEvents="none" pointerEvents="none"
style={[ style={[
styles.full, styles.full,
{ backgroundColor: "transparent", opacity: Number(loaded) }, { backgroundColor: "transparent", opacity: Number(loaded) },
]} ]}
/> />
{!loaded && ( {!loaded && (
<View
style={[
styles.full,
{ justifyContent: "center", alignItems: "center" },
]}
>
<Text color="text-muted" variant="heading-lg/semibold">
Loading...
</Text>
</View>
)}
</>
) : (
<View <View
style={[ style={[
styles.full, styles.full,