fix(viral-video): 分析/生成期间不再锁定页面其他控件(P0) #2141
@@ -560,8 +560,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
)
|
||||
|
||||
/* ── 图片 ── */
|
||||
const canEditAssets = task.uiStep === "step1_upload" || task.uiStep === "failed"
|
||||
|
||||
const appendImagesFromFiles = useCallback(
|
||||
async (files: FileList | File[]) => {
|
||||
const remaining = 9 - task.images.length
|
||||
@@ -964,10 +962,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
const outputUrl = task.job?.output_url || task.job?.result_video_url
|
||||
const errMsg = task.videoError || task.job?.error_message || task.job?.error_msg
|
||||
|
||||
const canEditStep2 =
|
||||
task.uiStep !== "step2_generating" &&
|
||||
task.uiStep !== "step3_generating" &&
|
||||
task.uiStep !== "step3_done"
|
||||
const step2Enabled =
|
||||
task.uiStep === "step1_done" ||
|
||||
task.uiStep === "step2_generating" ||
|
||||
@@ -1158,7 +1152,7 @@ const ViralVideoPage: React.FC = () => {
|
||||
) {
|
||||
return null
|
||||
}
|
||||
const locked = task.uiStep === "step3_generating" || task.uiStep === "step3_done"
|
||||
const locked = false
|
||||
const isMockPreview = sb === MOCK_STORYBOARD
|
||||
|
||||
return (
|
||||
@@ -1446,17 +1440,12 @@ const ViralVideoPage: React.FC = () => {
|
||||
<div className="vv-section-body" style={{ paddingTop: 4 }}>
|
||||
{/* 图片按钮 */}
|
||||
<div className="vv-action-row">
|
||||
<button
|
||||
className="vv-action-btn"
|
||||
onClick={() => imgInputRef.current?.click()}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<button className="vv-action-btn" onClick={() => imgInputRef.current?.click()}>
|
||||
<UploadOutlined /> 本地上传
|
||||
</button>
|
||||
<button
|
||||
className="vv-action-btn"
|
||||
onClick={() => setAssetPicker({ open: true, kind: "image", multiple: true })}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<FolderOpenOutlined /> 从素材库选择图片
|
||||
</button>
|
||||
@@ -1478,7 +1467,7 @@ const ViralVideoPage: React.FC = () => {
|
||||
已选 <strong style={{ color: "#111827" }}>{task.images.length}</strong>/9
|
||||
</span>
|
||||
{task.images.length > 0 && (
|
||||
<button className="vv-link-btn" onClick={clearImages} disabled={!canEditAssets}>
|
||||
<button className="vv-link-btn" onClick={clearImages}>
|
||||
清空图片
|
||||
</button>
|
||||
)}
|
||||
@@ -1511,7 +1500,7 @@ const ViralVideoPage: React.FC = () => {
|
||||
<button
|
||||
className="vv-icon-btn"
|
||||
onClick={() => moveImg(i, -1)}
|
||||
disabled={i === 0 || im.uploading || !canEditAssets}
|
||||
disabled={i === 0 || im.uploading}
|
||||
title="上移"
|
||||
>
|
||||
<ArrowUpOutlined />
|
||||
@@ -1519,7 +1508,7 @@ const ViralVideoPage: React.FC = () => {
|
||||
<button
|
||||
className="vv-icon-btn"
|
||||
onClick={() => moveImg(i, 1)}
|
||||
disabled={i === task.images.length - 1 || im.uploading || !canEditAssets}
|
||||
disabled={i === task.images.length - 1 || im.uploading}
|
||||
title="下移"
|
||||
>
|
||||
<ArrowDownOutlined />
|
||||
@@ -1527,7 +1516,7 @@ const ViralVideoPage: React.FC = () => {
|
||||
<button
|
||||
className="vv-icon-btn vv-icon-btn-danger"
|
||||
onClick={() => removeImg(im.localId)}
|
||||
disabled={im.uploading || !canEditAssets}
|
||||
disabled={!!im.uploading}
|
||||
title="删除"
|
||||
>
|
||||
<CloseOutlined />
|
||||
@@ -1546,11 +1535,7 @@ const ViralVideoPage: React.FC = () => {
|
||||
<span className="vv-subblock-hint">最大 200MB · 最长 120 秒</span>
|
||||
</div>
|
||||
<div className="vv-action-row">
|
||||
<button
|
||||
className="vv-action-btn"
|
||||
onClick={() => videoInputRef.current?.click()}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<button className="vv-action-btn" onClick={() => videoInputRef.current?.click()}>
|
||||
<UploadOutlined /> 本地上传视频
|
||||
</button>
|
||||
<button
|
||||
@@ -1558,7 +1543,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
onClick={() =>
|
||||
setTask({ voicePanel: task.voicePanel === "douyin" ? null : "douyin" })
|
||||
}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<LinkOutlined /> 抖音链接识别
|
||||
</button>
|
||||
@@ -1609,11 +1593,7 @@ const ViralVideoPage: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
className="vv-link-btn"
|
||||
onClick={removeRefVideo}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<button className="vv-link-btn" onClick={removeRefVideo}>
|
||||
删除重传
|
||||
</button>
|
||||
{task.refVideo.ossUrl && (
|
||||
@@ -1627,7 +1607,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
key={s.value}
|
||||
className={`vv-pill ${task.styleStrength === s.value ? "active" : ""}`}
|
||||
onClick={() => setTask({ styleStrength: s.value })}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
{s.label}
|
||||
</button>
|
||||
@@ -1650,7 +1629,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
<button
|
||||
className={`vv-audio-cell ${task.refAudio?.source === "preset" ? "selected" : ""}`}
|
||||
onClick={() => setVoicePickerOpen(true)}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<FileTextOutlined className="vv-audio-ic" />
|
||||
<span>选择内置音色</span>
|
||||
@@ -1658,7 +1636,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
<button
|
||||
className={`vv-audio-cell ${task.voicePanel === "upload" ? "active" : ""} ${task.refAudio?.source === "upload" ? "selected" : ""}`}
|
||||
onClick={() => voiceInputRef.current?.click()}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<UploadOutlined className="vv-audio-ic" />
|
||||
<span>本地上传</span>
|
||||
@@ -1666,7 +1643,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
<button
|
||||
className={`vv-audio-cell ${task.voicePanel === "library" ? "active" : ""} ${task.refAudio?.source === "library" ? "selected" : ""}`}
|
||||
onClick={() => setAssetPicker({ open: true, kind: "voice", multiple: false })}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<FolderOpenOutlined className="vv-audio-ic" />
|
||||
<span>从素材库选择</span>
|
||||
@@ -1674,7 +1650,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
<button
|
||||
className={`vv-audio-cell ${task.voicePanel === "record" ? "active" : ""} ${task.refAudio?.source === "clone" ? "selected" : ""}`}
|
||||
onClick={() => setCloneModalOpen(true)}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<AudioMutedOutlined className="vv-audio-ic" />
|
||||
<span>直接录音</span>
|
||||
@@ -1694,11 +1669,7 @@ const ViralVideoPage: React.FC = () => {
|
||||
<div className="vv-selected-audio">
|
||||
<SoundOutlined style={{ color: "#7c3aed", marginRight: 6 }} />
|
||||
<span style={{ flex: 1 }}>已选:{task.refAudio.name}</span>
|
||||
<button
|
||||
className="vv-link-btn"
|
||||
onClick={() => setTask({ refAudio: null })}
|
||||
disabled={!canEditAssets}
|
||||
>
|
||||
<button className="vv-link-btn" onClick={() => setTask({ refAudio: null })}>
|
||||
移除
|
||||
</button>
|
||||
</div>
|
||||
@@ -1810,7 +1781,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
key={f.value}
|
||||
className={`vv-fusion-btn ${task.fusionLevel === f.value ? "active" : ""}`}
|
||||
onClick={() => setTask({ fusionLevel: f.value })}
|
||||
disabled={!canEditStep2}
|
||||
>
|
||||
<strong>{f.label}</strong>
|
||||
{f.desc}
|
||||
@@ -1832,7 +1802,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
}
|
||||
value={task.userCopy}
|
||||
onChange={(e) => setTask({ userCopy: e.target.value })}
|
||||
disabled={!canEditStep2}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -1848,7 +1817,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
placeholder="如:家具店、宠物店、装修公司"
|
||||
value={task.industry}
|
||||
onChange={(e) => setTask({ industry: e.target.value })}
|
||||
disabled={!canEditStep2}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row">
|
||||
@@ -1861,7 +1829,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
onChange={(v) => setTask({ targetCustomer: v })}
|
||||
options={TARGET_CUSTOMERS.map((i) => ({ value: i, label: i }))}
|
||||
allowClear
|
||||
disabled={!canEditStep2}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row">
|
||||
@@ -1872,7 +1839,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.language}
|
||||
onChange={(v) => setTask({ language: v })}
|
||||
options={LANGUAGES.map((i) => ({ value: i, label: i }))}
|
||||
disabled={!canEditStep2}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row">
|
||||
@@ -1885,7 +1851,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.persona || undefined}
|
||||
onChange={(v) => setTask({ persona: v })}
|
||||
options={PERSONAS.map((i) => ({ value: i, label: i }))}
|
||||
disabled={!canEditStep2}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row">
|
||||
@@ -1896,7 +1861,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.viralStructure}
|
||||
onChange={(v) => setTask({ viralStructure: v })}
|
||||
options={STRUCTURES.map((i) => ({ value: i, label: i }))}
|
||||
disabled={!canEditStep2}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row">
|
||||
@@ -1907,7 +1871,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.marketingPurpose}
|
||||
onChange={(v) => setTask({ marketingPurpose: v })}
|
||||
options={PURPOSES.map((i) => ({ value: i, label: i }))}
|
||||
disabled={!canEditStep2}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row" style={{ gridColumn: "1 / -1" }}>
|
||||
@@ -1918,7 +1881,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.duration}
|
||||
onChange={(v) => setTask({ duration: v })}
|
||||
options={DURATIONS.map((n) => ({ value: n, label: `${n}秒` }))}
|
||||
disabled={!canEditStep2}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2002,7 +1964,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.videoRatio}
|
||||
onChange={(v) => setTask({ videoRatio: v })}
|
||||
options={RATIOS.map((r) => ({ value: r.v, label: r.v }))}
|
||||
disabled={task.uiStep === "step3_generating" || task.uiStep === "step3_done"}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row">
|
||||
@@ -2013,7 +1974,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.videoModel}
|
||||
onChange={(v) => setTask({ videoModel: v })}
|
||||
options={MODELS.map((m) => ({ value: m.v, label: m.label }))}
|
||||
disabled={task.uiStep === "step3_generating" || task.uiStep === "step3_done"}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row">
|
||||
@@ -2024,7 +1984,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.quality}
|
||||
onChange={(v) => setTask({ quality: v })}
|
||||
options={QUALITY_OPTIONS.map((m) => ({ value: m.v, label: m.label }))}
|
||||
disabled={task.uiStep === "step3_generating" || task.uiStep === "step3_done"}
|
||||
/>
|
||||
</div>
|
||||
<div className="vv-form-row">
|
||||
@@ -2035,7 +1994,6 @@ const ViralVideoPage: React.FC = () => {
|
||||
value={task.upscale}
|
||||
onChange={(v) => setTask({ upscale: v })}
|
||||
options={UPSCALE_OPTIONS.map((m) => ({ value: m.v, label: m.label }))}
|
||||
disabled={task.uiStep === "step3_generating" || task.uiStep === "step3_done"}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user