diff --git a/src/App.js b/src/App.js index 0c895d9..56f41be 100644 --- a/src/App.js +++ b/src/App.js @@ -30,7 +30,8 @@ const TreeNode = React.forwardRef(({ }, ref) => { const [children, setChildren] = useState([]); const isExpanded = expandedPaths.includes(item.path); - + const itemRef = ref || React.createRef(); // Use the forwarded ref or create a new one + // Update your expand function const expand = useCallback(async (item) => { @@ -70,7 +71,31 @@ const TreeNode = React.forwardRef(({ performExpand(); }, [item, isExpanded, invoke]); - + useEffect(() => { + // Only scroll into view if the current item is selected and not already in view + if (isSelected(item.path) && !isItemInView(itemRef.current)) { + itemRef.current.scrollIntoView({ + behavior: 'smooth', + block: 'nearest' + }); + } + }, [isSelected, item.path, itemRef]); + + // Helper function to check if the element is in view + function isItemInView(element) { + if (!element) { + return false; + } + const rect = element.getBoundingClientRect(); + return ( + rect.top >= 0 && + rect.left >= 0 && + rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && + rect.right <= (window.innerWidth || document.documentElement.clientWidth) + ); + } + + const handleToggle = (e) => { e.stopPropagation(); if (item.is_dir) { @@ -99,6 +124,7 @@ const TreeNode = React.forwardRef(({ return (
{ - // State hooks for play state and progress - const [isPlaying, setIsPlaying] = useState(true); // State for if the animation is playing - const [progress, setProgress] = useState(0); // State for the progress of the animation - const animationRef = useRef(null); // Ref hook to reference the animation DOM element + const [isPlaying, setIsPlaying] = useState(true); + const [progress, setProgress] = useState(0); + const animationRef = useRef(null); + const progressBarRef = useRef(null); - // Effect hook to handle play/pause changes useEffect(() => { if (animationRef.current) { - if (isPlaying) { - animationRef.current.play(); // Play animation if isPlaying is true - } else { - animationRef.current.pause(); // Pause animation if isPlaying is false - } + isPlaying ? animationRef.current.play() : animationRef.current.pause(); } - }, [isPlaying]); // This effect depends on the isPlaying state + }, [isPlaying]); + - // Effect hook to handle progress changes useEffect(() => { if (animationRef.current) { const frame = Math.floor(animationRef.current.totalFrames * progress); - animationRef.current.goToAndStop(frame, true); // Go to a specific frame based on progress + animationRef.current.goToAndStop(frame, true); } - }, [progress]); // This effect depends on the progress state + }, [progress]); - // Function to toggle the play state - const togglePlay = () => { - setIsPlaying(!isPlaying); // Sets isPlaying to the opposite of its current state - }; + const togglePlay = () => setIsPlaying(!isPlaying); - // Function to update the progress state - const updateProgress = (value) => { - setProgress(parseFloat(value)); // Parses the string value to a float and updates the progress state - }; + const setProgressFromEvent = useCallback((e) => { + if (progressBarRef.current) { + const bounds = progressBarRef.current.getBoundingClientRect(); + const newProgress = (e.clientX - bounds.left) / bounds.width; + setProgress(Math.min(Math.max(0, newProgress), 1)); + } else { + console.log('progressBarRef.current is null during setProgressFromEvent'); + } + }, []); - // Function to determine the button class based on the play state - const getButtonClass = () => { - return isPlaying ? "playBtn" : "pauseBtn"; // Returns the appropriate class name based on isPlaying + const handleMouseMove = useCallback((e) => { + if (progressBarRef.current) { + setProgressFromEvent(e); + } else { + console.log('progressBarRef.current is null during handleMouseMove'); + } + }, [setProgressFromEvent]); + + const handleMouseUp = useCallback(() => { + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + }, [handleMouseMove]); + + const handleMouseDown = useCallback((event) => { + event.preventDefault(); + setProgressFromEvent(event); + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + }, [setProgressFromEvent, handleMouseMove, handleMouseUp]); + + // Function to update progress when animation updates + const handleAnimationUpdate = (animationProgress) => { + setProgress(animationProgress); }; - // The component returns a UI structure rendered as JSX return (
{ isPlaying={isPlaying} progress={progress} animationRef={animationRef} + onEnterFrame={({ currentTime, totalTime }) => handleAnimationUpdate(currentTime / totalTime)} />
- updateProgress(e.target.value)} - /> +
+ + +
); }; -export default PlayerUI; // Exports the component for use in other parts of the application +export default PlayerUI; diff --git a/src/svgUIelements/progressBar.svg b/src/svgUIelements/progressBar.svg new file mode 100644 index 0000000..5201a99 --- /dev/null +++ b/src/svgUIelements/progressBar.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/svgUIelements/progressBarHandle.svg b/src/svgUIelements/progressBarHandle.svg new file mode 100644 index 0000000..5f2fbcf --- /dev/null +++ b/src/svgUIelements/progressBarHandle.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file