Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import type { Editor } from "prosekit/core";
2import type { FC, MutableRefObject, ReactNode } from "react";
3import { createContext, useContext, useEffect, useRef } from "react";
4import type { EditorExtension } from "@/helpers/prosekit/extension";
5import { setMarkdownContent } from "@/helpers/prosekit/markdownContent";
6
7interface EditorHandle {
8 insertText: (text: string) => void;
9 setMarkdown: (markdown: string) => void;
10}
11
12const HandleContext =
13 createContext<MutableRefObject<EditorHandle | null> | null>(null);
14const SetHandleContext = createContext<((handle: EditorHandle) => void) | null>(
15 null
16);
17
18interface EditorProps {
19 children: ReactNode;
20}
21
22const Provider = ({ children }: EditorProps) => {
23 const handleRef = useRef<EditorHandle | null>(null);
24
25 const setHandle = (handle: EditorHandle) => {
26 handleRef.current = handle;
27 };
28
29 return (
30 <HandleContext.Provider value={handleRef}>
31 <SetHandleContext.Provider value={setHandle}>
32 {children}
33 </SetHandleContext.Provider>
34 </HandleContext.Provider>
35 );
36};
37
38export const useEditorContext = (): EditorHandle | null => {
39 return useContext(HandleContext)?.current ?? null;
40};
41
42export const useEditorHandle = (editor: Editor<EditorExtension>) => {
43 const setHandle = useContext(SetHandleContext);
44
45 useEffect(() => {
46 const handle: EditorHandle = {
47 insertText: (text: string): void => {
48 if (!editor.mounted) {
49 return;
50 }
51
52 editor.commands.insertText({ text });
53 },
54 setMarkdown: (markdown: string): void => {
55 setMarkdownContent(editor, markdown);
56 }
57 };
58
59 setHandle?.(handle);
60 }, [setHandle, editor]);
61};
62
63export const withEditorContext = <Props extends object>(
64 Component: FC<Props>
65): FC<Props> => {
66 const WithEditorContext: FC<Props> = (props: Props) => {
67 return (
68 <Provider>
69 <Component {...props} />
70 </Provider>
71 );
72 };
73
74 return WithEditorContext;
75};