/ src / components / DreamSpace.jsx
DreamSpace.jsx
 1  import React, { useState, useEffect, useCallback } from 'react';
 2  import { Canvas } from '@react-three/fiber';
 3  import * as THREE from 'three';
 4  import DreamGraph from './DreamGraph';
 5  import CameraController from './CameraController';
 6  import useDreamNodes from '../hooks/useDreamNodes';
 7  
 8  const DreamSpace = ({ onNodeRightClick, onFileRightClick, dreamGraphRef, onDrop, onHover }) => {
 9    const { dreamNodes, error } = useDreamNodes();
10    const [initialNodes, setInitialNodes] = useState([]);
11    const [resetCamera, setResetCamera] = useState(null);
12    const [hoveredNode, setHoveredNode] = useState(null);
13  
14    useEffect(() => {
15      if (dreamNodes.length > 0) {
16        setInitialNodes(dreamNodes.map(node => ({
17          ...node
18        })));
19      }
20    }, [dreamNodes]);
21  
22    const handleNodeRightClick = (event, repoName) => {
23      onNodeRightClick(repoName, event);
24    };
25  
26    const onResetCamera = useCallback((resetFunc) => {
27      setResetCamera(() => resetFunc);
28    }, []);
29  
30    const handleDrop = useCallback((event) => {
31      event.preventDefault();
32      if (hoveredNode) {
33        console.log(`Item dropped on ${hoveredNode}`);
34      } else {
35        onDrop(event);
36      }
37    }, [hoveredNode, onDrop]);
38  
39    const handleHover = useCallback((repoName) => {
40      setHoveredNode(repoName);
41      if (onHover) {
42        onHover(repoName);
43      }
44    }, [onHover]);
45  
46    useEffect(() => {
47      const handleKeyDown = (event) => {
48        if (event.key === 'Escape' && resetCamera) {
49          resetCamera();
50        }
51      };
52  
53      window.addEventListener('keydown', handleKeyDown);
54      window.addEventListener('dragover', (e) => e.preventDefault());
55      window.addEventListener('drop', handleDrop);
56  
57      return () => {
58        window.removeEventListener('keydown', handleKeyDown);
59        window.removeEventListener('dragover', (e) => e.preventDefault());
60        window.removeEventListener('drop', handleDrop);
61      };
62    }, [resetCamera, handleDrop]);
63  
64    if (error) {
65      return <div>Error: {error}</div>;
66    }
67  
68    return (
69      <div style={{ width: '100vw', height: '100vh' }}>
70        <Canvas camera={{ position: [0, 0, 100], fov: 75, near: 0.1, far: 3000 }}>
71          <CameraController onResetCamera={onResetCamera} />
72          <ambientLight intensity={0.5} />
73          <pointLight position={[10, 10, 10]} />
74          {initialNodes.length > 0 && (
75            <DreamGraph 
76              ref={dreamGraphRef}
77              initialNodes={initialNodes} 
78              onNodeRightClick={handleNodeRightClick}
79              onFileRightClick={onFileRightClick}
80              resetCamera={resetCamera}
81              onHover={handleHover}
82            />
83          )}
84        </Canvas>
85        {dreamNodes.length === 0 && (
86          <div style={{ color: 'white', position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}>
87            Loading...
88          </div>
89        )}
90      </div>
91    );
92  };
93  
94  export default DreamSpace;