import { useEffect, useRef } from "react"; import { socketAtom } from "@/features/websocket/atoms/socket-atom.ts"; import { useAtom } from "jotai"; import { treeDataAtom } from "@/features/page/tree/atoms/tree-data-atom.ts"; import { WebSocketEvent } from "@/features/websocket/types"; import { SpaceTreeNode } from "@/features/page/tree/types.ts"; import { useQueryClient } from "@tanstack/react-query"; import { SimpleTree } from "react-arborist"; export const useTreeSocket = () => { const [socket] = useAtom(socketAtom); const [treeData, setTreeData] = useAtom(treeDataAtom); const queryClient = useQueryClient(); const initialTreeData = useRef(treeData); useEffect(() => { initialTreeData.current = treeData; }, [treeData]); useEffect(() => { socket?.on("message", (event: WebSocketEvent) => { const initialData = initialTreeData.current; const treeApi = new SimpleTree(initialData); switch (event.operation) { case "updateOne": if (event.entity[0] === "pages") { if (treeApi.find(event.id)) { if (event.payload?.title) { treeApi.update({ id: event.id, changes: { name: event.payload.title } }); } if (event.payload?.icon) { treeApi.update({ id: event.id, changes: { icon: event.payload.icon } }); } setTreeData(treeApi.data); } } break; case 'addTreeNode': if (treeApi.find(event.payload.data.id)) return; treeApi.create({ parentId: event.payload.parentId, index: event.payload.index, data: event.payload.data }); setTreeData(treeApi.data); break; case 'moveTreeNode': // move node if (treeApi.find(event.payload.id)) { treeApi.move({ id: event.payload.id, parentId: event.payload.parentId, index: event.payload.index }); // update node position treeApi.update({ id: event.payload.id, changes: { position: event.payload.position, } }); setTreeData(treeApi.data); } break; case "deleteTreeNode": if (treeApi.find(event.payload.node.id)){ treeApi.drop({ id: event.payload.node.id }); setTreeData(treeApi.data); queryClient.invalidateQueries({ queryKey: ['pages', event.payload.node.slugId].filter(Boolean), }); } break; } }); }, [socket]); };