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
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:
@@ -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") {
|
||||
|
||||
Reference in New Issue
Block a user