diff --git a/app/frontend/components/error_handling/ErrorBoundary.tsx b/app/frontend/components/error_handling/ErrorBoundary.tsx new file mode 100644 index 00000000..df0d9a8d --- /dev/null +++ b/app/frontend/components/error_handling/ErrorBoundary.tsx @@ -0,0 +1,87 @@ +import SwayLogo from "app/frontend/components/SwayLogo"; +import axios from "axios"; +import { useEffect, useState } from "react"; +import { Button } from "react-bootstrap"; + +const STYLE = { + width: "100%", + height: "100%", + minHeight: "100vh", + display: "flex", + flexDirection: "column", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + margin: "0 auto", +} as React.CSSProperties; + +const getCookies = () => + document.cookie.split(";").reduce((sum, kvString) => { + const [key, value] = kvString.split("="); + return { + ...sum, + [key.trim()]: value.trim(), + }; + }, {}) as Record; + +const handleLogOut = () => { + const csrfToken = + (document.querySelector("meta[name=csrf-token]") as HTMLMetaElement | undefined)?.content || + getCookies()["XSRF-TOKEN"]; + + axios + .delete("/users/webauthn/sessions/0", { + headers: { + "X-CSRF-Token": csrfToken, + }, + }) + .finally(window.location.reload); +}; + +const ErrorBoundary = () => { + const [seconds, setSeconds] = useState(60); + + useEffect(() => { + let timer: number | undefined; + + if (seconds === 0) { + if (window.location.pathname === "/") { + try { + localStorage.clear(); + sessionStorage.clear(); + } catch (error) { + console.warn(error); + } + window.location.reload(); + } else { + window.location.href = "/"; + } + } else { + timer = window.setTimeout(() => { + setSeconds(seconds - 1); + }, 1000); + } + + return () => { + if (timer) { + window.clearTimeout(timer); + } + }; + }, [seconds]); + + return ( +
+ +
Sway had an issue loading the page.
+
+ Resetting and reloading Sway in {seconds} seconds. +
+
Try refreshing the page first but if this issue persists try to:
+
+ +
+
+ ); +}; + +export default ErrorBoundary; diff --git a/app/frontend/components/error_handling/RenderErrorHandler.tsx b/app/frontend/components/error_handling/RenderErrorHandler.tsx deleted file mode 100644 index 96281ea7..00000000 --- a/app/frontend/components/error_handling/RenderErrorHandler.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { useEffect, useState } from "react"; - -const STYLE = { - width: "100%", - height: "100%", - minHeight: "100vh", - display: "flex", - flexDirection: "column", - alignItems: "center", - justifyContent: "center", - textAlign: "center", - margin: "0 auto", -} as React.CSSProperties; - -const RenderErrorHandler = () => { - const [seconds, setSeconds] = useState(60); - - useEffect(() => { - if (seconds === 0) { - if (window.location.pathname === "/") { - try { - localStorage.clear(); - sessionStorage.clear(); - } catch (error) { - console.warn(error); - } - window.location.reload(); - } else { - window.location.href = "/"; - } - } else { - setTimeout(() => { - setSeconds(seconds - 1); - }, 1000); - } - }, [seconds]); - - return ( -
-
Sway had an issue loading the page.
-
Resetting and reloading Sway in {seconds} seconds.
-
- ); -}; - -export default RenderErrorHandler; diff --git a/app/frontend/components/error_handling/utils.ts b/app/frontend/components/error_handling/utils.ts index ae528088..a97a0ca3 100644 --- a/app/frontend/components/error_handling/utils.ts +++ b/app/frontend/components/error_handling/utils.ts @@ -1,6 +1,5 @@ import { captureException } from "@sentry/react"; import { notify } from "app/frontend/sway_utils"; -import axios from "axios"; export const onRenderError = (e: unknown) => { const error = e as Error; @@ -52,6 +51,4 @@ export const onRenderError = (e: unknown) => { .then((names) => names.forEach(async (name) => await caches.delete(name))) .catch(console.error); } - - axios.delete("/users/webauthn/sessions/0").catch(console.warn); }; diff --git a/app/frontend/entrypoints/application.tsx b/app/frontend/entrypoints/application.tsx index 759eacf5..0b09c53e 100644 --- a/app/frontend/entrypoints/application.tsx +++ b/app/frontend/entrypoints/application.tsx @@ -5,7 +5,7 @@ import { InertiaProgress } from "@inertiajs/progress"; import { createInertiaApp } from "@inertiajs/react"; import LayoutWithPage from "app/frontend/components/Layout"; import NoAuthLayout from "app/frontend/components/NoAuthLayout"; -import RenderErrorHandler from "app/frontend/components/error_handling/RenderErrorHandler"; +import ErrorBoundary from "app/frontend/components/error_handling/ErrorBoundary"; import { onRenderError } from "app/frontend/components/error_handling/utils"; import axios from "axios"; import { StrictMode } from "react"; @@ -53,14 +53,14 @@ document.addEventListener("DOMContentLoaded", () => { */ setup({ el, App, props }) { logDev("application.tsx - render App", { el, App, props: props.initialPage.props }); - Sentry.then(({ ErrorBoundary }) => { + Sentry.then(({ ErrorBoundary: SentryErrorBoundary }) => { createRoot(el!).render( - }> + }> - , + , ); }); },