|
|
|
@ -656,34 +656,17 @@ function isVideoHandle(handleId: string | null | undefined): boolean { |
|
|
|
return handleId === "video" || handleId.startsWith("video-") || handleId.includes("video"); |
|
|
|
} |
|
|
|
|
|
|
|
function isImageHandle(handleId: string | null | undefined): boolean { |
|
|
|
if (!handleId) return false; |
|
|
|
return handleId === "image" || handleId.startsWith("image-") || handleId.includes("frame"); |
|
|
|
} |
|
|
|
|
|
|
|
function isTextHandle(handleId: string | null | undefined): boolean { |
|
|
|
if (!handleId) return false; |
|
|
|
return handleId === "text" || handleId.startsWith("text-") || handleId.includes("prompt"); |
|
|
|
} |
|
|
|
|
|
|
|
function isAudioHandle(handleId: string | null | undefined): boolean { |
|
|
|
if (!handleId) return false; |
|
|
|
return handleId === "audio" || handleId.startsWith("audio-") || handleId.includes("audio"); |
|
|
|
} |
|
|
|
|
|
|
|
function getConnectedEdgeIdsByType( |
|
|
|
targetNodeId: string, |
|
|
|
nodes: WorkflowNode[], |
|
|
|
edges: WorkflowEdge[], |
|
|
|
type: ComposerReferenceMaterialType | "text" |
|
|
|
): string[] { |
|
|
|
return edges |
|
|
|
.filter((edge) => { |
|
|
|
if (edge.target !== targetNodeId) return false; |
|
|
|
const handleIds = [edge.targetHandle, edge.sourceHandle]; |
|
|
|
if (type === "image") return handleIds.some(isImageHandle); |
|
|
|
if (type === "video") return handleIds.some(isVideoHandle); |
|
|
|
if (type === "audio") return handleIds.some(isAudioHandle); |
|
|
|
return handleIds.some(isTextHandle); |
|
|
|
const sourceNode = nodes.find((node) => node.id === edge.source); |
|
|
|
return sourceNode ? getNodeOutputMediaType(sourceNode) === type : false; |
|
|
|
}) |
|
|
|
.map((edge) => edge.id); |
|
|
|
} |
|
|
|
@ -1822,12 +1805,12 @@ export function GenerationComposer() { |
|
|
|
const connectedTextItems = useMemo(() => getConnectedTextItems(connectedInputs), [connectedInputs]); |
|
|
|
const connectedTextCards = useMemo<ComposerConnectedTextItem[]>(() => { |
|
|
|
if (!context.node) return connectedTextItems.map((text) => ({ text })); |
|
|
|
const textEdgeIds = getConnectedEdgeIdsByType(context.node.id, edges, "text"); |
|
|
|
const textEdgeIds = getConnectedEdgeIdsByType(context.node.id, nodes, edges, "text"); |
|
|
|
return connectedTextItems.map((text, index) => ({ |
|
|
|
text, |
|
|
|
...(textEdgeIds[index] ? { edgeId: textEdgeIds[index] } : {}), |
|
|
|
})); |
|
|
|
}, [connectedTextItems, context.node, edges]); |
|
|
|
}, [connectedTextItems, context.node, edges, nodes]); |
|
|
|
const promptValue = draft.prompt; |
|
|
|
const promptReadOnly = false; |
|
|
|
const activeCapability = context.mode === "empty-create" |
|
|
|
@ -1892,34 +1875,34 @@ export function GenerationComposer() { |
|
|
|
const referenceImageInputs = useMemo<ComposerReferenceInput[]>(() => { |
|
|
|
const imageEdgeIds = |
|
|
|
context.mode === "node-edit" && context.node && connectedReferenceImages.length > 0 |
|
|
|
? getConnectedEdgeIdsByType(context.node.id, edges, "image") |
|
|
|
? getConnectedEdgeIdsByType(context.node.id, nodes, edges, "image") |
|
|
|
: []; |
|
|
|
return referenceImages.map((url, index) => ({ |
|
|
|
url, |
|
|
|
...(imageEdgeIds[index] ? { edgeId: imageEdgeIds[index] } : {}), |
|
|
|
})); |
|
|
|
}, [connectedReferenceImages.length, context.mode, context.node, edges, referenceImages]); |
|
|
|
}, [connectedReferenceImages.length, context.mode, context.node, edges, nodes, referenceImages]); |
|
|
|
const referenceVideoInputs = useMemo<ComposerReferenceInput[]>(() => { |
|
|
|
const videoEdgeIds = |
|
|
|
context.mode === "node-edit" && context.node |
|
|
|
? getConnectedEdgeIdsByType(context.node.id, edges, "video") |
|
|
|
? getConnectedEdgeIdsByType(context.node.id, nodes, edges, "video") |
|
|
|
: []; |
|
|
|
return connectedReferenceVideos.map((url, index) => ({ |
|
|
|
url, |
|
|
|
...(connectedVideoDurations[index] && connectedVideoDurations[index] > 0 ? { duration: connectedVideoDurations[index] } : {}), |
|
|
|
...(videoEdgeIds[index] ? { edgeId: videoEdgeIds[index] } : {}), |
|
|
|
})); |
|
|
|
}, [connectedReferenceVideos, connectedVideoDurations, context.mode, context.node, edges]); |
|
|
|
}, [connectedReferenceVideos, connectedVideoDurations, context.mode, context.node, edges, nodes]); |
|
|
|
const referenceAudioInputs = useMemo<ComposerReferenceInput[]>(() => { |
|
|
|
const audioEdgeIds = |
|
|
|
context.mode === "node-edit" && context.node |
|
|
|
? getConnectedEdgeIdsByType(context.node.id, edges, "audio") |
|
|
|
? getConnectedEdgeIdsByType(context.node.id, nodes, edges, "audio") |
|
|
|
: []; |
|
|
|
return connectedReferenceAudio.map((url, index) => ({ |
|
|
|
url, |
|
|
|
...(audioEdgeIds[index] ? { edgeId: audioEdgeIds[index] } : {}), |
|
|
|
})); |
|
|
|
}, [connectedReferenceAudio, context.mode, context.node, edges]); |
|
|
|
}, [connectedReferenceAudio, context.mode, context.node, edges, nodes]); |
|
|
|
const baseReferenceMaterials = useMemo(() => buildComposerReferenceMaterials( |
|
|
|
referenceImageInputs, |
|
|
|
referenceVideoInputs, |
|
|
|
|