import { computed, ref, watch } from 'vue'; import type { Id, MNode, MPage } from '@tmagic/schema'; import { getNodePath } from '@tmagic/utils'; import { LayerNodeStatus, Services } from '@editor/type'; import { traverseNode } from '@editor/utils'; import { updateStatus } from '@editor/utils/tree'; const createPageNodeStatus = (page: MPage, initalLayerNodeStatus?: Map) => { const map = new Map(); map.set(page.id, { visible: true, expand: true, selected: true, draggable: false, }); page.items.forEach((node: MNode) => traverseNode(node, (node) => { map.set( node.id, initalLayerNodeStatus?.get(node.id) || { visible: true, expand: false, selected: false, draggable: true, }, ); }), ); return map; }; export const useNodeStatus = (services: Services | undefined) => { const page = computed(() => services?.editorService.get('page')); const nodes = computed(() => services?.editorService.get('nodes') || []); /** 所有页面的节点状态 */ const nodeStatusMaps = ref(new Map>()); /** 当前页面的节点状态 */ const nodeStatusMap = computed(() => page.value ? nodeStatusMaps.value.get(page.value.id) : new Map(), ); // 切换页面或者新增页面,重新生成节点状态 watch( page, (page) => { if (!page) { return; } // 生成节点状态 nodeStatusMaps.value.set(page.id, createPageNodeStatus(page, nodeStatusMaps.value.get(page.id))); }, { immediate: true, }, ); // 选中状态变化,更新节点状态 watch( nodes, (nodes) => { if (!nodeStatusMap.value) return; for (const [id, status] of nodeStatusMap.value.entries()) { status.selected = nodes.some((node) => node.id === id); if (status.selected) { getNodePath(id, page.value?.items).forEach((node) => { updateStatus(nodeStatusMap.value!, node.id, { expand: true, }); }); } } }, { immediate: true, }, ); services?.editorService.on('add', (newNodes: MNode[]) => { newNodes.forEach((node) => { traverseNode(node, (node: MNode) => { nodeStatusMap.value?.set(node.id, { visible: true, expand: Array.isArray(node.items), selected: true, draggable: true, }); }); }); }); services?.editorService.on('remove', (nodes: MNode[]) => { nodes.forEach((node) => { traverseNode(node, (node: MNode) => { nodeStatusMap.value?.delete(node.id); }); }); }); return { nodeStatusMaps, nodeStatusMap, }; };