refactor: shifting lots of stuff around
This commit is contained in:
134
frontend/src/contexts/Notifications.tsx
Normal file
134
frontend/src/contexts/Notifications.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
import { InferOutput, safeParse } from "valibot";
|
||||
import { useSearchImageContext } from "./SearchImageContext";
|
||||
import { createStore } from "solid-js/store";
|
||||
import {
|
||||
Component,
|
||||
createContext,
|
||||
createEffect,
|
||||
onCleanup,
|
||||
ParentProps,
|
||||
useContext,
|
||||
} from "solid-js";
|
||||
import { base } from "@network/index";
|
||||
import { processingImagesValidator } from "@network/notifications";
|
||||
|
||||
type NotificationState = {
|
||||
ProcessingImages: Record<
|
||||
string,
|
||||
InferOutput<typeof processingImagesValidator> | undefined
|
||||
>;
|
||||
};
|
||||
|
||||
export const Notifications = (onCompleteImage: () => void) => {
|
||||
const [state, setState] = createStore<NotificationState>({
|
||||
ProcessingImages: {},
|
||||
});
|
||||
|
||||
const { processingImages } = useSearchImageContext();
|
||||
|
||||
const access = localStorage.getItem("access");
|
||||
if (access == null) {
|
||||
throw new Error("Access token not defined");
|
||||
}
|
||||
|
||||
const dataEventListener = (e: MessageEvent<unknown>) => {
|
||||
if (typeof e.data !== "string") {
|
||||
console.error("Error type is not string");
|
||||
return;
|
||||
}
|
||||
|
||||
let jsonData: object = {};
|
||||
try {
|
||||
jsonData = JSON.parse(e.data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return;
|
||||
}
|
||||
|
||||
const processingImage = safeParse(processingImagesValidator, jsonData);
|
||||
if (!processingImage.success) {
|
||||
console.error("Processing image could not be parsed.", e.data);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("SSE: ", processingImage);
|
||||
|
||||
const { ImageID, Status } = processingImage.output;
|
||||
|
||||
if (Status === "complete") {
|
||||
setState("ProcessingImages", ImageID, undefined);
|
||||
onCompleteImage();
|
||||
} else {
|
||||
setState("ProcessingImages", ImageID, processingImage.output);
|
||||
}
|
||||
};
|
||||
|
||||
const upsertImageProcessing = (
|
||||
images: NotificationState["ProcessingImages"],
|
||||
) => {
|
||||
setState("ProcessingImages", (currentImages) => ({
|
||||
...currentImages,
|
||||
...images,
|
||||
}));
|
||||
};
|
||||
|
||||
createEffect(() => {
|
||||
const images = processingImages();
|
||||
if (images == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
upsertImageProcessing(
|
||||
Object.fromEntries(
|
||||
images.map((i) => [
|
||||
i.ImageID,
|
||||
{
|
||||
ImageID: i.ImageID,
|
||||
ImageName: i.Image.ImageName,
|
||||
Status: i.Status,
|
||||
},
|
||||
]),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
const events = new EventSource(`${base}/notifications?token=${access}`);
|
||||
|
||||
events.addEventListener("data", dataEventListener);
|
||||
|
||||
events.onerror = (e) => {
|
||||
console.error(e);
|
||||
};
|
||||
|
||||
onCleanup(() => {
|
||||
events.removeEventListener("data", dataEventListener);
|
||||
events.close();
|
||||
});
|
||||
|
||||
return {
|
||||
state,
|
||||
};
|
||||
};
|
||||
|
||||
export const NotificationsContext =
|
||||
createContext<ReturnType<typeof Notifications>>();
|
||||
|
||||
export const useNotifications = () => {
|
||||
const notifications = useContext(NotificationsContext);
|
||||
if (notifications == null) {
|
||||
throw new Error("Cannot use this hook with an unmounted notifications");
|
||||
}
|
||||
|
||||
return notifications;
|
||||
};
|
||||
|
||||
export const WithNotifications: Component<ParentProps> = (props) => {
|
||||
const { onRefetchImages } = useSearchImageContext();
|
||||
const notifications = Notifications(onRefetchImages);
|
||||
|
||||
return (
|
||||
<NotificationsContext.Provider value={notifications}>
|
||||
{props.children}
|
||||
</NotificationsContext.Provider>
|
||||
);
|
||||
};
|
||||
2
frontend/src/contexts/index.ts
Normal file
2
frontend/src/contexts/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./SearchImageContext";
|
||||
export * from "./Notifications";
|
||||
Reference in New Issue
Block a user