From 604de8a683b7998c02a2106da29b7255bb625eb3 Mon Sep 17 00:00:00 2001 From: LukeGus Date: Tue, 12 May 2026 22:50:51 -0500 Subject: [PATCH] fix: remote desktop blank screen --- src/locales/en.json | 4 +- src/ui/desktop/navigation/AppView.tsx | 263 ++++++++++++++++---------- 2 files changed, 164 insertions(+), 103 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 35579388..aa4b82e2 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -537,7 +537,9 @@ "remove": "Remove", "revoke": "Revoke", "create": "Create", - "update": "Update" + "update": "Update", + "pageOutdated": "This page is outdated. Please refresh to load the latest version.", + "refreshPage": "Refresh Page" }, "nav": { "home": "Home", diff --git a/src/ui/desktop/navigation/AppView.tsx b/src/ui/desktop/navigation/AppView.tsx index e7d07e17..e077a82d 100644 --- a/src/ui/desktop/navigation/AppView.tsx +++ b/src/ui/desktop/navigation/AppView.tsx @@ -1,4 +1,6 @@ import React, { + Component, + type ErrorInfo, Suspense, lazy, useEffect, @@ -26,6 +28,61 @@ import { useTheme } from "@/components/theme-provider"; import { SimpleLoader } from "@/ui/desktop/navigation/animations/SimpleLoader.tsx"; import { useTranslation } from "react-i18next"; +class ChunkErrorBoundaryInner extends Component< + { children: React.ReactNode; message: string; buttonLabel: string }, + { hasChunkError: boolean } +> { + constructor(props: { + children: React.ReactNode; + message: string; + buttonLabel: string; + }) { + super(props); + this.state = { hasChunkError: false }; + } + + static getDerivedStateFromError(error: Error) { + const isChunkError = + error.name === "ChunkLoadError" || + /Loading chunk \d+ failed/i.test(error.message) || + /Failed to fetch dynamically imported module/i.test(error.message) || + /error loading dynamically imported module/i.test(error.message); + if (isChunkError) return { hasChunkError: true }; + throw error; + } + + componentDidCatch(_error: Error, _info: ErrorInfo) {} + + render() { + if (this.state.hasChunkError) { + return ( +
+ {this.props.message} + +
+ ); + } + return this.props.children; + } +} + +function ChunkErrorBoundary({ children }: { children: React.ReactNode }) { + const { t } = useTranslation(); + return ( + + {children} + + ); +} + const Terminal = lazy(() => import("@/ui/desktop/apps/features/terminal/Terminal.tsx").then((module) => ({ default: module.Terminal, @@ -449,111 +506,113 @@ export function AppView({ : "var(--bg-base)", }} > - - } - > - {t.type === "terminal" ? ( - 0} - onClose={() => removeTab(t.id)} - onTitleChange={(title) => updateTab(t.id, { title })} - onOpenFileManager={ - (t.hostConfig as any)?.enableFileManager - ? (path?: string) => - addTab({ - type: "file_manager", - title: t.title, - hostConfig: path - ? { - ...t.hostConfig!, - defaultPath: path, - } - : t.hostConfig, - }) - : undefined - } - previewTheme={ - t.id === currentTab ? previewTerminalTheme : null - } - /> - ) : t.type === "server_stats" ? ( - - ) : t.type === "rdp" || - t.type === "vnc" || - t.type === "telnet" ? ( - t.connectionConfig ? ( - + + } + > + {t.type === "terminal" ? ( + removeTab(t.id)} - onError={(err) => { - toast.error(err); - removeTab(t.id); - }} + title={t.title} + showTitle={false} + splitScreen={allSplitScreenTab.length > 0} + onClose={() => removeTab(t.id)} + onTitleChange={(title) => updateTab(t.id, { title })} + onOpenFileManager={ + (t.hostConfig as any)?.enableFileManager + ? (path?: string) => + addTab({ + type: "file_manager", + title: t.title, + hostConfig: path + ? { + ...t.hostConfig!, + defaultPath: path, + } + : t.hostConfig, + }) + : undefined + } + previewTheme={ + t.id === currentTab ? previewTerminalTheme : null + } + /> + ) : t.type === "server_stats" ? ( + + ) : t.type === "rdp" || + t.type === "vnc" || + t.type === "telnet" ? ( + t.connectionConfig ? ( + removeTab(t.id)} + onError={(err) => { + toast.error(err); + removeTab(t.id); + }} + /> + ) : ( +
+ Missing connection configuration +
+ ) + ) : t.type === "network_graph" ? ( + + ) : t.type === "tunnel" ? ( + + ) : t.type === "docker" ? ( + removeTab(t.id)} /> ) : ( -
- Missing connection configuration -
- ) - ) : t.type === "network_graph" ? ( - - ) : t.type === "tunnel" ? ( - - ) : t.type === "docker" ? ( - removeTab(t.id)} - /> - ) : ( - removeTab(t.id)} - /> - )} -
+ removeTab(t.id)} + /> + )} +
+ );