diff --git a/editor/src/components/editor/advice/advice-manager.ts b/editor/src/components/editor/advice/advice-manager.ts new file mode 100644 index 0000000..7a3450e --- /dev/null +++ b/editor/src/components/editor/advice/advice-manager.ts @@ -0,0 +1,61 @@ +import { Advice } from "@/components/editor/advice/advice"; + +type EventHandler = (data: any) => void; + +export class AdviceManager { + private static instance: AdviceManager; + + static getInstance(): AdviceManager { + if (!AdviceManager.instance) { + AdviceManager.instance = new AdviceManager(); + } + return AdviceManager.instance; + } + + private constructor() {} + + private advices: Record = {}; + + // pub sub + private handlers: Record = {}; + + on(event: string, handler: EventHandler) { + if (!this.handlers[event]) { + this.handlers[event] = []; + } + this.handlers[event].push(handler); + } + + emit(event: string, data: any) { + if (this.handlers[event]) { + this.handlers[event].forEach((handler) => handler(data)); + } + } + + addAdvice(advice: Advice) { + this.advices[advice.id] = advice; + this.emit('add', advice); + } + + getAdvice(id: string) { + return this.advices[id]; + } + + updateAdvice(id: string, data: Advice) { + this.advices[id] = { + ...this.advices[id], + ...data, + }; + } + + updateAdvices(data: Advice[]) { + Object.keys(data).forEach((id) => { + // @ts-ignore + this.updateAdvice(id, data[id]); + }); + } + + getAdvices(): Advice[] { + return Object.values(this.advices); + } +} \ No newline at end of file diff --git a/editor/src/components/editor/advice/advice.tsx b/editor/src/components/editor/advice/advice.ts similarity index 77% rename from editor/src/components/editor/advice/advice.tsx rename to editor/src/components/editor/advice/advice.ts index 1b6de5c..b41068e 100644 --- a/editor/src/components/editor/advice/advice.tsx +++ b/editor/src/components/editor/advice/advice.ts @@ -7,7 +7,7 @@ export interface Advice { createdAt: Date } -export const getNewComment = (content: string): Advice => { +export const newAdvice = (content: string): Advice => { return { id: `a${v4()}a`, content, diff --git a/editor/src/components/editor/intelli/menu/menu-bubble.tsx b/editor/src/components/editor/intelli/menu/menu-bubble.tsx index dde5974..6c86e2e 100644 --- a/editor/src/components/editor/intelli/menu/menu-bubble.tsx +++ b/editor/src/components/editor/intelli/menu/menu-bubble.tsx @@ -6,7 +6,7 @@ import { Editor } from "@tiptap/core"; import { CookieIcon } from "@radix-ui/react-icons"; import { ActionExecutor } from "@/components/editor/action/ActionExecutor"; import { Button, DropdownMenu } from "@radix-ui/themes"; -import { getNewComment } from '../../advice/advice'; +import { newAdvice } from '../../advice/advice'; export const MenuBubble = ({ editor }: { editor: Editor @@ -102,7 +102,7 @@ export const MenuBubble = ({ editor }: { variant="outline" key={index} onClick={() => { - const newComment = getNewComment("TODO, we are working on it") + const newComment = newAdvice("TODO, we are working on it") editor.commands?.setAdvice(newComment.id) editor.commands?.setAdviceCommand(newComment) menu.action?.(editor) diff --git a/editor/src/components/editor/live-editor.tsx b/editor/src/components/editor/live-editor.tsx index 8c4b9d6..e338105 100644 --- a/editor/src/components/editor/live-editor.tsx +++ b/editor/src/components/editor/live-editor.tsx @@ -24,69 +24,18 @@ import { Sidebar } from './sidebar' import "./editor.css" import { Advice } from "@/components/editor/advice/advice"; +import { AdviceManager } from "@/components/editor/advice/advice-manager"; const md = new MarkdownIt() -type EventHandler = (data: any) => void; - -class AdviceManager { - private advices: Record = {}; - - // pub sub - private handlers: Record = {}; - - on(event: string, handler: EventHandler) { - if (!this.handlers[event]) { - this.handlers[event] = []; - } - this.handlers[event].push(handler); - } - - emit(event: string, data: any) { - if (this.handlers[event]) { - this.handlers[event].forEach((handler) => handler(data)); - } - } - - addAdvice(advice: Advice) { - this.advices[advice.id] = advice; - this.emit('add', advice); - } - - getAdvice(id: string) { - return this.advices[id]; - } - - updateAdvice(id: string, data: Advice) { - this.advices[id] = { - ...this.advices[id], - ...data, - }; - } - - updateAdvices(data: Advice[]) { - Object.keys(data).forEach((id) => { - // @ts-ignore - this.updateAdvice(id, data[id]); - }); - } - - getAdvices(): Advice[] { - return Object.values(this.advices); - } -} - const LiveEditor = () => { const { t, i18n } = useTranslation(); - const adviceManager = new AdviceManager(); - // based on : https://github.com/sereneinserenade/tiptap-comment-extension/blob/d8ad0d01e98ac416e69f27ab237467b782076c16/demos/react/src/components/Tiptap.tsx const [activeCommentId, setActiveId] = useState(null) const commentsSectionRef = useRef(null) const focusAdviceWithActiveId = (id: string) => { - console.log(commentsSectionRef.current) if (!commentsSectionRef.current) return const commentInput = commentsSectionRef.current.querySelector(`input#${id}`) @@ -110,7 +59,7 @@ const LiveEditor = () => { class: "my-advice", }, setAdviceCommand: (advice: Advice) => { - adviceManager.addAdvice(advice); + AdviceManager.getInstance().addAdvice(advice); }, onAdviceActivated: (adviceId) => { setActiveId(adviceId) @@ -140,7 +89,7 @@ const LiveEditor = () => { ] useEffect(() => { - adviceManager.on('add', (advice) => { + AdviceManager.getInstance().on('add', (advice) => { setAdvices((prevAdvices) => { const newAdvice = [...prevAdvices, advice]; setActiveId(advice.id); @@ -163,8 +112,7 @@ const LiveEditor = () => { const [debouncedEditor] = useDebounce(editor?.state.doc.content, 2000); useEffect(() => { if (debouncedEditor) { - // save - console.info('save', debouncedEditor) + console.info('todo: add save logic', debouncedEditor) } }, [debouncedEditor]);