完善视频复刻
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
Package,
|
||||
RefreshCw,
|
||||
Replace,
|
||||
ShieldCheck,
|
||||
Upload,
|
||||
UserRound,
|
||||
X,
|
||||
@@ -53,6 +54,8 @@ const REPLACE_MODE_COPY = {
|
||||
temporaryFallback: "临时商品素材",
|
||||
generatingTitle: "正在进行商品复刻",
|
||||
generatingCopy: "正在匹配商品外观与原片镜头",
|
||||
reviewingTitle: "正在审核参考素材",
|
||||
reviewingCopy: "真人视频需先通过合规审核,通过后自动开始复刻",
|
||||
resultTitle: "商品复刻已完成",
|
||||
resultPreview: "商品复刻预览",
|
||||
consistency: "商品一致性检查通过",
|
||||
@@ -76,6 +79,8 @@ const REPLACE_MODE_COPY = {
|
||||
temporaryFallback: "临时角色素材",
|
||||
generatingTitle: "正在进行角色复刻",
|
||||
generatingCopy: "正在匹配角色外观、表情与原片动作",
|
||||
reviewingTitle: "正在审核参考素材",
|
||||
reviewingCopy: "真人视频需先通过合规审核,通过后自动开始复刻",
|
||||
resultTitle: "角色复刻已完成",
|
||||
resultPreview: "角色复刻预览",
|
||||
consistency: "角色一致性检查通过",
|
||||
@@ -254,6 +259,7 @@ export function VideoReplacePage({
|
||||
const videoInputRef = useRef<HTMLInputElement>(null);
|
||||
const tempInputRef = useRef<HTMLInputElement>(null);
|
||||
const completedNoticeRef = useRef("");
|
||||
const wasReviewingRef = useRef(false);
|
||||
|
||||
const videoConfigs = useMemo(
|
||||
() => modelConfigs.filter((config) => config.capability === "video" && config.status === "active"),
|
||||
@@ -307,15 +313,17 @@ export function VideoReplacePage({
|
||||
}, billingRates);
|
||||
const points = estimated.points || 220;
|
||||
const generating = Boolean(job && isInFlight(job.status)) || submitting || videoUploading;
|
||||
const reviewing = submitting || Boolean(job && (job.review_stage === "reviewing" || job.status === "created"));
|
||||
const hasResult = Boolean(job && job.status === "succeeded" && job.video_url);
|
||||
const resultCopy = hasResult && job ? REPLACE_MODE_COPY[modeFromTask(job)] : copy;
|
||||
const panelClass = [
|
||||
"video-result-panel replace-result-panel",
|
||||
generating ? "is-generating" : "",
|
||||
reviewing ? "is-reviewing" : "",
|
||||
hasResult ? "has-result" : "",
|
||||
].filter(Boolean).join(" ");
|
||||
const generateLabel = generating
|
||||
? "正在复刻…"
|
||||
? (reviewing ? "正在审核素材…" : "正在复刻…")
|
||||
: hasResult
|
||||
? `再次${copy.modeLabel} · 消耗 ${points} 积分`
|
||||
: `开始${copy.modeLabel} · 消耗 ${points} 积分`;
|
||||
@@ -364,8 +372,14 @@ export function VideoReplacePage({
|
||||
const data = await api.pollVideoReplace(jobId);
|
||||
if (cancelled) return;
|
||||
setJob(data.task);
|
||||
const stillReviewing = data.task.review_stage === "reviewing" || data.task.status === "created";
|
||||
if (stillReviewing) wasReviewingRef.current = true;
|
||||
else if (wasReviewingRef.current && isInFlight(data.task.status)) {
|
||||
wasReviewingRef.current = false;
|
||||
onNotify("success", "素材审核已通过,正在复刻");
|
||||
}
|
||||
if (isInFlight(data.task.status)) {
|
||||
timer = window.setTimeout(poll, 2500);
|
||||
timer = window.setTimeout(poll, stillReviewing ? 2000 : 2500);
|
||||
return;
|
||||
}
|
||||
if (data.task.status === "succeeded") {
|
||||
@@ -575,7 +589,12 @@ export function VideoReplacePage({
|
||||
setJobId(data.task.id);
|
||||
rememberJob(data.task.id);
|
||||
completedNoticeRef.current = "";
|
||||
onNotify("success", "视频复刻任务已开始");
|
||||
wasReviewingRef.current = data.task.review_stage === "reviewing" || data.task.status === "created";
|
||||
if (wasReviewingRef.current) {
|
||||
onNotify("success", "已提交素材审核,通过后自动开始复刻");
|
||||
} else {
|
||||
onNotify("success", "视频复刻任务已开始");
|
||||
}
|
||||
if (!isInFlight(data.task.status) && data.task.status === "succeeded") {
|
||||
onNotify("success", "视频复刻成片已生成");
|
||||
void loadHistory();
|
||||
@@ -879,11 +898,11 @@ export function VideoReplacePage({
|
||||
<div className="replace-generating-state" role="status" aria-live="polite">
|
||||
<div className="replace-generating-content">
|
||||
<div className="replace-generating-visual">
|
||||
<span className="replace-generating-frame"><Clapperboard /></span>
|
||||
<span className="replace-generating-frame">{reviewing ? <ShieldCheck /> : <Clapperboard />}</span>
|
||||
<span className="replace-generating-product">{replaceMode === "character" ? <UserRound /> : <Package />}</span>
|
||||
</div>
|
||||
<strong>{copy.generatingTitle}</strong>
|
||||
<span>{copy.generatingCopy}</span>
|
||||
<strong>{reviewing ? copy.reviewingTitle : copy.generatingTitle}</strong>
|
||||
<span>{reviewing ? copy.reviewingCopy : copy.generatingCopy}</span>
|
||||
<div className="replace-generating-bar" aria-hidden="true"><span /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user