diff --git a/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx b/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx index 512cec6..9e290b0 100644 --- a/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx +++ b/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx @@ -1,5 +1,6 @@ import React from "react"; import { hasStack, isComponentStack } from "@core/ui/reporter/utils/isStack"; +import parseErrorStack from "@core/ui/reporter/utils/parseErrorStack"; import { getDebugInfo, toggleSafeMode } from "@lib/api/debug"; import { BundleUpdaterManager } from "@lib/api/native/modules"; import { settings } from "@lib/api/settings"; @@ -9,201 +10,119 @@ import { tokens } from "@metro/common"; import { showToast } from "@lib/ui/toasts"; import { Button, + Card, SafeAreaProvider, SafeAreaView, Text, TableRowGroup, TableRow, + TableSwitchRow, + Stack, } from "@metro/common/components"; -import { ScrollView, View, Clipboard } from "react-native"; +import { ScrollView, View } from "react-native"; import ErrorComponentStackCard from "./ErrorComponentStackCard"; import ErrorStackCard from "./ErrorStackCard"; +import { NavigationNative } from "@metro/common"; -const useStyles = createStyles(() => ({ +const useStyles = createStyles({ container: { flex: 1, backgroundColor: tokens.colors.BG_BASE_SECONDARY, + paddingHorizontal: 16, + height: "100%", + gap: 12, }, - scrollContent: { - paddingBottom: 100, // Extra space for fixed buttons - }, - header: { - alignItems: "center", - paddingVertical: 32, - backgroundColor: tokens.colors.BG_BASE_SECONDARY, - }, - headerText: { - textAlign: "center", - marginBottom: 8, - }, - debugInfo: { - fontSize: 12, - color: tokens.colors.TEXT_MUTED, - textAlign: "center", - marginTop: 8, - }, - section: { - marginHorizontal: 16, - marginBottom: 12, - }, - fixedButtonContainer: { - position: "absolute", - bottom: 0, - left: 0, - right: 0, - backgroundColor: tokens.colors.BG_MOD_STRONG, - padding: 16, - gap: 8, - }, - buttonRow: { - flexDirection: "row", - gap: 8, - }, - fullButton: { - flex: 1, - }, - errorMessageRow: { - backgroundColor: tokens.colors.BG_MOD_FAINT, - borderRadius: 8, - marginVertical: 4, - overflow: "hidden", - }, - centeredErrorText: { - color: tokens.colors.TEXT_DANGER, - fontSize: 14, - textAlign: "center", - paddingVertical: 8, - flex: 1, - }, -})); +}); +// Component entrypoint export default function ErrorBoundaryScreen(props: { error: Error; rerender: () => void; }) { + // Hooks MUST be at the top level and unconditionally called. const styles = useStyles(); const debugInfo = getDebugInfo(); + const navigation = NavigationNative.useNavigation(); - const copyErrorDetails = () => { - const errorText = `Error: ${props.error.message}\n\nStack: ${props.error.stack || "No stack trace"}`; - Clipboard.setString(errorText); - showToast("Error details copied"); - }; + // Bisect UI state (fixes ReferenceError when referenced below) + const [bisectBatches, setBisectBatches] = React.useState( + null, + ); + const [bisectIndex, setBisectIndex] = React.useState(0); + const [showBisectUI, setShowBisectUI] = React.useState(false); - const copyStackTrace = () => { - if (props.error.stack) { - Clipboard.setString(props.error.stack); - showToast("Stack trace copied"); - } else { - showToast("No stack trace available"); - } - }; + // Use a safe fallback so renders don't throw if state hasn't been initialized yet + const batches = bisectBatches ?? []; + const currentBatch = batches[bisectIndex] ?? []; return ( - {/* Scrollable Content */} - - {/* Header - Using the same approach as About.tsx */} - - - Uh oh. - - - A crash occurred while rendering a component - - - {debugInfo.os.name} • Discord {debugInfo.discord.version} •{" "} - {debugInfo.bunny.version} - - + + Uh oh. + + A crash occurred while rendering a component. This could be caused + by a plugin, ShiggyCord, or Discord itself. + + + {debugInfo.os.name}; {debugInfo.discord.build} ( + {debugInfo.discord.version}); {debugInfo.bunny.version} + + + + + {props.error.message || "Unknown error occurred"} + - {/* Error Details */} - - - - - {props.error.message || "Unknown error occurred"} - - } - onPress={copyErrorDetails} - style={{ justifyContent: "center" }} - /> - - - - - {/* Stack Traces */} - {hasStack(props.error) && ( - - - - - - - - )} - - {isComponentStack(props.error) && ( - - - - - - - - )} - - {/* Quick Actions */} - - - - {props.error.stack && ( - - )} - - + {hasStack(props.error) && } + {isComponentStack(props.error) ? ( + + ) : null} - - {/* Fixed Bottom Buttons - Always visible */} - - + +