diff --git a/src/components/App/error.tsx b/src/components/App/error.tsx new file mode 100644 index 000000000..560a5523e --- /dev/null +++ b/src/components/App/error.tsx @@ -0,0 +1,212 @@ +import { Button, Divider, Group, ScrollArea, Text } from "@mantine/core"; +import { Box, Paper, Stack, Title } from "@mantine/core"; +import { FallbackProps } from "react-error-boundary"; +import { Icon } from "../Icon"; +import { iconBug, iconCheck, iconCopy, iconReset, iconWarning } from "~/util/icons"; +import { adapter } from "~/adapter"; +import { useVersionCopy } from "~/hooks/debug"; + +export function AppErrorHandler({ error, resetErrorBoundary }: FallbackProps) { + const [copyDebug, clipboard] = useVersionCopy(); + + const message = error instanceof Error + ? error.message + : error; + + return ( + + + + + + Surrealist encountered an error + + + + You can find a detailed error message below. If you believe this is a bug, please report it on our GitHub repository. + + + + + + + + + + + {message && ( + + + Message + + + + {message} + + + )} + + {error.cause && ( + + + Cause + + + + {error.cause} + + + )} + + {error.stack && ( + + + Stack trace + + + + {error.stack} + + + )} + + + + //
+ //
+ //

Something went wrong!

+ // {error.name &&

{error.name}

} + //
+ //

Message

+ //

+ // {message} + //

+ //
+ // {error.cause && ( + //
+ //

Cause

+ //

+ // {error.cause} + //

+ //
+ // )} + // {error.stack && ( + //
+ //

Stack trace

+ //

+ // {error.stack} + //

+ //
+ // )} + //
+ // + //
+ //
+ //
+ ); +} \ No newline at end of file diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index ace072493..baf45b7a6 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -6,9 +6,8 @@ import { useStable } from "~/hooks/stable"; import { Icon } from "../Icon"; import { adapter } from "~/adapter"; import { useInterfaceStore } from "~/stores/interface"; -import { useConfigStore } from "~/stores/config"; import { Scaffold } from "../Scaffold"; -import { ErrorBoundary, FallbackProps } from "react-error-boundary"; +import { ErrorBoundary } from "react-error-boundary"; import { MANTINE_THEME } from "~/util/mantine"; import { useColorScheme, useIsLight } from "~/hooks/theme"; import { ContextMenuProvider } from "mantine-contextmenu"; @@ -17,9 +16,9 @@ import { iconClose } from "~/util/icons"; import { FeatureFlagsProvider } from "~/providers/FeatureFlags"; import { ConfirmationProvider } from "~/providers/Confirmation"; import { useUrlHandler } from "~/hooks/url"; +import { AppErrorHandler } from "./error"; export function App() { - const { softReset } = useConfigStore.getState(); const { hideAvailableUpdate } = useInterfaceStore.getState(); const isLight = useIsLight(); @@ -37,6 +36,10 @@ export function App() { closeUpdate(); }); + const handleReset = useStable(() => { + location.reload(); + }); + useUrlHandler(); return ( @@ -57,7 +60,7 @@ export function App() { @@ -103,89 +106,4 @@ export function App() { ); -} - -function AppErrorHandler({ error, resetErrorBoundary }: FallbackProps) { - const message = error instanceof Error ? error.message : error; - - return ( -
-
-

Something went wrong!

- {error.name &&

{error.name}

} -
-

Message

-

- {message} -

-
- {error.cause && ( -
-

Cause

-

- {error.cause} -

-
- )} - {error.stack && ( -
-

Stack trace

-

- {error.stack} -

-
- )} -
- -
-
-
- ); -} +} \ No newline at end of file diff --git a/src/components/Scaffold/settings/index.tsx b/src/components/Scaffold/settings/index.tsx index c14a0a3aa..95bd07bdb 100644 --- a/src/components/Scaffold/settings/index.tsx +++ b/src/components/Scaffold/settings/index.tsx @@ -11,14 +11,13 @@ import { Entry } from "../../Entry"; import { useEffect, useRef, useState } from "react"; import { Spacer } from "../../Spacer"; import { Icon } from "../../Icon"; -import { useClipboard } from "@mantine/hooks"; -import { useStable } from "~/hooks/stable"; -import { adapter, isDesktop } from "~/adapter"; +import { isDesktop } from "~/adapter"; import { useFeatureFlags } from "~/util/feature-flags"; import { FeatureFlagsTab } from "./tabs/FeatureFlags"; import { LicensesTab } from "./tabs/Licenses"; import { FeatureCondition } from "~/types"; import { useIntent } from "~/hooks/url"; +import { useVersionCopy } from "~/hooks/debug"; interface Category { id: string; @@ -28,8 +27,6 @@ interface Category { disabled?: FeatureCondition; } -const VERSION = import.meta.env.VERSION; - const CATEGORIES: Category[] = [ { id: "behaviour", @@ -82,9 +79,9 @@ export function Settings({ onClose, onOpen }: SettingsProps) { - const [flags, setFlags] = useFeatureFlags(); const isLight = useIsLight(); - const clipboard = useClipboard({ timeout: 1000 }); + const [flags, setFlags] = useFeatureFlags(); + const [copyDebug, clipboard] = useVersionCopy(); const [activeTab, setActiveTab] = useState("behaviour"); const [logoClicked, setLogoClicked] = useState([]); const tabsRef = useRef(null); @@ -97,21 +94,6 @@ export function Settings({ const activeCategory = categories.find((c) => c.id === activeTab)!; const Component = activeCategory.component; - const copyDebug = useStable(async () => { - const debugDump = await adapter.dumpDebug(); - const debugData = { - ...debugDump, - "Version": VERSION, - "Flags": Object.entries(flags).map(([key, value]) => `${key}: ${value}`).join(", ") - }; - - const debugText = Object.entries(debugData).reduce((acc, [key, value]) => { - return `${acc}${key}: ${value}\n`; - }, ""); - - clipboard.copy(debugText); - }); - useEffect(() => { const now = new Date(); const valid = logoClicked.filter((d) => d.getTime() > (now.getTime() - 2000)); @@ -169,7 +151,7 @@ export function Settings({ style={{ cursor: 'pointer' }} onClick={copyDebug} > - {clipboard.copied ? "Copied to clipboard!" : `Version ${VERSION}`} + {clipboard.copied ? "Copied to clipboard!" : `Version ${import.meta.env.VERSION}`} diff --git a/src/hooks/debug.ts b/src/hooks/debug.ts new file mode 100644 index 000000000..291ee3d01 --- /dev/null +++ b/src/hooks/debug.ts @@ -0,0 +1,26 @@ +import { useClipboard } from "@mantine/hooks"; +import { useStable } from "./stable"; +import { adapter } from "~/adapter"; +import { useFeatureFlags } from "~/util/feature-flags"; + +export function useVersionCopy() { + const [flags] = useFeatureFlags(); + const clipboard = useClipboard({ timeout: 1000 }); + + const copy = useStable(async () => { + const debugDump = await adapter.dumpDebug(); + const debugData = { + ...debugDump, + "Version": import.meta.env.VERSION, + "Flags": Object.entries(flags).map(([key, value]) => `${key}: ${value}`).join(", ") + }; + + const debugText = Object.entries(debugData).reduce((acc, [key, value]) => { + return `${acc}${key}: ${value}\n`; + }, ""); + + clipboard.copy(debugText); + }); + + return [copy, clipboard] as const; +} \ No newline at end of file diff --git a/src/stores/config.tsx b/src/stores/config.tsx index 2730a7257..6faf3f734 100644 --- a/src/stores/config.tsx +++ b/src/stores/config.tsx @@ -63,8 +63,7 @@ export type ConfigStore = SurrealistConfig & { pushCommand: (command: string) => void; updateViewedNews: () => void; completeOnboarding: (key: string) => void; - resetOnboardings: () => void; - softReset: () => void; + resetOnboardings: () => void } export const useConfigStore = create()( @@ -231,11 +230,6 @@ export const useConfigStore = create()( } })), - softReset: () => set(() => ({ - activeConnection: null, - activeView: "query" - })), - updateBehaviorSettings: (settings) => set((state) => ({ settings: { ...state.settings,