feat: 视频脚本添加分镜最后一个按钮不隐藏-自带脚本移除上传文件

This commit is contained in:
hh
2026-07-07 14:07:17 +08:00
parent 2fcd6d996c
commit 45ff7838d8
2 changed files with 20 additions and 4 deletions
+2
View File
@@ -220,6 +220,8 @@
.shot-insert-gap .add-shot-btn svg { width: 12px; height: 12px; } .shot-insert-gap .add-shot-btn svg { width: 12px; height: 12px; }
.shot-insert-gap:hover .add-shot-btn { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; } .shot-insert-gap:hover .add-shot-btn { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.shot-insert-gap .add-shot-btn:hover { background: var(--heat-12); border-style: solid; border-color: var(--heat); } .shot-insert-gap .add-shot-btn:hover { background: var(--heat-12); border-style: solid; border-color: var(--heat); }
.shot-insert-gap--bottom { height: 72px; padding: 14px 0; }
.shot-insert-gap--bottom .add-shot-btn { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
/* ── Stage 4 · 视频详情弹窗(对齐设计稿 video-detail-modal) ── */ /* ── Stage 4 · 视频详情弹窗(对齐设计稿 video-detail-modal) ── */
.asset-modal-bg { position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 1010; display: flex; align-items: center; justify-content: center; padding: 40px; } .asset-modal-bg { position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 1010; display: flex; align-items: center; justify-content: center; padding: 40px; }
+18 -4
View File
@@ -1451,6 +1451,10 @@ export function PipelinePage(props: {
} }
if (setupSource === "manual") { if (setupSource === "manual") {
const base = chatText.trim(); const base = chatText.trim();
if (!base) {
chatTextareaRef.current?.focus();
return;
}
setChatText(""); setChatText("");
await runScriptGeneration(`${base ? `${base}\n` : ""}据此整理成镜头脚本。风格:${styleLabel},目标人群:${personaLabel}`, `自带脚本 · ${styleLabel} · ${personaLabel}`, "manual"); await runScriptGeneration(`${base ? `${base}\n` : ""}据此整理成镜头脚本。风格:${styleLabel},目标人群:${personaLabel}`, `自带脚本 · ${styleLabel} · ${personaLabel}`, "manual");
return; return;
@@ -1513,7 +1517,13 @@ export function PipelinePage(props: {
setSetupOpen(true); setSetupOpen(true);
// 一句话主题:开卡时不再 push 提示(否则 chatMsgs 非空,点返回就回不到三选项); // 一句话主题:开卡时不再 push 提示(否则 chatMsgs 非空,点返回就回不到三选项);
// 主题改成在「确定」(确认风格/人物)之后由模型来问,更像对话流。 // 主题改成在「确定」(确认风格/人物)之后由模型来问,更像对话流。
if (source === "manual") { pickScriptMode(); } if (source === "manual") {
setChatText("");
setChatAttachments([]);
window.setTimeout(() => chatTextareaRef.current?.focus(), 0);
}
// 文件上传入口先保留,当前「自带脚本」改为粘贴文本。
// if (source === "manual") { pickScriptMode(); }
} }
function pickScriptMode() { function pickScriptMode() {
setChatMode("manual"); setChatMode("manual");
@@ -2668,7 +2678,7 @@ export function PipelinePage(props: {
onCommit={(d) => { setDraftShots((list) => list.filter((x) => x.id !== d.id)); if ((d.narration || d.visual).trim()) void onAddShot(d.afterId || shot.id, { narration: d.narration, visual_prompt: d.visual }); }} onCommit={(d) => { setDraftShots((list) => list.filter((x) => x.id !== d.id)); if ((d.narration || d.visual).trim()) void onAddShot(d.afterId || shot.id, { narration: d.narration, visual_prompt: d.visual }); }}
onCancel={(id) => setDraftShots((list) => list.filter((x) => x.id !== id))} /> onCancel={(id) => setDraftShots((list) => list.filter((x) => x.id !== id))} />
))} ))}
<div className="shot-insert-gap"> <div className={`shot-insert-gap${index === shots.length - 1 ? " shot-insert-gap--bottom" : ""}`}>
<button className="add-shot-btn" type="button" disabled={loading} onClick={() => setDraftShots((list) => [...list, { id: `draft-${Date.now()}`, afterId: shot.id, narration: "", visual: "" }])}> <button className="add-shot-btn" type="button" disabled={loading} onClick={() => setDraftShots((list) => [...list, { id: `draft-${Date.now()}`, afterId: shot.id, narration: "", visual: "" }])}>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 5v14M5 12h14" /></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 5v14M5 12h14" /></svg>
</button> </button>
@@ -2738,7 +2748,7 @@ export function PipelinePage(props: {
setSetupStyle(SETUP_STYLE_KEYS[Math.floor(Math.random() * SETUP_STYLE_KEYS.length)] || setupStyle); setSetupStyle(SETUP_STYLE_KEYS[Math.floor(Math.random() * SETUP_STYLE_KEYS.length)] || setupStyle);
setSetupPersona(SETUP_PERSONA_KEYS[Math.floor(Math.random() * SETUP_PERSONA_KEYS.length)] || setupPersona); setSetupPersona(SETUP_PERSONA_KEYS[Math.floor(Math.random() * SETUP_PERSONA_KEYS.length)] || setupPersona);
}}></button> }}></button>
<button type="button" className="btn btn-primary btn-sm" disabled={loading} onClick={() => void runScriptWithSetup()}></button> <button type="button" className="btn btn-primary btn-sm" disabled={loading || (setupSource === "manual" && !chatText.trim())} onClick={() => void runScriptWithSetup()}></button>
</div> </div>
</div> </div>
<div className="time">{nowHm()}</div> <div className="time">{nowHm()}</div>
@@ -2777,7 +2787,7 @@ export function PipelinePage(props: {
</span> </span>
))} ))}
</div> </div>
<textarea ref={chatTextareaRef} className="chat-input-area" id="chat-textarea" placeholder={chatMode === "theme" ? "用一句话描述主题,如:熬夜党的早八续命面膜 ·(Enter 发送 / Shift+Enter 换行)" : chatMode === "manual" ? "粘贴或上传你的脚本,AI 将据此生成镜头脚本 ·(Enter 发送)" : "直接说怎么改,如:更像小红书种草 / 换成熬夜党 ·(Enter 发送)"} rows={2} value={chatText} onChange={(event) => setChatText(event.target.value)} <textarea ref={chatTextareaRef} className="chat-input-area" id="chat-textarea" placeholder={chatMode === "theme" ? "用一句话描述主题,如:熬夜党的早八续命面膜 ·(Enter 发送 / Shift+Enter 换行)" : chatMode === "manual" ? "粘贴你的脚本,AI 将据此生成镜头脚本 ·(Enter 发送)" : "直接说怎么改,如:更像小红书种草 / 换成熬夜党 ·(Enter 发送)"} rows={2} value={chatText} onChange={(event) => setChatText(event.target.value)}
onKeyDown={(event) => { onKeyDown={(event) => {
// 行31 · Enter 发送,Shift+Enter 换行(输入法组合期不触发) // 行31 · Enter 发送,Shift+Enter 换行(输入法组合期不触发)
if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) { if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
@@ -2785,11 +2795,15 @@ export function PipelinePage(props: {
submitChat(); submitChat();
} }
}}></textarea> }}></textarea>
{/* ,
<input ref={chatFileRef} type="file" accept=".txt,.md,.text,text/plain" style={{ display: "none" }} onChange={onPickScriptFile} /> <input ref={chatFileRef} type="file" accept=".txt,.md,.text,text/plain" style={{ display: "none" }} onChange={onPickScriptFile} />
*/}
<div className="chat-input-foot"> <div className="chat-input-foot">
{/* ,
<button className="chat-icon-btn" id="chat-upload-btn" type="button" title="上传脚本附件" aria-label="上传脚本附件" onClick={() => chatFileRef.current?.click()}> <button className="chat-icon-btn" id="chat-upload-btn" type="button" title="上传脚本附件" aria-label="上传脚本附件" onClick={() => chatFileRef.current?.click()}>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 5v14M5 12h14" /></svg> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 5v14M5 12h14" /></svg>
</button> </button>
*/}
{/* 模型选择小按钮(输入框下方,对齐 ChatGPT/Lovart)· 复用 restraint chip 下拉,向上展开 */} {/* 模型选择小按钮(输入框下方,对齐 ChatGPT/Lovart)· 复用 restraint chip 下拉,向上展开 */}
{textModels && textModels.length > 0 ? ( {textModels && textModels.length > 0 ? (
<div className={`chip-wrap chat-model-pick${modelMenuOpen ? " open" : ""}`}> <div className={`chip-wrap chat-model-pick${modelMenuOpen ? " open" : ""}`}>