Files
KGStudio/src/components/track/TrackInfoPanel.tsx
T

108 lines
3.4 KiB
TypeScript

import React, { useState } from 'react';
import './Track.css';
import { KGTrack } from '../../core/track/KGTrack';
import { useProjectStore } from '../../stores/projectStore';
import TrackInfoItem from './TrackInfoItem';
interface TrackInfoPanelProps {
tracks: KGTrack[];
onTrackClick?: () => void;
onTrackNameEdit: (track: KGTrack, newName: string) => void;
onTracksReordered: (fromIndex: number, toIndex: number) => void;
}
const TrackInfoPanel: React.FC<TrackInfoPanelProps> = ({
tracks,
onTrackClick,
onTrackNameEdit,
onTracksReordered
}) => {
const { setSelectedTrack } = useProjectStore();
// Drag state for track reordering
const [draggedTrackIndex, setDraggedTrackIndex] = useState<number | null>(null);
const [dragOverTrackIndex, setDragOverTrackIndex] = useState<number | null>(null);
// Handle track drag events
const handleTrackDragStart = (e: React.DragEvent<HTMLDivElement>, index: number) => {
setDraggedTrackIndex(index);
// Set a custom drag image or data if needed
e.dataTransfer.setData('text/plain', index.toString());
e.dataTransfer.effectAllowed = 'move';
// Add a class to the dragged element - store a reference to avoid null issues
const element = e.currentTarget;
if (element) {
// Add class immediately instead of using setTimeout
element.classList.add('dragging');
}
};
const handleTrackDragOver = (e: React.DragEvent<HTMLDivElement>, index: number) => {
e.preventDefault(); // Necessary to allow dropping
// Only update if the drag over index has changed
if (dragOverTrackIndex !== index) {
setDragOverTrackIndex(index);
}
e.dataTransfer.dropEffect = 'move';
};
const handleTrackDrop = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
if (draggedTrackIndex !== null && dragOverTrackIndex !== null && draggedTrackIndex !== dragOverTrackIndex) {
// Notify parent component about the reordering
onTracksReordered(draggedTrackIndex, dragOverTrackIndex);
// Select the track that was moved (it's now at the dragOverTrackIndex position)
const movedTrack = tracks[draggedTrackIndex];
if (movedTrack) {
setSelectedTrack(movedTrack.getId().toString());
}
}
// Reset drag state
setDraggedTrackIndex(null);
setDragOverTrackIndex(null);
// Remove the dragging class from all elements
document.querySelectorAll('.track-info.dragging').forEach(el => {
el.classList.remove('dragging');
});
};
const handleTrackDragEnd = (e: React.DragEvent<HTMLDivElement>) => {
// Reset drag state
setDraggedTrackIndex(null);
setDragOverTrackIndex(null);
// Remove the dragging class
if (e.currentTarget) {
e.currentTarget.classList.remove('dragging');
}
};
return (
<div className="info-container">
{tracks.map((track, index) => (
<TrackInfoItem
key={track.getId()}
track={track}
index={index}
isDragging={draggedTrackIndex === index}
isDragOver={dragOverTrackIndex === index}
onTrackClick={onTrackClick}
onTrackNameEdit={onTrackNameEdit}
onDragStart={handleTrackDragStart}
onDragOver={handleTrackDragOver}
onDrop={handleTrackDrop}
onDragEnd={handleTrackDragEnd}
/>
))}
</div>
);
};
export default TrackInfoPanel;