refactor: performance
This commit is contained in:
@@ -31,7 +31,7 @@ import {
|
||||
import { useTheme } from '@/lib/themeContext'
|
||||
import { usePlatform } from '@/app/kosmos/KosmosContext'
|
||||
import { useCanvasGraph } from '@/app/canvas/useCanvasGraph'
|
||||
import { getExampleGraph } from '@/app/canvas/canvasGraphUtils'
|
||||
import { getExampleGraph, backfillEdgeTargetTypes } from '@/app/canvas/canvasGraphUtils'
|
||||
import { ContextMenu, ContextMenuTrigger } from '@/components/ui/context-menu'
|
||||
import { CanvasContextMenuContent } from '@/app/canvas/CanvasContextMenuContent'
|
||||
import { useCanvasConnectionPath } from '@/app/canvas/useCanvasConnectionPath'
|
||||
@@ -189,6 +189,9 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
|
||||
|
||||
const nodesRef = useRef(nodes)
|
||||
nodesRef.current = nodes
|
||||
const graphRef = useRef<{ nodes: AppNode[]; edges: AppEdge[] }>({ nodes: [], edges: [] })
|
||||
graphRef.current.nodes = nodes
|
||||
graphRef.current.edges = edges
|
||||
|
||||
const [apiTodosCount, setApiTodosCount] = React.useState<number | null>(null)
|
||||
React.useEffect(() => {
|
||||
@@ -244,7 +247,12 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
|
||||
)
|
||||
|
||||
const onConnect = useCallback(
|
||||
(params: Connection) => setEdges((eds) => addEdge(params, eds)),
|
||||
(params: Connection) => {
|
||||
const targetType =
|
||||
nodesRef.current.find((n) => n.id === params.target)?.type ?? ''
|
||||
const conn = { ...params, data: { targetType } as Record<string, unknown> }
|
||||
setEdges((eds) => addEdge(conn, eds))
|
||||
},
|
||||
[setEdges]
|
||||
)
|
||||
|
||||
@@ -324,7 +332,9 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
|
||||
toast.error('Invalid file: expected nodes and edges arrays')
|
||||
return
|
||||
}
|
||||
setStateImmediate({ nodes: state.nodes as AppNode[], edges: state.edges as AppEdge[] })
|
||||
const nodes = state.nodes as AppNode[]
|
||||
const edges = backfillEdgeTargetTypes(nodes, state.edges as AppEdge[])
|
||||
setStateImmediate({ nodes, edges })
|
||||
if (state.version != null && state.version > PROJECT_VERSION) {
|
||||
toast.error('Project was created with a newer app version')
|
||||
} else {
|
||||
@@ -393,8 +403,8 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
|
||||
}, [])
|
||||
|
||||
const graphContextValue = useMemo(
|
||||
() => ({ nodes, setNodes, edges, setEdges }),
|
||||
[nodes, setNodes, edges, setEdges]
|
||||
() => ({ setNodes, setEdges, graphRef, edges }),
|
||||
[setNodes, setEdges, edges]
|
||||
)
|
||||
const connectionPathContextValue = useMemo(
|
||||
() => ({
|
||||
@@ -438,18 +448,36 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
|
||||
]
|
||||
)
|
||||
|
||||
const nodesForFlow = useMemo(
|
||||
() =>
|
||||
nodes.map((n) => ({
|
||||
const prevNodesRef = useRef<AppNode[]>([])
|
||||
const prevNodesForFlowRef = useRef<Node[]>([])
|
||||
const nodesForFlow = useMemo(() => {
|
||||
const prev = prevNodesRef.current
|
||||
if (nodes === prev) return prevNodesForFlowRef.current
|
||||
const prevById = new Map(prev.map((n) => [n.id, n]))
|
||||
const prevWrappedById = new Map(
|
||||
prevNodesForFlowRef.current.map((w, i) => [prev[i]?.id, w])
|
||||
)
|
||||
const result = nodes.map((n) => {
|
||||
const prevNode = prevById.get(n.id)
|
||||
if (prevNode === n && prevWrappedById.has(n.id)) {
|
||||
return prevWrappedById.get(n.id)!
|
||||
}
|
||||
return {
|
||||
...n,
|
||||
className: [n.className, 'nowheel'].filter(Boolean).join(' '),
|
||||
})),
|
||||
[nodes]
|
||||
)
|
||||
}
|
||||
})
|
||||
prevNodesRef.current = nodes
|
||||
prevNodesForFlowRef.current = result
|
||||
return result
|
||||
}, [nodes])
|
||||
const edgesForFlow = useMemo(
|
||||
() =>
|
||||
edges.map((e) => {
|
||||
const targetType = nodes.find((nd) => nd.id === e.target)?.type ?? ''
|
||||
const targetType =
|
||||
(typeof e.data === 'object' && e.data !== null && (e.data as Record<string, unknown>).targetType != null
|
||||
? (e.data as Record<string, unknown>).targetType
|
||||
: '') as string
|
||||
const connectionLabel = getConnectionLabelForTarget(targetType)
|
||||
const baseData =
|
||||
typeof e.data === 'object' && e.data !== null ? (e.data as Record<string, unknown>) : {}
|
||||
@@ -458,7 +486,7 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
|
||||
data: { ...baseData, connectionLabel },
|
||||
}
|
||||
}),
|
||||
[edges, nodes]
|
||||
[edges]
|
||||
)
|
||||
|
||||
const onContextMenuCapture = useCallback((ev: React.MouseEvent) => {
|
||||
|
||||
Reference in New Issue
Block a user