Skip to content

Commit

Permalink
Display server error in the page (#214)
Browse files Browse the repository at this point in the history
  • Loading branch information
zonia3000 authored Oct 1, 2024
1 parent eed2e74 commit ede3232
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
37 changes: 32 additions & 5 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ThemeProvider } from "@material-ui/styles";
import { ThemeProvider, makeStyles } from "@material-ui/styles";
import { Provider, atom } from "jotai";
import { useSetAtom } from "jotai";
import { useAtomValue, useSetAtom } from "jotai";
import * as React from "react";
import ReactDOM from "react-dom/client";

import Menu from "./components/Menu";
import Viewer from "./components/Viewer";
import "./codecs/register";
import { type ImageLayerConfig, type ViewState, addImageAtom, atomWithEffect } from "./state";
import { type ImageLayerConfig, type ViewState, addImageAtom, atomWithEffect, sourceErrorAtom } from "./state";
import theme from "./theme";
import { defer, typedEmitter } from "./utils";

Expand All @@ -26,6 +26,22 @@ export interface VizarrViewer {
destroy(): void;
}

const useStyles = makeStyles({
errorContainer: {
position: "fixed",
top: 0,
bottom: 0,
left: 0,
right: 0,
color: "#fff",
display: "flex",
alignItems: "center",
textAlign: "center",
justifyContent: "center",
fontSize: "120%",
},
});

export function createViewer(element: HTMLElement, options: { menuOpen?: boolean } = {}): Promise<VizarrViewer> {
const ref = React.createRef<VizarrViewer>();
const emitter = typedEmitter<Events>();
Expand All @@ -36,6 +52,7 @@ export function createViewer(element: HTMLElement, options: { menuOpen?: boolean
const { promise, resolve } = defer<VizarrViewer>();

function App() {
const sourceError = useAtomValue(sourceErrorAtom);
const addImage = useSetAtom(addImageAtom);
const setViewState = useSetAtom(viewStateAtom);
React.useImperativeHandle(
Expand All @@ -53,10 +70,20 @@ export function createViewer(element: HTMLElement, options: { menuOpen?: boolean
resolve(ref.current);
}
}, []);
const classes = useStyles();
return (
<>
<Menu open={options.menuOpen ?? true} />
<Viewer viewStateAtom={viewStateAtom} />
{sourceError === null && (
<>
<Menu open={options.menuOpen ?? true} />
<Viewer viewStateAtom={viewStateAtom} />
</>
)}
{sourceError !== null && (
<div className={classes.errorContainer}>
<p>{`Error: server replied with "${sourceError}" when loading the resource`}</p>
</div>
)}
</>
);
}
Expand Down
16 changes: 11 additions & 5 deletions src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,23 @@ export type ControllerProps<T = object> = {
layerAtom: PrimitiveAtom<WithId<LayerState>>;
} & T;

export const sourceErrorAtom = atom<string | null>(null);

export const sourceInfoAtom = atom<WithId<SourceData>[]>([]);

export const addImageAtom = atom(null, async (get, set, config: ImageLayerConfig) => {
const { createSourceData } = await import("./io");
const id = Math.random().toString(36).slice(2);
const sourceData = await createSourceData(config);
const prevSourceInfo = get(sourceInfoAtom);
if (!sourceData.name) {
sourceData.name = `image_${Object.keys(prevSourceInfo).length}`;
try {
const sourceData = await createSourceData(config);
const prevSourceInfo = get(sourceInfoAtom);
if (!sourceData.name) {
sourceData.name = `image_${Object.keys(prevSourceInfo).length}`;
}
set(sourceInfoAtom, [...prevSourceInfo, { id, ...sourceData }]);
} catch (err) {
set(sourceErrorAtom, (err as Error).message);
}
set(sourceInfoAtom, [...prevSourceInfo, { id, ...sourceData }]);
});

export const sourceInfoAtomAtoms = splitAtom(sourceInfoAtom);
Expand Down

0 comments on commit ede3232

Please sign in to comment.