Skip to content
File

Blob: src/client/components/page-mention/context.ts

typescript41 lines
1import { createContext, use, useEffect, useSyncExternalStore } from "react";
2import type { MentionEntry, PageMentionResolver } from "./resolver";
3 
4export interface PageMentionContextValue {
5 resolver: PageMentionResolver | null;
6 navigate: (pageId: string) => void;
7}
8 
9const EMPTY_ENTRY: MentionEntry = { status: "pending", source: null, accessible: false, title: null, icon: null };
10 
11export const PageMentionContext = createContext<PageMentionContextValue>({
12 resolver: null,
13 navigate: () => {},
14});
15 
16export function usePageMentions(): PageMentionContextValue {
17 return use(PageMentionContext);
18}
19 
20export function usePageMentionEntry(pageId: string | null): MentionEntry {
21 const { resolver } = usePageMentions();
22 
23 useEffect(() => {
24 if (!resolver || !pageId) return;
25 resolver.request(pageId);
26 }, [resolver, pageId]);
27 
28 return useSyncExternalStore(
29 (listener) => {
30 if (!resolver || !pageId) return () => {};
31 return resolver.subscribe(pageId, listener);
32 },
33 () => resolver?.get(pageId) ?? EMPTY_ENTRY,
34 () => EMPTY_ENTRY,
35 );
36}
37 
38export function usePageMentionNavigate() {
39 return usePageMentions().navigate;
40}