movie-web/src/hooks/useOverlayRouter.ts

82 lines
2.0 KiB
TypeScript
Raw Normal View History

2023-10-09 21:00:58 +02:00
import { useCallback } from "react";
import { useQueryParam } from "@/hooks/useQueryParams";
2023-10-09 21:00:58 +02:00
import { useOverlayStore } from "@/stores/overlay/store";
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) {
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);
const routerActive = !!route && route.startsWith(`/${id}`);
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-09 21:00:58 +02:00
function showBackwardsTransition(path: string) {
if (!transition) return false;
const current = joinPath(splitPath(path, id));
2023-10-09 21:00:58 +02:00
if (current === transition.to && transition.from.startsWith(transition.to))
return true;
if (
current === transition.from &&
transition.to.startsWith(transition.from)
)
return true;
return false;
}
2023-10-09 21:00:58 +02:00
function isCurrentPage(path: string) {
return routerActive && route === joinPath(splitPath(path, id));
}
function isOverlayActive() {
return routerActive;
}
2023-10-09 21:00:58 +02:00
const close = useCallback(() => {
setTransition(null);
setRoute(null);
2023-10-09 21:00:58 +02:00
}, [setRoute, setTransition]);
2023-10-09 21:00:58 +02:00
const open = useCallback(() => {
setTransition(null);
setRoute(`/${id}`);
2023-10-09 21:00:58 +02:00
}, [id, setRoute, setTransition]);
return {
2023-10-09 21:00:58 +02:00
showBackwardsTransition,
isCurrentPage,
isOverlayActive,
navigate,
close,
open,
};
}
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-09 21:00:58 +02:00
open: router.open,
close: router.close,
navigate: router.navigate,
};
}