2023-10-09 21:00:58 +02:00
|
|
|
import { useCallback } from "react";
|
|
|
|
|
2023-10-08 19:35:11 +02:00
|
|
|
import { useQueryParam } from "@/hooks/useQueryParams";
|
2023-10-09 21:00:58 +02:00
|
|
|
import { useOverlayStore } from "@/stores/overlay/store";
|
2023-10-08 19:35:11 +02:00
|
|
|
|
2023-10-09 21:00:58 +02:00
|
|
|
function splitPath(path: string, prefix?: string): string[] {
|
|
|
|
const parts = [prefix ?? "", ...path.split("/")];
|
|
|
|
return parts.filter((v) => v.length > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function joinPath(path: string[]): string {
|
|
|
|
return `/${path.join("/")}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function useInternalOverlayRouter(id: string) {
|
2023-10-08 19:35:11 +02:00
|
|
|
const [route, setRoute] = useQueryParam("r");
|
2023-10-09 21:00:58 +02:00
|
|
|
const transition = useOverlayStore((s) => s.transition);
|
|
|
|
const setTransition = useOverlayStore((s) => s.setTransition);
|
2023-10-11 22:09:28 +02:00
|
|
|
const setAnchorPoint = useOverlayStore((s) => s.setAnchorPoint);
|
2023-10-09 21:00:58 +02:00
|
|
|
const routerActive = !!route && route.startsWith(`/${id}`);
|
2023-10-08 19:35:11 +02:00
|
|
|
|
2023-10-11 22:09:28 +02:00
|
|
|
function makePath(path: string) {
|
|
|
|
return joinPath(splitPath(path, id));
|
|
|
|
}
|
|
|
|
|
2023-10-08 19:35:11 +02:00
|
|
|
function navigate(path: string) {
|
2023-10-09 21:00:58 +02:00
|
|
|
const oldRoute = route;
|
|
|
|
const newRoute = joinPath(splitPath(path, id));
|
|
|
|
setTransition({
|
|
|
|
from: oldRoute ?? "/",
|
|
|
|
to: newRoute,
|
|
|
|
});
|
|
|
|
setRoute(newRoute);
|
2023-10-08 19:35:11 +02:00
|
|
|
}
|
|
|
|
|
2023-10-09 21:00:58 +02:00
|
|
|
function showBackwardsTransition(path: string) {
|
2023-10-11 22:09:28 +02:00
|
|
|
if (!transition) return "none";
|
2023-10-09 21:00:58 +02:00
|
|
|
const current = joinPath(splitPath(path, id));
|
2023-10-08 19:35:11 +02:00
|
|
|
|
2023-10-09 21:00:58 +02:00
|
|
|
if (current === transition.to && transition.from.startsWith(transition.to))
|
2023-10-11 22:09:28 +02:00
|
|
|
return "yes";
|
2023-10-09 21:00:58 +02:00
|
|
|
if (
|
|
|
|
current === transition.from &&
|
|
|
|
transition.to.startsWith(transition.from)
|
|
|
|
)
|
2023-10-11 22:09:28 +02:00
|
|
|
return "yes";
|
|
|
|
return "no";
|
2023-10-08 19:35:11 +02:00
|
|
|
}
|
|
|
|
|
2023-10-09 21:00:58 +02:00
|
|
|
function isCurrentPage(path: string) {
|
|
|
|
return routerActive && route === joinPath(splitPath(path, id));
|
2023-10-08 19:35:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function isOverlayActive() {
|
|
|
|
return routerActive;
|
|
|
|
}
|
|
|
|
|
2023-10-09 21:00:58 +02:00
|
|
|
const close = useCallback(() => {
|
|
|
|
setTransition(null);
|
2023-10-08 20:12:31 +02:00
|
|
|
setRoute(null);
|
2023-10-09 21:00:58 +02:00
|
|
|
}, [setRoute, setTransition]);
|
2023-10-08 20:12:31 +02:00
|
|
|
|
2023-10-09 21:00:58 +02:00
|
|
|
const open = useCallback(() => {
|
2023-10-11 22:09:28 +02:00
|
|
|
const anchor = document.getElementById(`__overlayRouter::${id}`);
|
|
|
|
if (anchor) {
|
|
|
|
const rect = anchor.getBoundingClientRect();
|
|
|
|
setAnchorPoint({
|
|
|
|
h: rect.height,
|
|
|
|
w: rect.width,
|
|
|
|
x: rect.x,
|
|
|
|
y: rect.y,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
setAnchorPoint(null);
|
|
|
|
}
|
|
|
|
|
2023-10-09 21:00:58 +02:00
|
|
|
setTransition(null);
|
2023-10-08 20:12:31 +02:00
|
|
|
setRoute(`/${id}`);
|
2023-10-11 22:09:28 +02:00
|
|
|
}, [id, setRoute, setTransition, setAnchorPoint]);
|
2023-10-08 19:35:11 +02:00
|
|
|
|
|
|
|
return {
|
2023-10-09 21:00:58 +02:00
|
|
|
showBackwardsTransition,
|
|
|
|
isCurrentPage,
|
2023-10-08 19:35:11 +02:00
|
|
|
isOverlayActive,
|
|
|
|
navigate,
|
|
|
|
close,
|
2023-10-08 20:12:31 +02:00
|
|
|
open,
|
2023-10-11 22:09:28 +02:00
|
|
|
makePath,
|
|
|
|
currentRoute: route,
|
2023-10-08 19:35:11 +02:00
|
|
|
};
|
|
|
|
}
|
2023-10-09 21:00:58 +02:00
|
|
|
|
|
|
|
export function useOverlayRouter(id: string) {
|
|
|
|
const router = useInternalOverlayRouter(id);
|
|
|
|
return {
|
2023-10-09 21:25:52 +02:00
|
|
|
id,
|
2023-10-11 23:04:41 +02:00
|
|
|
isRouterActive: router.isOverlayActive(),
|
2023-10-09 21:00:58 +02:00
|
|
|
open: router.open,
|
|
|
|
close: router.close,
|
|
|
|
navigate: router.navigate,
|
|
|
|
};
|
|
|
|
}
|