mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 23:00:03 +00:00
fix(studio): close the review findings that survived the stack
Selector reads now go through one inverse of `idSelector`. Every writer emits `[id="01-hook-hero"]` for an id a `#id` selector can't address, but the readers still matched `#id` only, so the post-commit keyframe-cache refresh, the AST load and the remove-all-keyframes clear all silently skipped exactly the ids `idSelector` was added to support. A keyframe merged from two tweens with different eases kept whichever ease iterated last. Readers that don't check `easeAmbiguous` showed a curve from a different animation than an edit would target, so the ambiguous flag now clears `ease` instead of leaving an arbitrary one behind. One tolerance for "the playhead is on this keyframe". The motion-path drag used 0.05% while the toolbar and the playhead apply used 1%, so a drag that landed a fraction of a percent off an authored waypoint skipped the update-point branch and appended a near-duplicate. `buildTemporalArcKeyframes` now owns the invariant and replaces any keyframe inside the tolerance, rather than trusting each caller's own pre-check. The pending-retime bookkeeping matches on keyframe identity, not just on "something is near that percentage" — an evenly spaced row cleared the entry off an unrelated sibling. The neighbour clamp composes pending destinations in before sorting, so a second drag can't cross a neighbour that already moved. Also: `keyframeCache`/`gsapAnimations` setters return the same state for a write that changes nothing (every no-op re-rendered every subscriber), the auto-expand set drops clips that left the source so an undo/paste under the same id expands again, `invalidateGsapCache` has a stable identity instead of re-creating the whole timeline edit context each render, the studio test hook deletes its window key rather than leaving it enumerable as undefined, and the past-last-row extrapolation documents why it uses TRACK_H where the pre-first-row branch uses row 0's own height. Covers `idFromSelector` round-trips, the insert boundary band across plain, expanded and unusable row heights, and the collapsed selection key for a colon-bearing element id.
This commit is contained in:
@@ -157,6 +157,9 @@ export function StudioApp() {
|
||||
pendingTimelineEditPathRef,
|
||||
});
|
||||
const invalidateGsapCacheRef = useRef<() => void>(() => {});
|
||||
// Stable identity — what the ref indirection is for. An inline arrow re-created
|
||||
// the memoized timeline handlers (it is in their deps) on every render.
|
||||
const invalidateGsapCache = useCallback(() => invalidateGsapCacheRef.current(), []);
|
||||
const timelineEditing = useTimelineEditing({
|
||||
projectId,
|
||||
activeCompPath,
|
||||
@@ -174,7 +177,7 @@ export function StudioApp() {
|
||||
sdkSession: editFlowSdkSession,
|
||||
publishSdkSession: sdkHandle.publish,
|
||||
forceReloadSdkSession: sdkHandle.forceReload,
|
||||
invalidateGsapCache: () => invalidateGsapCacheRef.current(),
|
||||
invalidateGsapCache,
|
||||
handleDomZIndexReorderCommitRef,
|
||||
});
|
||||
const handleTimelineElementsMove: TimelineMoveEditsHandler = useCallback(
|
||||
|
||||
Reference in New Issue
Block a user