Browse Source

fix(switch): make smart cascade type-aware so text inputs don't rescue dimmed image paths

A Prompt (text) connecting to a Generate node shouldn't prevent dimming
when the image input from a disabled Switch is blocked. The cascade now
only un-dims a node if an active input provides the same data type as
the blocked path (e.g., another image source replaces a disabled image).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 5 months ago
parent
commit
798babc6b3
  1. 48
      src/store/utils/dimmingUtils.ts

48
src/store/utils/dimmingUtils.ts

@ -32,32 +32,46 @@ export function computeDimmedNodes(
});
});
// Step 2: Smart cascade — remove nodes that have at least one active input
// A node stays active if any incoming edge comes from a source NOT in potentiallyDimmed
// AND that source is not a Switch with a disabled output pointing to this node
// Step 2: Type-aware smart cascade — only un-dim if an active input replaces
// the SAME data type that was blocked by the disabled Switch output.
// e.g. a Prompt (text) does NOT rescue a node whose image input is disabled.
const finalDimmed = new Set<string>();
potentiallyDimmed.forEach(nodeId => {
const incomingEdges = edges.filter(e => e.target === nodeId);
// Check if any incoming edge provides an active path
const hasActiveInput = incomingEdges.some(edge => {
// Source is not potentially dimmed — it's an active source
if (!potentiallyDimmed.has(edge.source)) {
// But also check: is this edge coming from a disabled Switch output?
const sourceNode = nodes.find(n => n.id === edge.source);
if (sourceNode?.type === "switch") {
const switchData = sourceNode.data as SwitchNodeData;
const switchEntry = switchData.switches?.find(s => s.id === edge.sourceHandle);
// If this specific switch output is disabled, it's not an active path
if (switchEntry && !switchEntry.enabled) return false;
// Collect which handle types are blocked on this node
// (from disabled Switch outputs or from transitively dimmed sources)
const blockedTypes = new Set<string>();
incomingEdges.forEach(edge => {
const sourceNode = nodes.find(n => n.id === edge.source);
if (sourceNode?.type === "switch") {
const switchData = sourceNode.data as SwitchNodeData;
const switchEntry = switchData.switches?.find(s => s.id === edge.sourceHandle);
if (switchEntry && !switchEntry.enabled && edge.targetHandle) {
blockedTypes.add(edge.targetHandle);
}
return true; // Active source, not dimmed
} else if (potentiallyDimmed.has(edge.source) && edge.targetHandle) {
blockedTypes.add(edge.targetHandle);
}
return false; // Source is also dimmed
});
if (!hasActiveInput) {
// Check if any active input provides the same type as a blocked type
const hasReplacementInput = incomingEdges.some(edge => {
// Skip dimmed sources
if (potentiallyDimmed.has(edge.source)) return false;
// Skip disabled Switch outputs
const sourceNode = nodes.find(n => n.id === edge.source);
if (sourceNode?.type === "switch") {
const switchData = sourceNode.data as SwitchNodeData;
const switchEntry = switchData.switches?.find(s => s.id === edge.sourceHandle);
if (switchEntry && !switchEntry.enabled) return false;
}
// Active input — only counts if it provides a blocked type
return edge.targetHandle ? blockedTypes.has(edge.targetHandle) : false;
});
if (!hasReplacementInput) {
finalDimmed.add(nodeId);
}
});

Loading…
Cancel
Save