mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-08 02:36:10 +00:00
* fix(studio): preserve composition playback continuity * feat(studio): drag compositions into the timeline * fix(studio): collapse expanded composition move aliases * fix(studio): make timeline cuts atomic * fix(studio): group inspector gesture history * test(studio): cover masked text selection * fix(studio): harden composition timeline reliability * fix(studio): satisfy CI source gates * fix(studio): harden composition mutation requests
30 lines
1.2 KiB
TypeScript
30 lines
1.2 KiB
TypeScript
import type { TimelineElement } from "../store/playerStore";
|
|
|
|
const keyOf = (element: TimelineElement) => element.key ?? element.id;
|
|
|
|
/** Authored track numbers only compare within one source file. */
|
|
export const sameSourceFile = (a: TimelineElement, b: TimelineElement): boolean =>
|
|
(a.sourceFile ?? null) === (b.sourceFile ?? null);
|
|
|
|
/** Translate a display lane into the source-file track to persist. */
|
|
export function authoredTrackForLane(
|
|
lane: number,
|
|
elements: TimelineElement[],
|
|
dragged: TimelineElement,
|
|
): number {
|
|
const dragKey = keyOf(dragged);
|
|
const peers = elements.filter((element) => {
|
|
return keyOf(element) !== dragKey && sameSourceFile(element, dragged);
|
|
});
|
|
const occupant = peers.find((element) => element.track === lane);
|
|
if (occupant) return occupant.authoredTrack ?? occupant.track;
|
|
|
|
let nearest: TimelineElement | null = null;
|
|
for (const peer of peers) {
|
|
if (!nearest || Math.abs(peer.track - lane) < Math.abs(nearest.track - lane)) nearest = peer;
|
|
}
|
|
if (!nearest) return lane;
|
|
// Synthetic expanded-child display rows can be fractional; authored tracks cannot.
|
|
return Math.round((nearest.authoredTrack ?? nearest.track) + (lane - nearest.track));
|
|
}
|