Browse Source

固定 下面的输入框

feature/071
yun 1 week ago
parent
commit
71d6dc2fc9
  1. 39
      src/components/WorkflowCanvas.tsx
  2. 22
      src/components/composer/NodeGenerationComposer.tsx
  3. 2
      src/components/nodes/BaseNode.tsx

39
src/components/WorkflowCanvas.tsx

@ -34,7 +34,6 @@ import { ConnectionDropMenu, type ConnectionIntent } from "./ConnectionDropMenu"
import { MultiSelectToolbar } from "./MultiSelectToolbar";
import { EdgeToolbar } from "./EdgeToolbar";
import { GlobalImageHistory } from "./GlobalImageHistory";
import { NodeGenerationComposer } from "./composer/NodeGenerationComposer";
import { NodeType, NanoBananaNodeData, HandleType, PromptNodeData, SmartTextNodeData, LLMGenerateNodeData, PromptConstructorNodeData, AvailableVariable, SelectedModel, WorkflowNode } from "@/types";
import { DEFAULT_NODE_DIMENSIONS, defaultNodeDimensions } from "@/store/utils/nodeDefaults";
import { NodeHeaderProvider } from "./nodes/NodeHeaderContext";
@ -76,7 +75,6 @@ import { useI18n } from "@/i18n";
import { buildDefaultGenerationNodeCreation } from "@/utils/defaultGenerationNodeModel";
import { isSmartImageGenerateMode } from "@/utils/smartImageMode";
import { deriveSmartTextMode } from "@/utils/smartTextMode";
import { useCanvasPreviewMode } from "@/components/CanvasPreviewModeContext";
import { getNodePrimaryImageUrl, getNodePrimaryMediaUrl, isTextOnlyContextMenuNode } from "@/utils/canvasNodeMedia";
import {
canConnectOutputMediaToNode,
@ -524,7 +522,6 @@ function getCanvasPanOnDrag(disabled: boolean): PanOnDragValue {
export function WorkflowCanvas() {
const { t } = useI18n();
const isPreviewMode = useCanvasPreviewMode();
const searchParams = useSearchParams();
const urlWorkflowId = searchParams?.get("workflowId") ?? null;
const { nodes, edges, groups, isModalOpen, navigationTarget, canvasNavigationSettings, dimmedNodeIds, skippedNodeIds, providerSettings, isRunning } =
@ -1003,35 +1000,6 @@ export function WorkflowCanvas() {
() => allNodes.filter((node) => node.selected),
[allNodes]
);
const isSingleCanvasSelection = selectedCanvasNodes.length === 1;
const selectedComposerTarget = useMemo(() => {
if (isPreviewMode) return null;
if (!isSingleCanvasSelection) return null;
const node = selectedCanvasNodes[0];
if (!node || node.type === "group") return null;
const position = absoluteNodePositions.get(node.id) ?? node.position;
const dimensions = getWorkflowNodeDimensions(node);
return {
nodeId: node.id,
position: {
x: position.x + dimensions.width / 2,
y: position.y + dimensions.height,
},
};
}, [absoluteNodePositions, isPreviewMode, isSingleCanvasSelection, selectedCanvasNodes]);
const [globalComposerTarget, setGlobalComposerTarget] = useState<{
nodeId: string;
selected: boolean;
position: { x: number; y: number };
} | null>(null);
useEffect(() => {
if (selectedComposerTarget) {
setGlobalComposerTarget({ ...selectedComposerTarget, selected: true });
return;
}
setGlobalComposerTarget((current) => current ? { ...current, selected: false } : null);
}, [selectedComposerTarget]);
const selectedBatchSourceNodeIds = useMemo(() => {
const selectedGroupIds = selectedCanvasNodes
@ -3193,13 +3161,6 @@ export function WorkflowCanvas() {
}}
/>
)}
{globalComposerTarget ? (
<NodeGenerationComposer
nodeId={globalComposerTarget.nodeId}
selected={globalComposerTarget.selected}
position={globalComposerTarget.position}
/>
) : null}
</ViewportPortal>
</ReactFlow>
</NodeHeaderProvider>

22
src/components/composer/NodeGenerationComposer.tsx

@ -14,7 +14,6 @@ import { isSmartImageAutoTaskNode } from "@/utils/smartImageMode";
interface NodeGenerationComposerProps {
nodeId: string;
selected: boolean;
position?: { x: number; y: number };
}
function getNodeImageSource(node: WorkflowNode | null): string | null {
@ -49,18 +48,15 @@ function isAutoImageTaskNode(node: WorkflowNode | null): boolean {
export function NodeGenerationComposer({
nodeId,
selected,
position,
}: NodeGenerationComposerProps) {
return <EditableNodeGenerationComposer nodeId={nodeId} selected={selected} position={position} />;
return <EditableNodeGenerationComposer nodeId={nodeId} selected={selected} />;
}
function NodeGenerationComposerFrame({
hidden,
position,
children,
}: {
hidden: boolean;
position: { x: number; y: number };
children: ReactNode;
}) {
const { zoom } = useViewport();
@ -70,14 +66,10 @@ function NodeGenerationComposerFrame({
<div
data-canvas-generator-root
hidden={hidden}
className="pointer-events-none absolute overflow-visible"
style={{
left: `${position.x}px`,
top: `${position.y}px`,
}}
className="pointer-events-none absolute left-0 top-0 h-full w-full overflow-visible"
>
<div
className="node-floating-ui nodrag nopan nowheel pointer-events-auto absolute z-[10020]"
className="node-floating-ui nodrag nopan nowheel pointer-events-auto absolute left-1/2 top-full z-[10020]"
style={{
transform: `translateX(-50%) translateY(${12 / safeZoom}px) scale(${1 / safeZoom})`,
transformOrigin: "top center",
@ -89,11 +81,7 @@ function NodeGenerationComposerFrame({
);
}
function EditableNodeGenerationComposer({
nodeId,
selected,
position = { x: 0, y: 0 },
}: NodeGenerationComposerProps) {
function EditableNodeGenerationComposer({ nodeId, selected }: Pick<NodeGenerationComposerProps, "nodeId" | "selected">) {
const selectedNodeCount = useSelectedNodeCount();
const nodes = useWorkflowStore((state) => state.nodes);
const edges = useWorkflowStore((state) => state.edges);
@ -157,7 +145,7 @@ function EditableNodeGenerationComposer({
}
return (
<NodeGenerationComposerFrame hidden={isFrameHidden} position={position}>
<NodeGenerationComposerFrame hidden={isFrameHidden}>
{canUseMultiAngle && context.node && imageSource ? (
<NodeMultiAnglePanel node={context.node} imageSource={imageSource} onClose={closePanel} />
) : null}

2
src/components/nodes/BaseNode.tsx

@ -4,6 +4,7 @@ import { ReactNode, useRef, useLayoutEffect } from "react";
import { Node, useReactFlow } from "@xyflow/react";
import { useWorkflowStore } from "@/store/workflowStore";
import { isPanningRef, isDraggingNodeRef } from "@/components/WorkflowCanvas";
import { NodeGenerationComposer } from "@/components/composer/NodeGenerationComposer";
import { useCanvasPreviewMode } from "@/components/CanvasPreviewModeContext";
import { useI18n } from "@/i18n";
import { isPopiProviderMode } from "@/lib/providerMode";
@ -326,6 +327,7 @@ export function BaseNode({
{header}
<div ref={contentRef} style={{ contain: "layout style" }} className={contentClassName ?? (autoSizeContent ? "relative h-full w-full" : fullBleed ? "flex-1 min-h-0 relative" : "px-3 pb-4 flex-1 min-h-0 overflow-visible flex flex-col")}>{children}</div>
{floatingPanel}
{!isPreviewMode && <NodeGenerationComposer nodeId={id} selected={selected} />}
</div>
{settingsPanel && (
<div ref={settingsPanelRef}>

Loading…
Cancel
Save