diff --git a/src/components/timeline/TrackTimeline.tsx b/src/components/timeline/TrackTimeline.tsx index ad2a166..0dc227a 100644 --- a/src/components/timeline/TrackTimeline.tsx +++ b/src/components/timeline/TrackTimeline.tsx @@ -27,6 +27,7 @@ interface TrackTimelineProps { currentTime: number onSegmentClick?: (segment: TrackSegment) => void onSegmentHover?: (segment: TrackSegment | null) => void + onSegmentNameChange?: (segmentId: string, newName: string) => void } export const TrackTimeline: React.FC = ({ @@ -34,8 +35,11 @@ export const TrackTimeline: React.FC = ({ totalDuration, currentTime, onSegmentClick, - onSegmentHover + onSegmentHover, + onSegmentNameChange }) => { + const [editingSegmentId, setEditingSegmentId] = React.useState(null) + const [editingName, setEditingName] = React.useState('') const getSegmentColor = (type: string) => { switch (type) { case 'video': return 'bg-blue-500 hover:bg-blue-600' @@ -73,6 +77,38 @@ export const TrackTimeline: React.FC = ({ return `${minutes}:${secs.padStart(5, '0')}` } + const handleSegmentDoubleClick = (segment: TrackSegment) => { + setEditingSegmentId(segment.id) + setEditingName(segment.name) + } + + const handleSegmentRightClick = (e: React.MouseEvent, segment: TrackSegment) => { + e.preventDefault() + setEditingSegmentId(segment.id) + setEditingName(segment.name) + } + + const handleNameSubmit = (segmentId: string) => { + if (onSegmentNameChange && editingName.trim()) { + onSegmentNameChange(segmentId, editingName.trim()) + } + setEditingSegmentId(null) + setEditingName('') + } + + const handleNameCancel = () => { + setEditingSegmentId(null) + setEditingName('') + } + + const handleKeyDown = (e: React.KeyboardEvent, segmentId: string) => { + if (e.key === 'Enter') { + handleNameSubmit(segmentId) + } else if (e.key === 'Escape') { + handleNameCancel() + } + } + return (
{/* Track Header */} @@ -113,8 +149,8 @@ export const TrackTimeline: React.FC = ({ return (
= ({ minWidth: '80px' }} onClick={() => onSegmentClick?.(segment)} + onDoubleClick={() => handleSegmentDoubleClick(segment)} + onContextMenu={(e) => handleSegmentRightClick(e, segment)} onMouseEnter={() => onSegmentHover?.(segment)} onMouseLeave={() => onSegmentHover?.(null)} title={`${segment.name}\n类型: ${segment.type}\n开始: ${formatTime(segment.start_time)}\n结束: ${formatTime(segment.end_time)}\n时长: ${formatTime(segment.duration)}${segment.resource_path ? `\n资源: ${segment.resource_path}` : ''}`} > -
- {segment.name} -
-
- {formatTime(segment.duration)} -
+ {editingSegmentId === segment.id ? ( + setEditingName(e.target.value)} + onBlur={() => handleNameSubmit(segment.id)} + onKeyDown={(e) => handleKeyDown(e, segment.id)} + className="w-full bg-transparent text-inherit border-none outline-none" + autoFocus + onClick={(e) => e.stopPropagation()} + /> + ) : ( +
+ {segment.name} +
+ )}
) })} diff --git a/src/pages/TemplateDetailPage.tsx b/src/pages/TemplateDetailPage.tsx index 42e99d4..a3cef6f 100644 --- a/src/pages/TemplateDetailPage.tsx +++ b/src/pages/TemplateDetailPage.tsx @@ -108,6 +108,26 @@ const TemplateDetailPage: React.FC = () => { } } + const handleSegmentNameChange = (segmentId: string, newName: string) => { + if (!templateDetail) return + + // Update the segment name in the local state + const updatedDetail = { + ...templateDetail, + tracks: templateDetail.tracks.map(track => ({ + ...track, + segments: track.segments.map(segment => + segment.id === segmentId ? { ...segment, name: newName } : segment + ) + })) + } + + setTemplateDetail(updatedDetail) + + // TODO: Save to backend + console.log(`Segment ${segmentId} renamed to: ${newName}`) + } + if (loading) { return (
@@ -266,6 +286,7 @@ const TemplateDetailPage: React.FC = () => { // Could show segment details in a tooltip console.log('Hovering segment:', segment?.name) }} + onSegmentNameChange={handleSegmentNameChange} /> ))}