refactor(studio): double-cast test fixtures and split three dense functions

CONTRIBUTING.md allows `as unknown as T` with a justification, not a bare
`as T`; the gsapShared fixtures only carry the fields under test.

The fallow complexity gate flagged three functions on this branch. Each is
split at its natural seam rather than suppressed: the auto-expand scan moves
out of the effect, the four repeated attribute guards in
nodeMatchesManifestClip collapse into one table-driven check, and the
segment-% interpolation moves out of onPathDown.
This commit is contained in:
Miguel Angel Simon Sierra
2026-07-28 00:40:46 +02:00
parent b8ff8bf0f3
commit e317f1fbe3
4 changed files with 55 additions and 34 deletions
@@ -11,6 +11,24 @@ import { animationContributesLane } from "./TimelinePropertyLanes";
* — tracked per-clip so a later user collapse sticks and never bounces back open
* (and clips added later still auto-expand).
*/
/**
* Prunes clips that left the source, then returns the ones that newly contribute
* a lane. The prune matters because the set is otherwise append-only: a clip
* deleted and reinserted under the same id (undo, paste) would be remembered as
* already-expanded and never auto-expand again.
*/
function freshLaneClips(gsapAnimations: Map<string, GsapAnimation[]>, clips: Set<string>) {
for (const key of clips) {
if (!gsapAnimations.has(key)) clips.delete(key);
}
const fresh: string[] = [];
for (const [key, animations] of gsapAnimations) {
if (clips.has(key)) continue;
if (animations.some(animationContributesLane)) fresh.push(key);
}
return fresh;
}
export function useAutoExpandKeyframedClips(gsapAnimations: Map<string, GsapAnimation[]>): void {
const expandClips = usePlayerStore((s) => s.expandClips);
const projectId = useStudioShellContextOptional()?.projectId ?? null;
@@ -24,17 +42,7 @@ export function useAutoExpandKeyframedClips(gsapAnimations: Map<string, GsapAnim
} else {
seen.current.source = gsapAnimations;
}
// Drop clips that are no longer in the source at all. Without this the set
// is append-only, so a clip deleted and reinserted under the same id (undo,
// paste) is remembered as already-expanded and never auto-expands again.
for (const key of seen.current.clips) {
if (!gsapAnimations.has(key)) seen.current.clips.delete(key);
}
const fresh: string[] = [];
for (const [key, animations] of gsapAnimations) {
if (seen.current.clips.has(key)) continue;
if (animations.some(animationContributesLane)) fresh.push(key);
}
const fresh = freshLaneClips(gsapAnimations, seen.current.clips);
if (fresh.length === 0) return;
for (const key of fresh) seen.current.clips.add(key);
expandClips(fresh);