Codex/generation task reliability #20
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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()}
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<textarea
|
|
||||||
className="studio-canvas-marking-input"
|
|
||||||
placeholder="描述标记内容,如:主角站在桥上,远处是城市天际线"
|
placeholder="描述标记内容,如:主角站在桥上,远处是城市天际线"
|
||||||
value={imageNode.marking || ""}
|
onChange={(value) => {
|
||||||
onChange={(e) => {
|
|
||||||
const val = e.target.value;
|
|
||||||
setImageNodes((nodes) =>
|
setImageNodes((nodes) =>
|
||||||
nodes.map((n) => (n.id === imageNode.id ? { ...n, marking: val } : n)),
|
nodes.map((node) => (node.id === imageNode.id ? { ...node, marking: value } : node)),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
onClear={() => {
|
||||||
|
setImageNodes((nodes) =>
|
||||||
|
nodes.map((node) => (node.id === imageNode.id ? { ...node, marking: "" } : node)),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
onDone={() => setMarkingPopoverNodeId(null)}
|
||||||
/>
|
/>
|
||||||
<div className="studio-canvas-marking-actions">
|
) : null}
|
||||||
{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()}
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<textarea
|
|
||||||
className="studio-canvas-marking-input"
|
|
||||||
placeholder="描述标记内容,如:主角在城市街头行走"
|
placeholder="描述标记内容,如:主角在城市街头行走"
|
||||||
value={videoNode.marking || ""}
|
onChange={(value) => {
|
||||||
onChange={(e) => {
|
|
||||||
const val = e.target.value;
|
|
||||||
setVideoNodes((nodes) =>
|
setVideoNodes((nodes) =>
|
||||||
nodes.map((n) => (n.id === videoNode.id ? { ...n, marking: val } : n)),
|
nodes.map((node) => (node.id === videoNode.id ? { ...node, marking: value } : node)),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
onClear={() => {
|
||||||
|
setVideoNodes((nodes) =>
|
||||||
|
nodes.map((node) => (node.id === videoNode.id ? { ...node, marking: "" } : node)),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
onDone={() => setMarkingPopoverNodeId(null)}
|
||||||
/>
|
/>
|
||||||
<div className="studio-canvas-marking-actions">
|
) : null}
|
||||||
{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"
|
||||||
|
|||||||
Reference in New Issue
Block a user