diff --git a/src/pages/developer/TestView.tsx b/src/pages/developer/TestView.tsx
index 6c175eb2..96fd2da4 100644
--- a/src/pages/developer/TestView.tsx
+++ b/src/pages/developer/TestView.tsx
@@ -1,80 +1,12 @@
-import { OverlayAnchor } from "@/components/overlays/OverlayAnchor";
-import { Overlay, OverlayDisplay } from "@/components/overlays/OverlayDisplay";
-import { OverlayPage } from "@/components/overlays/OverlayPage";
-import { OverlayRouter } from "@/components/overlays/OverlayRouter";
-import { useOverlayRouter } from "@/hooks/useOverlayRouter";
+import { useState } from "react";
-// simple empty view, perfect for putting in tests
+import { Button } from "@/components/Button";
+
+// mostly empty view, add whatever you need
export default function TestView() {
- const router = useOverlayRouter("test");
+ const [val, setVal] = useState(false);
+
+ if (val) throw new Error("I crashed");
- return (
-
-
-
-
-
-
-
-
-
HOME
-
-
-
-
-
-
-
ONE
-
-
-
-
-
-
TWO
-
-
-
-
-
-
-
- );
+ return
;
}
diff --git a/src/pages/errors/ErrorBoundary.tsx b/src/pages/errors/ErrorBoundary.tsx
new file mode 100644
index 00000000..a6c7ac98
--- /dev/null
+++ b/src/pages/errors/ErrorBoundary.tsx
@@ -0,0 +1,44 @@
+import { Component } from "react";
+
+import { ErrorPart } from "@/pages/parts/errors/ErrorPart";
+
+interface ErrorBoundaryState {
+ error?: {
+ error: any;
+ errorInfo: any;
+ };
+}
+
+export class ErrorBoundary extends Component<
+ Record
,
+ ErrorBoundaryState
+> {
+ constructor(props: { children: any }) {
+ super(props);
+ this.state = {
+ error: undefined,
+ };
+ }
+
+ componentDidCatch(error: any, errorInfo: any) {
+ console.error("Render error caught", error, errorInfo);
+ this.setState((s) => ({
+ ...s,
+ error: {
+ error,
+ errorInfo,
+ },
+ }));
+ }
+
+ render() {
+ if (!this.state.error) return this.props.children as any;
+
+ return (
+
+ );
+ }
+}
diff --git a/src/pages/errors/NotFoundPage.tsx b/src/pages/errors/NotFoundPage.tsx
index a944e05f..cf9cfa7e 100644
--- a/src/pages/errors/NotFoundPage.tsx
+++ b/src/pages/errors/NotFoundPage.tsx
@@ -1,23 +1,5 @@
-import { useTranslation } from "react-i18next";
-
-import { IconPatch } from "@/components/buttons/IconPatch";
-import { Icons } from "@/components/Icon";
-import { ArrowLink } from "@/components/text/ArrowLink";
-import { Title } from "@/components/text/Title";
-import { ErrorWrapperPart } from "@/pages/parts/errors/ErrorWrapperPart";
+import { NotFoundPart } from "@/pages/parts/errors/ErrorWrapperPart";
export function NotFoundPage() {
- const { t } = useTranslation();
-
- return (
-
-
- {t("notFound.page.title")}
- {t("notFound.page.description")}
-
-
- );
+ return ;
}
diff --git a/src/pages/layouts/SubPageLayout.tsx b/src/pages/layouts/SubPageLayout.tsx
index f5c7ca50..0b12de6a 100644
--- a/src/pages/layouts/SubPageLayout.tsx
+++ b/src/pages/layouts/SubPageLayout.tsx
@@ -1,6 +1,16 @@
import { FooterView } from "@/components/layout/Footer";
import { Navigation } from "@/components/layout/Navigation";
+export function BlurEllipsis() {
+ return (
+ <>
+ {/* Blur elipsis */}
+
+
+ >
+ );
+}
+
export function SubPageLayout(props: { children: React.ReactNode }) {
return (
- {/* Blur elipsis */}
-
-
-
+
{/* Main page */}
diff --git a/src/pages/parts/errors/ErrorPart.tsx b/src/pages/parts/errors/ErrorPart.tsx
new file mode 100644
index 00000000..a547f649
--- /dev/null
+++ b/src/pages/parts/errors/ErrorPart.tsx
@@ -0,0 +1,33 @@
+import { ButtonPlain } from "@/components/Button";
+import { Icons } from "@/components/Icon";
+import { IconPill } from "@/components/layout/IconPill";
+import { Title } from "@/components/text/Title";
+import { Paragraph } from "@/components/utils/Text";
+import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout";
+
+export function ErrorPart(props: { error: any; errorInfo: any }) {
+ const data = JSON.stringify({
+ error: props.error,
+ errorInfo: props.errorInfo,
+ });
+ return (
+
+
+
+
+ It broke
+ Failed to load meta data
+ {data}
+ window.location.reload()}
+ >
+ Reload the page
+
+
+
+
+
+ );
+}
diff --git a/src/pages/parts/errors/ErrorWrapperPart.tsx b/src/pages/parts/errors/ErrorWrapperPart.tsx
index 37410c49..64d36459 100644
--- a/src/pages/parts/errors/ErrorWrapperPart.tsx
+++ b/src/pages/parts/errors/ErrorWrapperPart.tsx
@@ -1,10 +1,15 @@
-import { ReactNode } from "react";
import { Helmet } from "react-helmet-async";
import { useTranslation } from "react-i18next";
+import { Button } from "@/components/Button";
+import { Icons } from "@/components/Icon";
+import { IconPill } from "@/components/layout/IconPill";
import { Navigation } from "@/components/layout/Navigation";
+import { Title } from "@/components/text/Title";
+import { Paragraph } from "@/components/utils/Text";
+import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout";
-export function ErrorWrapperPart(props: { children?: ReactNode }) {
+export function NotFoundPart() {
const { t } = useTranslation();
return (
@@ -14,7 +19,28 @@ export function ErrorWrapperPart(props: { children?: ReactNode }) {
- {props.children}
+
+
+
+ {t("notFound.genericTitle")}
+
+ Failed to load meta data
+
+ Oh, my apowogies, sweetie! The itty-bitty movie-web did its utmost
+ bestest, but alas, no wucky videos to be spotted anywhere (ยดโฯโ`)
+ Please don't be angwy, wittle movie-web ish twying so hard.
+ Can you find it in your heart to forgive? UwU ๐
+
+
+
+
);
diff --git a/src/pages/parts/migrations/MigrationPart.tsx b/src/pages/parts/migrations/MigrationPart.tsx
new file mode 100644
index 00000000..da8c027e
--- /dev/null
+++ b/src/pages/parts/migrations/MigrationPart.tsx
@@ -0,0 +1,26 @@
+import { BrandPill } from "@/components/layout/BrandPill";
+import { Loading } from "@/components/layout/Loading";
+import { BlurEllipsis } from "@/pages/layouts/SubPageLayout";
+
+export function MigrationPart() {
+ return (
+
+ {/* Overlaid elements */}
+
+
+
+
+
+ {/* Content */}
+
+
+ Please hold, we are migrating your data. This shouldn't take long.
+ Also, fuck you.
+
+
+
25%
+
+ );
+}
diff --git a/tailwind.config.js b/tailwind.config.js
index 76b647bd..3783226d 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -26,23 +26,23 @@ module.exports = {
"ash-400": "#3D394D",
"ash-300": "#2C293A",
"ash-200": "#2B2836",
- "ash-100": "#1E1C26",
+ "ash-100": "#1E1C26"
},
/* fonts */
fontFamily: {
- "open-sans": "'Open Sans'",
+ "open-sans": "'Open Sans'"
},
/* animations */
keyframes: {
"loading-pin": {
"0%, 40%, 100%": { height: "0.5em", "background-color": "#282336" },
- "20%": { height: "1em", "background-color": "white" },
- },
+ "20%": { height: "1em", "background-color": "white" }
+ }
},
- animation: { "loading-pin": "loading-pin 1.8s ease-in-out infinite" },
- },
+ animation: { "loading-pin": "loading-pin 1.8s ease-in-out infinite" }
+ }
},
plugins: [
require("tailwind-scrollbar"),
@@ -52,31 +52,31 @@ module.exports = {
colors: {
// Branding
pill: {
- background: "#1C1C36",
+ background: "#1C1C36"
},
// meta data for the theme itself
global: {
accentA: "#505DBD",
- accentB: "#3440A1",
+ accentB: "#3440A1"
},
// light bar
lightBar: {
- light: "#2A2A71",
+ light: "#2A2A71"
},
// Buttons
buttons: {
toggle: "#8D44D6",
- toggleDisabled: "#202836",
+ toggleDisabled: "#202836"
},
// only used for body colors/textures
background: {
main: "#0A0A10",
accentA: "#6E3B80",
- accentB: "#1F1F50",
+ accentB: "#1F1F50"
},
// typography
@@ -85,7 +85,7 @@ module.exports = {
text: "#73739D",
dimmed: "#926CAD",
divider: "#262632",
- secondary: "#64647B",
+ secondary: "#64647B"
},
// search bar
@@ -94,7 +94,7 @@ module.exports = {
focused: "#24243C",
placeholder: "#4A4A71",
icon: "#545476",
- text: "#FFFFFF",
+ text: "#FFFFFF"
},
// media cards
@@ -106,7 +106,7 @@ module.exports = {
barColor: "#4B4B63",
barFillColor: "#BA7FD6",
badge: "#151522",
- badgeText: "#5F5F7A",
+ badgeText: "#5F5F7A"
},
// Error page
@@ -115,14 +115,20 @@ module.exports = {
border: "#252534",
type: {
- secondary: "#62627D",
- },
+ secondary: "#62627D"
+ }
},
// About page
about: {
circle: "#262632",
- circleText: "#9A9AC3",
+ circleText: "#9A9AC3"
+ },
+
+ progress: {
+ background: "#8787A8",
+ preloaded: "#8787A8",
+ filled: "#A75FC9"
},
// video player
@@ -134,17 +140,11 @@ module.exports = {
error: "#E44F4F",
success: "#40B44B",
loading: "#B759D8",
- noresult: "#64647B",
- },
-
- progress: {
- background: "#8787A8",
- preloaded: "#8787A8",
- watched: "#A75FC9",
+ noresult: "#64647B"
},
audio: {
- set: "#A75FC9",
+ set: "#A75FC9"
},
buttons: {
@@ -157,7 +157,7 @@ module.exports = {
purple: "#6b298a",
purpleHover: "#7f35a1",
cancel: "#252533",
- cancelHover: "#3C3C4A",
+ cancelHover: "#3C3C4A"
},
context: {
@@ -177,19 +177,19 @@ module.exports = {
buttons: {
list: "#161C26",
- active: "#0D1317",
+ active: "#0D1317"
},
type: {
main: "#617A8A",
secondary: "#374A56",
- accent: "#A570FA",
- },
- },
- },
- },
- },
- },
- }),
- ],
+ accent: "#A570FA"
+ }
+ }
+ }
+ }
+ }
+ }
+ })
+ ]
};