6ede33ccdb
Build and Push Docker Images / create_manifest (web, surfsense-web, , cpu) (push) Has been cancelled
Build and Push Docker Images / finalize_release (push) Has been cancelled
Obsidian Plugin Lint / lint (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_web, cpu, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-24.04-arm, linux/arm64, arm64, , runner, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_web, cpu, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-latest, linux/amd64, amd64, , runner, false, cpu) (push) Has been cancelled
Build and Push Docker Images / compute_version (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cpu, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, , production, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cpu, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, , production, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu126, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, -cuda126, production, true, cuda126) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu126, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, -cuda126, production, true, cuda126) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu128, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, -cuda, production, true, cuda) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu128, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, -cuda, production, true, cuda) (push) Has been cancelled
Build and Push Docker Images / verify_digests (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, , cpu) (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, -cuda, cuda) (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, -cuda126, cuda126) (push) Has been cancelled
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useAtomValue } from "jotai";
|
|
import { useEffect, useState } from "react";
|
|
import { createPortal } from "react-dom";
|
|
import { globalLoadingAtom } from "@/atoms/ui/loading.atoms";
|
|
import { Spinner } from "@/components/ui/spinner";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
/**
|
|
* GlobalLoadingProvider renders a persistent loading overlay.
|
|
* The spinner is ALWAYS in the DOM to prevent animation reset when
|
|
* loading states change between different pages/components.
|
|
*
|
|
* Visibility is controlled via CSS opacity/pointer-events, NOT mounting/unmounting.
|
|
*/
|
|
export function GlobalLoadingProvider({ children }: { children: React.ReactNode }) {
|
|
const [mounted, setMounted] = useState(false);
|
|
const { isLoading } = useAtomValue(globalLoadingAtom);
|
|
|
|
useEffect(() => {
|
|
setMounted(true);
|
|
}, []);
|
|
|
|
// The overlay is ALWAYS rendered, but visibility is controlled by CSS
|
|
// This prevents the spinner animation from resetting
|
|
const loadingOverlay = (
|
|
<div
|
|
className={cn(
|
|
"fixed inset-0 z-[9999]",
|
|
isLoading
|
|
? "opacity-100 pointer-events-auto"
|
|
: "opacity-0 pointer-events-none transition-opacity duration-150"
|
|
)}
|
|
aria-hidden={!isLoading}
|
|
>
|
|
<div className="flex min-h-screen flex-col items-center justify-center bg-main-panel">
|
|
<div className="h-12 w-12 flex items-center justify-center">
|
|
<Spinner size="lg" className="text-muted-foreground" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
// Render inline during SSR/before hydration, use portal after mounting
|
|
// This prevents the white flash during initial render
|
|
return (
|
|
<>
|
|
{children}
|
|
{mounted ? createPortal(loadingOverlay, document.body) : loadingOverlay}
|
|
</>
|
|
);
|
|
}
|