import { sleep } from '@decky/ui'; import { FunctionComponent, useEffect, useReducer, useState } from 'react'; import { uninstallPlugin } from '../plugin'; import { VerInfo, doRestart, doShutdown } from '../updater'; import { ValveReactErrorInfo, getLikelyErrorSourceFromValveReactError } from '../utils/errors'; import { useSetting } from '../utils/hooks/useSetting'; import { UpdateBranch } from './settings/pages/general/BranchSelect'; interface DeckyErrorBoundaryProps { error: ValveReactErrorInfo; errorKey: string; identifier: string; reset: () => void; } declare global { interface Window { SystemNetworkStore?: any; } } export const startSSH = DeckyBackend.callable('utilities/start_ssh'); export const starrCEFForwarding = DeckyBackend.callable('utilities/allow_remote_debugging'); function ipToString(ip: number) { return [(ip >>> 24) & 255, (ip >>> 16) & 255, (ip >>> 8) & 255, (ip >>> 0) & 255].join('.'); } // Intentionally not localized since we can't really trust React here const DeckyErrorBoundary: FunctionComponent = ({ error, identifier, reset }) => { const [actionLog, addLogLine] = useReducer((log: string, line: string) => (log += '\n' + line), ''); const [actionsEnabled, setActionsEnabled] = useState(true); const [debugAllowed, setDebugAllowed] = useState(true); // Intentionally doesn't use DeckyState. const [versionInfo, setVersionInfo] = useState(); const [errorSource, wasCausedByPlugin, shouldReportToValve] = getLikelyErrorSourceFromValveReactError(error); useEffect(() => { if (!shouldReportToValve) DeckyPluginLoader.errorBoundaryHook.temporarilyDisableReporting(); DeckyPluginLoader.updateVersion().then(setVersionInfo); }, []); const [selectedBranch, setSelectedBranch] = useSetting('branch', UpdateBranch.Stable); const [isChecking, setIsChecking] = useState(false); const [updateProgress, setUpdateProgress] = useState(-1); const [versionToUpdateTo, setSetVersionToUpdateTo] = useState(''); useEffect(() => { const a = DeckyBackend.addEventListener('updater/update_download_percentage', (percentage) => { setUpdateProgress(percentage); }); const b = DeckyBackend.addEventListener('updater/finish_download', () => { setUpdateProgress(-2); }); return () => { DeckyBackend.removeEventListener('updater/update_download_percentage', a); DeckyBackend.removeEventListener('updater/finish_download', b); }; }, []); return ( <>

⚠️ An error occured while rendering this content.

          
            {identifier && `Error Reference: ${identifier}`}
            {versionInfo?.current && `\nDecky Version: ${versionInfo.current}`}
          
        

This error likely occured in {errorSource}.

{actionLog?.length > 0 && (
            
              Running actions...
              {actionLog}
            
          
)} {actionsEnabled && ( <>

Actions:

Use the touch screen.

{debugAllowed && (
)} {
{updateProgress > -1 ? 'Update in progress... ' + updateProgress + '%' : updateProgress == -2 ? 'Update complete. Restarting...' : 'Changing your Decky Loader branch and/or \n checking for updates might help!\n'} {updateProgress == -1 && (
)}
} {wasCausedByPlugin && (
{'\n'}
)} )}
          
            {error.error.stack}
            {'\n\n'}
            Component Stack:
            {error.info.componentStack}
          
        
); }; export default DeckyErrorBoundary;