fix
This commit is contained in:
parent
8908f0c9c1
commit
455d929ba5
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react'
|
||||
import { SegmentContextMenu } from './SegmentContextMenu'
|
||||
import { SegmentTooltip } from './SegmentTooltip'
|
||||
import { ResourceCategoryServiceV2, ResourceCategoryV2 } from '../../services/resourceCategoryServiceV2'
|
||||
|
||||
export interface TrackSegment {
|
||||
id: string
|
||||
|
|
@ -40,7 +41,6 @@ export const TrackTimeline: React.FC<TrackTimelineProps> = ({
|
|||
onSegmentNameChange
|
||||
}) => {
|
||||
const [editingSegmentId, setEditingSegmentId] = React.useState<string | null>(null)
|
||||
const [editingName, setEditingName] = React.useState('')
|
||||
const [contextMenu, setContextMenu] = React.useState<{
|
||||
isOpen: boolean
|
||||
position: { x: number; y: number }
|
||||
|
|
@ -48,6 +48,31 @@ export const TrackTimeline: React.FC<TrackTimelineProps> = ({
|
|||
}>({ isOpen: false, position: { x: 0, y: 0 }, segment: null })
|
||||
const [hoveredSegment, setHoveredSegment] = React.useState<TrackSegment | null>(null)
|
||||
const [mousePosition, setMousePosition] = React.useState({ x: 0, y: 0 })
|
||||
const [categories, setCategories] = React.useState<ResourceCategoryV2[]>([])
|
||||
const [loadingCategories, setLoadingCategories] = React.useState(false)
|
||||
|
||||
// 加载分类数据
|
||||
const loadCategories = React.useCallback(async () => {
|
||||
if (loadingCategories) return
|
||||
|
||||
try {
|
||||
setLoadingCategories(true)
|
||||
const result = await ResourceCategoryServiceV2.getAllCategories({
|
||||
include_cloud: true
|
||||
})
|
||||
setCategories(result)
|
||||
} catch (error) {
|
||||
console.error('Failed to load categories:', error)
|
||||
} finally {
|
||||
setLoadingCategories(false)
|
||||
}
|
||||
}, [loadingCategories])
|
||||
|
||||
// 组件挂载时加载分类
|
||||
React.useEffect(() => {
|
||||
loadCategories()
|
||||
}, [loadCategories])
|
||||
|
||||
const getSegmentColor = (type: string) => {
|
||||
switch (type) {
|
||||
case 'video': return 'bg-blue-500 hover:bg-blue-600'
|
||||
|
|
@ -85,9 +110,13 @@ export const TrackTimeline: React.FC<TrackTimelineProps> = ({
|
|||
return `${minutes}:${secs.padStart(5, '0')}`
|
||||
}
|
||||
|
||||
const handleSegmentDoubleClick = (segment: TrackSegment) => {
|
||||
const handleSegmentDoubleClick = async (segment: TrackSegment) => {
|
||||
setEditingSegmentId(segment.id)
|
||||
setEditingName(segment.name)
|
||||
|
||||
// 确保分类数据已加载
|
||||
if (categories.length === 0 && !loadingCategories) {
|
||||
await loadCategories()
|
||||
}
|
||||
}
|
||||
|
||||
const handleSegmentRightClick = (e: React.MouseEvent, segment: TrackSegment) => {
|
||||
|
|
@ -101,26 +130,14 @@ export const TrackTimeline: React.FC<TrackTimelineProps> = ({
|
|||
})
|
||||
}
|
||||
|
||||
const handleNameSubmit = (segmentId: string) => {
|
||||
if (onSegmentNameChange && editingName.trim()) {
|
||||
onSegmentNameChange(segmentId, editingName.trim())
|
||||
const handleCategorySelect = (segmentId: string, categoryTitle: string) => {
|
||||
if (onSegmentNameChange && categoryTitle) {
|
||||
onSegmentNameChange(segmentId, categoryTitle)
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
const handleSegmentMouseEnter = (e: React.MouseEvent, segment: TrackSegment) => {
|
||||
setHoveredSegment(segment)
|
||||
|
|
@ -141,10 +158,14 @@ export const TrackTimeline: React.FC<TrackTimelineProps> = ({
|
|||
setContextMenu({ isOpen: false, position: { x: 0, y: 0 }, segment: null })
|
||||
}
|
||||
|
||||
const handleContextMenuEdit = () => {
|
||||
const handleContextMenuEdit = async () => {
|
||||
if (contextMenu.segment) {
|
||||
setEditingSegmentId(contextMenu.segment.id)
|
||||
setEditingName(contextMenu.segment.name)
|
||||
|
||||
// 确保分类数据已加载
|
||||
if (categories.length === 0 && !loadingCategories) {
|
||||
await loadCategories()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,16 +226,38 @@ export const TrackTimeline: React.FC<TrackTimelineProps> = ({
|
|||
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}` : ''}`}
|
||||
>
|
||||
{editingSegmentId === segment.id ? (
|
||||
<input
|
||||
type="text"
|
||||
value={editingName}
|
||||
onChange={(e) => 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()}
|
||||
/>
|
||||
<div className="w-full relative" onClick={(e) => e.stopPropagation()}>
|
||||
{loadingCategories ? (
|
||||
<div className="w-full bg-white text-gray-900 border border-gray-300 rounded px-2 py-1 text-sm">
|
||||
加载分类中...
|
||||
</div>
|
||||
) : (
|
||||
<select
|
||||
value=""
|
||||
onChange={(e) => {
|
||||
if (e.target.value) {
|
||||
handleCategorySelect(segment.id, e.target.value)
|
||||
}
|
||||
}}
|
||||
onBlur={() => setEditingSegmentId(null)}
|
||||
className="w-full bg-white text-gray-900 border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer"
|
||||
autoFocus
|
||||
size={Math.min(categories.length + 2, 8)} // 限制下拉框高度
|
||||
>
|
||||
<option value="">选择分类...</option>
|
||||
<option value={segment.name} className="text-gray-600">
|
||||
保持原名称: {segment.name}
|
||||
</option>
|
||||
{categories
|
||||
.filter(category => category.is_active)
|
||||
.map((category) => (
|
||||
<option key={category.id} value={category.title} className="flex items-center">
|
||||
{category.title}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="truncate flex-1">
|
||||
{segment.name}
|
||||
|
|
|
|||
|
|
@ -400,7 +400,6 @@ const TemplateDetailPageV2: React.FC = () => {
|
|||
<h2 className="text-lg font-semibold text-gray-900 mb-4">轨道时间轴</h2>
|
||||
<div className="space-y-4">
|
||||
{templateDetail.tracks.map((track) => {
|
||||
console.log(track)
|
||||
return (
|
||||
<TrackTimeline
|
||||
key={track.id}
|
||||
|
|
|
|||
Loading…
Reference in New Issue