File
Blob: src/client/components/page-mention/canonical-surface.tsx
| 1 | import { useCallback, useMemo, type ReactNode } from "react"; |
| 2 | import { useNavigate, useParams } from "@tanstack/react-router"; |
| 3 | import { PageMentionProvider } from "./provider"; |
| 4 | import { useCanonicalPageContext } from "@/client/components/workspace/use-canonical-page-context"; |
| 5 | import { useActivePageState } from "@/client/components/active-page/use-active-page"; |
| 6 | import { useOnline } from "@/client/hooks/use-online"; |
| 7 | import { useActiveWorkspacePages } from "@/client/stores/workspace-replica"; |
| 8 | |
| 9 | export function CanonicalPageMentionSurface({ children }: { children: ReactNode }) { |
| 10 | const navigate = useNavigate(); |
| 11 | const params = useParams({ strict: false }) as { workspaceSlug: string; pageId?: string }; |
| 12 | const { workspaceId, workspace, accessMode } = useCanonicalPageContext(); |
| 13 | const activePageState = useActivePageState(); |
| 14 | const online = useOnline(); |
| 15 | const pages = useActiveWorkspacePages(workspaceId); |
| 16 | |
| 17 | const cacheMode = activePageState.kind === "ready" && activePageState.backing === "cache" ? "cache" : "live"; |
| 18 | const workspaceSlug = workspace?.slug ?? params.workspaceSlug; |
| 19 | |
| 20 | const pagesById = useMemo(() => { |
| 21 | const map = new Map<string, { title: string; icon: string | null }>(); |
| 22 | for (const page of pages) { |
| 23 | map.set(page.id, { title: page.title, icon: page.icon }); |
| 24 | } |
| 25 | return map; |
| 26 | }, [pages]); |
| 27 | |
| 28 | const scopeKey = workspaceId ? `canonical:${workspaceId}:${accessMode ?? "unknown"}` : null; |
| 29 | |
| 30 | const lookupCachedPage = useCallback( |
| 31 | (pageId: string) => { |
| 32 | return pagesById.get(pageId) ?? null; |
| 33 | }, |
| 34 | [pagesById], |
| 35 | ); |
| 36 | |
| 37 | const handleNavigate = useCallback( |
| 38 | (pageId: string) => { |
| 39 | navigate({ |
| 40 | to: "/$workspaceSlug/$pageId", |
| 41 | params: { workspaceSlug, pageId }, |
| 42 | }); |
| 43 | }, |
| 44 | [navigate, workspaceSlug], |
| 45 | ); |
| 46 | |
| 47 | return ( |
| 48 | <PageMentionProvider |
| 49 | workspaceId={workspaceId ?? undefined} |
| 50 | scopeKey={scopeKey} |
| 51 | cacheMode={cacheMode} |
| 52 | networkEnabled={online} |
| 53 | lookupCachedPage={lookupCachedPage} |
| 54 | navigate={handleNavigate} |
| 55 | > |
| 56 | {children} |
| 57 | </PageMentionProvider> |
| 58 | ); |
| 59 | } |