1- import { useState , useCallback } from "react" ;
1+ import { useState , useCallback , useMemo } from "react" ;
22import {
33 ReactFlow ,
44 MiniMap ,
@@ -16,33 +16,19 @@ import "@xyflow/react/dist/style.css";
1616import { Button } from "@/components/ui/button" ;
1717import { Input } from "@/components/ui/input" ;
1818import { Textarea } from "@/components/ui/textarea" ;
19- import { ArrowLeft , MessageSquare , Plus , Square , Circle , X } from "lucide-react" ;
19+ import { ArrowLeft , MessageSquare , Plus , FileText , Image , Video , Music , X } from "lucide-react" ;
2020import { Card } from "@/components/ui/card" ;
21+ import { TextNode , ImageNode , VideoNode , AudioNode , type NodeType } from "./nodes" ;
2122
2223interface CanvasViewProps {
2324 projectId : string ;
2425 projectName : string ;
2526 onBack : ( ) => void ;
2627}
2728
28- const initialNodes : Node [ ] = [
29- {
30- id : "1" ,
31- type : "default" ,
32- data : { label : "开始节点" } ,
33- position : { x : 250 , y : 100 } ,
34- } ,
35- {
36- id : "2" ,
37- type : "default" ,
38- data : { label : "处理节点" } ,
39- position : { x : 250 , y : 250 } ,
40- } ,
41- ] ;
29+ const initialNodes : Node [ ] = [ ] ;
4230
43- const initialEdges : Edge [ ] = [
44- { id : "e1-2" , source : "1" , target : "2" , animated : true } ,
45- ] ;
31+ const initialEdges : Edge [ ] = [ ] ;
4632
4733export function CanvasView ( {
4834 projectId,
@@ -54,12 +40,55 @@ export function CanvasView({
5440 const [ chatMessage , setChatMessage ] = useState ( "" ) ;
5541 const [ nodes , setNodes , onNodesChange ] = useNodesState ( initialNodes ) ;
5642 const [ edges , setEdges , onEdgesChange ] = useEdgesState ( initialEdges ) ;
43+ const [ nodeIdCounter , setNodeIdCounter ] = useState ( 1 ) ;
44+
45+ // Define custom node types
46+ const nodeTypes = useMemo (
47+ ( ) => ( {
48+ text : TextNode ,
49+ image : ImageNode ,
50+ video : VideoNode ,
51+ audio : AudioNode ,
52+ } ) ,
53+ [ ]
54+ ) ;
5755
5856 const onConnect = useCallback (
59- ( connection : Connection ) => setEdges ( ( eds ) => addEdge ( connection , eds ) ) ,
57+ ( connection : Connection ) => {
58+ // Create animated edge with data flow
59+ const newEdge = {
60+ ...connection ,
61+ animated : true ,
62+ style : { stroke : '#3b82f6' } ,
63+ } ;
64+ setEdges ( ( eds ) => addEdge ( newEdge , eds ) ) ;
65+
66+ // TODO: Trigger data processing from source to target node
67+ // This would involve calling your AI model API
68+ } ,
6069 [ setEdges ]
6170 ) ;
6271
72+ const addNode = useCallback (
73+ ( type : NodeType ) => {
74+ const newNode : Node = {
75+ id : `node-${ nodeIdCounter } ` ,
76+ type : type ,
77+ position : {
78+ x : Math . random ( ) * 400 + 100 ,
79+ y : Math . random ( ) * 400 + 100
80+ } ,
81+ data : {
82+ label : `${ type === 'text' ? '文本' : type === 'image' ? '图片' : type === 'video' ? '视频' : '音频' } 节点 ${ nodeIdCounter } ` ,
83+ type : type ,
84+ } ,
85+ } ;
86+ setNodes ( ( nds ) => [ ...nds , newNode ] ) ;
87+ setNodeIdCounter ( ( c ) => c + 1 ) ;
88+ } ,
89+ [ nodeIdCounter , setNodes ]
90+ ) ;
91+
6392 return (
6493 < div className = "flex h-full relative" >
6594 { /* 主要内容区域 - 全屏 */ }
@@ -93,14 +122,37 @@ export function CanvasView({
93122 < div className = "absolute left-4 top-20 z-10 flex flex-col gap-2" >
94123 < Card className = "p-2 shadow-lg" >
95124 < div className = "flex flex-col gap-2" >
96- < Button variant = "ghost" size = "icon" title = "添加节点" >
97- < Plus className = "h-4 w-4" />
125+ < Button
126+ variant = "ghost"
127+ size = "icon"
128+ title = "文本节点"
129+ onClick = { ( ) => addNode ( "text" ) }
130+ >
131+ < FileText className = "h-4 w-4" />
98132 </ Button >
99- < Button variant = "ghost" size = "icon" title = "矩形" >
100- < Square className = "h-4 w-4" />
133+ < Button
134+ variant = "ghost"
135+ size = "icon"
136+ title = "图片节点"
137+ onClick = { ( ) => addNode ( "image" ) }
138+ >
139+ < Image className = "h-4 w-4" />
140+ </ Button >
141+ < Button
142+ variant = "ghost"
143+ size = "icon"
144+ title = "视频节点"
145+ onClick = { ( ) => addNode ( "video" ) }
146+ >
147+ < Video className = "h-4 w-4" />
101148 </ Button >
102- < Button variant = "ghost" size = "icon" title = "圆形" >
103- < Circle className = "h-4 w-4" />
149+ < Button
150+ variant = "ghost"
151+ size = "icon"
152+ title = "音频节点"
153+ onClick = { ( ) => addNode ( "audio" ) }
154+ >
155+ < Music className = "h-4 w-4" />
104156 </ Button >
105157 </ div >
106158 </ Card >
@@ -114,6 +166,7 @@ export function CanvasView({
114166 onNodesChange = { onNodesChange }
115167 onEdgesChange = { onEdgesChange }
116168 onConnect = { onConnect }
169+ nodeTypes = { nodeTypes }
117170 fitView
118171 >
119172 < Controls />
0 commit comments