refactor: image processing notifications

This commit is contained in:
2025-07-18 15:43:06 +01:00
parent 6e2c6acd9d
commit 510cb3012b
6 changed files with 60 additions and 39 deletions

View File

@ -12,6 +12,7 @@ import { SearchImageContextProvider } from "@contexts/SearchImageContext";
import { WithNotifications } from "@contexts/Notifications"; import { WithNotifications } from "@contexts/Notifications";
import { ProtectedRoute } from "@components/protected-route"; import { ProtectedRoute } from "@components/protected-route";
import { AppWrapper } from "@components/app-wrapper"; import { AppWrapper } from "@components/app-wrapper";
import { WithTopbarAndDock } from "@components/app-wrapper/with-topbar-and-dock";
export const App = () => { export const App = () => {
onAndroidMount(); onAndroidMount();
@ -24,10 +25,12 @@ export const App = () => {
<Route path="/" component={ProtectedRoute}> <Route path="/" component={ProtectedRoute}>
<Route path="/" component={WithNotifications}> <Route path="/" component={WithNotifications}>
<Route path="/" component={FrontPage} /> <Route path="/" component={WithTopbarAndDock}>
<Route path="/image/:imageId" component={ImagePage} /> <Route path="/" component={FrontPage} />
<Route path="/entity/:entityId" component={Entity} /> <Route path="/image/:imageId" component={ImagePage} />
<Route path="/gallery/:entity" component={Gallery} /> <Route path="/entity/:entityId" component={Entity} />
<Route path="/gallery/:entity" component={Gallery} />
</Route>
</Route> </Route>
<Route path="/settings" component={Settings} /> <Route path="/settings" component={Settings} />
</Route> </Route>

View File

@ -4,7 +4,7 @@ import { Component } from "solid-js";
export const Dock: Component = () => { export const Dock: Component = () => {
return ( return (
<div class="w-full mt-auto h-16 bg-white flex justify-between m-4 rounded-xl"> <div class="w-full mt-auto h-16 bg-white flex justify-between rounded-xl">
<A href="/" class="w-full flex justify-center items-center"> <A href="/" class="w-full flex justify-center items-center">
<IconHome /> <IconHome />
</A> </A>

View File

@ -1,14 +1,10 @@
import { Component, ParentProps } from "solid-js"; import { Component, ParentProps } from "solid-js";
import { Topbar } from "./topbar";
import { Dock } from "./dock";
export const AppWrapper: Component<ParentProps> = (props) => { export const AppWrapper: Component<ParentProps> = (props) => {
return ( return (
<div class="w-full flex flex-col items-center h-screen"> <div class="w-full flex flex-col items-center h-screen">
<div class="container flex flex-col w-full h-full"> <div class="container flex flex-col w-full h-full gap-4 m-4">
<Topbar />
{props.children} {props.children}
<Dock />
</div> </div>
</div> </div>
); );

View File

@ -1,16 +1,23 @@
import { useNavigate } from "@solidjs/router"; import { ProcessingImages } from "@components/notifications/ProcessingImage";
import { useLocation, useNavigate } from "@solidjs/router";
import { IconArrowLeft } from "@tabler/icons-solidjs"; import { IconArrowLeft } from "@tabler/icons-solidjs";
import { Component } from "solid-js"; import { Component, Show } from "solid-js";
export const Topbar: Component = () => { export const Topbar: Component = () => {
const nav = useNavigate(); const nav = useNavigate();
const location = useLocation();
return ( return (
<div class="w-full flex items-center bg-white rounded-xl h-16"> <div class="w-full flex items-center bg-white rounded-xl h-16 px-4 gap-4">
<div class="cursor-pointer" onClick={() => nav(-1)}> <Show when={location.pathname !== "/"}>
<IconArrowLeft /> <div class="cursor-pointer" onClick={() => nav(-1)}>
</div> <IconArrowLeft />
</div>
</Show>
<h1 class="font-bold text-2xl">Haystack</h1> <h1 class="font-bold text-2xl">Haystack</h1>
<div class="ml-auto">
<ProcessingImages />
</div>
</div> </div>
); );
}; };

View File

@ -0,0 +1,13 @@
import { Component, ParentProps } from "solid-js";
import { Topbar } from "./topbar";
import { Dock } from "./dock";
export const WithTopbarAndDock: Component<ParentProps> = (props) => {
return (
<>
<Topbar />
{props.children}
<Dock />
</>
);
};

View File

@ -11,27 +11,29 @@ export const ProcessingImages: Component = () => {
Object.keys(notifications.state.ProcessingImages).length; Object.keys(notifications.state.ProcessingImages).length;
return ( return (
<Show when={processingNumber() > 0}> <Popover sameWidth gutter={4}>
<Popover sameWidth gutter={4}> <Popover.Trigger class="w-full flex justify-between rounded-xl px-4 py-2">
<Popover.Trigger class="w-full flex justify-between rounded-xl bg-slate-800 text-gray-100 px-4 py-2"> <Show when={processingNumber() > 0}>
<p class="text-md">
Processing {processingNumber()}{" "}
{processingNumber() === 1 ? "image" : "images"}
</p>
</Show>
<Show
when={processingNumber() === 0}
fallback={<LoadingCircle status="loading" />}
>
<LoadingCircle status="complete" />
</Show>
</Popover.Trigger>
<Popover.Portal>
<Popover.Content class="shadow-2xl flex flex-col gap-2 bg-white rounded-xl p-2">
<Show <Show
when={processingNumber() > 0} when={
fallback={<p class="text-md">No images to process</p>} Object.entries(notifications.state.ProcessingImages).length > 0
}
fallback={<p>No images to process</p>}
> >
<p class="text-md">
Processing {processingNumber()}{" "}
{processingNumber() === 1 ? "image" : "images"}
</p>
</Show>
<Show
when={processingNumber() === 0}
fallback={<LoadingCircle status="loading" />}
>
<LoadingCircle status="complete" />
</Show>
</Popover.Trigger>
<Popover.Portal>
<Popover.Content class="shadow-2xl flex flex-col gap-2 bg-slate-800 rounded-xl p-2">
<For each={Object.entries(notifications.state.ProcessingImages)}> <For each={Object.entries(notifications.state.ProcessingImages)}>
{([id, _image]) => ( {([id, _image]) => (
<Show when={_image}> <Show when={_image}>
@ -54,9 +56,9 @@ export const ProcessingImages: Component = () => {
</Show> </Show>
)} )}
</For> </For>
</Popover.Content> </Show>
</Popover.Portal> </Popover.Content>
</Popover> </Popover.Portal>
</Show> </Popover>
); );
}; };