@hyperframes/studio 0.7.79 → 0.7.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{hyperframes-player-mFah2TZE.js → hyperframes-player-Csai0_vh.js} +1 -1
- package/dist/assets/{index-Bqj3h_1a.js → index-B5aYTg-4.js} +1 -1
- package/dist/assets/{index-DlZMDyYs.js → index-BhdJN49y.js} +200 -200
- package/dist/assets/{index-hmnoiSEV.js → index-By-YiRxq.js} +1 -1
- package/dist/assets/index-D379YOKT.css +1 -0
- package/dist/index.d.ts +45 -3
- package/dist/index.html +2 -2
- package/dist/index.js +652 -465
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/components/StudioRightPanel.tsx +2 -1
- package/src/components/editor/AnimationCard.test.tsx +225 -18
- package/src/components/editor/AnimationCard.tsx +24 -3
- package/src/components/editor/EaseCurveSection.test.tsx +147 -2
- package/src/components/editor/EaseCurveSection.tsx +77 -15
- package/src/components/editor/GsapAnimationSection.test.tsx +102 -0
- package/src/components/editor/GsapAnimationSection.tsx +6 -1
- package/src/components/editor/KeyframeEaseList.tsx +4 -0
- package/src/components/editor/MotionPathOverlay.tsx +54 -19
- package/src/components/editor/PropertyPanel.tsx +4 -0
- package/src/components/editor/PropertyPanelFlat.tsx +6 -91
- package/src/components/editor/gsapAnimationCallbacks.test.ts +8 -1
- package/src/components/editor/gsapAnimationCallbacks.ts +8 -0
- package/src/components/editor/holdEaseSeek.test.ts +37 -0
- package/src/components/editor/propertyPanelFlatMotionSection.test.tsx +69 -0
- package/src/components/editor/propertyPanelFlatMotionSection.tsx +2 -1
- package/src/components/editor/propertyPanelFlatProps.ts +91 -0
- package/src/components/editor/propertyPanelTypes.ts +2 -0
- package/src/contexts/DomEditContext.tsx +4 -0
- package/src/hooks/gsapKeyframeCacheHelpers.test.ts +132 -43
- package/src/hooks/gsapKeyframeCacheHelpers.ts +150 -50
- package/src/hooks/gsapTweenSynth.test.ts +70 -15
- package/src/hooks/gsapTweenSynth.ts +50 -23
- package/src/hooks/keyframeCacheAstLoad.ts +4 -12
- package/src/hooks/useDomEditSession.test.tsx +152 -3
- package/src/hooks/useDomEditSession.ts +4 -53
- package/src/hooks/useGsapTweenCache.ts +40 -34
- package/src/hooks/useKeyframeEaseCommits.ts +78 -0
- package/src/player/components/KeyframeDiamondContextMenu.test.tsx +21 -0
- package/src/player/components/KeyframeDiamondContextMenu.tsx +19 -12
- package/src/player/components/TimelineClipDiamonds.test.tsx +18 -6
- package/src/player/components/TimelineDiamondConnectors.tsx +118 -85
- package/src/player/components/timelineDiamondTypes.ts +4 -3
- package/src/player/components/timelineKeyframeIdentity.ts +3 -0
- package/src/player/components/useTimelineKeyframeHandlers.test.tsx +52 -32
- package/src/player/components/useTimelineKeyframeHandlers.ts +1 -0
- package/src/player/hooks/useExpandedTimelineElements.test.ts +29 -0
- package/src/player/hooks/useExpandedTimelineElements.ts +24 -0
- package/src/player/store/keyframeSlice.ts +15 -5
- package/dist/assets/index-gGVKuFg5.css +0 -1
package/dist/index.js
CHANGED
|
@@ -3586,7 +3586,15 @@ function clampChildToParent(child, parentStart, parentEnd) {
|
|
|
3586
3586
|
const clampedDuration = Math.min(childEnd, parentEnd) - clampedStart;
|
|
3587
3587
|
return clampedDuration > 0 ? { start: clampedStart, duration: clampedDuration } : null;
|
|
3588
3588
|
}
|
|
3589
|
-
function
|
|
3589
|
+
function hostElementState(flat) {
|
|
3590
|
+
if (!flat) return {};
|
|
3591
|
+
return {
|
|
3592
|
+
hidden: flat.hidden,
|
|
3593
|
+
timelineLocked: flat.timelineLocked,
|
|
3594
|
+
timelineRole: flat.timelineRole
|
|
3595
|
+
};
|
|
3596
|
+
}
|
|
3597
|
+
function buildChildElements(siblings, display, editBasis, expandedHostKey, elements) {
|
|
3590
3598
|
const result = [];
|
|
3591
3599
|
for (const child of siblings) {
|
|
3592
3600
|
const clamped = clampChildToParent(child, display.start, display.end);
|
|
@@ -3607,6 +3615,7 @@ function buildChildElements(siblings, display, editBasis, expandedHostKey) {
|
|
|
3607
3615
|
});
|
|
3608
3616
|
result.push({
|
|
3609
3617
|
...base2,
|
|
3618
|
+
...hostElementState(elements.find((element) => element.key === key)),
|
|
3610
3619
|
key,
|
|
3611
3620
|
start: clamped.start,
|
|
3612
3621
|
duration: clamped.duration,
|
|
@@ -3681,7 +3690,8 @@ function buildExpandedElements(elements, manifest, parentMap, topLevelId, siblin
|
|
|
3681
3690
|
track: topLevelElement.track
|
|
3682
3691
|
},
|
|
3683
3692
|
editBasis,
|
|
3684
|
-
parentKey
|
|
3693
|
+
parentKey,
|
|
3694
|
+
elements
|
|
3685
3695
|
);
|
|
3686
3696
|
if (expanded.length === 0) return filterToTopLevel(elements, parentMap);
|
|
3687
3697
|
const drillPath = /* @__PURE__ */ new Set();
|
|
@@ -7212,23 +7222,50 @@ function EaseParameterField({
|
|
|
7212
7222
|
if (wiggleConfig !== null) return /* @__PURE__ */ jsx18(WiggleField, { config: wiggleConfig, onCommit });
|
|
7213
7223
|
return /* @__PURE__ */ jsx18(EaseBezierField, { tuple, onCommit });
|
|
7214
7224
|
}
|
|
7225
|
+
var PENDING_EASE_TIMEOUT_MS = 2e3;
|
|
7215
7226
|
function EaseCurveSection({
|
|
7216
7227
|
ease,
|
|
7217
|
-
onCustomEaseCommit
|
|
7228
|
+
onCustomEaseCommit,
|
|
7229
|
+
collidingAnimationTargets
|
|
7218
7230
|
}) {
|
|
7219
|
-
const
|
|
7231
|
+
const [pendingEase, setPendingEase] = useState9(null);
|
|
7232
|
+
const inFlightEasesRef = useRef12([]);
|
|
7233
|
+
const displayedEase = pendingEase ?? ease;
|
|
7234
|
+
const springBounce = parseSpringBounce3(displayedEase);
|
|
7220
7235
|
const isSpring = springBounce !== null;
|
|
7221
|
-
const wiggleConfig = parseWiggleEase3(
|
|
7236
|
+
const wiggleConfig = parseWiggleEase3(displayedEase);
|
|
7222
7237
|
const isWiggle = wiggleConfig !== null;
|
|
7223
7238
|
const mode = isSpring ? "spring" : isWiggle ? "wiggle" : "curve";
|
|
7224
|
-
const curve = resolveEditableCurve(
|
|
7239
|
+
const curve = resolveEditableCurve(displayedEase, springBounce);
|
|
7225
7240
|
const [draft, setDraft] = useState9(null);
|
|
7226
7241
|
const [hover, setHover] = useState9(null);
|
|
7227
7242
|
const draggingRef = useRef12(null);
|
|
7228
7243
|
const svgRef = useRef12(null);
|
|
7229
7244
|
useEffect11(() => {
|
|
7230
7245
|
setDraft(null);
|
|
7246
|
+
const inFlight = inFlightEasesRef.current;
|
|
7247
|
+
const landed = inFlight.indexOf(ease);
|
|
7248
|
+
if (landed < 0) {
|
|
7249
|
+
inFlight.length = 0;
|
|
7250
|
+
setPendingEase(null);
|
|
7251
|
+
return;
|
|
7252
|
+
}
|
|
7253
|
+
inFlight.splice(0, landed + 1);
|
|
7254
|
+
if (inFlight.length === 0) setPendingEase(null);
|
|
7231
7255
|
}, [ease]);
|
|
7256
|
+
useEffect11(() => {
|
|
7257
|
+
if (pendingEase === null) return;
|
|
7258
|
+
const timer = setTimeout(() => {
|
|
7259
|
+
inFlightEasesRef.current.length = 0;
|
|
7260
|
+
setPendingEase(null);
|
|
7261
|
+
}, PENDING_EASE_TIMEOUT_MS);
|
|
7262
|
+
return () => clearTimeout(timer);
|
|
7263
|
+
}, [pendingEase]);
|
|
7264
|
+
const commitEase = (nextEase) => {
|
|
7265
|
+
inFlightEasesRef.current.push(nextEase);
|
|
7266
|
+
setPendingEase(nextEase);
|
|
7267
|
+
onCustomEaseCommit(nextEase);
|
|
7268
|
+
};
|
|
7232
7269
|
const activeTuple = draft ?? curve;
|
|
7233
7270
|
const displayTuple = activeTuple ?? DEFAULT_CURVE;
|
|
7234
7271
|
const [x1, y1, x2, y2] = displayTuple;
|
|
@@ -7236,8 +7273,8 @@ function EaseCurveSection({
|
|
|
7236
7273
|
const a1 = { x: xToSvg(1), y: yToSvg(1) };
|
|
7237
7274
|
const p1 = { x: xToSvg(x1), y: yToSvg(clampView(y1)) };
|
|
7238
7275
|
const p2 = { x: xToSvg(x2), y: yToSvg(clampView(y2)) };
|
|
7239
|
-
const curvePath2 = curvePathFor(
|
|
7240
|
-
const showGraph = activeTuple !== null || isWiggle ||
|
|
7276
|
+
const curvePath2 = curvePathFor(displayedEase, springBounce, wiggleConfig, displayTuple);
|
|
7277
|
+
const showGraph = activeTuple !== null || isWiggle || displayedEase === "hold";
|
|
7241
7278
|
const showHandles = curve !== null && !isSpring && !isWiggle;
|
|
7242
7279
|
const handlePointerDown = (handle, e) => {
|
|
7243
7280
|
e.preventDefault();
|
|
@@ -7262,8 +7299,7 @@ function EaseCurveSection({
|
|
|
7262
7299
|
if (!draggingRef.current || !draft) return;
|
|
7263
7300
|
draggingRef.current = null;
|
|
7264
7301
|
const path = `M0,0 C${draft[0]},${draft[1]} ${draft[2]},${draft[3]} 1,1`;
|
|
7265
|
-
|
|
7266
|
-
queueMicrotask(() => setDraft(null));
|
|
7302
|
+
commitEase(`custom(${path})`);
|
|
7267
7303
|
};
|
|
7268
7304
|
const handleKeyDown = (handle, event) => {
|
|
7269
7305
|
const next = nudgeCurve(displayTuple, handle, event.key, event.shiftKey ? 0.1 : 0.01);
|
|
@@ -7271,17 +7307,21 @@ function EaseCurveSection({
|
|
|
7271
7307
|
event.preventDefault();
|
|
7272
7308
|
event.stopPropagation();
|
|
7273
7309
|
setDraft(next);
|
|
7274
|
-
|
|
7275
|
-
queueMicrotask(() => setDraft(null));
|
|
7310
|
+
commitEase(`custom(M0,0 C${next[0]},${next[1]} ${next[2]},${next[3]} 1,1)`);
|
|
7276
7311
|
};
|
|
7277
7312
|
const top = yToSvg(1);
|
|
7278
7313
|
const bottom = yToSvg(0);
|
|
7279
7314
|
const left = xToSvg(0);
|
|
7280
7315
|
const right = xToSvg(1);
|
|
7281
|
-
const label = resolveEditorLabel(
|
|
7316
|
+
const label = resolveEditorLabel(displayedEase, springBounce, isWiggle);
|
|
7282
7317
|
return /* @__PURE__ */ jsxs15("div", { className: "rounded-lg bg-neutral-900/50 p-2", children: [
|
|
7283
|
-
/* @__PURE__ */ jsx18(EaseTypeDropdown, { kind: mode, ease, label, onSelect:
|
|
7284
|
-
/* @__PURE__ */
|
|
7318
|
+
/* @__PURE__ */ jsx18(EaseTypeDropdown, { kind: mode, ease: displayedEase, label, onSelect: commitEase }),
|
|
7319
|
+
collidingAnimationTargets && collidingAnimationTargets.length > 1 && /* @__PURE__ */ jsxs15("p", { className: "mb-1 text-[9px] text-neutral-500", children: [
|
|
7320
|
+
"Applies to ",
|
|
7321
|
+
collidingAnimationTargets.length,
|
|
7322
|
+
" animations"
|
|
7323
|
+
] }),
|
|
7324
|
+
/* @__PURE__ */ jsx18(EaseModeToggle, { mode, onCommit: commitEase }),
|
|
7285
7325
|
/* @__PURE__ */ jsxs15("span", { className: "sr-only", "aria-live": "polite", children: [
|
|
7286
7326
|
MODE_LABELS[mode],
|
|
7287
7327
|
" ease editor selected"
|
|
@@ -7441,7 +7481,7 @@ function EaseCurveSection({
|
|
|
7441
7481
|
springBounce,
|
|
7442
7482
|
wiggleConfig,
|
|
7443
7483
|
tuple: displayTuple,
|
|
7444
|
-
onCommit:
|
|
7484
|
+
onCommit: commitEase
|
|
7445
7485
|
}
|
|
7446
7486
|
)
|
|
7447
7487
|
] }) : /* @__PURE__ */ jsxs15("p", { className: "px-0.5 py-1.5 text-[10px] leading-relaxed text-neutral-500", children: [
|
|
@@ -7463,7 +7503,6 @@ function TimelineDiamondConnectors({
|
|
|
7463
7503
|
keyframeTarget: keyframeTarget2,
|
|
7464
7504
|
onSelectSegment
|
|
7465
7505
|
}) {
|
|
7466
|
-
const pressXRef = useRef13(null);
|
|
7467
7506
|
return /* @__PURE__ */ jsx19(Fragment9, { children: markers.map((marker, i) => {
|
|
7468
7507
|
const previous = markers[i - 1];
|
|
7469
7508
|
if (!previous) return null;
|
|
@@ -7473,9 +7512,6 @@ function TimelineDiamondConnectors({
|
|
|
7473
7512
|
if (x2 - x1 < 1) return null;
|
|
7474
7513
|
const connectorLeft = x1 + previous.visualSize / 2;
|
|
7475
7514
|
const connectorWidth = x2 - x1 - previous.visualSize / 2 - marker.visualSize / 2;
|
|
7476
|
-
const target = keyframeTarget2(kf);
|
|
7477
|
-
const ease = kf.ease ?? globalEase;
|
|
7478
|
-
const roomForFullTarget = connectorWidth >= 24;
|
|
7479
7515
|
return /* @__PURE__ */ jsxs16(Fragment8, { children: [
|
|
7480
7516
|
/* @__PURE__ */ jsx19(
|
|
7481
7517
|
"div",
|
|
@@ -7494,66 +7530,90 @@ function TimelineDiamondConnectors({
|
|
|
7494
7530
|
}
|
|
7495
7531
|
}
|
|
7496
7532
|
),
|
|
7497
|
-
onSelectSegment &&
|
|
7498
|
-
|
|
7533
|
+
onSelectSegment && showsEaseControl(kf) && /* @__PURE__ */ jsx19(
|
|
7534
|
+
SegmentEaseControl,
|
|
7535
|
+
{
|
|
7536
|
+
left: x1,
|
|
7537
|
+
width: x2 - x1,
|
|
7538
|
+
centerY,
|
|
7539
|
+
ease: kf.ease ?? globalEase,
|
|
7540
|
+
target: keyframeTarget2(kf),
|
|
7541
|
+
roomForFullTarget: connectorWidth >= 24,
|
|
7542
|
+
onSelectSegment
|
|
7543
|
+
}
|
|
7544
|
+
)
|
|
7545
|
+
] }, `line-${i}-${previous.keyframe.percentage}-${kf.percentage}`);
|
|
7546
|
+
}) });
|
|
7547
|
+
}
|
|
7548
|
+
function showsEaseControl(kf) {
|
|
7549
|
+
return kf.animationId !== void 0;
|
|
7550
|
+
}
|
|
7551
|
+
function SegmentEaseControl({
|
|
7552
|
+
left,
|
|
7553
|
+
width,
|
|
7554
|
+
centerY,
|
|
7555
|
+
ease,
|
|
7556
|
+
target,
|
|
7557
|
+
roomForFullTarget,
|
|
7558
|
+
onSelectSegment
|
|
7559
|
+
}) {
|
|
7560
|
+
const pressXRef = useRef13(null);
|
|
7561
|
+
return /* @__PURE__ */ jsx19(
|
|
7562
|
+
"div",
|
|
7563
|
+
{
|
|
7564
|
+
className: "group absolute",
|
|
7565
|
+
"data-keyframe-ease-segment": "",
|
|
7566
|
+
style: {
|
|
7567
|
+
left,
|
|
7568
|
+
top: centerY,
|
|
7569
|
+
width,
|
|
7570
|
+
height: 18,
|
|
7571
|
+
transform: "translateY(-50%)",
|
|
7572
|
+
// Own a stacking context above the diamond buttons. At fit zoom the 16px
|
|
7573
|
+
// ease control can overlap its neighbouring diamond; without a z-index
|
|
7574
|
+
// here the later diamond wins the hit test even though the child button
|
|
7575
|
+
// has z-index 3.
|
|
7576
|
+
zIndex: 3,
|
|
7577
|
+
// Only the centered control is interactive. The transparent segment
|
|
7578
|
+
// wrapper must not swallow connector/clip gestures.
|
|
7579
|
+
pointerEvents: "none"
|
|
7580
|
+
},
|
|
7581
|
+
children: /* @__PURE__ */ jsx19(
|
|
7582
|
+
"button",
|
|
7499
7583
|
{
|
|
7500
|
-
|
|
7501
|
-
"data-keyframe-ease-
|
|
7584
|
+
type: "button",
|
|
7585
|
+
"data-keyframe-ease-button": "",
|
|
7586
|
+
"aria-label": `Edit ${ease} easing`,
|
|
7587
|
+
title: `Edit ${ease} easing`,
|
|
7588
|
+
className: `absolute flex items-center justify-center rounded opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100 ${roomForFullTarget ? "before:absolute before:left-1/2 before:top-1/2 before:h-6 before:w-6 before:-translate-x-1/2 before:-translate-y-1/2 before:content-['']" : ""}`,
|
|
7502
7589
|
style: {
|
|
7503
|
-
left:
|
|
7504
|
-
top:
|
|
7505
|
-
width:
|
|
7506
|
-
height:
|
|
7507
|
-
transform: "
|
|
7508
|
-
// Own a stacking context above the diamond buttons. At fit
|
|
7509
|
-
// zoom the 16px ease control can overlap its neighbouring
|
|
7510
|
-
// diamond; without a z-index here the later diamond wins the
|
|
7511
|
-
// hit test even though the child button has z-index 3.
|
|
7590
|
+
left: "50%",
|
|
7591
|
+
top: "50%",
|
|
7592
|
+
width: 16,
|
|
7593
|
+
height: 16,
|
|
7594
|
+
transform: "translate(-50%, -50%)",
|
|
7512
7595
|
zIndex: 3,
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7596
|
+
pointerEvents: "auto",
|
|
7597
|
+
padding: 0,
|
|
7598
|
+
border: "1px solid rgba(255, 255, 255, 0.14)",
|
|
7599
|
+
background: "#171717",
|
|
7600
|
+
cursor: "pointer"
|
|
7516
7601
|
},
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
width: 16,
|
|
7529
|
-
height: 16,
|
|
7530
|
-
transform: "translate(-50%, -50%)",
|
|
7531
|
-
zIndex: 3,
|
|
7532
|
-
pointerEvents: "auto",
|
|
7533
|
-
padding: 0,
|
|
7534
|
-
border: "1px solid rgba(255, 255, 255, 0.14)",
|
|
7535
|
-
background: "#171717",
|
|
7536
|
-
cursor: "pointer"
|
|
7537
|
-
},
|
|
7538
|
-
onPointerDown: (e) => {
|
|
7539
|
-
pressXRef.current = e.clientX;
|
|
7540
|
-
},
|
|
7541
|
-
onClick: (e) => {
|
|
7542
|
-
e.stopPropagation();
|
|
7543
|
-
const pressX = pressXRef.current;
|
|
7544
|
-
pressXRef.current = null;
|
|
7545
|
-
if (pressX !== null && Math.abs(e.clientX - pressX) >= KEYFRAME_DRAG_THRESHOLD_PX) {
|
|
7546
|
-
return;
|
|
7547
|
-
}
|
|
7548
|
-
onSelectSegment(target);
|
|
7549
|
-
},
|
|
7550
|
-
children: /* @__PURE__ */ jsx19(MiniCurveSvg, { ease, active: true, size: 12 })
|
|
7551
|
-
}
|
|
7552
|
-
)
|
|
7602
|
+
onPointerDown: (e) => {
|
|
7603
|
+
pressXRef.current = e.clientX;
|
|
7604
|
+
},
|
|
7605
|
+
onClick: (e) => {
|
|
7606
|
+
e.stopPropagation();
|
|
7607
|
+
const pressX = pressXRef.current;
|
|
7608
|
+
pressXRef.current = null;
|
|
7609
|
+
if (pressX !== null && Math.abs(e.clientX - pressX) >= KEYFRAME_DRAG_THRESHOLD_PX) return;
|
|
7610
|
+
onSelectSegment(target);
|
|
7611
|
+
},
|
|
7612
|
+
children: /* @__PURE__ */ jsx19(MiniCurveSvg, { ease, active: true, size: 12 })
|
|
7553
7613
|
}
|
|
7554
7614
|
)
|
|
7555
|
-
|
|
7556
|
-
|
|
7615
|
+
}
|
|
7616
|
+
);
|
|
7557
7617
|
}
|
|
7558
7618
|
|
|
7559
7619
|
// src/components/editor/KeyframeNavigation.tsx
|
|
@@ -7800,7 +7860,8 @@ function keyframeTarget(keyframe) {
|
|
|
7800
7860
|
percentage: keyframe.percentage,
|
|
7801
7861
|
tweenPercentage: keyframe.tweenPercentage,
|
|
7802
7862
|
propertyGroup: keyframe.propertyGroup,
|
|
7803
|
-
animationId: keyframe.animationId
|
|
7863
|
+
animationId: keyframe.animationId,
|
|
7864
|
+
collidingAnimationTargets: keyframe.collidingAnimationTargets
|
|
7804
7865
|
};
|
|
7805
7866
|
}
|
|
7806
7867
|
|
|
@@ -8440,16 +8501,24 @@ function isStaticPositionHold(anim) {
|
|
|
8440
8501
|
const propKeys = Object.keys(anim.properties).filter((k) => k !== "immediateRender");
|
|
8441
8502
|
return propKeys.length > 0 && propKeys.every((k) => k === "x" || k === "y");
|
|
8442
8503
|
}
|
|
8504
|
+
function accumulateCollidingAnimationTargets(keyframe, incoming) {
|
|
8505
|
+
const primaryId = keyframe.animationId;
|
|
8506
|
+
if (primaryId === incoming.animationId) return;
|
|
8507
|
+
const collisionTargets = keyframe.collidingAnimationTargets;
|
|
8508
|
+
if (collisionTargets?.some((target) => target.animationId === incoming.animationId)) return;
|
|
8509
|
+
keyframe.collidingAnimationTargets = [
|
|
8510
|
+
...collisionTargets === void 0 || collisionTargets.length === 0 ? [{ animationId: primaryId, tweenPercentage: keyframe.tweenPercentage }] : collisionTargets,
|
|
8511
|
+
{ animationId: incoming.animationId, tweenPercentage: incoming.tweenPercentage }
|
|
8512
|
+
];
|
|
8513
|
+
}
|
|
8443
8514
|
function deduplicateKeyframes(keyframes) {
|
|
8444
8515
|
const byPct = /* @__PURE__ */ new Map();
|
|
8445
8516
|
for (const kf of keyframes) {
|
|
8446
8517
|
const existing = byPct.get(kf.percentage);
|
|
8447
8518
|
if (existing) {
|
|
8448
8519
|
existing.properties = { ...existing.properties, ...kf.properties };
|
|
8449
|
-
|
|
8450
|
-
|
|
8451
|
-
}
|
|
8452
|
-
if (existing.easeAmbiguous) delete existing.ease;
|
|
8520
|
+
accumulateCollidingAnimationTargets(existing, kf);
|
|
8521
|
+
if ((existing.collidingAnimationTargets?.length ?? 0) > 1) delete existing.ease;
|
|
8453
8522
|
else if (kf.ease) existing.ease = kf.ease;
|
|
8454
8523
|
} else {
|
|
8455
8524
|
byPct.set(kf.percentage, { ...kf, properties: { ...kf.properties } });
|
|
@@ -13519,7 +13588,7 @@ var KeyframeDiamondContextMenu = memo11(function KeyframeDiamondContextMenu2({
|
|
|
13519
13588
|
animationId: state.animationId
|
|
13520
13589
|
};
|
|
13521
13590
|
const menuWidth = 200;
|
|
13522
|
-
const menuHeight = onMoveToPlayhead ?
|
|
13591
|
+
const menuHeight = 10 + (1 + (onMoveToPlayhead ? 1 : 0) + (onDelete ? 1 : 0)) * 30;
|
|
13523
13592
|
const overflowY = state.y + menuHeight - window.innerHeight;
|
|
13524
13593
|
const adjustedX = state.x + menuWidth > window.innerWidth ? state.x - menuWidth : state.x;
|
|
13525
13594
|
const adjustedY = overflowY > 0 ? state.y - overflowY - 8 : state.y;
|
|
@@ -13543,7 +13612,7 @@ var KeyframeDiamondContextMenu = memo11(function KeyframeDiamondContextMenu2({
|
|
|
13543
13612
|
children: "Move to Playhead"
|
|
13544
13613
|
}
|
|
13545
13614
|
),
|
|
13546
|
-
/* @__PURE__ */ jsx32(
|
|
13615
|
+
onDelete && /* @__PURE__ */ jsx32(
|
|
13547
13616
|
"button",
|
|
13548
13617
|
{
|
|
13549
13618
|
type: "button",
|
|
@@ -14025,7 +14094,8 @@ function DomEditProvider({
|
|
|
14025
14094
|
commitMutation,
|
|
14026
14095
|
applyMarqueeSelection,
|
|
14027
14096
|
handleUpdateKeyframeEase,
|
|
14028
|
-
handleSetAllKeyframeEases
|
|
14097
|
+
handleSetAllKeyframeEases,
|
|
14098
|
+
handleUpdateSegmentEase
|
|
14029
14099
|
},
|
|
14030
14100
|
children
|
|
14031
14101
|
}) {
|
|
@@ -14102,6 +14172,7 @@ function DomEditProvider({
|
|
|
14102
14172
|
commitMutation: stableCommitMutation,
|
|
14103
14173
|
applyMarqueeSelection,
|
|
14104
14174
|
handleUpdateKeyframeEase,
|
|
14175
|
+
handleUpdateSegmentEase,
|
|
14105
14176
|
handleSetAllKeyframeEases
|
|
14106
14177
|
}),
|
|
14107
14178
|
[
|
|
@@ -14170,6 +14241,7 @@ function DomEditProvider({
|
|
|
14170
14241
|
stableCommitMutation,
|
|
14171
14242
|
applyMarqueeSelection,
|
|
14172
14243
|
handleUpdateKeyframeEase,
|
|
14244
|
+
handleUpdateSegmentEase,
|
|
14173
14245
|
handleSetAllKeyframeEases
|
|
14174
14246
|
]
|
|
14175
14247
|
);
|
|
@@ -14835,6 +14907,7 @@ function useTimelineKeyframeHandlers({
|
|
|
14835
14907
|
if (target.animationId !== void 0 && target.tweenPercentage !== void 0) {
|
|
14836
14908
|
usePlayerStore.getState().setFocusedEaseSegment({
|
|
14837
14909
|
animationId: target.animationId,
|
|
14910
|
+
collidingAnimationTargets: target.collidingAnimationTargets,
|
|
14838
14911
|
tweenPercentage: target.tweenPercentage,
|
|
14839
14912
|
elementId: elId
|
|
14840
14913
|
});
|
|
@@ -24898,6 +24971,154 @@ var DomEditOverlay = memo22(function DomEditOverlay2({
|
|
|
24898
24971
|
);
|
|
24899
24972
|
});
|
|
24900
24973
|
|
|
24974
|
+
// src/hooks/gsapKeyframeCacheHelpers.ts
|
|
24975
|
+
function sameEntries(before, after) {
|
|
24976
|
+
if (before.size !== after.size) return false;
|
|
24977
|
+
for (const [key, value] of before) {
|
|
24978
|
+
if (after.get(key) !== value) return false;
|
|
24979
|
+
}
|
|
24980
|
+
return true;
|
|
24981
|
+
}
|
|
24982
|
+
function publishKeyframeCache(edit) {
|
|
24983
|
+
const { keyframeCache, gsapAnimations } = usePlayerStore.getState();
|
|
24984
|
+
const draft = {
|
|
24985
|
+
keyframeCache: new Map(keyframeCache),
|
|
24986
|
+
gsapAnimations: new Map(gsapAnimations)
|
|
24987
|
+
};
|
|
24988
|
+
edit(draft);
|
|
24989
|
+
if (sameEntries(keyframeCache, draft.keyframeCache) && sameEntries(gsapAnimations, draft.gsapAnimations))
|
|
24990
|
+
return;
|
|
24991
|
+
usePlayerStore.setState({
|
|
24992
|
+
keyframeCache: draft.keyframeCache,
|
|
24993
|
+
gsapAnimations: draft.gsapAnimations
|
|
24994
|
+
});
|
|
24995
|
+
}
|
|
24996
|
+
function updateKeyframeCacheFromParsed(animations, targetPath, selectionId, mutation, doc) {
|
|
24997
|
+
const { elements, domClipChildren } = usePlayerStore.getState();
|
|
24998
|
+
const idsWithKeyframes = /* @__PURE__ */ new Set();
|
|
24999
|
+
const merged = /* @__PURE__ */ new Map();
|
|
25000
|
+
const sourceAnimations = /* @__PURE__ */ new Map();
|
|
25001
|
+
for (const anim of animations) {
|
|
25002
|
+
const kfSource = anim.keyframes?.keyframes ?? synthesizeFlatTweenKeyframes(anim)?.keyframes ?? [];
|
|
25003
|
+
if (kfSource.length === 0) continue;
|
|
25004
|
+
for (const id of resolveSelectorElementIds(anim.targetSelector, doc)) {
|
|
25005
|
+
idsWithKeyframes.add(id);
|
|
25006
|
+
sourceAnimations.set(id, [...sourceAnimations.get(id) ?? [], anim]);
|
|
25007
|
+
const { elStart, elDuration } = resolveClipTimingBasis(
|
|
25008
|
+
id,
|
|
25009
|
+
targetPath,
|
|
25010
|
+
elements,
|
|
25011
|
+
domClipChildren
|
|
25012
|
+
);
|
|
25013
|
+
const clipKeyframes = toClipKeyframes(kfSource, anim, elStart, elDuration);
|
|
25014
|
+
const existing = merged.get(id);
|
|
25015
|
+
if (existing) {
|
|
25016
|
+
existing.keyframes = deduplicateKeyframes([...existing.keyframes, ...clipKeyframes]);
|
|
25017
|
+
} else {
|
|
25018
|
+
merged.set(id, {
|
|
25019
|
+
...anim.keyframes,
|
|
25020
|
+
format: anim.keyframes?.format ?? "percentage",
|
|
25021
|
+
keyframes: clipKeyframes
|
|
25022
|
+
});
|
|
25023
|
+
}
|
|
25024
|
+
}
|
|
25025
|
+
}
|
|
25026
|
+
const mutationSelector = mutation.targetSelector;
|
|
25027
|
+
const mutated = mutationSelector ? resolveSelectorElementIds(mutationSelector, doc) : [];
|
|
25028
|
+
const targetIds = mutated.length > 0 ? mutated : selectionId ? [selectionId] : [];
|
|
25029
|
+
publishKeyframeCache((draft) => {
|
|
25030
|
+
for (const [id, entry] of merged) {
|
|
25031
|
+
writeElementIntoDraft(draft, targetPath, id, entry, sourceAnimations.get(id));
|
|
25032
|
+
}
|
|
25033
|
+
for (const targetId of targetIds) {
|
|
25034
|
+
if (!idsWithKeyframes.has(targetId)) deleteElementFromDraft(draft, targetPath, targetId);
|
|
25035
|
+
}
|
|
25036
|
+
});
|
|
25037
|
+
}
|
|
25038
|
+
function writeElementIntoDraft(draft, sourceFile, elementId, entry, animations) {
|
|
25039
|
+
for (const key of elementCacheKeys(sourceFile, elementId)) {
|
|
25040
|
+
draft.keyframeCache.set(key, entry);
|
|
25041
|
+
if (animations) draft.gsapAnimations.set(key, animations);
|
|
25042
|
+
else draft.gsapAnimations.delete(key);
|
|
25043
|
+
}
|
|
25044
|
+
}
|
|
25045
|
+
function deleteElementFromDraft(draft, sourceFile, elementId) {
|
|
25046
|
+
for (const key of elementCacheKeys(sourceFile, elementId)) {
|
|
25047
|
+
draft.keyframeCache.delete(key);
|
|
25048
|
+
draft.gsapAnimations.delete(key);
|
|
25049
|
+
}
|
|
25050
|
+
}
|
|
25051
|
+
function clearKeyframeCacheForElement(sourceFile, elementId) {
|
|
25052
|
+
publishKeyframeCache((draft) => deleteElementFromDraft(draft, sourceFile, elementId));
|
|
25053
|
+
}
|
|
25054
|
+
function cachedElementIdsForFile(sourceFile, keyframeCache, gsapAnimations) {
|
|
25055
|
+
const sfPrefix = `${sourceFile}#`;
|
|
25056
|
+
const ids = /* @__PURE__ */ new Set();
|
|
25057
|
+
for (const key of [...keyframeCache.keys(), ...gsapAnimations.keys()]) {
|
|
25058
|
+
if (!key.startsWith(sfPrefix)) continue;
|
|
25059
|
+
ids.add(key.slice(sfPrefix.length));
|
|
25060
|
+
}
|
|
25061
|
+
return ids;
|
|
25062
|
+
}
|
|
25063
|
+
function pruneKeyframeCacheToFiles(files) {
|
|
25064
|
+
const keep = new Set(files);
|
|
25065
|
+
const { keyframeCache, gsapAnimations } = usePlayerStore.getState();
|
|
25066
|
+
const stale = /* @__PURE__ */ new Map();
|
|
25067
|
+
for (const key of [...keyframeCache.keys(), ...gsapAnimations.keys()]) {
|
|
25068
|
+
const hash = key.indexOf("#");
|
|
25069
|
+
if (hash < 0) continue;
|
|
25070
|
+
const sourceFile = key.slice(0, hash);
|
|
25071
|
+
if (keep.has(sourceFile)) continue;
|
|
25072
|
+
const ids = stale.get(sourceFile) ?? /* @__PURE__ */ new Set();
|
|
25073
|
+
ids.add(key.slice(hash + 1));
|
|
25074
|
+
stale.set(sourceFile, ids);
|
|
25075
|
+
}
|
|
25076
|
+
publishKeyframeCache((draft) => {
|
|
25077
|
+
for (const [sourceFile, ids] of stale) {
|
|
25078
|
+
for (const id of ids) deleteElementFromDraft(draft, sourceFile, id);
|
|
25079
|
+
}
|
|
25080
|
+
});
|
|
25081
|
+
}
|
|
25082
|
+
function scopedElementKey(element) {
|
|
25083
|
+
return `${element.sourceFile || "index.html"}#${element.id}`;
|
|
25084
|
+
}
|
|
25085
|
+
function elementCacheKeys(sourceFile, elementId) {
|
|
25086
|
+
return sourceFile === "index.html" ? [`index.html#${elementId}`, elementId] : [`${sourceFile}#${elementId}`, `index.html#${elementId}`, elementId];
|
|
25087
|
+
}
|
|
25088
|
+
function replaceKeyframeCacheForFile(sourceFile, entries, animationsByElement) {
|
|
25089
|
+
publishKeyframeCache((draft) => {
|
|
25090
|
+
for (const id of cachedElementIdsForFile(
|
|
25091
|
+
sourceFile,
|
|
25092
|
+
draft.keyframeCache,
|
|
25093
|
+
draft.gsapAnimations
|
|
25094
|
+
)) {
|
|
25095
|
+
deleteElementFromDraft(draft, sourceFile, id);
|
|
25096
|
+
}
|
|
25097
|
+
for (const [id, entry] of entries) {
|
|
25098
|
+
writeElementIntoDraft(draft, sourceFile, id, entry, animationsByElement.get(id));
|
|
25099
|
+
}
|
|
25100
|
+
});
|
|
25101
|
+
}
|
|
25102
|
+
function writeGsapAnimationsForElement(sourceFile, elementId, animations) {
|
|
25103
|
+
publishKeyframeCache((draft) => {
|
|
25104
|
+
for (const key of elementCacheKeys(sourceFile, elementId)) {
|
|
25105
|
+
if (animations) draft.gsapAnimations.set(key, animations);
|
|
25106
|
+
else draft.gsapAnimations.delete(key);
|
|
25107
|
+
}
|
|
25108
|
+
});
|
|
25109
|
+
}
|
|
25110
|
+
function buildCacheKey(sourceFile, elementId) {
|
|
25111
|
+
return `${sourceFile}#${elementId}`;
|
|
25112
|
+
}
|
|
25113
|
+
function readKeyframeSnapshot(sourceFile, elementId) {
|
|
25114
|
+
if (!elementId) return void 0;
|
|
25115
|
+
return usePlayerStore.getState().keyframeCache.get(buildCacheKey(sourceFile, elementId));
|
|
25116
|
+
}
|
|
25117
|
+
function writeKeyframeCache(sourceFile, elementId, data) {
|
|
25118
|
+
if (!elementId) return;
|
|
25119
|
+
usePlayerStore.getState().setKeyframeCache(buildCacheKey(sourceFile, elementId), data);
|
|
25120
|
+
}
|
|
25121
|
+
|
|
24901
25122
|
// src/components/editor/MotionPathOverlay.tsx
|
|
24902
25123
|
import { memo as memo23, useEffect as useEffect30, useRef as useRef43, useState as useState32 } from "react";
|
|
24903
25124
|
|
|
@@ -26017,7 +26238,7 @@ var MotionPathOverlay = memo23(function MotionPathOverlay2({
|
|
|
26017
26238
|
const activeKeyframePct = usePlayerStore((s) => s.activeKeyframePct);
|
|
26018
26239
|
const timelineElement = usePlayerStore((state) => {
|
|
26019
26240
|
if (!selection) return void 0;
|
|
26020
|
-
const sourceScopedId =
|
|
26241
|
+
const sourceScopedId = scopedElementKey(selection);
|
|
26021
26242
|
return state.elements.find(
|
|
26022
26243
|
(element) => (element.key ?? element.id) === sourceScopedId || element.id === selection.id
|
|
26023
26244
|
);
|
|
@@ -26242,18 +26463,31 @@ var MotionPathOverlay = memo23(function MotionPathOverlay2({
|
|
|
26242
26463
|
};
|
|
26243
26464
|
const elementId = selection?.id ?? null;
|
|
26244
26465
|
const onNodeContextMenu = (e, ref) => {
|
|
26245
|
-
if (
|
|
26466
|
+
if (!animId || !elementId || !timelineElement) return;
|
|
26246
26467
|
e.preventDefault();
|
|
26247
26468
|
e.stopPropagation();
|
|
26248
26469
|
setKfMenu({
|
|
26249
|
-
|
|
26250
|
-
|
|
26251
|
-
|
|
26252
|
-
|
|
26253
|
-
|
|
26254
|
-
|
|
26470
|
+
ref,
|
|
26471
|
+
state: {
|
|
26472
|
+
x: e.clientX,
|
|
26473
|
+
y: e.clientY,
|
|
26474
|
+
element: timelineElement,
|
|
26475
|
+
elementId,
|
|
26476
|
+
// A waypoint carries no percentage of its own: one tween-level ease owns
|
|
26477
|
+
// every segment, and its index is the identity the delete acts on. The
|
|
26478
|
+
// menu never reads this for a waypoint, because the only entry that
|
|
26479
|
+
// would (Move to Playhead) is hidden below.
|
|
26480
|
+
percentage: ref.type === "keyframe" ? ref.pct : 0,
|
|
26481
|
+
tweenPercentage: ref.type === "keyframe" ? ref.pct : 0
|
|
26482
|
+
}
|
|
26255
26483
|
});
|
|
26256
26484
|
};
|
|
26485
|
+
const menuRef = kfMenu?.ref;
|
|
26486
|
+
const onMenuDelete = menuRef === void 0 || !animId ? void 0 : menuRef.type === "keyframe" ? (_elId, keyframe) => {
|
|
26487
|
+
handleGsapRemoveKeyframe(animId, keyframe.percentage);
|
|
26488
|
+
} : removable ? () => {
|
|
26489
|
+
void commitRemoveWaypoint(animId, menuRef.index, commitMutation);
|
|
26490
|
+
} : void 0;
|
|
26257
26491
|
return /* @__PURE__ */ jsxs48(Fragment21, { children: [
|
|
26258
26492
|
/* @__PURE__ */ jsxs48(
|
|
26259
26493
|
"svg",
|
|
@@ -26342,11 +26576,11 @@ var MotionPathOverlay = memo23(function MotionPathOverlay2({
|
|
|
26342
26576
|
kfMenu && /* @__PURE__ */ jsx62(
|
|
26343
26577
|
KeyframeDiamondContextMenu,
|
|
26344
26578
|
{
|
|
26345
|
-
state: kfMenu,
|
|
26579
|
+
state: kfMenu.state,
|
|
26346
26580
|
onClose: () => setKfMenu(null),
|
|
26347
|
-
onDelete:
|
|
26581
|
+
onDelete: onMenuDelete,
|
|
26348
26582
|
onDeleteAll: () => animId && handleGsapRemoveAllKeyframes(animId),
|
|
26349
|
-
onMoveToPlayhead: (_element, keyframe) => animId && handleGsapMoveKeyframeToPlayhead(animId, keyframe.percentage)
|
|
26583
|
+
onMoveToPlayhead: kfMenu.ref.type === "keyframe" ? (_element, keyframe) => animId && handleGsapMoveKeyframeToPlayhead(animId, keyframe.percentage) : void 0
|
|
26350
26584
|
}
|
|
26351
26585
|
)
|
|
26352
26586
|
] });
|
|
@@ -29238,106 +29472,6 @@ async function tryGsapRotationIntercept(selection, angle, animations, iframe, co
|
|
|
29238
29472
|
return true;
|
|
29239
29473
|
}
|
|
29240
29474
|
|
|
29241
|
-
// src/hooks/gsapKeyframeCacheHelpers.ts
|
|
29242
|
-
function updateKeyframeCacheFromParsed(animations, targetPath, selectionId, mutation, doc) {
|
|
29243
|
-
const { setKeyframeCache, elements, domClipChildren } = usePlayerStore.getState();
|
|
29244
|
-
const idsWithKeyframes = /* @__PURE__ */ new Set();
|
|
29245
|
-
const merged = /* @__PURE__ */ new Map();
|
|
29246
|
-
const sourceAnimations = /* @__PURE__ */ new Map();
|
|
29247
|
-
for (const anim of animations) {
|
|
29248
|
-
const kfSource = anim.keyframes?.keyframes ?? synthesizeFlatTweenKeyframes(anim)?.keyframes ?? [];
|
|
29249
|
-
if (kfSource.length === 0) continue;
|
|
29250
|
-
for (const id of resolveSelectorElementIds(anim.targetSelector, doc)) {
|
|
29251
|
-
idsWithKeyframes.add(id);
|
|
29252
|
-
sourceAnimations.set(id, [...sourceAnimations.get(id) ?? [], anim]);
|
|
29253
|
-
const { elStart, elDuration } = resolveClipTimingBasis(
|
|
29254
|
-
id,
|
|
29255
|
-
targetPath,
|
|
29256
|
-
elements,
|
|
29257
|
-
domClipChildren
|
|
29258
|
-
);
|
|
29259
|
-
const clipKeyframes = toClipKeyframes(kfSource, anim, elStart, elDuration);
|
|
29260
|
-
const existing = merged.get(id);
|
|
29261
|
-
if (existing) {
|
|
29262
|
-
existing.keyframes = deduplicateKeyframes([...existing.keyframes, ...clipKeyframes]);
|
|
29263
|
-
} else {
|
|
29264
|
-
merged.set(id, {
|
|
29265
|
-
...anim.keyframes,
|
|
29266
|
-
format: anim.keyframes?.format ?? "percentage",
|
|
29267
|
-
keyframes: clipKeyframes
|
|
29268
|
-
});
|
|
29269
|
-
}
|
|
29270
|
-
}
|
|
29271
|
-
}
|
|
29272
|
-
for (const [id, entry] of merged) {
|
|
29273
|
-
for (const key of elementCacheKeys(targetPath, id)) setKeyframeCache(key, entry);
|
|
29274
|
-
writeGsapAnimationsForElement(targetPath, id, sourceAnimations.get(id));
|
|
29275
|
-
}
|
|
29276
|
-
const mutationSelector = mutation.targetSelector;
|
|
29277
|
-
const mutated = mutationSelector ? resolveSelectorElementIds(mutationSelector, doc) : [];
|
|
29278
|
-
const targetIds = mutated.length > 0 ? mutated : selectionId ? [selectionId] : [];
|
|
29279
|
-
for (const targetId of targetIds) {
|
|
29280
|
-
if (!idsWithKeyframes.has(targetId)) clearKeyframeCacheForElement(targetPath, targetId);
|
|
29281
|
-
}
|
|
29282
|
-
}
|
|
29283
|
-
function clearKeyframeCacheForElement(sourceFile, elementId) {
|
|
29284
|
-
const { keyframeCache, setKeyframeCache, gsapAnimations, setGsapAnimations } = usePlayerStore.getState();
|
|
29285
|
-
const keys = elementCacheKeys(sourceFile, elementId);
|
|
29286
|
-
for (const key of keys) {
|
|
29287
|
-
if (keyframeCache.has(key)) setKeyframeCache(key, void 0);
|
|
29288
|
-
if (gsapAnimations.has(key)) setGsapAnimations(key, void 0);
|
|
29289
|
-
}
|
|
29290
|
-
}
|
|
29291
|
-
function clearKeyframeCacheForFile(sourceFile) {
|
|
29292
|
-
const { keyframeCache, gsapAnimations } = usePlayerStore.getState();
|
|
29293
|
-
const sfPrefix = `${sourceFile}#`;
|
|
29294
|
-
const ids = /* @__PURE__ */ new Set();
|
|
29295
|
-
for (const key of [...keyframeCache.keys(), ...gsapAnimations.keys()]) {
|
|
29296
|
-
if (!key.startsWith(sfPrefix)) continue;
|
|
29297
|
-
ids.add(key.slice(sfPrefix.length));
|
|
29298
|
-
}
|
|
29299
|
-
for (const id of ids) {
|
|
29300
|
-
clearKeyframeCacheForElement(sourceFile, id);
|
|
29301
|
-
}
|
|
29302
|
-
}
|
|
29303
|
-
function pruneKeyframeCacheToFiles(files) {
|
|
29304
|
-
const keep = new Set(files);
|
|
29305
|
-
const { keyframeCache, gsapAnimations } = usePlayerStore.getState();
|
|
29306
|
-
const stale = /* @__PURE__ */ new Map();
|
|
29307
|
-
for (const key of [...keyframeCache.keys(), ...gsapAnimations.keys()]) {
|
|
29308
|
-
const hash = key.indexOf("#");
|
|
29309
|
-
if (hash < 0) continue;
|
|
29310
|
-
const sourceFile = key.slice(0, hash);
|
|
29311
|
-
if (keep.has(sourceFile)) continue;
|
|
29312
|
-
const ids = stale.get(sourceFile) ?? /* @__PURE__ */ new Set();
|
|
29313
|
-
ids.add(key.slice(hash + 1));
|
|
29314
|
-
stale.set(sourceFile, ids);
|
|
29315
|
-
}
|
|
29316
|
-
for (const [sourceFile, ids] of stale) {
|
|
29317
|
-
for (const id of ids) clearKeyframeCacheForElement(sourceFile, id);
|
|
29318
|
-
}
|
|
29319
|
-
}
|
|
29320
|
-
function elementCacheKeys(sourceFile, elementId) {
|
|
29321
|
-
return sourceFile === "index.html" ? [`index.html#${elementId}`, elementId] : [`${sourceFile}#${elementId}`, `index.html#${elementId}`, elementId];
|
|
29322
|
-
}
|
|
29323
|
-
function writeGsapAnimationsForElement(sourceFile, elementId, animations) {
|
|
29324
|
-
const { setGsapAnimations } = usePlayerStore.getState();
|
|
29325
|
-
for (const key of elementCacheKeys(sourceFile, elementId)) {
|
|
29326
|
-
setGsapAnimations(key, animations);
|
|
29327
|
-
}
|
|
29328
|
-
}
|
|
29329
|
-
function buildCacheKey(sourceFile, elementId) {
|
|
29330
|
-
return `${sourceFile}#${elementId}`;
|
|
29331
|
-
}
|
|
29332
|
-
function readKeyframeSnapshot(sourceFile, elementId) {
|
|
29333
|
-
if (!elementId) return void 0;
|
|
29334
|
-
return usePlayerStore.getState().keyframeCache.get(buildCacheKey(sourceFile, elementId));
|
|
29335
|
-
}
|
|
29336
|
-
function writeKeyframeCache(sourceFile, elementId, data) {
|
|
29337
|
-
if (!elementId) return;
|
|
29338
|
-
usePlayerStore.getState().setKeyframeCache(buildCacheKey(sourceFile, elementId), data);
|
|
29339
|
-
}
|
|
29340
|
-
|
|
29341
29475
|
// src/hooks/keyframeCacheAstLoad.ts
|
|
29342
29476
|
import { isStudioHoldSet } from "@hyperframes/core/gsap-parser";
|
|
29343
29477
|
function hasAnimations(value) {
|
|
@@ -29362,8 +29496,6 @@ async function fetchParsedAnimations(projectId, sourceFile) {
|
|
|
29362
29496
|
async function populateKeyframeCacheFromAst(projectId, sf, doc) {
|
|
29363
29497
|
const parsed = await fetchParsedAnimations(projectId, sf);
|
|
29364
29498
|
if (!parsed) return;
|
|
29365
|
-
const { setKeyframeCache } = usePlayerStore.getState();
|
|
29366
|
-
clearKeyframeCacheForFile(sf);
|
|
29367
29499
|
const { elements, domClipChildren } = usePlayerStore.getState();
|
|
29368
29500
|
const mergedByElement = /* @__PURE__ */ new Map();
|
|
29369
29501
|
const sourceByElement = /* @__PURE__ */ new Map();
|
|
@@ -29384,10 +29516,7 @@ async function populateKeyframeCacheFromAst(projectId, sf, doc) {
|
|
|
29384
29516
|
}
|
|
29385
29517
|
}
|
|
29386
29518
|
}
|
|
29387
|
-
|
|
29388
|
-
for (const key of elementCacheKeys(sf, id)) setKeyframeCache(key, kfData);
|
|
29389
|
-
writeGsapAnimationsForElement(sf, id, sourceByElement.get(id));
|
|
29390
|
-
}
|
|
29519
|
+
replaceKeyframeCacheForFile(sf, mergedByElement, sourceByElement);
|
|
29391
29520
|
}
|
|
29392
29521
|
|
|
29393
29522
|
// src/hooks/useGsapTweenCache.ts
|
|
@@ -29593,9 +29722,10 @@ function useGsapAnimationsForElement(projectId, sourceFile, target, version, ifr
|
|
|
29593
29722
|
...ease ? { ease } : {},
|
|
29594
29723
|
...easeEach ? { easeEach } : {}
|
|
29595
29724
|
};
|
|
29596
|
-
|
|
29597
|
-
|
|
29598
|
-
|
|
29725
|
+
publishKeyframeCache((draft) => {
|
|
29726
|
+
draft.keyframeCache.set(`${sourceFile}#${elementId}`, merged);
|
|
29727
|
+
draft.keyframeCache.set(elementId, merged);
|
|
29728
|
+
});
|
|
29599
29729
|
}, [elementId, sourceFile, animations, domClipChildrenKey]);
|
|
29600
29730
|
return { animations, multipleTimelines, unsupportedTimelinePattern };
|
|
29601
29731
|
}
|
|
@@ -29646,25 +29776,26 @@ function usePopulateKeyframeCacheForFile(projectId, sourceFile, version, iframeR
|
|
|
29646
29776
|
}
|
|
29647
29777
|
const scanned = scanAllRuntimeKeyframes(iframe, clipById);
|
|
29648
29778
|
if (scanned.size === 0) return false;
|
|
29649
|
-
|
|
29650
|
-
|
|
29651
|
-
|
|
29652
|
-
|
|
29653
|
-
|
|
29654
|
-
|
|
29655
|
-
|
|
29656
|
-
|
|
29657
|
-
|
|
29779
|
+
publishKeyframeCache((draft) => {
|
|
29780
|
+
for (const [id, data] of scanned) {
|
|
29781
|
+
const cacheKey = `${sf}#${id}`;
|
|
29782
|
+
const fallbackKey = `index.html#${id}`;
|
|
29783
|
+
const alreadyCached = draft.keyframeCache.has(cacheKey) || draft.keyframeCache.has(fallbackKey) || draft.keyframeCache.has(id);
|
|
29784
|
+
if (alreadyCached) continue;
|
|
29785
|
+
const isPosOnly = data.keyframes.length === 1 && Object.keys(data.keyframes[0].properties).every((k) => k === "x" || k === "y");
|
|
29786
|
+
if (isPosOnly) {
|
|
29787
|
+
continue;
|
|
29788
|
+
}
|
|
29789
|
+
const entry = {
|
|
29790
|
+
format: "percentage",
|
|
29791
|
+
keyframes: data.keyframes,
|
|
29792
|
+
...data.easeEach ? { easeEach: data.easeEach } : {}
|
|
29793
|
+
};
|
|
29794
|
+
draft.keyframeCache.set(cacheKey, entry);
|
|
29795
|
+
if (sf !== "index.html") draft.keyframeCache.set(fallbackKey, entry);
|
|
29796
|
+
draft.keyframeCache.set(id, entry);
|
|
29658
29797
|
}
|
|
29659
|
-
|
|
29660
|
-
format: "percentage",
|
|
29661
|
-
keyframes: data.keyframes,
|
|
29662
|
-
...data.easeEach ? { easeEach: data.easeEach } : {}
|
|
29663
|
-
};
|
|
29664
|
-
setKeyframeCache(cacheKey, entry);
|
|
29665
|
-
if (sf !== "index.html") setKeyframeCache(fallbackKey, entry);
|
|
29666
|
-
setKeyframeCache(id, entry);
|
|
29667
|
-
}
|
|
29798
|
+
});
|
|
29668
29799
|
runtimeScanDoneRef.current = `kf-cache:${projectId}:${sf}:${version}`;
|
|
29669
29800
|
return true;
|
|
29670
29801
|
};
|
|
@@ -37558,6 +37689,7 @@ function KeyframeEaseList({
|
|
|
37558
37689
|
keyframes,
|
|
37559
37690
|
globalEase,
|
|
37560
37691
|
expandedPct,
|
|
37692
|
+
collidingAnimationTargets,
|
|
37561
37693
|
onToggle,
|
|
37562
37694
|
onEaseCommit,
|
|
37563
37695
|
onApplyAll
|
|
@@ -37622,6 +37754,7 @@ function KeyframeEaseList({
|
|
|
37622
37754
|
EaseCurveSection,
|
|
37623
37755
|
{
|
|
37624
37756
|
ease: segEase,
|
|
37757
|
+
collidingAnimationTargets,
|
|
37625
37758
|
onCustomEaseCommit: (ease) => onEaseCommit(kf.percentage, ease)
|
|
37626
37759
|
}
|
|
37627
37760
|
) })
|
|
@@ -37831,6 +37964,7 @@ var AnimationCard = memo29(function AnimationCard2({
|
|
|
37831
37964
|
onSetArcPath,
|
|
37832
37965
|
onUpdateArcSegment,
|
|
37833
37966
|
onUpdateKeyframeEase,
|
|
37967
|
+
onUpdateSegmentEase,
|
|
37834
37968
|
onSetAllKeyframeEases,
|
|
37835
37969
|
onUnroll
|
|
37836
37970
|
}) {
|
|
@@ -37838,6 +37972,7 @@ var AnimationCard = memo29(function AnimationCard2({
|
|
|
37838
37972
|
const [addingProp, setAddingProp] = useState55(false);
|
|
37839
37973
|
const [addingFromProp, setAddingFromProp] = useState55(false);
|
|
37840
37974
|
const [expandedKfPct, setExpandedKfPct] = useState55(null);
|
|
37975
|
+
const [focusedCollidingAnimationTargets, setFocusedCollidingAnimationTargets] = useState55();
|
|
37841
37976
|
const cardRef = useRef62(null);
|
|
37842
37977
|
const pendingAutoScrollRef = useRef62(false);
|
|
37843
37978
|
useEffect49(() => {
|
|
@@ -37845,6 +37980,7 @@ var AnimationCard = memo29(function AnimationCard2({
|
|
|
37845
37980
|
setExpanded(true);
|
|
37846
37981
|
pendingAutoScrollRef.current = true;
|
|
37847
37982
|
setExpandedKfPct(focusedSegment.tweenPercentage);
|
|
37983
|
+
setFocusedCollidingAnimationTargets(focusedSegment.collidingAnimationTargets);
|
|
37848
37984
|
onFocusSegmentConsumed?.();
|
|
37849
37985
|
}, [focusedSegment, onFocusSegmentConsumed]);
|
|
37850
37986
|
useEffect49(() => {
|
|
@@ -38057,9 +38193,17 @@ var AnimationCard = memo29(function AnimationCard2({
|
|
|
38057
38193
|
keyframes: animation.keyframes.keyframes,
|
|
38058
38194
|
globalEase: animation.keyframes.easeEach ?? animation.ease ?? "none",
|
|
38059
38195
|
expandedPct: expandedKfPct,
|
|
38060
|
-
|
|
38196
|
+
collidingAnimationTargets: focusedCollidingAnimationTargets,
|
|
38197
|
+
onToggle: (pct) => {
|
|
38198
|
+
setExpandedKfPct(pct);
|
|
38199
|
+
setFocusedCollidingAnimationTargets(void 0);
|
|
38200
|
+
},
|
|
38061
38201
|
onEaseCommit: (pct, ease) => {
|
|
38062
|
-
|
|
38202
|
+
if (focusedCollidingAnimationTargets && focusedCollidingAnimationTargets.length > 1 && onUpdateSegmentEase) {
|
|
38203
|
+
onUpdateSegmentEase(focusedCollidingAnimationTargets, ease);
|
|
38204
|
+
} else {
|
|
38205
|
+
onUpdateKeyframeEase(animation.id, pct, ease);
|
|
38206
|
+
}
|
|
38063
38207
|
trackStudioSegmentEaseEdit({ action: "commit", ease });
|
|
38064
38208
|
},
|
|
38065
38209
|
onApplyAll: onSetAllKeyframeEases ? (ease) => onSetAllKeyframeEases(animation.id, ease) : void 0
|
|
@@ -38243,6 +38387,10 @@ function withTrackedGsapAnimationCallbacks(callbacks, track) {
|
|
|
38243
38387
|
} : void 0,
|
|
38244
38388
|
onLivePreview: callbacks.onLivePreview,
|
|
38245
38389
|
onLivePreviewEnd: callbacks.onLivePreviewEnd,
|
|
38390
|
+
onUpdateSegmentEase: callbacks.onUpdateSegmentEase ? (targets, ease) => {
|
|
38391
|
+
track("select", "Segment ease");
|
|
38392
|
+
callbacks.onUpdateSegmentEase?.(targets, ease);
|
|
38393
|
+
} : void 0,
|
|
38246
38394
|
onSetArcPath: callbacks.onSetArcPath ? (animationId, config) => {
|
|
38247
38395
|
track("toggle", config.autoRotate !== void 0 ? "Auto rotate" : "Arc motion");
|
|
38248
38396
|
callbacks.onSetArcPath?.(animationId, config);
|
|
@@ -38327,6 +38475,7 @@ import { jsx as jsx93, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
|
38327
38475
|
import { createElement } from "react";
|
|
38328
38476
|
var GsapAnimationSection = memo30(function GsapAnimationSection2({
|
|
38329
38477
|
animations,
|
|
38478
|
+
elementId,
|
|
38330
38479
|
multipleTimelines,
|
|
38331
38480
|
unsupportedTimelinePattern,
|
|
38332
38481
|
onAddAnimation,
|
|
@@ -38347,7 +38496,7 @@ var GsapAnimationSection = memo30(function GsapAnimationSection2({
|
|
|
38347
38496
|
key: anim.id,
|
|
38348
38497
|
animation: anim,
|
|
38349
38498
|
defaultExpanded: index === 0,
|
|
38350
|
-
focusedSegment: focusedEaseSegment?.animationId === anim.id ? focusedEaseSegment : null,
|
|
38499
|
+
focusedSegment: focusedEaseSegment?.elementId === elementId && focusedEaseSegment.animationId === anim.id ? focusedEaseSegment : null,
|
|
38351
38500
|
onFocusSegmentConsumed: clearFocusedEaseSegment
|
|
38352
38501
|
}
|
|
38353
38502
|
)),
|
|
@@ -40971,7 +41120,7 @@ function FlatMotionSection({
|
|
|
40971
41120
|
const [addMenuOpen, setAddMenuOpen] = useState62(false);
|
|
40972
41121
|
const trackedCallbacks = withTrackedGsapAnimationCallbacks(callbacks, track);
|
|
40973
41122
|
const focusedEaseSegment = usePlayerStore((s) => s.focusedEaseSegment);
|
|
40974
|
-
const renderedElementId =
|
|
41123
|
+
const renderedElementId = scopedElementKey(element);
|
|
40975
41124
|
const focusedHere = focusedEaseSegment && focusedEaseSegment.elementId === renderedElementId ? focusedEaseSegment : null;
|
|
40976
41125
|
return /* @__PURE__ */ jsxs87("div", { className: "space-y-3", children: [
|
|
40977
41126
|
showTiming && /* @__PURE__ */ jsx105(
|
|
@@ -44785,13 +44934,14 @@ function PropertyPanelFlat({
|
|
|
44785
44934
|
onUpdateArcSegment,
|
|
44786
44935
|
onUnroll,
|
|
44787
44936
|
onUpdateKeyframeEase,
|
|
44937
|
+
onUpdateSegmentEase,
|
|
44788
44938
|
onSetAllKeyframeEases
|
|
44789
44939
|
}) {
|
|
44790
44940
|
const [openGroupId, setOpenGroupId] = useState73(
|
|
44791
44941
|
() => isTextEditableSelection(element) ? "text" : showEditableSections ? "style" : sections.media ? "media" : "layout"
|
|
44792
44942
|
);
|
|
44793
44943
|
const focusedEaseSegment = usePlayerStore((s) => s.focusedEaseSegment);
|
|
44794
|
-
const renderedElementId =
|
|
44944
|
+
const renderedElementId = scopedElementKey(element);
|
|
44795
44945
|
const [consumedFocus, setConsumedFocus] = useState73(focusedEaseSegment);
|
|
44796
44946
|
if (focusedEaseSegment !== consumedFocus) {
|
|
44797
44947
|
setConsumedFocus(focusedEaseSegment);
|
|
@@ -44848,6 +44998,7 @@ function PropertyPanelFlat({
|
|
|
44848
44998
|
onUpdateArcSegment,
|
|
44849
44999
|
onUnroll,
|
|
44850
45000
|
onUpdateKeyframeEase,
|
|
45001
|
+
onUpdateSegmentEase,
|
|
44851
45002
|
onSetAllKeyframeEases
|
|
44852
45003
|
} : null;
|
|
44853
45004
|
const showMotionEffects = gsapEffectHandlers !== null;
|
|
@@ -45368,6 +45519,7 @@ var PropertyPanel = memo31(function PropertyPanel2(props) {
|
|
|
45368
45519
|
onUpdateArcSegment,
|
|
45369
45520
|
onUnroll,
|
|
45370
45521
|
onUpdateKeyframeEase,
|
|
45522
|
+
onUpdateSegmentEase,
|
|
45371
45523
|
onSetAllKeyframeEases,
|
|
45372
45524
|
onAddKeyframe,
|
|
45373
45525
|
onRemoveKeyframe,
|
|
@@ -45764,6 +45916,7 @@ var PropertyPanel = memo31(function PropertyPanel2(props) {
|
|
|
45764
45916
|
STUDIO_GSAP_PANEL_ENABLED && onUpdateGsapProperty && onUpdateGsapMeta && onDeleteGsapAnimation && onAddGsapProperty && onAddGsapAnimation && /* @__PURE__ */ jsx122(
|
|
45765
45917
|
GsapAnimationSection,
|
|
45766
45918
|
{
|
|
45919
|
+
elementId: scopedElementKey(element),
|
|
45767
45920
|
animations: gsapAnimations,
|
|
45768
45921
|
multipleTimelines: gsapMultipleTimelines,
|
|
45769
45922
|
unsupportedTimelinePattern: gsapUnsupportedTimelinePattern,
|
|
@@ -45781,7 +45934,8 @@ var PropertyPanel = memo31(function PropertyPanel2(props) {
|
|
|
45781
45934
|
onUpdateArcSegment,
|
|
45782
45935
|
onUnroll,
|
|
45783
45936
|
onUpdateKeyframeEase,
|
|
45784
|
-
onSetAllKeyframeEases
|
|
45937
|
+
onSetAllKeyframeEases,
|
|
45938
|
+
onUpdateSegmentEase
|
|
45785
45939
|
}
|
|
45786
45940
|
),
|
|
45787
45941
|
showEditableSections && /* @__PURE__ */ jsx122(
|
|
@@ -46607,7 +46761,7 @@ var FileTree = memo33(function FileTree2({
|
|
|
46607
46761
|
});
|
|
46608
46762
|
|
|
46609
46763
|
// src/App.tsx
|
|
46610
|
-
import { useState as useState132, useCallback as
|
|
46764
|
+
import { useState as useState132, useCallback as useCallback144, useRef as useRef134, useMemo as useMemo53, useEffect as useEffect116, useLayoutEffect as useLayoutEffect4 } from "react";
|
|
46611
46765
|
|
|
46612
46766
|
// src/components/renders/useRenderQueue.ts
|
|
46613
46767
|
import { useState as useState77, useEffect as useEffect66, useCallback as useCallback59, useRef as useRef77, useMemo as useMemo35 } from "react";
|
|
@@ -50602,7 +50756,7 @@ function persistTimelineMoveEditsAtomically(edits, coalesceKey, operation, deps,
|
|
|
50602
50756
|
}
|
|
50603
50757
|
|
|
50604
50758
|
// src/hooks/useDomEditSession.ts
|
|
50605
|
-
import { useCallback as
|
|
50759
|
+
import { useCallback as useCallback96 } from "react";
|
|
50606
50760
|
|
|
50607
50761
|
// src/hooks/useAskAgentModal.ts
|
|
50608
50762
|
import { useState as useState86, useCallback as useCallback74, useRef as useRef90, useEffect as useEffect71 } from "react";
|
|
@@ -55945,6 +56099,69 @@ function useStudioSelectionPublisher({
|
|
|
55945
56099
|
}, [domEditSelectionRef, previewDocumentVersion, refreshDomEditSelectionFromPreview]);
|
|
55946
56100
|
}
|
|
55947
56101
|
|
|
56102
|
+
// src/hooks/useKeyframeEaseCommits.ts
|
|
56103
|
+
import { useCallback as useCallback95 } from "react";
|
|
56104
|
+
function useKeyframeEaseCommits({
|
|
56105
|
+
gsapCommitMutation,
|
|
56106
|
+
domEditSelectionRef
|
|
56107
|
+
}) {
|
|
56108
|
+
const handleUpdateSegmentEase = useCallback95(
|
|
56109
|
+
(targets, ease) => {
|
|
56110
|
+
const selection = domEditSelectionRef.current;
|
|
56111
|
+
if (!selection || targets.length === 0) return;
|
|
56112
|
+
const options = {
|
|
56113
|
+
label: targets.length === 1 ? "Update keyframe ease" : "Update segment ease",
|
|
56114
|
+
softReload: true
|
|
56115
|
+
};
|
|
56116
|
+
const calls = targets.map(({ animationId, tweenPercentage }) => ({
|
|
56117
|
+
selection,
|
|
56118
|
+
mutation: {
|
|
56119
|
+
type: "update-keyframe",
|
|
56120
|
+
animationId,
|
|
56121
|
+
percentage: tweenPercentage,
|
|
56122
|
+
properties: {},
|
|
56123
|
+
ease
|
|
56124
|
+
},
|
|
56125
|
+
options
|
|
56126
|
+
}));
|
|
56127
|
+
if (calls.length === 1) {
|
|
56128
|
+
const call = calls[0];
|
|
56129
|
+
if (call) void gsapCommitMutation(call.selection, call.mutation, call.options);
|
|
56130
|
+
return;
|
|
56131
|
+
}
|
|
56132
|
+
const batch = gsapCommitMutation.batch;
|
|
56133
|
+
if (batch) {
|
|
56134
|
+
void batch(calls, options);
|
|
56135
|
+
return;
|
|
56136
|
+
}
|
|
56137
|
+
for (const call of calls)
|
|
56138
|
+
void gsapCommitMutation(call.selection, call.mutation, call.options);
|
|
56139
|
+
},
|
|
56140
|
+
[gsapCommitMutation, domEditSelectionRef]
|
|
56141
|
+
);
|
|
56142
|
+
const handleUpdateKeyframeEase = useCallback95(
|
|
56143
|
+
(animationId, percentage, ease) => handleUpdateSegmentEase([{ animationId, tweenPercentage: percentage }], ease),
|
|
56144
|
+
[handleUpdateSegmentEase]
|
|
56145
|
+
);
|
|
56146
|
+
const handleSetAllKeyframeEases = useCallback95(
|
|
56147
|
+
(animationId, ease) => {
|
|
56148
|
+
const sel = domEditSelectionRef.current;
|
|
56149
|
+
if (!sel) return;
|
|
56150
|
+
gsapCommitMutation(
|
|
56151
|
+
sel,
|
|
56152
|
+
{
|
|
56153
|
+
type: "update-meta",
|
|
56154
|
+
animationId,
|
|
56155
|
+
updates: { easeEach: ease, resetKeyframeEases: true }
|
|
56156
|
+
},
|
|
56157
|
+
{ label: "Apply ease to all segments", softReload: true }
|
|
56158
|
+
);
|
|
56159
|
+
},
|
|
56160
|
+
[gsapCommitMutation, domEditSelectionRef]
|
|
56161
|
+
);
|
|
56162
|
+
return { handleUpdateSegmentEase, handleUpdateKeyframeEase, handleSetAllKeyframeEases };
|
|
56163
|
+
}
|
|
56164
|
+
|
|
55948
56165
|
// src/hooks/useDomEditSession.ts
|
|
55949
56166
|
function useDomEditSession({
|
|
55950
56167
|
projectId,
|
|
@@ -56170,7 +56387,7 @@ function useDomEditSession({
|
|
|
56170
56387
|
clearDomSelection,
|
|
56171
56388
|
forceReloadSdkSession
|
|
56172
56389
|
});
|
|
56173
|
-
const handleGroupSelection =
|
|
56390
|
+
const handleGroupSelection = useCallback96(() => {
|
|
56174
56391
|
const group = domEditGroupSelectionsRef.current;
|
|
56175
56392
|
const single = domEditSelectionRef.current;
|
|
56176
56393
|
const members = group.length > 0 ? group : single ? [single] : [];
|
|
@@ -56181,7 +56398,7 @@ function useDomEditSession({
|
|
|
56181
56398
|
trackStudioEvent("group", { action: "create", count: members.length });
|
|
56182
56399
|
void groupSelection(members);
|
|
56183
56400
|
}, [domEditGroupSelectionsRef, domEditSelectionRef, groupSelection, showToast]);
|
|
56184
|
-
const handleUngroupSelection =
|
|
56401
|
+
const handleUngroupSelection = useCallback96(() => {
|
|
56185
56402
|
const sel = domEditSelectionRef.current;
|
|
56186
56403
|
if (!sel?.element.hasAttribute("data-hf-group")) {
|
|
56187
56404
|
showToast("Select a group to ungroup", "info");
|
|
@@ -56301,40 +56518,7 @@ function useDomEditSession({
|
|
|
56301
56518
|
setArcPath,
|
|
56302
56519
|
updateArcSegment
|
|
56303
56520
|
});
|
|
56304
|
-
const handleUpdateKeyframeEase =
|
|
56305
|
-
(animationId, percentage, ease) => {
|
|
56306
|
-
const sel = domEditSelectionRef.current;
|
|
56307
|
-
if (!sel) return;
|
|
56308
|
-
gsapCommitMutation(
|
|
56309
|
-
sel,
|
|
56310
|
-
{
|
|
56311
|
-
type: "update-keyframe",
|
|
56312
|
-
animationId,
|
|
56313
|
-
percentage,
|
|
56314
|
-
properties: {},
|
|
56315
|
-
ease
|
|
56316
|
-
},
|
|
56317
|
-
{ label: "Update keyframe ease", softReload: true }
|
|
56318
|
-
);
|
|
56319
|
-
},
|
|
56320
|
-
[gsapCommitMutation, domEditSelectionRef]
|
|
56321
|
-
);
|
|
56322
|
-
const handleSetAllKeyframeEases = useCallback95(
|
|
56323
|
-
(animationId, ease) => {
|
|
56324
|
-
const sel = domEditSelectionRef.current;
|
|
56325
|
-
if (!sel) return;
|
|
56326
|
-
gsapCommitMutation(
|
|
56327
|
-
sel,
|
|
56328
|
-
{
|
|
56329
|
-
type: "update-meta",
|
|
56330
|
-
animationId,
|
|
56331
|
-
updates: { easeEach: ease, resetKeyframeEases: true }
|
|
56332
|
-
},
|
|
56333
|
-
{ label: "Apply ease to all segments", softReload: true }
|
|
56334
|
-
);
|
|
56335
|
-
},
|
|
56336
|
-
[gsapCommitMutation, domEditSelectionRef]
|
|
56337
|
-
);
|
|
56521
|
+
const { handleUpdateSegmentEase, handleUpdateKeyframeEase, handleSetAllKeyframeEases } = useKeyframeEaseCommits({ gsapCommitMutation, domEditSelectionRef });
|
|
56338
56522
|
return {
|
|
56339
56523
|
// State
|
|
56340
56524
|
domEditSelection,
|
|
@@ -56413,6 +56597,7 @@ function useDomEditSession({
|
|
|
56413
56597
|
commitAnimatedProperty,
|
|
56414
56598
|
commitAnimatedProperties,
|
|
56415
56599
|
handleSetArcPath,
|
|
56600
|
+
handleUpdateSegmentEase,
|
|
56416
56601
|
handleUpdateArcSegment,
|
|
56417
56602
|
handleUnroll,
|
|
56418
56603
|
invalidateGsapCache: bumpGsapCache,
|
|
@@ -56438,7 +56623,7 @@ function useSdkSelectionSync(session, domEditSelection, domEditGroupSelections)
|
|
|
56438
56623
|
import { useEffect as useEffect80 } from "react";
|
|
56439
56624
|
|
|
56440
56625
|
// src/hooks/useSdkSession.ts
|
|
56441
|
-
import { useState as useState88, useEffect as useEffect79, useCallback as
|
|
56626
|
+
import { useState as useState88, useEffect as useEffect79, useCallback as useCallback97, useRef as useRef102 } from "react";
|
|
56442
56627
|
import { openComposition as openComposition3 } from "@hyperframes/sdk";
|
|
56443
56628
|
async function readProjectFileOptional(projectId, path) {
|
|
56444
56629
|
if (path.includes("\0") || path.includes("..")) return void 0;
|
|
@@ -56575,8 +56760,8 @@ function useSdkSession(projectId, activeCompPath, domEditSaveTimestampRef) {
|
|
|
56575
56760
|
}
|
|
56576
56761
|
};
|
|
56577
56762
|
}, [projectId, activeCompPath, reloadToken]);
|
|
56578
|
-
const forceReload =
|
|
56579
|
-
const publish =
|
|
56763
|
+
const forceReload = useCallback97(() => setReloadToken((t) => t + 1), []);
|
|
56764
|
+
const publish = useCallback97(({ candidate, expectedSession, targetPath }) => {
|
|
56580
56765
|
const expectedOwner = sessionOwnersRef.current.get(expectedSession);
|
|
56581
56766
|
const current = ownedSessionRef.current;
|
|
56582
56767
|
if (!isSessionOwnerActive(
|
|
@@ -56617,7 +56802,7 @@ function useStudioSdkSessions(projectId, activeCompPath, domEditSaveTimestampRef
|
|
|
56617
56802
|
}
|
|
56618
56803
|
|
|
56619
56804
|
// src/hooks/useBlockHandlers.ts
|
|
56620
|
-
import { useCallback as
|
|
56805
|
+
import { useCallback as useCallback98, useMemo as useMemo40, useRef as useRef103, useState as useState89 } from "react";
|
|
56621
56806
|
|
|
56622
56807
|
// src/utils/blockInstaller.ts
|
|
56623
56808
|
function getMaxZIndexFromIframe(iframe) {
|
|
@@ -56827,7 +57012,7 @@ function useBlockHandlers({
|
|
|
56827
57012
|
]
|
|
56828
57013
|
);
|
|
56829
57014
|
const installingBlockRef = useRef103(false);
|
|
56830
|
-
const runBlockInstall =
|
|
57015
|
+
const runBlockInstall = useCallback98(
|
|
56831
57016
|
async (blockName, install) => {
|
|
56832
57017
|
if (installingBlockRef.current) {
|
|
56833
57018
|
blockCtx.showToast("A block is already installing \u2014 one moment\u2026", "info");
|
|
@@ -56843,7 +57028,7 @@ function useBlockHandlers({
|
|
|
56843
57028
|
},
|
|
56844
57029
|
[blockCtx]
|
|
56845
57030
|
);
|
|
56846
|
-
const handleAddBlock =
|
|
57031
|
+
const handleAddBlock = useCallback98(
|
|
56847
57032
|
(blockName) => {
|
|
56848
57033
|
if (!projectId) return;
|
|
56849
57034
|
void (async () => {
|
|
@@ -56873,7 +57058,7 @@ function useBlockHandlers({
|
|
|
56873
57058
|
},
|
|
56874
57059
|
[projectId, blockCtx, previewIframeRef, runBlockInstall, setRightCollapsed, setRightPanelTab]
|
|
56875
57060
|
);
|
|
56876
|
-
const handleTimelineBlockDrop =
|
|
57061
|
+
const handleTimelineBlockDrop = useCallback98(
|
|
56877
57062
|
(blockName, placement) => {
|
|
56878
57063
|
if (!projectId) return;
|
|
56879
57064
|
void runBlockInstall(
|
|
@@ -56890,7 +57075,7 @@ function useBlockHandlers({
|
|
|
56890
57075
|
},
|
|
56891
57076
|
[projectId, blockCtx, previewIframeRef, runBlockInstall]
|
|
56892
57077
|
);
|
|
56893
|
-
const handleAddMediaOverlay =
|
|
57078
|
+
const handleAddMediaOverlay = useCallback98(
|
|
56894
57079
|
async (blockName, placement) => {
|
|
56895
57080
|
if (!projectId) return;
|
|
56896
57081
|
const { compositionPath, ...timelinePlacement } = placement;
|
|
@@ -56909,7 +57094,7 @@ function useBlockHandlers({
|
|
|
56909
57094
|
},
|
|
56910
57095
|
[projectId, blockCtx, previewIframeRef, runBlockInstall]
|
|
56911
57096
|
);
|
|
56912
|
-
const handlePreviewBlockDrop =
|
|
57097
|
+
const handlePreviewBlockDrop = useCallback98(
|
|
56913
57098
|
(blockName, position) => {
|
|
56914
57099
|
if (!projectId) return;
|
|
56915
57100
|
void runBlockInstall(
|
|
@@ -56937,7 +57122,7 @@ function useBlockHandlers({
|
|
|
56937
57122
|
}
|
|
56938
57123
|
|
|
56939
57124
|
// src/hooks/useAppHotkeys.ts
|
|
56940
|
-
import { useCallback as
|
|
57125
|
+
import { useCallback as useCallback99, useEffect as useEffect81, useRef as useRef104 } from "react";
|
|
56941
57126
|
function iframeContentWindow(iframe) {
|
|
56942
57127
|
try {
|
|
56943
57128
|
return iframe?.contentWindow ?? null;
|
|
@@ -57147,22 +57332,22 @@ function useAppHotkeys({
|
|
|
57147
57332
|
}) {
|
|
57148
57333
|
const previewHotkeyWindowRef = useRef104(null);
|
|
57149
57334
|
const previewHistoryCleanupRef = useRef104(null);
|
|
57150
|
-
const readHistoryFile =
|
|
57335
|
+
const readHistoryFile = useCallback99(
|
|
57151
57336
|
(path) => path === STUDIO_MOTION_PATH ? readOptionalProjectFile(path) : readProjectFile(path),
|
|
57152
57337
|
[readOptionalProjectFile, readProjectFile]
|
|
57153
57338
|
);
|
|
57154
|
-
const writeHistoryFile =
|
|
57339
|
+
const writeHistoryFile = useCallback99(
|
|
57155
57340
|
async (path, content) => {
|
|
57156
57341
|
domEditSaveTimestampRef.current = Date.now();
|
|
57157
57342
|
await writeProjectFile(path, content);
|
|
57158
57343
|
},
|
|
57159
57344
|
[domEditSaveTimestampRef, writeProjectFile]
|
|
57160
57345
|
);
|
|
57161
|
-
const serializeHistoryFiles =
|
|
57346
|
+
const serializeHistoryFiles = useCallback99(
|
|
57162
57347
|
(paths, task) => serializeStudioFileMutations(writeProjectFile, paths, task),
|
|
57163
57348
|
[writeProjectFile]
|
|
57164
57349
|
);
|
|
57165
|
-
const applyHistory =
|
|
57350
|
+
const applyHistory = useCallback99(
|
|
57166
57351
|
async (direction) => {
|
|
57167
57352
|
if (tryApplyBeatHistory(direction, editHistory.state, showToast)) return;
|
|
57168
57353
|
await waitForPendingDomEditSaves();
|
|
@@ -57200,8 +57385,8 @@ function useAppHotkeys({
|
|
|
57200
57385
|
forceReloadSdkSession
|
|
57201
57386
|
]
|
|
57202
57387
|
);
|
|
57203
|
-
const handleUndo =
|
|
57204
|
-
const handleRedo =
|
|
57388
|
+
const handleUndo = useCallback99(() => applyHistory("undo"), [applyHistory]);
|
|
57389
|
+
const handleRedo = useCallback99(() => applyHistory("redo"), [applyHistory]);
|
|
57205
57390
|
const cbRef = useRef104(null);
|
|
57206
57391
|
cbRef.current = {
|
|
57207
57392
|
handleTimelineElementDelete,
|
|
@@ -57221,7 +57406,7 @@ function useAppHotkeys({
|
|
|
57221
57406
|
domEditSelectionRef,
|
|
57222
57407
|
showToast
|
|
57223
57408
|
};
|
|
57224
|
-
const handleAppKeyDown =
|
|
57409
|
+
const handleAppKeyDown = useCallback99((event) => {
|
|
57225
57410
|
const cb = cbRef.current;
|
|
57226
57411
|
const key = event.key.toLowerCase();
|
|
57227
57412
|
if (event.metaKey || event.ctrlKey) {
|
|
@@ -57234,7 +57419,7 @@ function useAppHotkeys({
|
|
|
57234
57419
|
window.addEventListener("keydown", handleAppKeyDown, true);
|
|
57235
57420
|
return () => window.removeEventListener("keydown", handleAppKeyDown, true);
|
|
57236
57421
|
}, [handleAppKeyDown]);
|
|
57237
|
-
const syncPreviewTimelineHotkey =
|
|
57422
|
+
const syncPreviewTimelineHotkey = useCallback99(
|
|
57238
57423
|
(iframe) => {
|
|
57239
57424
|
const nextWindow = iframeContentWindow(iframe);
|
|
57240
57425
|
if (previewHotkeyWindowRef.current === nextWindow) return;
|
|
@@ -57259,7 +57444,7 @@ function useAppHotkeys({
|
|
|
57259
57444
|
},
|
|
57260
57445
|
[handleAppKeyDown]
|
|
57261
57446
|
);
|
|
57262
|
-
const handleHistoryHotkey =
|
|
57447
|
+
const handleHistoryHotkey = useCallback99((event) => {
|
|
57263
57448
|
if (!(event.metaKey || event.ctrlKey) || shouldIgnoreHistoryShortcut(event.target)) return;
|
|
57264
57449
|
handleUndoRedoKey(
|
|
57265
57450
|
event,
|
|
@@ -57267,7 +57452,7 @@ function useAppHotkeys({
|
|
|
57267
57452
|
() => void cbRef.current.handleRedo()
|
|
57268
57453
|
);
|
|
57269
57454
|
}, []);
|
|
57270
|
-
const syncPreviewHistoryHotkey =
|
|
57455
|
+
const syncPreviewHistoryHotkey = useCallback99(
|
|
57271
57456
|
(iframe) => {
|
|
57272
57457
|
previewHistoryCleanupRef.current?.();
|
|
57273
57458
|
previewHistoryCleanupRef.current = null;
|
|
@@ -57305,7 +57490,7 @@ function useAppHotkeys({
|
|
|
57305
57490
|
}
|
|
57306
57491
|
|
|
57307
57492
|
// src/hooks/useClipboard.ts
|
|
57308
|
-
import { useCallback as
|
|
57493
|
+
import { useCallback as useCallback100, useRef as useRef105 } from "react";
|
|
57309
57494
|
|
|
57310
57495
|
// src/utils/clipboardPayload.ts
|
|
57311
57496
|
function insertAsSibling(source, newHtml, selector, selectorIndex) {
|
|
@@ -57415,7 +57600,7 @@ function useClipboard({
|
|
|
57415
57600
|
const clipboardRef = useRef105(null);
|
|
57416
57601
|
const projectIdRef = useRef105(projectId);
|
|
57417
57602
|
projectIdRef.current = projectId;
|
|
57418
|
-
const handleCopy =
|
|
57603
|
+
const handleCopy = useCallback100(() => {
|
|
57419
57604
|
const { selectedElementId, elements } = usePlayerStore.getState();
|
|
57420
57605
|
if (selectedElementId) {
|
|
57421
57606
|
const element = elements.find((el) => (el.key ?? el.id) === selectedElementId);
|
|
@@ -57469,7 +57654,7 @@ function useClipboard({
|
|
|
57469
57654
|
}
|
|
57470
57655
|
return false;
|
|
57471
57656
|
}, [activeCompPath, domEditSelectionRef, previewIframeRef, showToast]);
|
|
57472
|
-
const handlePaste =
|
|
57657
|
+
const handlePaste = useCallback100(async () => {
|
|
57473
57658
|
const payload = clipboardRef.current;
|
|
57474
57659
|
if (!payload) {
|
|
57475
57660
|
showToast("Nothing to paste.", "info");
|
|
@@ -57525,7 +57710,7 @@ function useClipboard({
|
|
|
57525
57710
|
showToast,
|
|
57526
57711
|
writeProjectFile
|
|
57527
57712
|
]);
|
|
57528
|
-
const handleCut =
|
|
57713
|
+
const handleCut = useCallback100(async () => {
|
|
57529
57714
|
const copied = handleCopy();
|
|
57530
57715
|
if (!copied) return false;
|
|
57531
57716
|
const { selectedElementId, elements } = usePlayerStore.getState();
|
|
@@ -57887,11 +58072,11 @@ function useCaptionDetection({
|
|
|
57887
58072
|
}
|
|
57888
58073
|
|
|
57889
58074
|
// src/hooks/useRenderClipContent.ts
|
|
57890
|
-
import { useCallback as
|
|
58075
|
+
import { useCallback as useCallback103 } from "react";
|
|
57891
58076
|
import { createElement as createElement4 } from "react";
|
|
57892
58077
|
|
|
57893
58078
|
// src/player/components/AudioWaveform.tsx
|
|
57894
|
-
import { memo as memo34, useRef as useRef106, useState as useState90, useCallback as
|
|
58079
|
+
import { memo as memo34, useRef as useRef106, useState as useState90, useCallback as useCallback101, useEffect as useEffect83 } from "react";
|
|
57895
58080
|
import { jsx as jsx132, jsxs as jsxs112 } from "react/jsx-runtime";
|
|
57896
58081
|
var BAR_W = 2;
|
|
57897
58082
|
var GAP = 1;
|
|
@@ -57968,7 +58153,7 @@ var AudioWaveform = memo34(function AudioWaveform2({
|
|
|
57968
58153
|
cancelled = true;
|
|
57969
58154
|
};
|
|
57970
58155
|
}, [audioUrl, waveformUrl, cacheKey, peaks]);
|
|
57971
|
-
const draw =
|
|
58156
|
+
const draw = useCallback101(() => {
|
|
57972
58157
|
const container = containerRef.current;
|
|
57973
58158
|
const barsEl = barsRef.current;
|
|
57974
58159
|
if (!container || !barsEl || !peaks) return;
|
|
@@ -57989,7 +58174,7 @@ var AudioWaveform = memo34(function AudioWaveform2({
|
|
|
57989
58174
|
}
|
|
57990
58175
|
barsEl.innerHTML = html2;
|
|
57991
58176
|
}, [peaks, trimStartFraction, trimEndFraction]);
|
|
57992
|
-
const setContainerRef =
|
|
58177
|
+
const setContainerRef = useCallback101(
|
|
57993
58178
|
(el) => {
|
|
57994
58179
|
roRef.current?.disconnect();
|
|
57995
58180
|
containerRef.current = el;
|
|
@@ -58033,7 +58218,7 @@ var AudioWaveform = memo34(function AudioWaveform2({
|
|
|
58033
58218
|
});
|
|
58034
58219
|
|
|
58035
58220
|
// src/player/components/ImageThumbnail.tsx
|
|
58036
|
-
import { memo as memo35, useRef as useRef107, useState as useState91, useCallback as
|
|
58221
|
+
import { memo as memo35, useRef as useRef107, useState as useState91, useCallback as useCallback102, useEffect as useEffect84 } from "react";
|
|
58037
58222
|
import { jsx as jsx133, jsxs as jsxs113 } from "react/jsx-runtime";
|
|
58038
58223
|
var ImageThumbnail = memo35(function ImageThumbnail2({
|
|
58039
58224
|
imageSrc,
|
|
@@ -58046,7 +58231,7 @@ var ImageThumbnail = memo35(function ImageThumbnail2({
|
|
|
58046
58231
|
const [aspect, setAspect] = useState91(16 / 9);
|
|
58047
58232
|
const ioRef = useRef107(null);
|
|
58048
58233
|
const roRef = useRef107(null);
|
|
58049
|
-
const setContainerRef =
|
|
58234
|
+
const setContainerRef = useCallback102((el) => {
|
|
58050
58235
|
ioRef.current?.disconnect();
|
|
58051
58236
|
roRef.current?.disconnect();
|
|
58052
58237
|
if (!el) return;
|
|
@@ -58199,7 +58384,7 @@ function useRenderClipContent({
|
|
|
58199
58384
|
activePreviewUrl,
|
|
58200
58385
|
effectiveTimelineDuration
|
|
58201
58386
|
}) {
|
|
58202
|
-
return
|
|
58387
|
+
return useCallback103(
|
|
58203
58388
|
// Pre-existing clip-content dispatcher; reduced by extracting renderAudioClip.
|
|
58204
58389
|
// fallow-ignore-next-line complexity
|
|
58205
58390
|
(el, style) => {
|
|
@@ -58271,11 +58456,11 @@ function useRenderClipContent({
|
|
|
58271
58456
|
}
|
|
58272
58457
|
|
|
58273
58458
|
// src/hooks/useConsoleErrorCapture.ts
|
|
58274
|
-
import { useCallback as
|
|
58459
|
+
import { useCallback as useCallback104, useEffect as useEffect85, useRef as useRef108, useState as useState92 } from "react";
|
|
58275
58460
|
function useConsoleErrorCapture(previewIframe) {
|
|
58276
58461
|
const [consoleErrors, setConsoleErrors] = useState92(null);
|
|
58277
58462
|
const consoleErrorsRef = useRef108([]);
|
|
58278
|
-
const resetErrors =
|
|
58463
|
+
const resetErrors = useCallback104(() => {
|
|
58279
58464
|
consoleErrorsRef.current = [];
|
|
58280
58465
|
setConsoleErrors(null);
|
|
58281
58466
|
}, []);
|
|
@@ -58344,7 +58529,7 @@ function useConsoleErrorCapture(previewIframe) {
|
|
|
58344
58529
|
}
|
|
58345
58530
|
|
|
58346
58531
|
// src/hooks/useFrameCapture.ts
|
|
58347
|
-
import { useState as useState93, useCallback as
|
|
58532
|
+
import { useState as useState93, useCallback as useCallback105, useRef as useRef109 } from "react";
|
|
58348
58533
|
|
|
58349
58534
|
// src/utils/frameCapture.ts
|
|
58350
58535
|
function normalizeCompositionPath(compositionPath) {
|
|
@@ -58387,10 +58572,10 @@ function useFrameCapture({
|
|
|
58387
58572
|
setCaptureFrameTime(usePlayerStore.getState().currentTime);
|
|
58388
58573
|
return liveTime.subscribe(setCaptureFrameTime);
|
|
58389
58574
|
});
|
|
58390
|
-
const refreshCaptureFrameTime =
|
|
58575
|
+
const refreshCaptureFrameTime = useCallback105(() => {
|
|
58391
58576
|
setCaptureFrameTime(usePlayerStore.getState().currentTime);
|
|
58392
58577
|
}, []);
|
|
58393
|
-
const handleCaptureFrameClick =
|
|
58578
|
+
const handleCaptureFrameClick = useCallback105(
|
|
58394
58579
|
async (event) => {
|
|
58395
58580
|
if (!projectId) return;
|
|
58396
58581
|
event.preventDefault();
|
|
@@ -58467,7 +58652,7 @@ function useFrameCapture({
|
|
|
58467
58652
|
}
|
|
58468
58653
|
|
|
58469
58654
|
// src/hooks/useLintModal.ts
|
|
58470
|
-
import { useState as useState94, useCallback as
|
|
58655
|
+
import { useState as useState94, useCallback as useCallback106, useEffect as useEffect86, useRef as useRef110, useMemo as useMemo41 } from "react";
|
|
58471
58656
|
function parseFinding(f) {
|
|
58472
58657
|
return {
|
|
58473
58658
|
severity: f.severity === "error" ? "error" : "warning",
|
|
@@ -58482,7 +58667,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
58482
58667
|
const [linting, setLinting] = useState94(false);
|
|
58483
58668
|
const [backgroundFindings, setBackgroundFindings] = useState94([]);
|
|
58484
58669
|
const autoLintRanRef = useRef110(false);
|
|
58485
|
-
const runLint =
|
|
58670
|
+
const runLint = useCallback106(
|
|
58486
58671
|
async (opts) => {
|
|
58487
58672
|
if (!projectId) return;
|
|
58488
58673
|
if (!opts?.background) setLinting(true);
|
|
@@ -58507,7 +58692,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
58507
58692
|
},
|
|
58508
58693
|
[projectId]
|
|
58509
58694
|
);
|
|
58510
|
-
const handleLint =
|
|
58695
|
+
const handleLint = useCallback106(() => runLint(), [runLint]);
|
|
58511
58696
|
const prevProjectIdRef = useRef110(projectId);
|
|
58512
58697
|
useEffect86(() => {
|
|
58513
58698
|
if (projectId !== prevProjectIdRef.current) {
|
|
@@ -58523,8 +58708,8 @@ function useLintModal(projectId, refreshKey) {
|
|
|
58523
58708
|
const timer = setTimeout(() => void runLint({ background: true }), 1e3);
|
|
58524
58709
|
return () => clearTimeout(timer);
|
|
58525
58710
|
}, [projectId, refreshKey, runLint]);
|
|
58526
|
-
const closeLintModal =
|
|
58527
|
-
const groupFindings =
|
|
58711
|
+
const closeLintModal = useCallback106(() => setLintModal(null), []);
|
|
58712
|
+
const groupFindings = useCallback106(
|
|
58528
58713
|
(keyFn) => {
|
|
58529
58714
|
const map = /* @__PURE__ */ new Map();
|
|
58530
58715
|
for (const f of backgroundFindings) {
|
|
@@ -58556,7 +58741,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
58556
58741
|
}
|
|
58557
58742
|
|
|
58558
58743
|
// src/hooks/useToast.ts
|
|
58559
|
-
import { useState as useState95, useCallback as
|
|
58744
|
+
import { useState as useState95, useCallback as useCallback107, useRef as useRef111 } from "react";
|
|
58560
58745
|
var AUTO_DISMISS_MS2 = 4e3;
|
|
58561
58746
|
var EXIT_MS = 160;
|
|
58562
58747
|
var MAX_TOASTS = 3;
|
|
@@ -58564,21 +58749,21 @@ var nextToastId = 1;
|
|
|
58564
58749
|
function useToast() {
|
|
58565
58750
|
const [toasts, setToasts] = useState95([]);
|
|
58566
58751
|
const timersRef = useRef111(/* @__PURE__ */ new Map());
|
|
58567
|
-
const clearTimer =
|
|
58752
|
+
const clearTimer = useCallback107((id) => {
|
|
58568
58753
|
const timer = timersRef.current.get(id);
|
|
58569
58754
|
if (timer) {
|
|
58570
58755
|
clearTimeout(timer);
|
|
58571
58756
|
timersRef.current.delete(id);
|
|
58572
58757
|
}
|
|
58573
58758
|
}, []);
|
|
58574
|
-
const removeToast =
|
|
58759
|
+
const removeToast = useCallback107(
|
|
58575
58760
|
(id) => {
|
|
58576
58761
|
clearTimer(id);
|
|
58577
58762
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
58578
58763
|
},
|
|
58579
58764
|
[clearTimer]
|
|
58580
58765
|
);
|
|
58581
|
-
const dismissToast =
|
|
58766
|
+
const dismissToast = useCallback107(
|
|
58582
58767
|
(id) => {
|
|
58583
58768
|
clearTimer(id);
|
|
58584
58769
|
setToasts((prev) => prev.map((t) => t.id === id ? { ...t, leaving: true } : t));
|
|
@@ -58587,7 +58772,7 @@ function useToast() {
|
|
|
58587
58772
|
},
|
|
58588
58773
|
[clearTimer, removeToast]
|
|
58589
58774
|
);
|
|
58590
|
-
const showToast =
|
|
58775
|
+
const showToast = useCallback107(
|
|
58591
58776
|
(message, tone = "error") => {
|
|
58592
58777
|
const id = nextToastId++;
|
|
58593
58778
|
setToasts((prev) => {
|
|
@@ -58613,14 +58798,14 @@ function useToast() {
|
|
|
58613
58798
|
}
|
|
58614
58799
|
|
|
58615
58800
|
// src/hooks/useCompositionContentLoader.ts
|
|
58616
|
-
import { useCallback as
|
|
58801
|
+
import { useCallback as useCallback108 } from "react";
|
|
58617
58802
|
function useCompositionContentLoader({
|
|
58618
58803
|
projectId,
|
|
58619
58804
|
setEditingFile,
|
|
58620
58805
|
setActiveCompPath,
|
|
58621
58806
|
showToast
|
|
58622
58807
|
}) {
|
|
58623
|
-
return
|
|
58808
|
+
return useCallback108(
|
|
58624
58809
|
(comp) => {
|
|
58625
58810
|
setActiveCompPath(comp.endsWith(".html") ? comp : null);
|
|
58626
58811
|
setEditingFile({ path: comp, content: null });
|
|
@@ -58639,7 +58824,7 @@ function useCompositionContentLoader({
|
|
|
58639
58824
|
}
|
|
58640
58825
|
|
|
58641
58826
|
// src/hooks/useStudioUrlState.ts
|
|
58642
|
-
import { useCallback as
|
|
58827
|
+
import { useCallback as useCallback109, useEffect as useEffect87, useRef as useRef112, useState as useState96 } from "react";
|
|
58643
58828
|
|
|
58644
58829
|
// src/utils/studioUrlState.ts
|
|
58645
58830
|
var VALID_TABS = ["layers", "design", "renders", "slideshow", "variables"];
|
|
@@ -58772,7 +58957,7 @@ function useStudioUrlState({
|
|
|
58772
58957
|
const [selectionHydrated, setSelectionHydrated] = useState96(initialState2.selection == null);
|
|
58773
58958
|
const pendingSelectionRef = useRef112(initialState2.selection);
|
|
58774
58959
|
const stableTimeRef = useRef112(initialState2.currentTime);
|
|
58775
|
-
const buildUrlState =
|
|
58960
|
+
const buildUrlState = useCallback109(
|
|
58776
58961
|
() => ({
|
|
58777
58962
|
activeCompPath,
|
|
58778
58963
|
currentTime: stableTimeRef.current,
|
|
@@ -58783,7 +58968,7 @@ function useStudioUrlState({
|
|
|
58783
58968
|
}),
|
|
58784
58969
|
[activeCompPath, domEditSelection, rightCollapsed, rightPanelTab]
|
|
58785
58970
|
);
|
|
58786
|
-
const applyUrlSelection =
|
|
58971
|
+
const applyUrlSelection = useCallback109(
|
|
58787
58972
|
(selection) => {
|
|
58788
58973
|
if (!selection) {
|
|
58789
58974
|
applyDomSelection(null, { revealPanel: false });
|
|
@@ -58899,7 +59084,7 @@ function useStudioUrlState({
|
|
|
58899
59084
|
}
|
|
58900
59085
|
|
|
58901
59086
|
// src/hooks/useStudioContextValue.ts
|
|
58902
|
-
import { useCallback as
|
|
59087
|
+
import { useCallback as useCallback110, useMemo as useMemo42, useRef as useRef113, useState as useState97 } from "react";
|
|
58903
59088
|
function buildStudioContextValue(input) {
|
|
58904
59089
|
return {
|
|
58905
59090
|
projectId: input.projectId,
|
|
@@ -58956,21 +59141,21 @@ function useInspectorState(rightPanelTab, rightInspectorPanes, rightCollapsed, i
|
|
|
58956
59141
|
function useDragOverlay(onImportFiles) {
|
|
58957
59142
|
const [active, setActive] = useState97(false);
|
|
58958
59143
|
const counterRef = useRef113(0);
|
|
58959
|
-
const onDragOver =
|
|
59144
|
+
const onDragOver = useCallback110((e) => {
|
|
58960
59145
|
if (!e.dataTransfer.types.includes("Files")) return;
|
|
58961
59146
|
e.preventDefault();
|
|
58962
59147
|
}, []);
|
|
58963
|
-
const onDragEnter =
|
|
59148
|
+
const onDragEnter = useCallback110((e) => {
|
|
58964
59149
|
if (!e.dataTransfer.types.includes("Files")) return;
|
|
58965
59150
|
e.preventDefault();
|
|
58966
59151
|
counterRef.current++;
|
|
58967
59152
|
setActive(true);
|
|
58968
59153
|
}, []);
|
|
58969
|
-
const onDragLeave =
|
|
59154
|
+
const onDragLeave = useCallback110(() => {
|
|
58970
59155
|
counterRef.current--;
|
|
58971
59156
|
if (counterRef.current === 0) setActive(false);
|
|
58972
59157
|
}, []);
|
|
58973
|
-
const onDrop =
|
|
59158
|
+
const onDrop = useCallback110(
|
|
58974
59159
|
(e) => {
|
|
58975
59160
|
counterRef.current = 0;
|
|
58976
59161
|
setActive(false);
|
|
@@ -58983,7 +59168,7 @@ function useDragOverlay(onImportFiles) {
|
|
|
58983
59168
|
return { active, onDragOver, onDragEnter, onDragLeave, onDrop };
|
|
58984
59169
|
}
|
|
58985
59170
|
function useGlobalFileDrop(handleTimelineFileDrop) {
|
|
58986
|
-
const onDrop =
|
|
59171
|
+
const onDrop = useCallback110(
|
|
58987
59172
|
(files) => {
|
|
58988
59173
|
const start = usePlayerStore.getState().currentTime;
|
|
58989
59174
|
void handleTimelineFileDrop(Array.from(files), { start, track: 0 });
|
|
@@ -59070,7 +59255,7 @@ function PanelLayoutProvider({
|
|
|
59070
59255
|
// src/contexts/ViewModeContext.tsx
|
|
59071
59256
|
import {
|
|
59072
59257
|
createContext as createContext9,
|
|
59073
|
-
useCallback as
|
|
59258
|
+
useCallback as useCallback111,
|
|
59074
59259
|
useContext as useContext9,
|
|
59075
59260
|
useEffect as useEffect88,
|
|
59076
59261
|
useMemo as useMemo44,
|
|
@@ -59104,7 +59289,7 @@ function useViewModeState() {
|
|
|
59104
59289
|
const [viewMode, setMode] = useState98(() => readViewModeFromUrl());
|
|
59105
59290
|
const guardsRef = useRef114(/* @__PURE__ */ new Set());
|
|
59106
59291
|
const acceptedLocationRef = useRef114(readHistoryLocation());
|
|
59107
|
-
const canSetViewMode =
|
|
59292
|
+
const canSetViewMode = useCallback111((mode) => {
|
|
59108
59293
|
for (const guard of guardsRef.current) {
|
|
59109
59294
|
if (!guard(mode)) return false;
|
|
59110
59295
|
}
|
|
@@ -59126,7 +59311,7 @@ function useViewModeState() {
|
|
|
59126
59311
|
window.addEventListener("popstate", onPopState);
|
|
59127
59312
|
return () => window.removeEventListener("popstate", onPopState);
|
|
59128
59313
|
}, [canSetViewMode, viewMode]);
|
|
59129
|
-
const setViewMode =
|
|
59314
|
+
const setViewMode = useCallback111(
|
|
59130
59315
|
(mode) => {
|
|
59131
59316
|
if (!canSetViewMode(mode)) return false;
|
|
59132
59317
|
setMode(mode);
|
|
@@ -59136,7 +59321,7 @@ function useViewModeState() {
|
|
|
59136
59321
|
},
|
|
59137
59322
|
[canSetViewMode]
|
|
59138
59323
|
);
|
|
59139
|
-
const registerViewModeGuard =
|
|
59324
|
+
const registerViewModeGuard = useCallback111((guard) => {
|
|
59140
59325
|
guardsRef.current.add(guard);
|
|
59141
59326
|
return () => {
|
|
59142
59327
|
guardsRef.current.delete(guard);
|
|
@@ -59581,10 +59766,10 @@ function StudioHeader({
|
|
|
59581
59766
|
}
|
|
59582
59767
|
|
|
59583
59768
|
// src/hooks/useGestureCommit.ts
|
|
59584
|
-
import { useState as useState100, useCallback as
|
|
59769
|
+
import { useState as useState100, useCallback as useCallback113, useRef as useRef117, useEffect as useEffect90 } from "react";
|
|
59585
59770
|
|
|
59586
59771
|
// src/hooks/useGestureRecording.ts
|
|
59587
|
-
import { useCallback as
|
|
59772
|
+
import { useCallback as useCallback112, useEffect as useEffect89, useRef as useRef116, useState as useState99 } from "react";
|
|
59588
59773
|
function readBasePosition(element, iframeEl) {
|
|
59589
59774
|
let baseOpacity = 1;
|
|
59590
59775
|
let baseScale = 1;
|
|
@@ -59715,7 +59900,7 @@ function useGestureRecording() {
|
|
|
59715
59900
|
isRecordingRef.current = false;
|
|
59716
59901
|
};
|
|
59717
59902
|
}, []);
|
|
59718
|
-
const startRecording =
|
|
59903
|
+
const startRecording = useCallback112(
|
|
59719
59904
|
(element, iframeEl, elementEndTime) => {
|
|
59720
59905
|
if (isRecordingRef.current) return;
|
|
59721
59906
|
isRecordingRef.current = true;
|
|
@@ -59815,7 +60000,7 @@ function useGestureRecording() {
|
|
|
59815
60000
|
[]
|
|
59816
60001
|
// No deps — uses refs only for all mutable state
|
|
59817
60002
|
);
|
|
59818
|
-
const stopRecording =
|
|
60003
|
+
const stopRecording = useCallback112(() => {
|
|
59819
60004
|
if (!isRecordingRef.current) return [];
|
|
59820
60005
|
isRecordingRef.current = false;
|
|
59821
60006
|
const r = refs.current;
|
|
@@ -59845,7 +60030,7 @@ function useGestureRecording() {
|
|
|
59845
60030
|
setIsRecording(false);
|
|
59846
60031
|
return frozen;
|
|
59847
60032
|
}, []);
|
|
59848
|
-
const clearSamples =
|
|
60033
|
+
const clearSamples = useCallback112(() => {
|
|
59849
60034
|
const r = refs.current;
|
|
59850
60035
|
r.samples = [];
|
|
59851
60036
|
r.trail = [];
|
|
@@ -60108,7 +60293,7 @@ function useGestureCommit({
|
|
|
60108
60293
|
const commitInFlightRef = useRef117(false);
|
|
60109
60294
|
const capturedSelectionRef = useRef117(null);
|
|
60110
60295
|
useEffect90(() => () => clearInterval(recordingAutoStopRef.current), []);
|
|
60111
|
-
const stopAndCommitRecording =
|
|
60296
|
+
const stopAndCommitRecording = useCallback113(async () => {
|
|
60112
60297
|
clearInterval(recordingAutoStopRef.current);
|
|
60113
60298
|
if (commitInFlightRef.current) {
|
|
60114
60299
|
return;
|
|
@@ -60281,7 +60466,7 @@ function useGestureCommit({
|
|
|
60281
60466
|
commitInFlightRef.current = false;
|
|
60282
60467
|
}
|
|
60283
60468
|
}, [gestureRecording, showToast, isGestureRecordingRef, domEditSessionRef]);
|
|
60284
|
-
const handleToggleRecording =
|
|
60469
|
+
const handleToggleRecording = useCallback113(() => {
|
|
60285
60470
|
if (gestureStateRef.current === "recording") {
|
|
60286
60471
|
void stopAndCommitRecording();
|
|
60287
60472
|
return;
|
|
@@ -60439,20 +60624,20 @@ var GestureTrailOverlay = memo36(function GestureTrailOverlay2({
|
|
|
60439
60624
|
});
|
|
60440
60625
|
|
|
60441
60626
|
// src/components/StudioLeftSidebar.tsx
|
|
60442
|
-
import { useCallback as
|
|
60627
|
+
import { useCallback as useCallback120 } from "react";
|
|
60443
60628
|
|
|
60444
60629
|
// src/components/sidebar/LeftSidebar.tsx
|
|
60445
60630
|
import {
|
|
60446
60631
|
memo as memo40,
|
|
60447
60632
|
useState as useState108,
|
|
60448
|
-
useCallback as
|
|
60633
|
+
useCallback as useCallback119,
|
|
60449
60634
|
useImperativeHandle,
|
|
60450
60635
|
useRef as useRef123,
|
|
60451
60636
|
forwardRef as forwardRef3
|
|
60452
60637
|
} from "react";
|
|
60453
60638
|
|
|
60454
60639
|
// src/components/sidebar/CompositionsTab.tsx
|
|
60455
|
-
import { memo as memo37, useCallback as
|
|
60640
|
+
import { memo as memo37, useCallback as useCallback114, useEffect as useEffect91, useRef as useRef118, useState as useState101 } from "react";
|
|
60456
60641
|
import { jsx as jsx138, jsxs as jsxs116 } from "react/jsx-runtime";
|
|
60457
60642
|
var DEFAULT_PREVIEW_STAGE = { width: 1920, height: 1080 };
|
|
60458
60643
|
var CARD_W = 80;
|
|
@@ -60528,7 +60713,7 @@ function CompCard({
|
|
|
60528
60713
|
const hoverTimer = useRef118(null);
|
|
60529
60714
|
const syncTimer = useRef118(null);
|
|
60530
60715
|
const draggedRef = useRef118(false);
|
|
60531
|
-
const requestIframePlaybackSync =
|
|
60716
|
+
const requestIframePlaybackSync = useCallback114((shouldPlay) => {
|
|
60532
60717
|
if (syncTimer.current) {
|
|
60533
60718
|
clearTimeout(syncTimer.current);
|
|
60534
60719
|
syncTimer.current = null;
|
|
@@ -60749,7 +60934,7 @@ var CompositionsTab = memo37(function CompositionsTab2({
|
|
|
60749
60934
|
});
|
|
60750
60935
|
|
|
60751
60936
|
// src/components/sidebar/AssetsTab.tsx
|
|
60752
|
-
import { memo as memo38, useState as useState106, useCallback as
|
|
60937
|
+
import { memo as memo38, useState as useState106, useCallback as useCallback117, useRef as useRef121, useMemo as useMemo47, useEffect as useEffect96 } from "react";
|
|
60753
60938
|
|
|
60754
60939
|
// src/components/sidebar/assetHelpers.ts
|
|
60755
60940
|
function getCategory(path) {
|
|
@@ -60799,7 +60984,7 @@ var CATEGORY_LABELS = {
|
|
|
60799
60984
|
var FILTER_ORDER = ["audio", "images", "video", "fonts"];
|
|
60800
60985
|
|
|
60801
60986
|
// src/components/sidebar/AudioRow.tsx
|
|
60802
|
-
import { useState as useState102, useRef as useRef119, useEffect as useEffect92, useCallback as
|
|
60987
|
+
import { useState as useState102, useRef as useRef119, useEffect as useEffect92, useCallback as useCallback115 } from "react";
|
|
60803
60988
|
|
|
60804
60989
|
// src/components/sidebar/AssetContextMenu.tsx
|
|
60805
60990
|
import { jsx as jsx139, jsxs as jsxs117 } from "react/jsx-runtime";
|
|
@@ -60942,10 +61127,10 @@ function AudioRow({
|
|
|
60942
61127
|
const elements = usePlayerStore((s) => s.elements);
|
|
60943
61128
|
const setPreviewAsset = useAssetPreviewStore((s) => s.setPreviewAsset);
|
|
60944
61129
|
const clearPreviewAsset = useAssetPreviewStore((s) => s.clearPreviewAsset);
|
|
60945
|
-
const handlePointerDown =
|
|
61130
|
+
const handlePointerDown = useCallback115((e) => {
|
|
60946
61131
|
pointerDownRef.current = { x: e.clientX, y: e.clientY };
|
|
60947
61132
|
}, []);
|
|
60948
|
-
const handlePointerUp =
|
|
61133
|
+
const handlePointerUp = useCallback115(
|
|
60949
61134
|
(e) => {
|
|
60950
61135
|
const origin = pointerDownRef.current;
|
|
60951
61136
|
pointerDownRef.current = null;
|
|
@@ -61009,7 +61194,7 @@ function AudioRow({
|
|
|
61009
61194
|
}
|
|
61010
61195
|
return () => cancelAnimationFrame(animRef.current);
|
|
61011
61196
|
}, [playing]);
|
|
61012
|
-
const togglePlay =
|
|
61197
|
+
const togglePlay = useCallback115(async () => {
|
|
61013
61198
|
if (playing) {
|
|
61014
61199
|
audioRef.current?.pause();
|
|
61015
61200
|
setPlaying(false);
|
|
@@ -61178,7 +61363,7 @@ function GlobalAssetsView({ searchQuery }) {
|
|
|
61178
61363
|
}
|
|
61179
61364
|
|
|
61180
61365
|
// src/components/sidebar/AssetCard.tsx
|
|
61181
|
-
import { useState as useState105, useEffect as useEffect95, useRef as useRef120, useCallback as
|
|
61366
|
+
import { useState as useState105, useEffect as useEffect95, useRef as useRef120, useCallback as useCallback116 } from "react";
|
|
61182
61367
|
|
|
61183
61368
|
// src/components/ui/VideoFrameThumbnail.tsx
|
|
61184
61369
|
import { useState as useState104, useEffect as useEffect94 } from "react";
|
|
@@ -61309,10 +61494,10 @@ function AssetCard({
|
|
|
61309
61494
|
const elements = usePlayerStore((s) => s.elements);
|
|
61310
61495
|
const setPreviewAsset = useAssetPreviewStore((s) => s.setPreviewAsset);
|
|
61311
61496
|
const clearPreviewAsset = useAssetPreviewStore((s) => s.clearPreviewAsset);
|
|
61312
|
-
const handlePointerDown =
|
|
61497
|
+
const handlePointerDown = useCallback116((e) => {
|
|
61313
61498
|
pointerDownRef.current = { x: e.clientX, y: e.clientY };
|
|
61314
61499
|
}, []);
|
|
61315
|
-
const handlePointerUp =
|
|
61500
|
+
const handlePointerUp = useCallback116(
|
|
61316
61501
|
(e) => {
|
|
61317
61502
|
const origin = pointerDownRef.current;
|
|
61318
61503
|
pointerDownRef.current = null;
|
|
@@ -61542,7 +61727,7 @@ var AssetsTab = memo38(function AssetsTab2({
|
|
|
61542
61727
|
cancelled = true;
|
|
61543
61728
|
};
|
|
61544
61729
|
}, [projectId, assetsKey]);
|
|
61545
|
-
const handleDrop =
|
|
61730
|
+
const handleDrop = useCallback117(
|
|
61546
61731
|
(e) => {
|
|
61547
61732
|
e.preventDefault();
|
|
61548
61733
|
setDragOver(false);
|
|
@@ -61550,7 +61735,7 @@ var AssetsTab = memo38(function AssetsTab2({
|
|
|
61550
61735
|
},
|
|
61551
61736
|
[onImport]
|
|
61552
61737
|
);
|
|
61553
|
-
const handleCopyPath =
|
|
61738
|
+
const handleCopyPath = useCallback117(async (path) => {
|
|
61554
61739
|
const copied = await copyTextToClipboard(path);
|
|
61555
61740
|
if (copied) {
|
|
61556
61741
|
setCopiedPath(path);
|
|
@@ -61834,7 +62019,7 @@ var AssetsTab = memo38(function AssetsTab2({
|
|
|
61834
62019
|
});
|
|
61835
62020
|
|
|
61836
62021
|
// src/components/sidebar/BlocksTab.tsx
|
|
61837
|
-
import { memo as memo39, useState as useState107, useCallback as
|
|
62022
|
+
import { memo as memo39, useState as useState107, useCallback as useCallback118, useRef as useRef122, useEffect as useEffect97 } from "react";
|
|
61838
62023
|
import { createPortal as createPortal7 } from "react-dom";
|
|
61839
62024
|
import { jsx as jsx145, jsxs as jsxs122 } from "react/jsx-runtime";
|
|
61840
62025
|
var BlocksTab = memo39(function BlocksTab2({ onAddBlock, onPreviewBlock }) {
|
|
@@ -62049,13 +62234,13 @@ function BlockCard({
|
|
|
62049
62234
|
const hoverTimer = useRef122(null);
|
|
62050
62235
|
const colors = getCategoryColors(category);
|
|
62051
62236
|
const needsWebGL = tags?.includes("html-in-canvas") || tags?.includes("webgl");
|
|
62052
|
-
const handleEnter =
|
|
62237
|
+
const handleEnter = useCallback118(() => {
|
|
62053
62238
|
hoverTimer.current = setTimeout(() => {
|
|
62054
62239
|
setHovered(true);
|
|
62055
62240
|
onPreview?.({ videoUrl, posterUrl, title });
|
|
62056
62241
|
}, 300);
|
|
62057
62242
|
}, [onPreview, videoUrl, posterUrl, title]);
|
|
62058
|
-
const handleLeave =
|
|
62243
|
+
const handleLeave = useCallback118(() => {
|
|
62059
62244
|
if (hoverTimer.current) {
|
|
62060
62245
|
clearTimeout(hoverTimer.current);
|
|
62061
62246
|
hoverTimer.current = null;
|
|
@@ -62068,7 +62253,7 @@ function BlockCard({
|
|
|
62068
62253
|
if (hoverTimer.current) clearTimeout(hoverTimer.current);
|
|
62069
62254
|
};
|
|
62070
62255
|
}, []);
|
|
62071
|
-
const handleAdd =
|
|
62256
|
+
const handleAdd = useCallback118(
|
|
62072
62257
|
(e) => {
|
|
62073
62258
|
e.stopPropagation();
|
|
62074
62259
|
if (adding || !onAdd) return;
|
|
@@ -62079,7 +62264,7 @@ function BlockCard({
|
|
|
62079
62264
|
[onAdd, adding]
|
|
62080
62265
|
);
|
|
62081
62266
|
const { activeCompPath, compositionDimensions } = useStudioShellContext();
|
|
62082
|
-
const handleShowPrompt =
|
|
62267
|
+
const handleShowPrompt = useCallback118(
|
|
62083
62268
|
(e) => {
|
|
62084
62269
|
e.stopPropagation();
|
|
62085
62270
|
const state = usePlayerStore.getState();
|
|
@@ -62228,7 +62413,7 @@ function PromptPreviewModal({
|
|
|
62228
62413
|
useEffect97(() => {
|
|
62229
62414
|
requestAnimationFrame(() => textareaRef.current?.focus());
|
|
62230
62415
|
}, []);
|
|
62231
|
-
const handleCopy =
|
|
62416
|
+
const handleCopy = useCallback118(() => {
|
|
62232
62417
|
navigator.clipboard.writeText(value);
|
|
62233
62418
|
setCopied(true);
|
|
62234
62419
|
setTimeout(() => setCopied(false), 1500);
|
|
@@ -62355,12 +62540,12 @@ var LeftSidebar = memo40(
|
|
|
62355
62540
|
const [tab, setTab] = useState108(getPersistedTab);
|
|
62356
62541
|
const tabRef = useRef123(tab);
|
|
62357
62542
|
tabRef.current = tab;
|
|
62358
|
-
const selectTab =
|
|
62543
|
+
const selectTab = useCallback119((t) => {
|
|
62359
62544
|
setTab(t);
|
|
62360
62545
|
localStorage.setItem(STORAGE_KEY, t);
|
|
62361
62546
|
trackStudioEvent("tab_switch", { panel: "left_sidebar", tab: t });
|
|
62362
62547
|
}, []);
|
|
62363
|
-
const getTab =
|
|
62548
|
+
const getTab = useCallback119(() => tabRef.current, []);
|
|
62364
62549
|
useImperativeHandle(ref, () => ({ selectTab, getTab }), [selectTab, getTab]);
|
|
62365
62550
|
return /* @__PURE__ */ jsx146(
|
|
62366
62551
|
"div",
|
|
@@ -62703,7 +62888,7 @@ function StudioLeftSidebar({
|
|
|
62703
62888
|
handleImportFiles,
|
|
62704
62889
|
handleContentChange
|
|
62705
62890
|
} = useFileManagerContext();
|
|
62706
|
-
const handleRenderComposition =
|
|
62891
|
+
const handleRenderComposition = useCallback120(
|
|
62707
62892
|
async (comp) => {
|
|
62708
62893
|
await waitForPendingDomEditSaves();
|
|
62709
62894
|
const { format, quality, fps } = getPersistedRenderSettings();
|
|
@@ -62823,13 +63008,13 @@ function StudioLeftSidebar({
|
|
|
62823
63008
|
}
|
|
62824
63009
|
|
|
62825
63010
|
// src/components/StudioRightPanel.tsx
|
|
62826
|
-
import { useCallback as
|
|
63011
|
+
import { useCallback as useCallback136, useEffect as useEffect104, useRef as useRef129 } from "react";
|
|
62827
63012
|
|
|
62828
63013
|
// src/components/editor/LayersPanel.tsx
|
|
62829
|
-
import { memo as memo41, useState as useState111, useCallback as
|
|
63014
|
+
import { memo as memo41, useState as useState111, useCallback as useCallback122, useEffect as useEffect98, useRef as useRef125 } from "react";
|
|
62830
63015
|
|
|
62831
63016
|
// src/components/editor/useLayerDrag.ts
|
|
62832
|
-
import { useRef as useRef124, useState as useState110, useCallback as
|
|
63017
|
+
import { useRef as useRef124, useState as useState110, useCallback as useCallback121 } from "react";
|
|
62833
63018
|
var DRAG_THRESHOLD_PX3 = 4;
|
|
62834
63019
|
function isLayerDraggable(layer) {
|
|
62835
63020
|
if (!(layer.selector || layer.id)) return false;
|
|
@@ -62899,7 +63084,7 @@ function useLayerDrag({
|
|
|
62899
63084
|
const dragRef = useRef124(null);
|
|
62900
63085
|
const [dragKey, setDragKey] = useState110(null);
|
|
62901
63086
|
const [insertionLineY, setInsertionLineY] = useState110(null);
|
|
62902
|
-
const handleRowPointerDown =
|
|
63087
|
+
const handleRowPointerDown = useCallback121(
|
|
62903
63088
|
(layerIndex, e) => {
|
|
62904
63089
|
if (e.button !== 0) return;
|
|
62905
63090
|
const layer = visibleLayers[layerIndex];
|
|
@@ -62926,7 +63111,7 @@ function useLayerDrag({
|
|
|
62926
63111
|
},
|
|
62927
63112
|
[visibleLayers, scrollContainerRef, onSingleSibling]
|
|
62928
63113
|
);
|
|
62929
|
-
const handleContainerPointerMove =
|
|
63114
|
+
const handleContainerPointerMove = useCallback121(
|
|
62930
63115
|
(e) => {
|
|
62931
63116
|
const drag = dragRef.current;
|
|
62932
63117
|
if (!drag) return;
|
|
@@ -62952,7 +63137,7 @@ function useLayerDrag({
|
|
|
62952
63137
|
},
|
|
62953
63138
|
[visibleLayers, scrollContainerRef]
|
|
62954
63139
|
);
|
|
62955
|
-
const handleContainerPointerUp =
|
|
63140
|
+
const handleContainerPointerUp = useCallback121(() => {
|
|
62956
63141
|
const drag = dragRef.current;
|
|
62957
63142
|
dragRef.current = null;
|
|
62958
63143
|
setDragKey(null);
|
|
@@ -63109,7 +63294,7 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63109
63294
|
selectedElement: domEditSelection?.element ?? null
|
|
63110
63295
|
});
|
|
63111
63296
|
const isMasterView = !activeCompPath || activeCompPath === "index.html";
|
|
63112
|
-
const collectLayers =
|
|
63297
|
+
const collectLayers = useCallback122(() => {
|
|
63113
63298
|
const iframe = previewIframeRef.current;
|
|
63114
63299
|
if (!iframe) return;
|
|
63115
63300
|
let doc = null;
|
|
@@ -63156,7 +63341,7 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63156
63341
|
throttle.cancel();
|
|
63157
63342
|
};
|
|
63158
63343
|
}, [collectLayers]);
|
|
63159
|
-
const resolveSelection =
|
|
63344
|
+
const resolveSelection = useCallback122(
|
|
63160
63345
|
(layer) => {
|
|
63161
63346
|
let el = layer.element;
|
|
63162
63347
|
if (!el.isConnected) {
|
|
@@ -63176,7 +63361,7 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63176
63361
|
},
|
|
63177
63362
|
[activeCompPath, isMasterView, previewIframeRef, activeGroupElement]
|
|
63178
63363
|
);
|
|
63179
|
-
const seekToLayer =
|
|
63364
|
+
const seekToLayer = useCallback122(
|
|
63180
63365
|
async (layer) => {
|
|
63181
63366
|
const selection = await resolveSelection(layer);
|
|
63182
63367
|
if (!selection) return;
|
|
@@ -63205,7 +63390,7 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63205
63390
|
},
|
|
63206
63391
|
[currentTime, resolveSelection, timelineElements]
|
|
63207
63392
|
);
|
|
63208
|
-
const handleSelectLayer =
|
|
63393
|
+
const handleSelectLayer = useCallback122(
|
|
63209
63394
|
async (layer) => {
|
|
63210
63395
|
const selection = await resolveSelection(layer);
|
|
63211
63396
|
if (!selection) return;
|
|
@@ -63215,7 +63400,7 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63215
63400
|
},
|
|
63216
63401
|
[resolveSelection, applyDomSelection, seekToLayer, scheduleReveal]
|
|
63217
63402
|
);
|
|
63218
|
-
const handleLayerDoubleClick =
|
|
63403
|
+
const handleLayerDoubleClick = useCallback122(
|
|
63219
63404
|
async (layer) => {
|
|
63220
63405
|
const selection = await resolveSelection(layer);
|
|
63221
63406
|
if (selection?.element.hasAttribute("data-hf-group")) {
|
|
@@ -63226,7 +63411,7 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63226
63411
|
},
|
|
63227
63412
|
[resolveSelection, setActiveGroupElement, handleSelectLayer]
|
|
63228
63413
|
);
|
|
63229
|
-
const handleLayerHover =
|
|
63414
|
+
const handleLayerHover = useCallback122(
|
|
63230
63415
|
async (layer) => {
|
|
63231
63416
|
if (!layer) {
|
|
63232
63417
|
updateDomEditHoverSelection(null);
|
|
@@ -63237,11 +63422,11 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63237
63422
|
},
|
|
63238
63423
|
[resolveSelection, updateDomEditHoverSelection]
|
|
63239
63424
|
);
|
|
63240
|
-
const toggleCollapse =
|
|
63425
|
+
const toggleCollapse = useCallback122((key, e) => {
|
|
63241
63426
|
e.stopPropagation();
|
|
63242
63427
|
setCollapsed((prev) => ({ ...prev, [key]: !prev[key] }));
|
|
63243
63428
|
}, []);
|
|
63244
|
-
const handleReorder =
|
|
63429
|
+
const handleReorder = useCallback122(
|
|
63245
63430
|
(event) => {
|
|
63246
63431
|
const { siblingLayers, fromIndex, toIndex } = event;
|
|
63247
63432
|
const reordered = [...siblingLayers];
|
|
@@ -63304,7 +63489,7 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63304
63489
|
);
|
|
63305
63490
|
const selectedKey = domEditSelection ? getDomEditLayerKey(domEditSelection) : null;
|
|
63306
63491
|
const visibleLayers = getVisibleLayers(layers, collapsed);
|
|
63307
|
-
const handleSingleSibling =
|
|
63492
|
+
const handleSingleSibling = useCallback122(() => {
|
|
63308
63493
|
showToast("Only one layer at this level", "info");
|
|
63309
63494
|
}, [showToast]);
|
|
63310
63495
|
const {
|
|
@@ -63433,10 +63618,10 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
63433
63618
|
});
|
|
63434
63619
|
|
|
63435
63620
|
// src/captions/components/CaptionPropertyPanel.tsx
|
|
63436
|
-
import { memo as memo43, useCallback as
|
|
63621
|
+
import { memo as memo43, useCallback as useCallback124, useState as useState112 } from "react";
|
|
63437
63622
|
|
|
63438
63623
|
// src/captions/components/CaptionAnimationPanel.tsx
|
|
63439
|
-
import { memo as memo42, useCallback as
|
|
63624
|
+
import { memo as memo42, useCallback as useCallback123 } from "react";
|
|
63440
63625
|
|
|
63441
63626
|
// src/captions/components/shared.tsx
|
|
63442
63627
|
import { jsx as jsx150, jsxs as jsxs127 } from "react/jsx-runtime";
|
|
@@ -63599,25 +63784,25 @@ var CaptionAnimationPanel = memo42(function CaptionAnimationPanel2() {
|
|
|
63599
63784
|
}
|
|
63600
63785
|
const group = resolvedGroupId ? model?.groups.get(resolvedGroupId) : void 0;
|
|
63601
63786
|
const animation = group?.animation;
|
|
63602
|
-
const handleEntranceChange =
|
|
63787
|
+
const handleEntranceChange = useCallback123(
|
|
63603
63788
|
(update) => {
|
|
63604
63789
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "entrance", update);
|
|
63605
63790
|
},
|
|
63606
63791
|
[resolvedGroupId, updateGroupAnimation]
|
|
63607
63792
|
);
|
|
63608
|
-
const handleHighlightChange =
|
|
63793
|
+
const handleHighlightChange = useCallback123(
|
|
63609
63794
|
(update) => {
|
|
63610
63795
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "highlight", update);
|
|
63611
63796
|
},
|
|
63612
63797
|
[resolvedGroupId, updateGroupAnimation]
|
|
63613
63798
|
);
|
|
63614
|
-
const handleExitChange =
|
|
63799
|
+
const handleExitChange = useCallback123(
|
|
63615
63800
|
(update) => {
|
|
63616
63801
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "exit", update);
|
|
63617
63802
|
},
|
|
63618
63803
|
[resolvedGroupId, updateGroupAnimation]
|
|
63619
63804
|
);
|
|
63620
|
-
const handleApplyToAll =
|
|
63805
|
+
const handleApplyToAll = useCallback123(() => {
|
|
63621
63806
|
if (animation) applyAnimationToAll(animation);
|
|
63622
63807
|
}, [animation, applyAnimationToAll]);
|
|
63623
63808
|
if (!group || !resolvedGroupId || !animation) {
|
|
@@ -63695,7 +63880,7 @@ var CaptionPropertyPanel = memo43(function CaptionPropertyPanel2({
|
|
|
63695
63880
|
...groupStyle,
|
|
63696
63881
|
...segmentOverrides
|
|
63697
63882
|
};
|
|
63698
|
-
const applyToIframeDom =
|
|
63883
|
+
const applyToIframeDom = useCallback124(
|
|
63699
63884
|
(updates) => {
|
|
63700
63885
|
const iframe = iframeRef.current;
|
|
63701
63886
|
if (!iframe || !model) return;
|
|
@@ -63769,7 +63954,7 @@ var CaptionPropertyPanel = memo43(function CaptionPropertyPanel2({
|
|
|
63769
63954
|
},
|
|
63770
63955
|
[iframeRef, model, selectedSegmentIds]
|
|
63771
63956
|
);
|
|
63772
|
-
const handleStyleChange =
|
|
63957
|
+
const handleStyleChange = useCallback124(
|
|
63773
63958
|
(updates) => {
|
|
63774
63959
|
if (selectedGroupId) {
|
|
63775
63960
|
updateGroupStyle(selectedGroupId, updates);
|
|
@@ -63869,7 +64054,7 @@ var CaptionPropertyPanel = memo43(function CaptionPropertyPanel2({
|
|
|
63869
64054
|
});
|
|
63870
64055
|
|
|
63871
64056
|
// src/components/editor/BlockParamsPanel.tsx
|
|
63872
|
-
import { memo as memo44, useState as useState113, useCallback as
|
|
64057
|
+
import { memo as memo44, useState as useState113, useCallback as useCallback125 } from "react";
|
|
63873
64058
|
import { jsx as jsx153, jsxs as jsxs130 } from "react/jsx-runtime";
|
|
63874
64059
|
var BlockParamsPanel = memo44(function BlockParamsPanel2({
|
|
63875
64060
|
blockTitle,
|
|
@@ -63884,7 +64069,7 @@ var BlockParamsPanel = memo44(function BlockParamsPanel2({
|
|
|
63884
64069
|
}
|
|
63885
64070
|
return initial;
|
|
63886
64071
|
});
|
|
63887
|
-
const handleChange =
|
|
64072
|
+
const handleChange = useCallback125((key, value) => {
|
|
63888
64073
|
setValues((prev) => ({ ...prev, [key]: value }));
|
|
63889
64074
|
}, []);
|
|
63890
64075
|
return /* @__PURE__ */ jsxs130("div", { className: "flex flex-col h-full", children: [
|
|
@@ -63997,7 +64182,7 @@ function ParamControl({
|
|
|
63997
64182
|
import { memo as memo46, useState as useState115, useRef as useRef126, useEffect as useEffect99, useId as useId6 } from "react";
|
|
63998
64183
|
|
|
63999
64184
|
// src/components/renders/RenderQueueItem.tsx
|
|
64000
|
-
import { memo as memo45, useCallback as
|
|
64185
|
+
import { memo as memo45, useCallback as useCallback126, useState as useState114 } from "react";
|
|
64001
64186
|
import { Fragment as Fragment48, jsx as jsx154, jsxs as jsxs131 } from "react/jsx-runtime";
|
|
64002
64187
|
function formatDuration2(ms) {
|
|
64003
64188
|
if (ms < 1e3) return `${ms}ms`;
|
|
@@ -64020,10 +64205,10 @@ var RenderQueueItem = memo45(function RenderQueueItem2({
|
|
|
64020
64205
|
const [videoReady, setVideoReady] = useState114(false);
|
|
64021
64206
|
const [confirmingDelete, setConfirmingDelete] = useState114(false);
|
|
64022
64207
|
const fileSrc = `/api/projects/${projectId}/renders/file/${job.filename}`;
|
|
64023
|
-
const handleOpen =
|
|
64208
|
+
const handleOpen = useCallback126(() => {
|
|
64024
64209
|
window.open(fileSrc, "_blank");
|
|
64025
64210
|
}, [fileSrc]);
|
|
64026
|
-
const handleDownload =
|
|
64211
|
+
const handleDownload = useCallback126(
|
|
64027
64212
|
(e) => {
|
|
64028
64213
|
e.stopPropagation();
|
|
64029
64214
|
const a = document.createElement("a");
|
|
@@ -64607,11 +64792,11 @@ var RenderQueue = memo46(function RenderQueue2({
|
|
|
64607
64792
|
});
|
|
64608
64793
|
|
|
64609
64794
|
// src/components/panels/SlideshowPanel.tsx
|
|
64610
|
-
import { useState as useState117, useEffect as useEffect100, useCallback as
|
|
64795
|
+
import { useState as useState117, useEffect as useEffect100, useCallback as useCallback128, useRef as useRef127 } from "react";
|
|
64611
64796
|
import { parseSlideshowManifest } from "@hyperframes/core/slideshow";
|
|
64612
64797
|
|
|
64613
64798
|
// src/components/panels/SlideshowSubPanels.tsx
|
|
64614
|
-
import { useState as useState116, useCallback as
|
|
64799
|
+
import { useState as useState116, useCallback as useCallback127, useId as useId7 } from "react";
|
|
64615
64800
|
import { jsx as jsx156, jsxs as jsxs133 } from "react/jsx-runtime";
|
|
64616
64801
|
function SectionHeader({
|
|
64617
64802
|
children,
|
|
@@ -64796,7 +64981,7 @@ function BranchTree({
|
|
|
64796
64981
|
}) {
|
|
64797
64982
|
const [newLabel, setNewLabel] = useState116("");
|
|
64798
64983
|
const inputId = useId7();
|
|
64799
|
-
const handleCreate =
|
|
64984
|
+
const handleCreate = useCallback127(() => {
|
|
64800
64985
|
const label = newLabel.trim();
|
|
64801
64986
|
if (!label) return;
|
|
64802
64987
|
onCreateSequence(label);
|
|
@@ -64857,7 +65042,7 @@ function BranchItem({
|
|
|
64857
65042
|
}) {
|
|
64858
65043
|
const [editing, setEditing] = useState116(false);
|
|
64859
65044
|
const [draft, setDraft] = useState116(seq.label);
|
|
64860
|
-
const commitRename =
|
|
65045
|
+
const commitRename = useCallback127(() => {
|
|
64861
65046
|
const label = draft.trim();
|
|
64862
65047
|
if (label && label !== seq.label) onRename(seq.id, label);
|
|
64863
65048
|
setEditing(false);
|
|
@@ -64955,7 +65140,7 @@ function HotspotTool({
|
|
|
64955
65140
|
const selectedElementId = domEditSelection?.element?.id ?? null;
|
|
64956
65141
|
const selectedHfId = domEditSelection?.hfId ?? null;
|
|
64957
65142
|
const elementKey2 = selectedElementId || selectedHfId;
|
|
64958
|
-
const handleMakeHotspot =
|
|
65143
|
+
const handleMakeHotspot = useCallback127(() => {
|
|
64959
65144
|
if (!selectedSceneId || !targetSequenceId || !elementKey2) return;
|
|
64960
65145
|
const id = `hotspot-${elementKey2}-${generateId()}`;
|
|
64961
65146
|
const label = hotspotLabel.trim() || elementKey2;
|
|
@@ -65259,7 +65444,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65259
65444
|
manifestRef.current = parsed;
|
|
65260
65445
|
setSelectedSequenceId(null);
|
|
65261
65446
|
}, [compHtml]);
|
|
65262
|
-
const applyManifest =
|
|
65447
|
+
const applyManifest = useCallback128(
|
|
65263
65448
|
async (next) => {
|
|
65264
65449
|
const merged = notesCtrlRef.current.mergeIntoDiscrete(next);
|
|
65265
65450
|
setManifest(merged);
|
|
@@ -65272,7 +65457,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65272
65457
|
},
|
|
65273
65458
|
[onPersist]
|
|
65274
65459
|
);
|
|
65275
|
-
const applyNotesManifest =
|
|
65460
|
+
const applyNotesManifest = useCallback128(
|
|
65276
65461
|
(next) => {
|
|
65277
65462
|
setManifest(next);
|
|
65278
65463
|
manifestRef.current = next;
|
|
@@ -65286,7 +65471,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65286
65471
|
ctrl.flush();
|
|
65287
65472
|
};
|
|
65288
65473
|
}, []);
|
|
65289
|
-
const toggleSection =
|
|
65474
|
+
const toggleSection = useCallback128((key) => {
|
|
65290
65475
|
setExpandedSections((prev) => {
|
|
65291
65476
|
const next = new Set(prev);
|
|
65292
65477
|
if (next.has(key)) {
|
|
@@ -65300,25 +65485,25 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65300
65485
|
const activeSlides = selectedSequenceId ? (manifest.slideSequences ?? []).find((s) => s.id === selectedSequenceId)?.slides ?? [] : manifest.slides;
|
|
65301
65486
|
const selectedSlide = activeSlides.find((s) => s.sceneId === selectedSceneId);
|
|
65302
65487
|
const sequences = manifest.slideSequences ?? [];
|
|
65303
|
-
const handleSelectBranchSlide =
|
|
65488
|
+
const handleSelectBranchSlide = useCallback128((sequenceId, sceneId) => {
|
|
65304
65489
|
setSelectedSceneId(sceneId);
|
|
65305
65490
|
setSelectedSequenceId(sequenceId);
|
|
65306
65491
|
}, []);
|
|
65307
|
-
const handleToggleSlide =
|
|
65492
|
+
const handleToggleSlide = useCallback128(
|
|
65308
65493
|
(sceneId) => {
|
|
65309
65494
|
applyManifest(toggleMainLineSlide(manifestRef.current, sceneId)).catch(() => {
|
|
65310
65495
|
});
|
|
65311
65496
|
},
|
|
65312
65497
|
[applyManifest]
|
|
65313
65498
|
);
|
|
65314
|
-
const handleReorder =
|
|
65499
|
+
const handleReorder = useCallback128(
|
|
65315
65500
|
(sceneId, dir) => {
|
|
65316
65501
|
applyManifest(reorderMainLineSlide(manifestRef.current, sceneId, dir)).catch(() => {
|
|
65317
65502
|
});
|
|
65318
65503
|
},
|
|
65319
65504
|
[applyManifest]
|
|
65320
65505
|
);
|
|
65321
|
-
const handleSetNotes =
|
|
65506
|
+
const handleSetNotes = useCallback128(
|
|
65322
65507
|
(notes) => {
|
|
65323
65508
|
if (!selectedSceneId) return;
|
|
65324
65509
|
applyNotesManifest(
|
|
@@ -65327,7 +65512,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65327
65512
|
},
|
|
65328
65513
|
[selectedSceneId, selectedSequenceId, applyNotesManifest]
|
|
65329
65514
|
);
|
|
65330
|
-
const handleMarkFragment =
|
|
65515
|
+
const handleMarkFragment = useCallback128(() => {
|
|
65331
65516
|
if (!selectedSceneId) return;
|
|
65332
65517
|
applyManifest(
|
|
65333
65518
|
addFragment(
|
|
@@ -65339,7 +65524,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65339
65524
|
).catch(() => {
|
|
65340
65525
|
});
|
|
65341
65526
|
}, [selectedSceneId, selectedSequenceId, currentTime, applyManifest]);
|
|
65342
|
-
const handleRemoveFragment =
|
|
65527
|
+
const handleRemoveFragment = useCallback128(
|
|
65343
65528
|
(time) => {
|
|
65344
65529
|
if (!selectedSceneId) return;
|
|
65345
65530
|
applyManifest(
|
|
@@ -65349,7 +65534,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65349
65534
|
},
|
|
65350
65535
|
[selectedSceneId, selectedSequenceId, applyManifest]
|
|
65351
65536
|
);
|
|
65352
|
-
const handleCreateSequence =
|
|
65537
|
+
const handleCreateSequence = useCallback128(
|
|
65353
65538
|
(label) => {
|
|
65354
65539
|
const id = `seq-${generateId()}`;
|
|
65355
65540
|
applyManifest(createSequence(manifestRef.current, id, label)).catch(() => {
|
|
@@ -65357,14 +65542,14 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65357
65542
|
},
|
|
65358
65543
|
[applyManifest]
|
|
65359
65544
|
);
|
|
65360
|
-
const handleRenameSequence =
|
|
65545
|
+
const handleRenameSequence = useCallback128(
|
|
65361
65546
|
(id, label) => {
|
|
65362
65547
|
applyManifest(renameSequence(manifestRef.current, id, label)).catch(() => {
|
|
65363
65548
|
});
|
|
65364
65549
|
},
|
|
65365
65550
|
[applyManifest]
|
|
65366
65551
|
);
|
|
65367
|
-
const handleDeleteSequence =
|
|
65552
|
+
const handleDeleteSequence = useCallback128(
|
|
65368
65553
|
(id) => {
|
|
65369
65554
|
const seq = (manifestRef.current.slideSequences ?? []).find((s) => s.id === id);
|
|
65370
65555
|
const count = seq?.slides.length ?? 0;
|
|
@@ -65378,7 +65563,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65378
65563
|
},
|
|
65379
65564
|
[applyManifest]
|
|
65380
65565
|
);
|
|
65381
|
-
const handleAssign =
|
|
65566
|
+
const handleAssign = useCallback128(
|
|
65382
65567
|
(sequenceId, sceneId, assign) => {
|
|
65383
65568
|
applyManifest(assignToBranch(manifestRef.current, sequenceId, sceneId, assign)).catch(
|
|
65384
65569
|
() => {
|
|
@@ -65387,7 +65572,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65387
65572
|
},
|
|
65388
65573
|
[applyManifest]
|
|
65389
65574
|
);
|
|
65390
|
-
const handleAddHotspot =
|
|
65575
|
+
const handleAddHotspot = useCallback128(
|
|
65391
65576
|
(sceneId, hotspot) => {
|
|
65392
65577
|
applyManifest(
|
|
65393
65578
|
addHotspot(manifestRef.current, sceneId, hotspot, selectedSequenceId ?? void 0)
|
|
@@ -65396,7 +65581,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65396
65581
|
},
|
|
65397
65582
|
[selectedSequenceId, applyManifest]
|
|
65398
65583
|
);
|
|
65399
|
-
const handleRemoveHotspot =
|
|
65584
|
+
const handleRemoveHotspot = useCallback128(
|
|
65400
65585
|
(sceneId, hotspotId) => {
|
|
65401
65586
|
applyManifest(
|
|
65402
65587
|
removeHotspot(manifestRef.current, sceneId, hotspotId, selectedSequenceId ?? void 0)
|
|
@@ -65500,10 +65685,10 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
65500
65685
|
}
|
|
65501
65686
|
|
|
65502
65687
|
// src/components/panels/VariablesPanel.tsx
|
|
65503
|
-
import { memo as memo47, useCallback as
|
|
65688
|
+
import { memo as memo47, useCallback as useCallback132, useEffect as useEffect102, useMemo as useMemo48, useState as useState121 } from "react";
|
|
65504
65689
|
|
|
65505
65690
|
// src/hooks/useVariablesPersist.ts
|
|
65506
|
-
import { useCallback as
|
|
65691
|
+
import { useCallback as useCallback129 } from "react";
|
|
65507
65692
|
function useVariablesPersist({
|
|
65508
65693
|
sdkSession,
|
|
65509
65694
|
activeCompPath,
|
|
@@ -65514,7 +65699,7 @@ function useVariablesPersist({
|
|
|
65514
65699
|
domEditSaveTimestampRef,
|
|
65515
65700
|
publishSdkSession
|
|
65516
65701
|
}) {
|
|
65517
|
-
return
|
|
65702
|
+
return useCallback129(
|
|
65518
65703
|
async (label, mutate) => {
|
|
65519
65704
|
if (!sdkSession) return false;
|
|
65520
65705
|
const path = activeCompPath ?? "index.html";
|
|
@@ -65551,10 +65736,10 @@ function useVariablesPersist({
|
|
|
65551
65736
|
}
|
|
65552
65737
|
|
|
65553
65738
|
// src/components/panels/VariablesOtherCompositions.tsx
|
|
65554
|
-
import { useCallback as
|
|
65739
|
+
import { useCallback as useCallback131, useState as useState120 } from "react";
|
|
65555
65740
|
|
|
65556
65741
|
// src/hooks/useProjectCompositionVariables.ts
|
|
65557
|
-
import { useCallback as
|
|
65742
|
+
import { useCallback as useCallback130, useEffect as useEffect101, useState as useState118 } from "react";
|
|
65558
65743
|
import { openComposition as openComposition4 } from "@hyperframes/sdk";
|
|
65559
65744
|
async function readGroup(path, readProjectFile) {
|
|
65560
65745
|
let content;
|
|
@@ -65597,7 +65782,7 @@ function useProjectCompositionVariables(fileTree, excludePath, readProjectFile,
|
|
|
65597
65782
|
}
|
|
65598
65783
|
function useEditVariablesInFile(deps) {
|
|
65599
65784
|
const { readProjectFile, writeProjectFile, recordEdit, reloadPreview, domEditSaveTimestampRef } = deps;
|
|
65600
|
-
return
|
|
65785
|
+
return useCallback130(
|
|
65601
65786
|
async (path, label, mutate) => {
|
|
65602
65787
|
const originalContent = await readProjectFile(path);
|
|
65603
65788
|
await persistSdkSerialize(
|
|
@@ -65977,7 +66162,7 @@ function VariablesOtherCompositions({
|
|
|
65977
66162
|
domEditSaveTimestampRef
|
|
65978
66163
|
});
|
|
65979
66164
|
const [editingKey, setEditingKey] = useState120(null);
|
|
65980
|
-
const onSave =
|
|
66165
|
+
const onSave = useCallback131(
|
|
65981
66166
|
(path, decl) => {
|
|
65982
66167
|
setEditingKey(null);
|
|
65983
66168
|
void editInFile(
|
|
@@ -65988,7 +66173,7 @@ function VariablesOtherCompositions({
|
|
|
65988
66173
|
},
|
|
65989
66174
|
[editInFile]
|
|
65990
66175
|
);
|
|
65991
|
-
const onRemove =
|
|
66176
|
+
const onRemove = useCallback131(
|
|
65992
66177
|
(path, id) => {
|
|
65993
66178
|
void editInFile(
|
|
65994
66179
|
path,
|
|
@@ -66224,7 +66409,7 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
66224
66409
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66225
66410
|
[sdkSession, previewValues, refreshKey, revision]
|
|
66226
66411
|
);
|
|
66227
|
-
const copyToClipboard =
|
|
66412
|
+
const copyToClipboard = useCallback132(
|
|
66228
66413
|
(text, what) => {
|
|
66229
66414
|
void copyTextToClipboard(text).then(
|
|
66230
66415
|
(ok) => showToast(
|
|
@@ -66235,7 +66420,7 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
66235
66420
|
},
|
|
66236
66421
|
[showToast]
|
|
66237
66422
|
);
|
|
66238
|
-
const dropPreviewOverride =
|
|
66423
|
+
const dropPreviewOverride = useCallback132(
|
|
66239
66424
|
(id) => {
|
|
66240
66425
|
if (previewValues && id in previewValues) {
|
|
66241
66426
|
const next = { ...previewValues };
|
|
@@ -66245,7 +66430,7 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
66245
66430
|
},
|
|
66246
66431
|
[previewValues, setPreviewValues]
|
|
66247
66432
|
);
|
|
66248
|
-
const commitPreviewValue =
|
|
66433
|
+
const commitPreviewValue = useCallback132(
|
|
66249
66434
|
(id, value, declDefault) => {
|
|
66250
66435
|
const next = { ...previewValues ?? {} };
|
|
66251
66436
|
if (JSON.stringify(value) === JSON.stringify(declDefault)) {
|
|
@@ -66258,7 +66443,7 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
66258
66443
|
},
|
|
66259
66444
|
[previewValues, setPreviewValues, reloadPreview]
|
|
66260
66445
|
);
|
|
66261
|
-
const runSchemaEdit =
|
|
66446
|
+
const runSchemaEdit = useCallback132(
|
|
66262
66447
|
async (label, mutate) => {
|
|
66263
66448
|
try {
|
|
66264
66449
|
const changed = await persistVariables(label, mutate);
|
|
@@ -66272,7 +66457,7 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
66272
66457
|
},
|
|
66273
66458
|
[persistVariables, showToast]
|
|
66274
66459
|
);
|
|
66275
|
-
const handleAdd =
|
|
66460
|
+
const handleAdd = useCallback132(
|
|
66276
66461
|
(decl) => {
|
|
66277
66462
|
if (!sdkSession) return;
|
|
66278
66463
|
const check = sdkSession.can({ type: "declareVariable", declaration: decl });
|
|
@@ -66285,7 +66470,7 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
66285
66470
|
},
|
|
66286
66471
|
[sdkSession, runSchemaEdit, showToast]
|
|
66287
66472
|
);
|
|
66288
|
-
const handleUpdate =
|
|
66473
|
+
const handleUpdate = useCallback132(
|
|
66289
66474
|
(decl) => {
|
|
66290
66475
|
if (!sdkSession) return;
|
|
66291
66476
|
const check = sdkSession.can({
|
|
@@ -66305,7 +66490,7 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
66305
66490
|
},
|
|
66306
66491
|
[sdkSession, runSchemaEdit, showToast]
|
|
66307
66492
|
);
|
|
66308
|
-
const handleRemove =
|
|
66493
|
+
const handleRemove = useCallback132(
|
|
66309
66494
|
(id) => {
|
|
66310
66495
|
if (!sdkSession) return;
|
|
66311
66496
|
const check = sdkSession.can({ type: "removeVariableDeclaration", id });
|
|
@@ -66321,18 +66506,18 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
66321
66506
|
},
|
|
66322
66507
|
[sdkSession, runSchemaEdit, dropPreviewOverride, showToast]
|
|
66323
66508
|
);
|
|
66324
|
-
const handleSetDefault =
|
|
66509
|
+
const handleSetDefault = useCallback132(
|
|
66325
66510
|
(id, value) => {
|
|
66326
66511
|
void runSchemaEdit(`Set default for "${id}"`, (s) => s.setVariableValue(id, value));
|
|
66327
66512
|
dropPreviewOverride(id);
|
|
66328
66513
|
},
|
|
66329
66514
|
[runSchemaEdit, dropPreviewOverride]
|
|
66330
66515
|
);
|
|
66331
|
-
const resetPreview =
|
|
66516
|
+
const resetPreview = useCallback132(() => {
|
|
66332
66517
|
setPreviewValues(null);
|
|
66333
66518
|
reloadPreview();
|
|
66334
66519
|
}, [setPreviewValues, reloadPreview]);
|
|
66335
|
-
const handleBind =
|
|
66520
|
+
const handleBind = useCallback132(
|
|
66336
66521
|
// Guard chain (session, selection, type-compat) — one branch per guard.
|
|
66337
66522
|
// fallow-ignore-next-line complexity
|
|
66338
66523
|
(action, id) => {
|
|
@@ -66465,7 +66650,7 @@ function PanelTabButton({
|
|
|
66465
66650
|
}
|
|
66466
66651
|
|
|
66467
66652
|
// src/hooks/useSlideshowPersist.ts
|
|
66468
|
-
import { useCallback as
|
|
66653
|
+
import { useCallback as useCallback133 } from "react";
|
|
66469
66654
|
|
|
66470
66655
|
// src/utils/setSlideshowManifest.ts
|
|
66471
66656
|
import {
|
|
@@ -66523,7 +66708,7 @@ function useSlideshowPersist({
|
|
|
66523
66708
|
publishSdkSession,
|
|
66524
66709
|
coalesceKey
|
|
66525
66710
|
}) {
|
|
66526
|
-
return
|
|
66711
|
+
return useCallback133(
|
|
66527
66712
|
async (manifest) => {
|
|
66528
66713
|
if (!sdkSession) return;
|
|
66529
66714
|
const path = activeCompPath ?? "index.html";
|
|
@@ -66588,7 +66773,7 @@ function useSlideshowTabState(params) {
|
|
|
66588
66773
|
}
|
|
66589
66774
|
|
|
66590
66775
|
// src/components/DesignPanelPromoteProvider.tsx
|
|
66591
|
-
import { useCallback as
|
|
66776
|
+
import { useCallback as useCallback134 } from "react";
|
|
66592
66777
|
import { jsx as jsx163 } from "react/jsx-runtime";
|
|
66593
66778
|
function DesignPanelPromoteProvider({
|
|
66594
66779
|
selection,
|
|
@@ -66607,7 +66792,7 @@ function DesignPanelPromoteProvider({
|
|
|
66607
66792
|
publishSdkSession: handle.publish,
|
|
66608
66793
|
activeCompPath: targetPath
|
|
66609
66794
|
});
|
|
66610
|
-
const persist2 =
|
|
66795
|
+
const persist2 = useCallback134(
|
|
66611
66796
|
async (label, mutate) => {
|
|
66612
66797
|
const committed = await rawPersist(label, mutate);
|
|
66613
66798
|
if (committed) forceReloadSharedSdkSession?.();
|
|
@@ -66615,7 +66800,7 @@ function DesignPanelPromoteProvider({
|
|
|
66615
66800
|
},
|
|
66616
66801
|
[rawPersist, forceReloadSharedSdkSession]
|
|
66617
66802
|
);
|
|
66618
|
-
const handlePersistError =
|
|
66803
|
+
const handlePersistError = useCallback134(
|
|
66619
66804
|
(error) => showToast(getStudioSaveErrorMessage(error), "error"),
|
|
66620
66805
|
[showToast]
|
|
66621
66806
|
);
|
|
@@ -66850,14 +67035,14 @@ async function applyColorGradingScopeUpdate({
|
|
|
66850
67035
|
}
|
|
66851
67036
|
|
|
66852
67037
|
// src/hooks/useInspectorSplitResize.ts
|
|
66853
|
-
import { useCallback as
|
|
67038
|
+
import { useCallback as useCallback135, useRef as useRef128, useState as useState122 } from "react";
|
|
66854
67039
|
var MIN_INSPECTOR_SPLIT_PERCENT = 20;
|
|
66855
67040
|
var MAX_INSPECTOR_SPLIT_PERCENT = 75;
|
|
66856
67041
|
function useInspectorSplitResize() {
|
|
66857
67042
|
const [layersPanePercent, setLayersPanePercent] = useState122(40);
|
|
66858
67043
|
const splitContainerRef = useRef128(null);
|
|
66859
67044
|
const splitDragRef = useRef128(null);
|
|
66860
|
-
const handleInspectorSplitResizeStart =
|
|
67045
|
+
const handleInspectorSplitResizeStart = useCallback135(
|
|
66861
67046
|
(event) => {
|
|
66862
67047
|
event.preventDefault();
|
|
66863
67048
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
@@ -66870,7 +67055,7 @@ function useInspectorSplitResize() {
|
|
|
66870
67055
|
},
|
|
66871
67056
|
[layersPanePercent]
|
|
66872
67057
|
);
|
|
66873
|
-
const handleInspectorSplitResizeMove =
|
|
67058
|
+
const handleInspectorSplitResizeMove = useCallback135((event) => {
|
|
66874
67059
|
const drag = splitDragRef.current;
|
|
66875
67060
|
if (!drag || drag.height <= 0) return;
|
|
66876
67061
|
const deltaPercent = (event.clientY - drag.startY) / drag.height * 100;
|
|
@@ -66880,7 +67065,7 @@ function useInspectorSplitResize() {
|
|
|
66880
67065
|
);
|
|
66881
67066
|
setLayersPanePercent(next);
|
|
66882
67067
|
}, []);
|
|
66883
|
-
const handleInspectorSplitResizeEnd =
|
|
67068
|
+
const handleInspectorSplitResizeEnd = useCallback135(() => {
|
|
66884
67069
|
splitDragRef.current = null;
|
|
66885
67070
|
}, []);
|
|
66886
67071
|
return {
|
|
@@ -66970,6 +67155,7 @@ function StudioRightPanel({
|
|
|
66970
67155
|
handleUpdateArcSegment,
|
|
66971
67156
|
handleUnroll,
|
|
66972
67157
|
handleUpdateKeyframeEase,
|
|
67158
|
+
handleUpdateSegmentEase,
|
|
66973
67159
|
handleSetAllKeyframeEases,
|
|
66974
67160
|
handleGsapAddKeyframe,
|
|
66975
67161
|
handleGsapRemoveKeyframe,
|
|
@@ -67044,7 +67230,7 @@ function StudioRightPanel({
|
|
|
67044
67230
|
}
|
|
67045
67231
|
toggleRightInspectorPane(pane);
|
|
67046
67232
|
};
|
|
67047
|
-
const handleApplyColorGradingScope =
|
|
67233
|
+
const handleApplyColorGradingScope = useCallback136(
|
|
67048
67234
|
async (scope, value) => applyColorGradingScopeUpdate({
|
|
67049
67235
|
scope,
|
|
67050
67236
|
value,
|
|
@@ -67079,7 +67265,7 @@ function StudioRightPanel({
|
|
|
67079
67265
|
writeProjectFile
|
|
67080
67266
|
]
|
|
67081
67267
|
);
|
|
67082
|
-
const handleRemoveBackground =
|
|
67268
|
+
const handleRemoveBackground = useCallback136(
|
|
67083
67269
|
// fallow-ignore-next-line complexity
|
|
67084
67270
|
async (inputPath, options) => {
|
|
67085
67271
|
const response = await fetch(
|
|
@@ -67191,6 +67377,7 @@ function StudioRightPanel({
|
|
|
67191
67377
|
onUnroll: handleUnroll,
|
|
67192
67378
|
onUpdateKeyframeEase: handleUpdateKeyframeEase,
|
|
67193
67379
|
onSetAllKeyframeEases: handleSetAllKeyframeEases,
|
|
67380
|
+
onUpdateSegmentEase: handleUpdateSegmentEase,
|
|
67194
67381
|
recordingState,
|
|
67195
67382
|
recordingDuration,
|
|
67196
67383
|
onToggleRecording
|
|
@@ -67389,7 +67576,7 @@ import { useEffect as useEffect106, useRef as useRef130 } from "react";
|
|
|
67389
67576
|
import { Magnet, MagnifyingGlassMinus, MagnifyingGlassPlus } from "@phosphor-icons/react";
|
|
67390
67577
|
|
|
67391
67578
|
// src/hooks/useEnableKeyframes.ts
|
|
67392
|
-
import { useCallback as
|
|
67579
|
+
import { useCallback as useCallback137 } from "react";
|
|
67393
67580
|
var enableKeyframesTransactionCounter = 0;
|
|
67394
67581
|
function animatedProps(anim) {
|
|
67395
67582
|
if (!anim) return ["x", "y"];
|
|
@@ -67642,7 +67829,7 @@ async function applyArcKeyframeAtPlayhead(session, sel, arcAnim, t, iframe) {
|
|
|
67642
67829
|
);
|
|
67643
67830
|
}
|
|
67644
67831
|
function useEnableKeyframes(sessionRef) {
|
|
67645
|
-
return
|
|
67832
|
+
return useCallback137(async () => {
|
|
67646
67833
|
const session = sessionRef.current;
|
|
67647
67834
|
if (!session) return;
|
|
67648
67835
|
const sel = session.domEditSelection;
|
|
@@ -67724,7 +67911,7 @@ function useEnableKeyframes(sessionRef) {
|
|
|
67724
67911
|
}
|
|
67725
67912
|
|
|
67726
67913
|
// src/hooks/useKeyframeKeyboard.ts
|
|
67727
|
-
import { useEffect as useEffect105, useCallback as
|
|
67914
|
+
import { useEffect as useEffect105, useCallback as useCallback138 } from "react";
|
|
67728
67915
|
function isTextInput(el) {
|
|
67729
67916
|
if (!el) return false;
|
|
67730
67917
|
const tag = el.tagName;
|
|
@@ -67741,7 +67928,7 @@ function useKeyframeKeyboard({
|
|
|
67741
67928
|
onToggleExpand,
|
|
67742
67929
|
onNudgeKeyframe
|
|
67743
67930
|
}) {
|
|
67744
|
-
const handler =
|
|
67931
|
+
const handler = useCallback138(
|
|
67745
67932
|
(e) => {
|
|
67746
67933
|
if (!enabled2) return;
|
|
67747
67934
|
if (isTextInput(document.activeElement)) return;
|
|
@@ -68134,7 +68321,7 @@ import { useState as useState130 } from "react";
|
|
|
68134
68321
|
import { Copy as Copy2, Check as Check2 } from "@phosphor-icons/react";
|
|
68135
68322
|
|
|
68136
68323
|
// src/hooks/useStoryboard.ts
|
|
68137
|
-
import { useCallback as
|
|
68324
|
+
import { useCallback as useCallback139, useEffect as useEffect107, useRef as useRef131, useState as useState123 } from "react";
|
|
68138
68325
|
function useStoryboard(projectId) {
|
|
68139
68326
|
const [data, setData] = useState123(null);
|
|
68140
68327
|
const [loading, setLoading] = useState123(true);
|
|
@@ -68142,7 +68329,7 @@ function useStoryboard(projectId) {
|
|
|
68142
68329
|
const [reloadKey, setReloadKey] = useState123(0);
|
|
68143
68330
|
const hasDataRef = useRef131(false);
|
|
68144
68331
|
const lastProjectRef = useRef131(null);
|
|
68145
|
-
const reload =
|
|
68332
|
+
const reload = useCallback139(() => setReloadKey((k) => k + 1), []);
|
|
68146
68333
|
useEffect107(() => {
|
|
68147
68334
|
if (!projectId) return;
|
|
68148
68335
|
let cancelled = false;
|
|
@@ -68452,7 +68639,7 @@ function StoryboardScriptPanel({ script }) {
|
|
|
68452
68639
|
}
|
|
68453
68640
|
|
|
68454
68641
|
// src/components/storyboard/StoryboardSourceEditor.tsx
|
|
68455
|
-
import { useCallback as
|
|
68642
|
+
import { useCallback as useCallback140, useEffect as useEffect110, useMemo as useMemo50, useRef as useRef133, useState as useState125 } from "react";
|
|
68456
68643
|
import { marked } from "marked";
|
|
68457
68644
|
import DOMPurify from "dompurify";
|
|
68458
68645
|
import { jsx as jsx171, jsxs as jsxs143 } from "react/jsx-runtime";
|
|
@@ -68482,7 +68669,7 @@ function useEditableFile(path, onSaved) {
|
|
|
68482
68669
|
cancelled = true;
|
|
68483
68670
|
};
|
|
68484
68671
|
}, [path, readProjectFile]);
|
|
68485
|
-
const save =
|
|
68672
|
+
const save = useCallback140(() => {
|
|
68486
68673
|
if (saving) return;
|
|
68487
68674
|
setSaving(true);
|
|
68488
68675
|
setError(null);
|
|
@@ -68607,7 +68794,7 @@ function StoryboardSourceEditor({
|
|
|
68607
68794
|
}
|
|
68608
68795
|
|
|
68609
68796
|
// src/components/storyboard/StoryboardFrameFocus.tsx
|
|
68610
|
-
import { useCallback as
|
|
68797
|
+
import { useCallback as useCallback141, useEffect as useEffect112, useState as useState127 } from "react";
|
|
68611
68798
|
import { setFrameVoiceover } from "@hyperframes/core/storyboard";
|
|
68612
68799
|
|
|
68613
68800
|
// src/components/storyboard/AgentChatMessageButton.tsx
|
|
@@ -68667,7 +68854,7 @@ function StoryboardFrameFocus({
|
|
|
68667
68854
|
const [savedVoiceover, setSavedVoiceover] = useState127(frame.voiceover ?? "");
|
|
68668
68855
|
const [busy, setBusy] = useState127(false);
|
|
68669
68856
|
const [error, setError] = useState127(null);
|
|
68670
|
-
const applyEdit =
|
|
68857
|
+
const applyEdit = useCallback141(
|
|
68671
68858
|
async (edit) => {
|
|
68672
68859
|
if (busy) return false;
|
|
68673
68860
|
setBusy(true);
|
|
@@ -68689,7 +68876,7 @@ function StoryboardFrameFocus({
|
|
|
68689
68876
|
const title = frame.title ?? `Frame ${frame.index}`;
|
|
68690
68877
|
const dirty = draft !== savedVoiceover;
|
|
68691
68878
|
const canOpenPreview = frame.status !== "outline" && frame.srcExists && Boolean(frame.src);
|
|
68692
|
-
const saveVoiceover =
|
|
68879
|
+
const saveVoiceover = useCallback141(async () => {
|
|
68693
68880
|
const saved = await applyEdit((src) => setFrameVoiceover(src, frame.index, draft));
|
|
68694
68881
|
if (saved) setSavedVoiceover(draft);
|
|
68695
68882
|
}, [applyEdit, frame.index, draft]);
|
|
@@ -68701,7 +68888,7 @@ function StoryboardFrameFocus({
|
|
|
68701
68888
|
window.addEventListener("beforeunload", onBeforeUnload);
|
|
68702
68889
|
return () => window.removeEventListener("beforeunload", onBeforeUnload);
|
|
68703
68890
|
}, [dirty]);
|
|
68704
|
-
const confirmLeave =
|
|
68891
|
+
const confirmLeave = useCallback141(
|
|
68705
68892
|
() => !dirty || window.confirm("Discard unsaved voiceover changes?"),
|
|
68706
68893
|
[dirty]
|
|
68707
68894
|
);
|
|
@@ -69184,7 +69371,7 @@ function progressLabel(summary) {
|
|
|
69184
69371
|
}
|
|
69185
69372
|
|
|
69186
69373
|
// src/components/storyboard/useFrameComments.ts
|
|
69187
|
-
import { useCallback as
|
|
69374
|
+
import { useCallback as useCallback142, useEffect as useEffect113, useMemo as useMemo51, useState as useState128 } from "react";
|
|
69188
69375
|
|
|
69189
69376
|
// src/components/storyboard/frameComments.ts
|
|
69190
69377
|
var FRAME_COMMENTS_PATH = ".hyperframes/frame-comments.json";
|
|
@@ -69250,7 +69437,7 @@ function useFrameComments(frames) {
|
|
|
69250
69437
|
const [submitState, setSubmitState] = useState128("idle");
|
|
69251
69438
|
const [submitError, setSubmitError] = useState128(null);
|
|
69252
69439
|
const [pending, setPending] = useState128(null);
|
|
69253
|
-
const refreshPending =
|
|
69440
|
+
const refreshPending = useCallback142(async () => {
|
|
69254
69441
|
try {
|
|
69255
69442
|
const parsed = parseCommentsFile(await readOptionalProjectFile(FRAME_COMMENTS_PATH));
|
|
69256
69443
|
setPending(parsed && parsed.comments.length > 0 ? parsed.comments : null);
|
|
@@ -69263,14 +69450,14 @@ function useFrameComments(frames) {
|
|
|
69263
69450
|
window.addEventListener("focus", onFocus);
|
|
69264
69451
|
return () => window.removeEventListener("focus", onFocus);
|
|
69265
69452
|
}, [refreshPending]);
|
|
69266
|
-
const setDraft =
|
|
69453
|
+
const setDraft = useCallback142((index, text) => {
|
|
69267
69454
|
setDrafts((prev) => ({ ...prev, [index]: text }));
|
|
69268
69455
|
}, []);
|
|
69269
69456
|
const draftCount = useMemo51(
|
|
69270
69457
|
() => Object.values(drafts).filter((text) => text.trim().length > 0).length,
|
|
69271
69458
|
[drafts]
|
|
69272
69459
|
);
|
|
69273
|
-
const submit =
|
|
69460
|
+
const submit = useCallback142(async () => {
|
|
69274
69461
|
if (draftCount === 0 || submitState === "saving") return false;
|
|
69275
69462
|
setSubmitState("saving");
|
|
69276
69463
|
setSubmitError(null);
|
|
@@ -69723,12 +69910,12 @@ function useServerConnection() {
|
|
|
69723
69910
|
}
|
|
69724
69911
|
|
|
69725
69912
|
// src/hooks/useTimelineAddAtPlayhead.ts
|
|
69726
|
-
import { useCallback as
|
|
69913
|
+
import { useCallback as useCallback143 } from "react";
|
|
69727
69914
|
function useTimelineAddAtPlayhead(addAsset, addComposition) {
|
|
69728
69915
|
const placement = () => ({ start: usePlayerStore.getState().currentTime, track: 0 });
|
|
69729
69916
|
return {
|
|
69730
|
-
addAssetAtPlayhead:
|
|
69731
|
-
addCompositionAtPlayhead:
|
|
69917
|
+
addAssetAtPlayhead: useCallback143((path) => addAsset(path, placement()), [addAsset]),
|
|
69918
|
+
addCompositionAtPlayhead: useCallback143(
|
|
69732
69919
|
(path) => addComposition(path, placement()),
|
|
69733
69920
|
[addComposition]
|
|
69734
69921
|
)
|
|
@@ -69784,7 +69971,7 @@ function StudioApp() {
|
|
|
69784
69971
|
const handleDomZIndexReorderCommitRef = useRef134(null);
|
|
69785
69972
|
const pendingTimelineEditPathRef = useRef134(/* @__PURE__ */ new Set());
|
|
69786
69973
|
const isGestureRecordingRef = useRef134(false);
|
|
69787
|
-
const reloadPreview =
|
|
69974
|
+
const reloadPreview = useCallback144(() => setRefreshKey((k) => k + 1), []);
|
|
69788
69975
|
const fileManager = useFileManager({
|
|
69789
69976
|
projectId,
|
|
69790
69977
|
showToast,
|
|
@@ -69826,7 +70013,7 @@ function StudioApp() {
|
|
|
69826
70013
|
});
|
|
69827
70014
|
const invalidateGsapCacheRef = useRef134(() => {
|
|
69828
70015
|
});
|
|
69829
|
-
const invalidateGsapCache =
|
|
70016
|
+
const invalidateGsapCache = useCallback144(() => invalidateGsapCacheRef.current(), []);
|
|
69830
70017
|
const timelineEditing = useTimelineEditing({
|
|
69831
70018
|
projectId,
|
|
69832
70019
|
activeCompPath,
|
|
@@ -69847,7 +70034,7 @@ function StudioApp() {
|
|
|
69847
70034
|
invalidateGsapCache,
|
|
69848
70035
|
handleDomZIndexReorderCommitRef
|
|
69849
70036
|
});
|
|
69850
|
-
const handleTimelineElementsMove =
|
|
70037
|
+
const handleTimelineElementsMove = useCallback144(
|
|
69851
70038
|
async (edits, coalesceKey, operation = "timing", coalesceMs) => {
|
|
69852
70039
|
const deps = { handleTimelineGroupMove: timelineEditing.handleTimelineGroupMove };
|
|
69853
70040
|
await persistTimelineMoveEditsAtomically(edits, coalesceKey, operation, deps, coalesceMs);
|
|
@@ -70043,7 +70230,7 @@ function StudioApp() {
|
|
|
70043
70230
|
}
|
|
70044
70231
|
canvasRectRef.current = previewIframe.getBoundingClientRect();
|
|
70045
70232
|
}, [gestureState, previewIframe]);
|
|
70046
|
-
const handlePreviewIframeRef =
|
|
70233
|
+
const handlePreviewIframeRef = useCallback144(
|
|
70047
70234
|
(iframe) => {
|
|
70048
70235
|
previewIframeRef.current = iframe;
|
|
70049
70236
|
setPreviewIframe(iframe);
|
|
@@ -70267,32 +70454,32 @@ function StudioApp() {
|
|
|
70267
70454
|
}
|
|
70268
70455
|
|
|
70269
70456
|
// src/hooks/useElementPicker.ts
|
|
70270
|
-
import { useState as useState133, useCallback as
|
|
70457
|
+
import { useState as useState133, useCallback as useCallback145, useRef as useRef135 } from "react";
|
|
70271
70458
|
function useElementPicker(iframeRef, options) {
|
|
70272
70459
|
const [isPickMode, setIsPickMode] = useState133(false);
|
|
70273
70460
|
const [pickedElement, setPickedElement] = useState133(null);
|
|
70274
70461
|
const activeOverrideRef = useRef135(null);
|
|
70275
|
-
const getActiveIframe =
|
|
70462
|
+
const getActiveIframe = useCallback145(() => {
|
|
70276
70463
|
return activeOverrideRef.current ?? iframeRef.current;
|
|
70277
70464
|
}, [iframeRef]);
|
|
70278
|
-
const setActiveIframe =
|
|
70465
|
+
const setActiveIframe = useCallback145((el) => {
|
|
70279
70466
|
activeOverrideRef.current = el;
|
|
70280
70467
|
}, []);
|
|
70281
|
-
const enablePick =
|
|
70468
|
+
const enablePick = useCallback145(() => {
|
|
70282
70469
|
try {
|
|
70283
70470
|
postRuntimeControlMessage(getActiveIframe()?.contentWindow, "enable-pick-mode");
|
|
70284
70471
|
setIsPickMode(true);
|
|
70285
70472
|
} catch {
|
|
70286
70473
|
}
|
|
70287
70474
|
}, [getActiveIframe]);
|
|
70288
|
-
const disablePick =
|
|
70475
|
+
const disablePick = useCallback145(() => {
|
|
70289
70476
|
try {
|
|
70290
70477
|
postRuntimeControlMessage(getActiveIframe()?.contentWindow, "disable-pick-mode");
|
|
70291
70478
|
} catch {
|
|
70292
70479
|
}
|
|
70293
70480
|
setIsPickMode(false);
|
|
70294
70481
|
}, [getActiveIframe]);
|
|
70295
|
-
const clearPick =
|
|
70482
|
+
const clearPick = useCallback145(() => {
|
|
70296
70483
|
setPickedElement(null);
|
|
70297
70484
|
}, []);
|
|
70298
70485
|
useMountEffect(() => {
|
|
@@ -70347,7 +70534,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
70347
70534
|
});
|
|
70348
70535
|
const optionsRef = useRef135(options);
|
|
70349
70536
|
optionsRef.current = options;
|
|
70350
|
-
const syncToSource =
|
|
70537
|
+
const syncToSource = useCallback145(
|
|
70351
70538
|
(elementId, selector, op) => {
|
|
70352
70539
|
const opts = optionsRef.current;
|
|
70353
70540
|
if (!opts?.workspaceFiles || !opts.onSyncFiles || !elementId) return;
|
|
@@ -70363,7 +70550,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
70363
70550
|
},
|
|
70364
70551
|
[]
|
|
70365
70552
|
);
|
|
70366
|
-
const setStyle =
|
|
70553
|
+
const setStyle = useCallback145(
|
|
70367
70554
|
(prop, value) => {
|
|
70368
70555
|
const activeIframe = getActiveIframe();
|
|
70369
70556
|
if (!pickedElement?.selector || !activeIframe) return;
|
|
@@ -70405,7 +70592,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
70405
70592
|
},
|
|
70406
70593
|
[pickedElement, getActiveIframe, syncToSource]
|
|
70407
70594
|
);
|
|
70408
|
-
const setDataAttr =
|
|
70595
|
+
const setDataAttr = useCallback145(
|
|
70409
70596
|
(attr, value) => {
|
|
70410
70597
|
const activeIframe = getActiveIframe();
|
|
70411
70598
|
if (!pickedElement?.selector || !activeIframe) return;
|
|
@@ -70433,7 +70620,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
70433
70620
|
},
|
|
70434
70621
|
[pickedElement, getActiveIframe, syncToSource]
|
|
70435
70622
|
);
|
|
70436
|
-
const setTextContent =
|
|
70623
|
+
const setTextContent = useCallback145(
|
|
70437
70624
|
(text) => {
|
|
70438
70625
|
const activeIframe = getActiveIframe();
|
|
70439
70626
|
if (!pickedElement?.selector || !activeIframe) return;
|