mxivideo/src/components/timeline/SegmentTooltip.tsx

136 lines
4.0 KiB
TypeScript

import React from 'react'
interface TrackSegment {
id: string
type: 'video' | 'audio' | 'image' | 'text' | 'effect'
name: string
start_time: number
end_time: number
duration: number
resource_path?: string
properties?: any
effects?: any[]
}
interface SegmentTooltipProps {
segment: TrackSegment | null
position: { x: number; y: number }
isVisible: boolean
}
export const SegmentTooltip: React.FC<SegmentTooltipProps> = ({
segment,
position,
isVisible
}) => {
const formatTime = (seconds: number): string => {
const minutes = Math.floor(seconds / 60)
const secs = (seconds % 60).toFixed(2)
return `${minutes}:${secs.padStart(5, '0')}`
}
const getTypeLabel = (type: string) => {
switch (type) {
case 'video': return '视频'
case 'audio': return '音频'
case 'image': return '图片'
case 'text': return '文本'
case 'effect': return '特效'
default: return '未知'
}
}
const getTypeColor = (type: string) => {
switch (type) {
case 'video': return 'bg-blue-100 text-blue-800'
case 'audio': return 'bg-green-100 text-green-800'
case 'image': return 'bg-yellow-100 text-yellow-800'
case 'text': return 'bg-purple-100 text-purple-800'
case 'effect': return 'bg-gray-100 text-gray-800'
default: return 'bg-gray-100 text-gray-800'
}
}
if (!isVisible || !segment) return null
return (
<div
className="fixed bg-gray-900 text-white rounded-lg shadow-xl p-4 z-50 max-w-sm pointer-events-none"
style={{
left: position.x + 10,
top: position.y - 10,
transform: 'translateY(-100%)'
}}
>
{/* Segment Name */}
<div className="flex items-center gap-2 mb-3">
<span className={`px-2 py-1 rounded text-xs font-medium ${getTypeColor(segment.type)}`}>
{getTypeLabel(segment.type)}
</span>
<h3 className="font-semibold text-white">{segment.name}</h3>
</div>
{/* Time Information */}
<div className="space-y-2 text-sm">
<div className="grid grid-cols-2 gap-4">
<div>
<span className="text-gray-300">:</span>
<div className="font-mono text-white">{formatTime(segment.start_time)}</div>
</div>
<div>
<span className="text-gray-300">:</span>
<div className="font-mono text-white">{formatTime(segment.end_time)}</div>
</div>
</div>
<div>
<span className="text-gray-300">:</span>
<div className="font-mono text-white">{formatTime(segment.duration)}</div>
</div>
{/* Resource Path */}
{segment.resource_path && (
<div>
<span className="text-gray-300">:</span>
<div className="text-white text-xs break-all">
{segment.resource_path.split('/').pop() || segment.resource_path}
</div>
</div>
)}
{/* Effects */}
{segment.effects && segment.effects.length > 0 && (
<div>
<span className="text-gray-300">:</span>
<div className="text-white text-xs">
{segment.effects.length}
</div>
</div>
)}
{/* Properties */}
{segment.properties && Object.keys(segment.properties).length > 0 && (
<div>
<span className="text-gray-300">:</span>
<div className="text-white text-xs">
{Object.keys(segment.properties).length}
</div>
</div>
)}
</div>
{/* Tooltip Arrow */}
<div
className="absolute bottom-0 left-4 transform translate-y-full"
style={{
width: 0,
height: 0,
borderLeft: '6px solid transparent',
borderRight: '6px solid transparent',
borderTop: '6px solid rgb(17, 24, 39)' // gray-900
}}
/>
</div>
)
}