diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d4558d..1c61203 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# [1.4.0-dev.1](https://github.com/revenge-mod/revenge-bundle/compare/v1.3.1...v1.4.0-dev.1) (2024-10-26) + + +### Bug Fixes + +* actually fix improper FAB insets ([e987723](https://github.com/revenge-mod/revenge-bundle/commit/e9877234befc837126f4a24b23c837e7ed8f6b5b)) + + +### Features + +* port ErrorBoundary from dev ([f447910](https://github.com/revenge-mod/revenge-bundle/commit/f44791049a762fbce777b03e9d930fba0c0c6570)) +* **settings/pages/Developer:** show assets types, mark non-previewable assets in AssetBrowser ([b7aacf7](https://github.com/revenge-mod/revenge-bundle/commit/b7aacf734e665a7af613aa5eaae8507ea31be5cd)) + ## [1.3.1](https://github.com/revenge-mod/revenge-bundle/compare/v1.3.0...v1.3.1) (2024-10-23) diff --git a/scripts/build.mjs b/scripts/build.mjs index 47b3513..091e69a 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -20,7 +20,8 @@ const metroDeps = await (async () => { const args = yargs(process.argv.slice(2)); const { "release-branch": releaseBranch, - "build-minify": buildMinify + "build-minify": buildMinify, + "dev": dev } = args; let context = null; @@ -44,7 +45,7 @@ const config = { ".png": "dataurl" }, define: { - __DEV__: JSON.stringify(releaseBranch !== "main") + __DEV__: dev ?? JSON.stringify(releaseBranch !== "main") }, inject: ["./shims/asyncIteratorSymbol.js", "./shims/promiseAllSettled.js"], legalComments: "none", diff --git a/src/core/debug/patches/patchErrorBoundary.tsx b/src/core/debug/patches/patchErrorBoundary.tsx new file mode 100644 index 0000000..ccab32a --- /dev/null +++ b/src/core/debug/patches/patchErrorBoundary.tsx @@ -0,0 +1,21 @@ +import ErrorBoundaryScreen from "@core/ui/reporter/components/ErrorBoundaryScreen"; +import { after } from "@lib/api/patcher"; +import { _lazyContextSymbol } from "@metro/lazy"; +import { LazyModuleContext } from "@metro/types"; +import { findByNameLazy } from "@metro/wrappers"; + +function getErrorBoundaryContext() { + const ctxt: LazyModuleContext = findByNameLazy("ErrorBoundary")[_lazyContextSymbol]; + return new Promise(resolve => ctxt.getExports(exp => resolve(exp.prototype))); +} + +export default function patchErrorBoundary() { + return after.await("render", getErrorBoundaryContext(), function (this: any) { + if (!this.state.error) return; + + return this.setState({ info: null, error: null })} + />; + }); +} diff --git a/src/core/ui/components/AddonPage.tsx b/src/core/ui/components/AddonPage.tsx index 0cfc3d8..21e2e3a 100644 --- a/src/core/ui/components/AddonPage.tsx +++ b/src/core/ui/components/AddonPage.tsx @@ -4,10 +4,10 @@ import { findAssetId } from "@lib/api/assets"; import { settings } from "@lib/api/settings"; import AlertModal, { AlertActionButton } from "@lib/ui/components/wrappers/AlertModal"; import isValidHttpUrl from "@lib/utils/isValidHttpUrl"; -import { lazyDestructure } from "@lib/utils/lazy"; +import { lazyDestructure, proxyLazy } from "@lib/utils/lazy"; import { findByProps } from "@metro"; import { clipboard } from "@metro/common"; -import { Button, FlashList, FloatingActionButton, HelpMessage, IconButton, SafeAreaView, Stack, Text, TextInput } from "@metro/common/components"; +import { Button, FlashList, FloatingActionButton, HelpMessage, IconButton, Stack, Text, TextInput } from "@metro/common/components"; import { ErrorBoundary, Search } from "@ui/components"; import fuzzysort from "fuzzysort"; import { ComponentType, ReactNode, useCallback, useMemo } from "react"; @@ -39,6 +39,8 @@ interface AddonPageProps { ListFooterComponent?: ComponentType; } +const useSafeAreaInsets = proxyLazy(() => findByProps("useSafeAreaInsets").useSafeAreaInsets); + function InputAlert(props: { label: string, fetchFn: (url: string) => Promise; }) { const [value, setValue] = React.useState(""); const [error, setError] = React.useState(""); @@ -111,6 +113,7 @@ export default function AddonPage({ CardComponent, ...props }: const [search, setSearch] = React.useState(""); const [sortFn, setSortFn] = React.useState<((a: unknown, b: unknown) => number) | null>(() => null); + const insets = useSafeAreaInsets(); const results = useMemo(() => { let values = props.items; @@ -198,12 +201,13 @@ export default function AddonPage({ CardComponent, ...props }: renderItem={({ item }: any) => } /> {props.installAction && ( - + - + )} ); diff --git a/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx b/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx new file mode 100644 index 0000000..9c6174b --- /dev/null +++ b/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx @@ -0,0 +1,52 @@ +import { hasStack, isComponentStack } from "@core/ui/reporter/utils/isStack"; +import { getDebugInfo, toggleSafeMode } from "@lib/api/debug"; +import { BundleUpdaterManager } from "@lib/api/native/modules"; +import { settings } from "@lib/api/settings"; +import { Codeblock, ErrorBoundary } from "@lib/ui/components"; +import { createStyles } from "@lib/ui/styles"; +import { tokens } from "@metro/common"; +import { Button, Card, SafeAreaView, Text } from "@metro/common/components"; +import { ScrollView, View } from "react-native"; + +import ErrorComponentStackCard from "./ErrorComponentStackCard"; +import ErrorStackCard from "./ErrorStackCard"; + +const useStyles = createStyles({ + container: { + flex: 1, + backgroundColor: tokens.colors.BG_BASE_SECONDARY, + paddingHorizontal: 16, + height: "100%", + padding: 8, + gap: 12 + } +}); + + +export default function ErrorBoundaryScreen(props: { + error: Error; + rerender: () => void; +}) { + const styles = useStyles(); + const debugInfo = getDebugInfo(); + + return + + + Uh oh. + A crash occured while rendering a component. This could be caused by a plugin, Bunny or Discord itself. + {debugInfo.os.name}; {debugInfo.discord.build} ({debugInfo.discord.version}); {debugInfo.bunny.version} + + + {props.error.message} + {hasStack(props.error) && } + {isComponentStack(props.error) ? : null} + + +