feat(editor): highlight edges and show preview import loader

- Highlight all edges connected to selected scene

- Show overlay spinner while uploading/optimizing preview image

- macOS: keep control window independent from presentation

Made-with: Cursor
This commit is contained in:
Ivan Fontosh
2026-04-23 22:01:07 +08:00
parent 8f8eef53c9
commit a24e87035a
5 changed files with 94 additions and 7 deletions
@@ -20,8 +20,10 @@
}
.cardActive {
border-color: var(--graph-node-active-border);
box-shadow: 0 25px 50px -12px rgba(139, 92, 246, 0.1);
border-color: rgba(167, 139, 250, 0.95);
box-shadow:
0 0 0 2px rgba(167, 139, 250, 0.35),
0 25px 50px -12px rgba(167, 139, 250, 0.12);
}
.previewShell {
+23 -3
View File
@@ -365,16 +365,36 @@ function SceneGraphCanvas({
}, [currentSceneId, sceneCardById, sceneGraphNodes]);
const desiredEdges = useMemo<Edge[]>(() => {
const selectedGraphNodeIds = new Set<GraphNodeId>();
if (currentSceneId) {
for (const gn of sceneGraphNodes) {
if (gn.sceneId === currentSceneId) selectedGraphNodeIds.add(gn.id);
}
}
const hasSelection = selectedGraphNodeIds.size > 0;
return sceneGraphEdges.map((e) => ({
...(hasSelection
? {
style:
selectedGraphNodeIds.has(e.sourceGraphNodeId) || selectedGraphNodeIds.has(e.targetGraphNodeId)
? { stroke: 'rgba(167,139,250,0.95)', strokeWidth: 3 }
: { stroke: 'rgba(255,255,255,0.10)', strokeWidth: 2 },
markerEnd:
selectedGraphNodeIds.has(e.sourceGraphNodeId) || selectedGraphNodeIds.has(e.targetGraphNodeId)
? { type: MarkerType.ArrowClosed, color: 'rgba(167,139,250,0.95)', strokeWidth: 2 }
: { type: MarkerType.ArrowClosed, color: 'rgba(255,255,255,0.18)', strokeWidth: 2 },
}
: {
style: { stroke: 'rgba(167,139,250,0.55)', strokeWidth: 2 },
markerEnd: { type: MarkerType.ArrowClosed, color: 'rgba(167,139,250,0.85)', strokeWidth: 2 },
}),
id: e.id,
source: e.sourceGraphNodeId,
target: e.targetGraphNodeId,
type: 'smoothstep',
animated: false,
style: { stroke: 'rgba(167,139,250,0.55)', strokeWidth: 2 },
markerEnd: { type: MarkerType.ArrowClosed, color: 'rgba(167,139,250,0.85)', strokeWidth: 2 },
}));
}, [sceneGraphEdges]);
}, [currentSceneId, sceneGraphEdges, sceneGraphNodes]);
const [nodes, setNodes, onNodesChange] = useNodesState<Node<SceneCardData>>([]);
const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([]);