refactor: extract canvas marking popover
This commit is contained in:
@@ -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";
|
||||
import { CanvasNodeToolbar, CanvasNodeVideoPlayer, CanvasSelectChip } from "./canvasComponents";
|
||||
import type { CanvasNodeToolbarAction } from "./canvasComponents";
|
||||
import { CanvasMarkingPopover } from "./CanvasMarkingPopover";
|
||||
import { CanvasPromptMentionTextarea, CanvasTextPromptComposer } from "./CanvasTextPromptComposer";
|
||||
import { CanvasMultiGridPanel, CanvasUpscalePanel, CanvasInpaintPanel } from "./canvasToolPanels";
|
||||
import { CanvasSmoothedProgressRing } from "./CanvasSmoothedProgressRing";
|
||||
@@ -4472,47 +4473,23 @@ function CanvasPage({
|
||||
>
|
||||
<FileImageOutlined /><span>标记</span>
|
||||
</button>
|
||||
{markingPopoverNodeId === imageNode.id && (
|
||||
<div
|
||||
className="studio-canvas-marking-popover"
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<textarea
|
||||
className="studio-canvas-marking-input"
|
||||
{markingPopoverNodeId === imageNode.id ? (
|
||||
<CanvasMarkingPopover
|
||||
value={imageNode.marking}
|
||||
placeholder="描述标记内容,如:主角站在桥上,远处是城市天际线"
|
||||
value={imageNode.marking || ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
onChange={(value) => {
|
||||
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">
|
||||
{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>
|
||||
)}
|
||||
) : null}
|
||||
<button
|
||||
type="button"
|
||||
title="多宫格生成"
|
||||
@@ -4843,47 +4820,23 @@ function CanvasPage({
|
||||
>
|
||||
运镜{videoNode.cameraMotion ? ` ${CAMERA_MOTION_PRESETS.find((p) => p.value === videoNode.cameraMotion)?.label || ""}` : ""}
|
||||
</button>
|
||||
{markingPopoverNodeId === videoNode.id && (
|
||||
<div
|
||||
className="studio-canvas-marking-popover"
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<textarea
|
||||
className="studio-canvas-marking-input"
|
||||
{markingPopoverNodeId === videoNode.id ? (
|
||||
<CanvasMarkingPopover
|
||||
value={videoNode.marking}
|
||||
placeholder="描述标记内容,如:主角在城市街头行走"
|
||||
value={videoNode.marking || ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
onChange={(value) => {
|
||||
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">
|
||||
{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>
|
||||
)}
|
||||
) : null}
|
||||
{cameraMotionDropdownNodeId === videoNode.id && (
|
||||
<div
|
||||
className="studio-canvas-camera-dropdown"
|
||||
|
||||
Reference in New Issue
Block a user