fix(viral-video): 修复Frontend Lint警告——updaters改为useCallback+函数式setState
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 0s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m16s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 2m14s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m25s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m8s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 3m54s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 4m7s
AI Code Review / AI Code Review (pull_request) Successful in 6m46s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 10m38s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m47s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 17m43s
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s

- updateShot/updateStoryboard/updateOverview/updateConstraints/addConstraint/removeConstraint 用 useCallback + 函数式 setTask 包裹,避免闭包依赖 task.storyboard
- 加 eslint-disable 注释说明 setTask 是稳定 setter,无需加入依赖
- handleInlineCommit 依赖数组补全 updateShot/updateOverview/updateStoryboard(均已稳定)
This commit is contained in:
xiaoxia
2026-10-03 16:57:21 +08:00
parent b0c3c4e43b
commit 4281d64a10
@@ -1233,40 +1233,58 @@ const ViralVideoPage: React.FC = () => {
const [editingField, setEditingField] = useState<string | null>(null)
const editTaRef = useRef<HTMLTextAreaElement | null>(null)
const updateShot = (idx: number, patch: Partial<StoryboardShot>) => {
if (!task.storyboard) return
const shots = task.storyboard.shots.map((s, i) => (i === idx ? { ...s, ...patch } : s))
setTask({ storyboard: { ...task.storyboard, shots } })
}
const updateStoryboard = (patch: Partial<Storyboard>) => {
if (!task.storyboard) return
setTask({ storyboard: { ...task.storyboard, ...patch } })
}
const updateOverview = (patch: Partial<Storyboard["overview"]>) => {
if (!task.storyboard) return
setTask({
storyboard: { ...task.storyboard, overview: { ...task.storyboard.overview, ...patch } },
const updateShot = useCallback((idx: number, patch: Partial<StoryboardShot>) => {
setTask((t) => {
if (!t.storyboard) return t
const shots = t.storyboard.shots.map((s, i) => (i === idx ? { ...s, ...patch } : s))
return { ...t, storyboard: { ...t.storyboard, shots } }
})
}
const updateConstraints = (
list: "hard_constraints" | "negative_prompts",
idx: number,
v: string,
) => {
if (!task.storyboard) return
const arr = [...task.storyboard[list]]
arr[idx] = v
setTask({ storyboard: { ...task.storyboard, [list]: arr } })
}
const addConstraint = (list: "hard_constraints" | "negative_prompts") => {
if (!task.storyboard) return
setTask({ storyboard: { ...task.storyboard, [list]: [...task.storyboard[list], ""] } })
}
const removeConstraint = (list: "hard_constraints" | "negative_prompts", idx: number) => {
if (!task.storyboard) return
const arr = task.storyboard[list].filter((_, i) => i !== idx)
setTask({ storyboard: { ...task.storyboard, [list]: arr } })
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const updateStoryboard = useCallback((patch: Partial<Storyboard>) => {
setTask((t) => (t.storyboard ? { ...t, storyboard: { ...t.storyboard, ...patch } } : t))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const updateOverview = useCallback((patch: Partial<Storyboard["overview"]>) => {
setTask((t) =>
t.storyboard
? {
...t,
storyboard: { ...t.storyboard, overview: { ...t.storyboard.overview, ...patch } },
}
: t,
)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const updateConstraints = useCallback(
(list: "hard_constraints" | "negative_prompts", idx: number, v: string) => {
setTask((t) => {
if (!t.storyboard) return t
const arr = [...t.storyboard[list]]
arr[idx] = v
return { ...t, storyboard: { ...t.storyboard, [list]: arr } }
})
},
[], // eslint-disable-line react-hooks/exhaustive-deps
)
const addConstraint = useCallback((list: "hard_constraints" | "negative_prompts") => {
setTask((t) =>
t.storyboard
? { ...t, storyboard: { ...t.storyboard, [list]: [...t.storyboard[list], ""] } }
: t,
)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const removeConstraint = useCallback(
(list: "hard_constraints" | "negative_prompts", idx: number) => {
setTask((t) => {
if (!t.storyboard) return t
const arr = t.storyboard[list].filter((_, i) => i !== idx)
return { ...t, storyboard: { ...t.storyboard, [list]: arr } }
})
},
[], // eslint-disable-line react-hooks/exhaustive-deps
)
/* 内联编辑 helper —— 点击文本 → textarea,blur/Enter 保存 */
const handleInlineCommit = useCallback(() => {
@@ -1290,7 +1308,7 @@ const ViralVideoPage: React.FC = () => {
}
}
setEditingField(null)
}, [])
}, [updateShot, updateOverview, updateStoryboard])
const renderCopyResult = () => {
if (task.uiStep === "step2_generating") {