mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
Add loading indicator for admin asset initialization
Introduced a "loading" div to indicate when admin assets are being fetched. Updated rendering logic and styles in related components to account for this state. Prepared groundwork for potential view transitions.
This commit is contained in:
@@ -140,11 +140,13 @@ export class AdminController extends Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const theme = configs.server.admin.color_scheme ?? "light";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{/* dnd complains otherwise */}
|
{/* dnd complains otherwise */}
|
||||||
{html`<!DOCTYPE html>`}
|
{html`<!DOCTYPE html>`}
|
||||||
<html lang="en" class={configs.server.admin.color_scheme ?? "light"}>
|
<html lang="en" class={theme}>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta
|
<meta
|
||||||
@@ -173,9 +175,24 @@ export class AdminController extends Controller {
|
|||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body style={{ backgroundColor: theme === "light" ? "#fff" : "#000" }}>
|
||||||
<div id="root" />
|
<div id="root" />
|
||||||
<div id="app" />
|
<div id="app">
|
||||||
|
<div
|
||||||
|
id="loading"
|
||||||
|
style={{
|
||||||
|
height: "100vh",
|
||||||
|
width: "100vw",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
opacity: 0.3
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Initializing...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script
|
<script
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: bknd_context
|
__html: bknd_context
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ const Skeleton = ({ theme = "light" }: { theme?: string }) => {
|
|||||||
</header>
|
</header>
|
||||||
<AppShell.Content>
|
<AppShell.Content>
|
||||||
<div className="flex flex-col w-full h-full justify-center items-center">
|
<div className="flex flex-col w-full h-full justify-center items-center">
|
||||||
<span className="font-mono opacity-30">Loading</span>
|
{/*<span className="font-mono opacity-30">Loading</span>*/}
|
||||||
</div>
|
</div>
|
||||||
</AppShell.Content>
|
</AppShell.Content>
|
||||||
</AppShell.Root>
|
</AppShell.Root>
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ const useLocationFromRouter = (router) => {
|
|||||||
export function Link({
|
export function Link({
|
||||||
className,
|
className,
|
||||||
native,
|
native,
|
||||||
|
onClick,
|
||||||
...props
|
...props
|
||||||
}: { className?: string; native?: boolean } & LinkProps) {
|
}: { className?: string; native?: boolean; transition?: boolean } & LinkProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [path, navigate] = useLocationFromRouter(router);
|
const [path, navigate] = useLocationFromRouter(router);
|
||||||
|
|
||||||
@@ -69,17 +70,28 @@ export function Link({
|
|||||||
const absPath = absolutePath(path, router.base).replace("//", "/");
|
const absPath = absolutePath(path, router.base).replace("//", "/");
|
||||||
const active =
|
const active =
|
||||||
href.replace(router.base, "").length <= 1 ? href === absPath : isActive(absPath, href);
|
href.replace(router.base, "").length <= 1 ? href === absPath : isActive(absPath, href);
|
||||||
const a = useRoute(_href);
|
|
||||||
|
|
||||||
/*if (active) {
|
|
||||||
console.log("link", { a, path, absPath, href, to, active, router });
|
|
||||||
}*/
|
|
||||||
if (native) {
|
if (native) {
|
||||||
return <a className={`${active ? "active " : ""}${className}`} {...props} />;
|
return <a className={`${active ? "active " : ""}${className}`} {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wouterOnClick = (e: any) => {
|
||||||
|
// prepared for view transition
|
||||||
|
/*if (props.transition !== false) {
|
||||||
|
e.preventDefault();
|
||||||
|
onClick?.(e);
|
||||||
|
document.startViewTransition(() => {
|
||||||
|
navigate(props.href ?? props.to, props);
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// @ts-expect-error className is not typed on WouterLink
|
<WouterLink
|
||||||
<WouterLink className={`${active ? "active " : ""}${className}`} {...props} />
|
// @ts-expect-error className is not typed on WouterLink
|
||||||
|
className={`${active ? "active " : ""}${className}`}
|
||||||
|
{...props}
|
||||||
|
onClick={wouterOnClick}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,18 +64,36 @@ export function useNavigate() {
|
|||||||
(
|
(
|
||||||
url: string,
|
url: string,
|
||||||
options?:
|
options?:
|
||||||
| { query?: object; absolute?: boolean; replace?: boolean; state?: any }
|
| {
|
||||||
|
query?: object;
|
||||||
|
absolute?: boolean;
|
||||||
|
replace?: boolean;
|
||||||
|
state?: any;
|
||||||
|
transition?: boolean;
|
||||||
|
}
|
||||||
| { reload: true }
|
| { reload: true }
|
||||||
) => {
|
) => {
|
||||||
if (options && "reload" in options) {
|
const wrap = (fn: () => void) => {
|
||||||
window.location.href = url;
|
fn();
|
||||||
return;
|
// prepared for view transition
|
||||||
}
|
/*if (options && "transition" in options && options.transition === false) {
|
||||||
|
fn();
|
||||||
|
} else {
|
||||||
|
document.startViewTransition(fn);
|
||||||
|
}*/
|
||||||
|
};
|
||||||
|
|
||||||
const _url = options?.absolute ? `~/${basepath}${url}`.replace(/\/+/g, "/") : url;
|
wrap(() => {
|
||||||
navigate(options?.query ? withQuery(_url, options?.query) : _url, {
|
if (options && "reload" in options) {
|
||||||
replace: options?.replace,
|
window.location.href = url;
|
||||||
state: options?.state
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _url = options?.absolute ? `~/${basepath}${url}`.replace(/\/+/g, "/") : url;
|
||||||
|
navigate(options?.query ? withQuery(_url, options?.query) : _url, {
|
||||||
|
replace: options?.replace,
|
||||||
|
state: options?.state
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
location
|
location
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ function ClientApp() {
|
|||||||
|
|
||||||
// Render the app
|
// Render the app
|
||||||
const rootElement = document.getElementById("app")!;
|
const rootElement = document.getElementById("app")!;
|
||||||
if (!rootElement.innerHTML) {
|
const shouldRender =
|
||||||
|
!rootElement.innerHTML ||
|
||||||
|
(rootElement.childElementCount === 1 && rootElement.firstElementChild?.id === "loading");
|
||||||
|
if (shouldRender) {
|
||||||
const root = ReactDOM.createRoot(rootElement);
|
const root = ReactDOM.createRoot(rootElement);
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
|||||||
Reference in New Issue
Block a user