import { ContainerEdit } from '@kevisual/container/edit'; import { useCallback, useEffect, useRef, useState } from 'react'; import { useParams } from 'react-router'; import { query, useStore, ws } from '@/modules'; import { Button, message, Tooltip } from 'antd'; import { getContainerData } from '@/modules/deck-to-flow/deck'; import { usePanelStore } from '../store'; import { useShallow } from 'zustand/react/shallow'; import { TextArea } from '@/pages/container/components/TextArea'; import { CloseOutlined, MessageOutlined, SaveOutlined, SelectOutlined } from '@ant-design/icons'; import { useDeckPageStore } from './deck-store'; import { FormModal } from './Model.tsx'; import { useAiStore } from '@/pages/ai-chat/index.tsx'; export const clearBlank = (newStyle: any) => { let change = false; for (let key in newStyle) { if (newStyle[key] === '' || newStyle[key] === undefined || newStyle[key] === null) { delete newStyle[key]; change = true; } } return change; }; export const useListener = (id?: string, opts?: any) => { const { refresh, cids = [] } = opts || {}; const connected = useStore((state) => state.connected); // 监听服务器的消息 useEffect(() => { if (!id) return; if (!connected) return; if (cids.length === 0) return; console.log('cids', cids); ws.send( JSON.stringify({ type: 'subscribe', data: { type: 'pageEdit', data: { pid: id, cids: cids, }, }, }), ); ws.addEventListener('message', listener); return () => { if (!id) return; if (!connected) return; ws.removeEventListener('message', listener); }; }, [id, connected, cids]); const listener = (event) => { const parseIfJson = (data: string) => { try { return JSON.parse(data); } catch (e) { return data; } }; const receivedData = parseIfJson(event.data); if (typeof receivedData === 'string') return; if (receivedData.type === 'pageEdit' && receivedData.source === 'container') { const { data: containerData, pid } = receivedData; if (pid !== id) return; if (refresh) { refresh(containerData); } } }; }; export const Deck = () => { const params = useParams<{ id: string }>(); const id = params.id; const ref = useRef(null); const containerRef = useRef(null); const deckPageStore = useDeckPageStore(); const { code, setCode } = deckPageStore; const { selected, setSelected } = deckPageStore; const { cids } = deckPageStore; const aiStore = useAiStore( useShallow((state) => { return { setOpen: state.setOpen, setKey: state.setKey, }; }), ); const panelStore = usePanelStore( useShallow((state) => { return { updateNodeDataStyle: state.updateNodeDataStyle, }; }), ); useEffect(() => { if (!id) return; deckPageStore.setId(id); fetch(); }, []); useEffect(() => { ref.current?.addEventListener('onContainer', onContainer); return () => { ref.current?.removeEventListener('onContainer', onContainer); if (ref.current) { const children = ref.current; children.innerHTML = ''; } }; }, []); const fetch = async () => { const res = await query.post({ path: 'page', key: 'getDeck', id, }); if (res.code === 200) { const data = res.data; console.log('data', data); const { page, containerList } = data; const result = getContainerData({ page, containerList }); console.log('result', result); deckPageStore.setPageData(result); deckPageStore.setCids(); init(result); } }; const refresh = async (data: any) => { console.log('refresh', data); if (!data.id) return; const code = { codeId: data.id, code: data.code, hash: '', }; const container = containerRef.current!; // @ts-ignore await container.updateDataCode([code]); const containerList = container.data.filter((item) => item.codeId === data.id); await new Promise((resolve) => { setTimeout(resolve, 2000); }); // container.reRender(); containerList.forEach((item) => { container.renderId(item.id); }); // @ts-ignore window.c = container; }; useListener(id, { refresh, cids }); const onContainer = (e) => { const { data } = e; const types = ['position', 'resize']; if (types.includes(data.type)) { const { type, data: containerData } = data; if (type === 'position') { const { cid, left, top, rid } = containerData; const newData = { id: rid, nodeData: { id: cid, data: { style: { // position: 'absolute', left, top, }, }, }, }; if (left && top) { panelStore.updateNodeDataStyle(newData); } updateStyle(cid, { left, top }); setTimeout(() => { setCodeStyle(cid); }, 1000); } else if (type === 'resize') { const { cid, rid, width, height } = containerData; const newData = { id: rid, nodeData: { id: cid, data: { style: { width, height, }, }, }, }; if (width && height) { // @ts-ignore newData.nodeData.data.style.position = 'absolute'; panelStore.updateNodeDataStyle(newData); } updateStyle(cid, { width, height }); setTimeout(() => { setCodeStyle(cid); }, 1000); } } else if (data.type === 'active') { if (!data?.data?.cid) { setSelected(null); return; } const { cid, rid } = data?.data || {}; setSelected(data); setCodeStyle(cid); } else { console.log('onContainer', data); } }; const onSave = () => { const { cid, rid } = selected?.data || {}; let data: any; try { data = JSON.parse(code); } catch (error) { message.error('JSON format error'); return; } // clearBlank(data); const newData = { id: rid, nodeData: { id: cid, data: { style: data, }, }, }; panelStore.updateNodeDataStyle(newData, true); const newDataStyle = updateStyle(cid, data); reRender(newDataStyle, cid); }; const setCodeStyle = (cid: string) => { const pageData = deckPageStore.getPageData(); const selected = deckPageStore.getSeleted(); const _data = pageData.find((item) => item.id === cid); const node = _data?.data?.node || {}; if (selected?.data?.cid === cid) { setCode(''); setCode(JSON.stringify(node?.data?.style || {}, null, 2)); } }; useEffect(() => { if (selected) { const { cid } = selected?.data || {}; cid && setCodeStyle(cid); } }, [deckPageStore.selected]); const updateStyle = (rid: string, style: any) => { const pageData = deckPageStore.getPageData(); const _pageData = pageData.map((item) => { if (item.id === rid) { const newStyle = { ...item.data.node.data.style, ...style, }; // 过滤掉空的style clearBlank(newStyle); return { ...item, style: newStyle, data: { ...item.data, node: { ...item.data.node, data: { ...item.data.node.data, style: newStyle, }, }, }, }; } return item; }); deckPageStore.setPageData([..._pageData]); return _pageData; }; const init = async (data: any[]) => { // console.log('data', data, ref.current); const container = new ContainerEdit({ root: ref.current!, data: data, showChild: true, // edit: false, }); container.render(id!); containerRef.current = container; containerRef.current.event.on('save', (data) => { console.log('save', data); const { id, code } = data; }); }; const reRender = async (data: any[], cid?: string) => { if (containerRef.current) { const container = containerRef.current; await container.updateData(data); await container.renderId(cid!); return; } }; return (
Deck
{selected && (
{/*
{JSON.stringify(selected, null, 2)}
*/}