100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
import {
|
|
type Accessor,
|
|
type Component,
|
|
type ParentProps,
|
|
createContext,
|
|
createMemo,
|
|
createResource,
|
|
useContext,
|
|
} from "solid-js";
|
|
import { deleteImage, deleteImageFromStack, getUserImages, JustTheImageWhatAreTheseNames, reprocessImage } from "../network";
|
|
|
|
export type SearchImageStore = {
|
|
imagesByDate: Accessor<
|
|
Array<{ date: Date; images: JustTheImageWhatAreTheseNames }>
|
|
>;
|
|
|
|
lists: Accessor<Awaited<ReturnType<typeof getUserImages>>["lists"]>;
|
|
|
|
userImages: Accessor<JustTheImageWhatAreTheseNames>;
|
|
|
|
processingImages: Accessor<
|
|
Awaited<ReturnType<typeof getUserImages>>["processingImages"] | undefined
|
|
>;
|
|
|
|
onRefetchImages: () => void;
|
|
onDeleteImage: (imageID: string) => void;
|
|
onDeleteImageFromStack: (stackID: string, imageID: string) => void;
|
|
onRefreshImage: (imageID: string) => void;
|
|
};
|
|
|
|
const SearchImageContext = createContext<SearchImageStore>();
|
|
export const SearchImageContextProvider: Component<ParentProps> = (props) => {
|
|
const [data, { refetch }] = createResource(getUserImages);
|
|
|
|
const sortedImages = createMemo<ReturnType<SearchImageStore["imagesByDate"]>>(
|
|
() => {
|
|
const d = data();
|
|
if (d == null) {
|
|
return [];
|
|
}
|
|
|
|
// Sorted by day. But we could potentially add more in the future.
|
|
const buckets: Record<string, JustTheImageWhatAreTheseNames> = {};
|
|
|
|
for (const image of d.userImages) {
|
|
if (image.CreatedAt == null) {
|
|
continue;
|
|
}
|
|
|
|
const date = new Date(image.CreatedAt).toDateString();
|
|
if (!(date in buckets)) {
|
|
buckets[date] = [];
|
|
}
|
|
|
|
buckets[date].push(image);
|
|
}
|
|
|
|
return Object.entries(buckets)
|
|
.map(([date, images]) => ({ date: new Date(date), images }))
|
|
.sort((a, b) => b.date.getTime() - a.date.getTime());
|
|
},
|
|
);
|
|
|
|
const processingImages = () => data()?.processingImages ?? [];
|
|
|
|
return (
|
|
<SearchImageContext.Provider
|
|
value={{
|
|
imagesByDate: sortedImages,
|
|
lists: () => data()?.lists ?? [],
|
|
userImages: () => data()?.userImages ?? [],
|
|
processingImages,
|
|
onRefetchImages: refetch,
|
|
onDeleteImage: (imageID: string) => {
|
|
deleteImage(imageID).then(refetch);
|
|
},
|
|
onDeleteImageFromStack: (stackID: string, imageID: string) => {
|
|
deleteImageFromStack(stackID, imageID).then(refetch);
|
|
},
|
|
onRefreshImage: (imageID: string) => {
|
|
reprocessImage(imageID).then(refetch)
|
|
}
|
|
}}
|
|
>
|
|
{props.children}
|
|
</SearchImageContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useSearchImageContext = () => {
|
|
const context = useContext(SearchImageContext);
|
|
if (context == null) {
|
|
throw new Error(
|
|
"Unreachable: We should always have a mounted context and no undefined values",
|
|
);
|
|
}
|
|
|
|
return context;
|
|
};
|