"use client"; import { type PlaitBoard, type PlaitElement, toHostPointFromViewBoxPoint, toScreenPointFromHostPoint, } from "@plait/core"; import { MindElement, getRectangleByNode } from "@plait/mind"; import { FileText } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { getTopicDetails, getTopicTitle } from "@/lib/flow-board/topic-details"; import { getTopicTask } from "@/lib/flow-board/topic-tasks"; export function XmindTopicBadges({ board, elements, viewport, onNotes, onTask, }: { board: PlaitBoard | null; elements: PlaitElement[]; viewport: unknown; onNotes: (id: string) => void; onTask: (id: string) => void; }) { const hostRef = useRef(null); const [badges, setBadges] = useState< { id: string; title: string; notes: boolean; progress: number | null; left: number; top: number; }[] >([]); useEffect(() => { if (!board) return; const update = () => { const host = hostRef.current; if (!host) return; const origin = host.getBoundingClientRect(); const result: typeof badges = []; const visit = (children: PlaitElement[]) => { for (const element of children) { const notes = Boolean(getTopicDetails(element).notes.trim()), task = getTopicTask(element); if (notes || task) { const node = MindElement.getNode(element as MindElement); if (node) { const rect = getRectangleByNode(node); const point = toScreenPointFromHostPoint( board, toHostPointFromViewBoxPoint(board, [ rect.x + rect.width, rect.y + rect.height / 2, ]) ); result.push({ id: element.id, title: getTopicTitle(element), notes, progress: task?.progress ?? null, left: point[0] - origin.x + 5, top: point[1] - origin.y - 9, }); } } if (!element.isCollapsed && element.children) visit(element.children); } }; visit(elements); setBadges(result); }; const frame = requestAnimationFrame(update); window.addEventListener("resize", update); return () => { cancelAnimationFrame(frame); window.removeEventListener("resize", update); }; }, [board, elements, viewport]); return (
{badges.map((b) => (
{b.progress !== null ? ( ) : null} {b.notes ? ( ) : null}
))}
); }