From 9fda27f93ff485ddc7ba7851caa76d7ac6e889d4 Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Mon, 20 Jul 2026 19:32:57 +0200 Subject: [PATCH] perf(studio): follow playhead across virtualized rows --- bun.lock | 5 + packages/studio/package.json | 1 + .../player/components/LayerDisclosureRow.tsx | 1 + .../src/player/components/Timeline.test.ts | 78 ++++++++ .../studio/src/player/components/Timeline.tsx | 51 +++-- .../Timeline.virtualization.test.tsx | 104 +++++++++++ .../src/player/components/TimelineCanvas.tsx | 4 +- .../player/components/TimelineLaneTypes.ts | 5 + .../src/player/components/TimelineLanes.tsx | 46 +++-- .../player/components/TimelineTrackRow.tsx | 46 +++++ .../player/components/timelineEditing.test.ts | 32 ++++ .../src/player/components/timelineEditing.ts | 52 +++++- .../components/timelineFocusIdentity.test.ts | 21 +++ .../components/timelineFocusIdentity.ts | 21 +++ .../src/player/components/timelineLayout.ts | 41 +++++ .../player/components/useTimelinePlayhead.ts | 43 +++-- .../useTimelineRowVirtualization.ts | 135 ++++++++++++++ .../useTimelineVirtualRows.test.tsx | 174 ++++++++++++++++++ .../components/useTimelineVirtualRows.ts | 110 +++++++++++ 19 files changed, 901 insertions(+), 69 deletions(-) create mode 100644 packages/studio/src/player/components/Timeline.virtualization.test.tsx create mode 100644 packages/studio/src/player/components/TimelineTrackRow.tsx create mode 100644 packages/studio/src/player/components/timelineFocusIdentity.test.ts create mode 100644 packages/studio/src/player/components/timelineFocusIdentity.ts create mode 100644 packages/studio/src/player/components/useTimelineRowVirtualization.ts create mode 100644 packages/studio/src/player/components/useTimelineVirtualRows.test.tsx create mode 100644 packages/studio/src/player/components/useTimelineVirtualRows.ts diff --git a/bun.lock b/bun.lock index 797509c8ee..3ff8d8ced7 100644 --- a/bun.lock +++ b/bun.lock @@ -328,6 +328,7 @@ "@hyperframes/sdk": "workspace:*", "@hyperframes/studio-server": "workspace:*", "@phosphor-icons/react": "^2.1.10", + "@tanstack/react-virtual": "^3.14.6", "bpm-detective": "^2.0.5", "dompurify": "^3.2.4", "gsap": "^3.13.0", @@ -1106,6 +1107,10 @@ "@swc/helpers": ["@swc/helpers@0.5.21", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg=="], + "@tanstack/react-virtual": ["@tanstack/react-virtual@3.14.6", "", { "dependencies": { "@tanstack/virtual-core": "3.17.4" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-4+Uq8m0/gzO4kMCHUEpTtGX1RnONK0C+g88b2ltwPMWUBiaVarBuWKoPJaz7gj1cKCVRAdyu+U8GcKhwCc2beA=="], + + "@tanstack/virtual-core": ["@tanstack/virtual-core@3.17.4", "", {}, "sha512-nGm5KteqxasUdThLc2izl6dHUqLv0LQj7Nuyo5gYalTPf/U8a9ermvsl7reT+6ioBW1l8WfpP/mcU338nLXpqw=="], + "@tootallnate/once": ["@tootallnate/once@2.0.1", "", {}, "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ=="], "@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="], diff --git a/packages/studio/package.json b/packages/studio/package.json index b5971ff4ec..fd51b6c838 100644 --- a/packages/studio/package.json +++ b/packages/studio/package.json @@ -71,6 +71,7 @@ "@hyperframes/sdk": "workspace:*", "@hyperframes/studio-server": "workspace:*", "@phosphor-icons/react": "^2.1.10", + "@tanstack/react-virtual": "^3.14.6", "bpm-detective": "^2.0.5", "dompurify": "^3.2.4", "gsap": "^3.13.0", diff --git a/packages/studio/src/player/components/LayerDisclosureRow.tsx b/packages/studio/src/player/components/LayerDisclosureRow.tsx index b630482d69..2535ee2e09 100644 --- a/packages/studio/src/player/components/LayerDisclosureRow.tsx +++ b/packages/studio/src/player/components/LayerDisclosureRow.tsx @@ -28,6 +28,7 @@ export function LayerDisclosureRow({ >