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

Loading…
Cancel
Save