Codex/generation task reliability #20

Merged
stringadmin merged 20 commits from codex/generation-task-reliability into master 2026-06-08 05:56:38 +00:00
2 changed files with 75 additions and 82 deletions
Showing only changes of commit d09e5e673e - Show all commits
@@ -0,0 +1,40 @@
interface CanvasMarkingPopoverProps {
value?: string;
placeholder: string;
onChange: (value: string) => void;
onClear: () => void;
onDone: () => void;
}
export function CanvasMarkingPopover({
value,
placeholder,
onChange,
onClear,
onDone,
}: CanvasMarkingPopoverProps) {
return (
<div
className="studio-canvas-marking-popover"
onMouseDown={(event) => event.stopPropagation()}
onClick={(event) => event.stopPropagation()}
>
<textarea
className="studio-canvas-marking-input"
placeholder={placeholder}
value={value || ""}
onChange={(event) => onChange(event.target.value)}
/>
<div className="studio-canvas-marking-actions">
{value ? (
<button type="button" className="studio-canvas-marking-clear" onClick={onClear}>
</button>
) : null}
<button type="button" className="studio-canvas-marking-done" onClick={onDone}>
</button>
</div>
</div>
);
}
+35 -82
View File
@@ -186,6 +186,7 @@ import {
} from "./canvasWorkflowDeserialize"; } from "./canvasWorkflowDeserialize";
import { CanvasNodeToolbar, CanvasNodeVideoPlayer, CanvasSelectChip } from "./canvasComponents"; import { CanvasNodeToolbar, CanvasNodeVideoPlayer, CanvasSelectChip } from "./canvasComponents";
import type { CanvasNodeToolbarAction } from "./canvasComponents"; import type { CanvasNodeToolbarAction } from "./canvasComponents";
import { CanvasMarkingPopover } from "./CanvasMarkingPopover";
import { CanvasPromptMentionTextarea, CanvasTextPromptComposer } from "./CanvasTextPromptComposer"; import { CanvasPromptMentionTextarea, CanvasTextPromptComposer } from "./CanvasTextPromptComposer";
import { CanvasMultiGridPanel, CanvasUpscalePanel, CanvasInpaintPanel } from "./canvasToolPanels"; import { CanvasMultiGridPanel, CanvasUpscalePanel, CanvasInpaintPanel } from "./canvasToolPanels";
import { CanvasSmoothedProgressRing } from "./CanvasSmoothedProgressRing"; import { CanvasSmoothedProgressRing } from "./CanvasSmoothedProgressRing";
@@ -4472,47 +4473,23 @@ function CanvasPage({
> >
<FileImageOutlined /><span></span> <FileImageOutlined /><span></span>
</button> </button>
{markingPopoverNodeId === imageNode.id && ( {markingPopoverNodeId === imageNode.id ? (
<div <CanvasMarkingPopover
className="studio-canvas-marking-popover" value={imageNode.marking}
onMouseDown={(e) => e.stopPropagation()} placeholder="描述标记内容,如:主角站在桥上,远处是城市天际线"
onClick={(e) => e.stopPropagation()} onChange={(value) => {
> setImageNodes((nodes) =>
<textarea nodes.map((node) => (node.id === imageNode.id ? { ...node, marking: value } : node)),
className="studio-canvas-marking-input" );
placeholder="描述标记内容,如:主角站在桥上,远处是城市天际线" }}
value={imageNode.marking || ""} onClear={() => {
onChange={(e) => { setImageNodes((nodes) =>
const val = e.target.value; nodes.map((node) => (node.id === imageNode.id ? { ...node, marking: "" } : node)),
setImageNodes((nodes) => );
nodes.map((n) => (n.id === imageNode.id ? { ...n, marking: val } : n)), }}
); onDone={() => setMarkingPopoverNodeId(null)}
}} />
/> ) : null}
<div className="studio-canvas-marking-actions">
{imageNode.marking && (
<button
type="button"
className="studio-canvas-marking-clear"
onClick={() => {
setImageNodes((nodes) =>
nodes.map((n) => (n.id === imageNode.id ? { ...n, marking: "" } : n)),
);
}}
>
</button>
)}
<button
type="button"
className="studio-canvas-marking-done"
onClick={() => setMarkingPopoverNodeId(null)}
>
</button>
</div>
</div>
)}
<button <button
type="button" type="button"
title="多宫格生成" title="多宫格生成"
@@ -4843,47 +4820,23 @@ function CanvasPage({
> >
{videoNode.cameraMotion ? ` ${CAMERA_MOTION_PRESETS.find((p) => p.value === videoNode.cameraMotion)?.label || ""}` : ""} {videoNode.cameraMotion ? ` ${CAMERA_MOTION_PRESETS.find((p) => p.value === videoNode.cameraMotion)?.label || ""}` : ""}
</button> </button>
{markingPopoverNodeId === videoNode.id && ( {markingPopoverNodeId === videoNode.id ? (
<div <CanvasMarkingPopover
className="studio-canvas-marking-popover" value={videoNode.marking}
onMouseDown={(e) => e.stopPropagation()} placeholder="描述标记内容,如:主角在城市街头行走"
onClick={(e) => e.stopPropagation()} onChange={(value) => {
> setVideoNodes((nodes) =>
<textarea nodes.map((node) => (node.id === videoNode.id ? { ...node, marking: value } : node)),
className="studio-canvas-marking-input" );
placeholder="描述标记内容,如:主角在城市街头行走" }}
value={videoNode.marking || ""} onClear={() => {
onChange={(e) => { setVideoNodes((nodes) =>
const val = e.target.value; nodes.map((node) => (node.id === videoNode.id ? { ...node, marking: "" } : node)),
setVideoNodes((nodes) => );
nodes.map((n) => (n.id === videoNode.id ? { ...n, marking: val } : n)), }}
); onDone={() => setMarkingPopoverNodeId(null)}
}} />
/> ) : null}
<div className="studio-canvas-marking-actions">
{videoNode.marking && (
<button
type="button"
className="studio-canvas-marking-clear"
onClick={() => {
setVideoNodes((nodes) =>
nodes.map((n) => (n.id === videoNode.id ? { ...n, marking: "" } : n)),
);
}}
>
</button>
)}
<button
type="button"
className="studio-canvas-marking-done"
onClick={() => setMarkingPopoverNodeId(null)}
>
</button>
</div>
</div>
)}
{cameraMotionDropdownNodeId === videoNode.id && ( {cameraMotionDropdownNodeId === videoNode.id && (
<div <div
className="studio-canvas-camera-dropdown" className="studio-canvas-camera-dropdown"