refactor: delete VoiceMaterialSection.tsx (#1899 #1900)

This commit is contained in:
2026-09-14 20:44:30 +08:00
parent 78741ed588
commit 33a09b1a6c
@@ -1,132 +0,0 @@
import React from "react"
import { useNavigate } from "react-router-dom"
import type { ClipData } from "@/pages/editing-planner/types"
import { getGenderLabel } from "@/pages/editing-planner/utils/clipProperties"
import type { AssetItem } from "@/api/assets"
interface VoiceMaterialSectionProps {
clip: ClipData
voiceMaterials: AssetItem[]
voiceMaterialsLoading: boolean
onClipUpdate: (clipId: string, data: Partial<ClipData>) => void
onRefreshVoiceMaterials?: () => void
onClipVoiceSelect?: (clipId: string, asset: AssetItem | null) => void
previewingId: string | null
onPreviewVoice: (asset: AssetItem) => void
onStopPreview: () => void
}
/**
* 配音素材选择区(仅 voice 类型显示)
*/
export const VoiceMaterialSection: React.FC<VoiceMaterialSectionProps> = ({
clip,
voiceMaterials,
voiceMaterialsLoading,
onClipUpdate,
onRefreshVoiceMaterials,
onClipVoiceSelect,
previewingId,
onPreviewVoice,
onStopPreview,
}) => {
const navigate = useNavigate()
return (
<>
{/* 素材起始时间 */}
<div className="ep-clip-detail-field">
<div className="ep-clip-detail-label">素材起始时间</div>
<div className="ep-clip-detail-row">
<input
className="ep-duration-input"
type="number"
min={0}
max={9999}
step={0.1}
value={clip.startOffset}
onChange={(e) =>
onClipUpdate(clip.id, {
startOffset: Math.max(0, Math.min(9999, Number(e.target.value) || 0)),
})
}
/>
<span className="ep-clip-detail-unit">秒</span>
</div>
</div>
{/* 配音素材选择 */}
<div className="ep-clip-detail-field">
<div className="ep-clip-detail-label">
配音素材
{onRefreshVoiceMaterials && (
<button
type="button"
className="ep-voice-refresh-btn"
title="刷新配音列表"
onClick={() => onRefreshVoiceMaterials()}
disabled={voiceMaterialsLoading}
>
{voiceMaterialsLoading ? "⏳" : "🔄"}
</button>
)}
</div>
{voiceMaterialsLoading && voiceMaterials.length === 0 ? (
<div className="ep-voice-loading">加载中...</div>
) : (
<>
<div className="ep-voice-select-row">
<select
className="ep-clip-detail-select"
value={clip.voice_asset_id ?? ""}
onChange={(e) => {
const assetId = e.target.value
if (!onClipVoiceSelect) return
if (!assetId) {
onClipVoiceSelect(clip.id, null)
} else {
const asset = voiceMaterials.find((m) => m.id === assetId)
if (asset) onClipVoiceSelect(clip.id, asset)
}
onStopPreview()
}}
>
<option value="">未选择</option>
{voiceMaterials.map((m) => {
const gender = getGenderLabel(m)
const label = gender ? `${m.name}(${gender})` : m.name
return (
<option key={m.id} value={m.id}>
{label}
</option>
)
})}
</select>
{clip.voice_asset_id && (
<button
type="button"
className="ep-voice-preview-btn"
title={previewingId === clip.voice_asset_id ? "暂停" : "试听"}
onClick={() => {
const asset = voiceMaterials.find((m) => m.id === clip.voice_asset_id)
if (asset) onPreviewVoice(asset)
}}
>
{previewingId === clip.voice_asset_id ? "⏸" : "▶️"}
</button>
)}
</div>
{voiceMaterials.length === 0 && (
<div className="ep-voice-empty">暂无配音素材,请先上传</div>
)}
</>
)}
<button className="ep-voice-upload-btn" onClick={() => navigate("/app/voice-materials")}>
+ 上传新配音
</button>
</div>
</>
)
}