@hyperframes/studio 0.8.87 → 0.8.89
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-CtNVImMi.js → hyperframes-player-CVoS7kv8.js} +1 -1
- package/dist/assets/{index-DZKcDAtf.js → index-BM8PwYby.js} +187 -187
- package/dist/assets/{index-DJ-Ol7YS.js → index-D35-L_yn.js} +1 -1
- package/dist/assets/{index-B_MF86RE.js → index-DBub9qQY.js} +1 -1
- package/dist/{chunk-7PLTC6SV.js → chunk-KU4F7QZ3.js} +9 -1
- package/dist/chunk-KU4F7QZ3.js.map +1 -0
- package/dist/index.d.ts +42 -5
- package/dist/index.html +1 -1
- package/dist/index.js +269 -94
- package/dist/index.js.map +1 -1
- package/dist/player.js +1 -1
- package/package.json +8 -8
- package/src/components/TimelineHistoryButtons.dom.test.tsx +14 -3
- package/src/components/TimelineToolPicker.tsx +90 -0
- package/src/components/TimelineToolbar.tsx +2 -27
- package/src/components/editor/DomEditOverlay.tsx +7 -4
- package/src/components/editor/domEditOverlayGestures.ts +4 -4
- package/src/components/editor/useDomEditNudge.ts +2 -2
- package/src/hooks/appHotkeysDispatch.ts +8 -0
- package/src/hooks/useAppHotkeys.test.ts +58 -1
- package/src/hooks/useDomGeometryCommit.test.tsx +226 -0
- package/src/hooks/useDomGeometryCommit.ts +147 -0
- package/src/hooks/useGsapAwareEditing.ts +9 -4
- package/src/index.ts +3 -1
- package/src/player/components/Timeline.showKeyframes.test.tsx +91 -0
- package/src/player/components/TimelineTypes.ts +1 -0
- package/src/player/components/studioShortcuts.ts +2 -0
- package/src/player/components/useTimelineKeyframeData.ts +14 -0
- package/src/player/components/useTimelineProviderState.tsx +5 -3
- package/src/player/store/playerStore.ts +16 -0
- package/dist/chunk-7PLTC6SV.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
whenPreviewBooted,
|
|
67
67
|
wrapTimeline,
|
|
68
68
|
writeStudioUiPreferences
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-KU4F7QZ3.js";
|
|
70
70
|
import {
|
|
71
71
|
Button,
|
|
72
72
|
ContextMenu,
|
|
@@ -600,6 +600,8 @@ var DEFAULT_SHORTCUT_SECTIONS = [
|
|
|
600
600
|
{ key: "\u2318X", label: "Cut element" },
|
|
601
601
|
{ key: hintKey(STUDIO_PLAIN_KEYS.split), label: "Split clip at playhead" },
|
|
602
602
|
{ key: "\u21E7Click", label: "Razor tool: split all tracks" },
|
|
603
|
+
{ key: "[", label: "Select clips starting before the playhead" },
|
|
604
|
+
{ key: "]", label: "Select clips starting at or after the playhead" },
|
|
603
605
|
{ key: "\u2318G", label: "Group elements" },
|
|
604
606
|
{ key: "\u2318\u21E7G", label: "Ungroup" },
|
|
605
607
|
{ key: "Del", label: "Delete selected element (no keyframe selected)" }
|
|
@@ -10657,6 +10659,17 @@ function useTimelineLabelColumn(animationsByElement, elements) {
|
|
|
10657
10659
|
return { labelMode, contentOrigin };
|
|
10658
10660
|
}
|
|
10659
10661
|
|
|
10662
|
+
// src/player/components/useTimelineKeyframeData.ts
|
|
10663
|
+
var HIDDEN = {
|
|
10664
|
+
gsapAnimations: /* @__PURE__ */ new Map(),
|
|
10665
|
+
keyframeCache: /* @__PURE__ */ new Map()
|
|
10666
|
+
};
|
|
10667
|
+
function useTimelineKeyframeData(showKeyframes) {
|
|
10668
|
+
const gsapAnimations = usePlayerStore((s) => s.gsapAnimations);
|
|
10669
|
+
const keyframeCache = usePlayerStore((s) => s.keyframeCache);
|
|
10670
|
+
return showKeyframes ? { gsapAnimations, keyframeCache } : HIDDEN;
|
|
10671
|
+
}
|
|
10672
|
+
|
|
10660
10673
|
// src/player/components/useTimelineScrollViewport.ts
|
|
10661
10674
|
import { useCallback as useCallback14, useEffect as useEffect17, useRef as useRef19, useState as useState10 } from "react";
|
|
10662
10675
|
|
|
@@ -12743,6 +12756,7 @@ function useTimelineProviderState({
|
|
|
12743
12756
|
canPasteClip,
|
|
12744
12757
|
theme: themeOverrides,
|
|
12745
12758
|
showAudioEffects = true,
|
|
12759
|
+
showKeyframes = true,
|
|
12746
12760
|
sessionEpoch = 0,
|
|
12747
12761
|
previewIframeRef,
|
|
12748
12762
|
onZIndexReorder
|
|
@@ -12779,8 +12793,9 @@ function useTimelineProviderState({
|
|
|
12779
12793
|
const selectedElementId = usePlayerStore((s) => s.selectedElementId);
|
|
12780
12794
|
const selectedElementIds = usePlayerStore((s) => s.selectedElementIds);
|
|
12781
12795
|
const focusedEaseSegment = usePlayerStore((s) => s.focusedEaseSegment);
|
|
12782
|
-
const gsapAnimations =
|
|
12783
|
-
const
|
|
12796
|
+
const { gsapAnimations, keyframeCache } = useTimelineKeyframeData(showKeyframes);
|
|
12797
|
+
const namedAnimations = usePlayerStore((s) => s.gsapAnimations);
|
|
12798
|
+
const { labelMode, contentOrigin } = useTimelineLabelColumn(namedAnimations, timelineElements);
|
|
12784
12799
|
const setSelectedElementId = usePlayerStore((s) => s.setSelectedElementId);
|
|
12785
12800
|
const currentTime = usePlayerStore((s) => s.currentTime);
|
|
12786
12801
|
const beatDragging = usePlayerStore((s) => s.beatDragging);
|
|
@@ -12805,7 +12820,6 @@ function useTimelineProviderState({
|
|
|
12805
12820
|
() => getEffectiveTimelineDuration(duration, timelineElements),
|
|
12806
12821
|
[duration, timelineElements]
|
|
12807
12822
|
);
|
|
12808
|
-
const keyframeCache = usePlayerStore((s) => s.keyframeCache);
|
|
12809
12823
|
useAutoExpandKeyframedClips(gsapAnimations);
|
|
12810
12824
|
const {
|
|
12811
12825
|
tracks,
|
|
@@ -77132,8 +77146,15 @@ function useGsapAwareEditing({
|
|
|
77132
77146
|
);
|
|
77133
77147
|
const handleGsapAwareBoxSizeCommit = useCallback135(
|
|
77134
77148
|
async (selection, next, offset, restore = () => void 0) => {
|
|
77135
|
-
|
|
77136
|
-
|
|
77149
|
+
let targetAnimations;
|
|
77150
|
+
try {
|
|
77151
|
+
const ownedAnimations = getGsapAnimationsForSelection(selection);
|
|
77152
|
+
targetAnimations = Array.isArray(ownedAnimations) ? ownedAnimations : await ownedAnimations;
|
|
77153
|
+
} catch (error) {
|
|
77154
|
+
restore();
|
|
77155
|
+
trackGsapInteractionFailure(error, selection, "resize", "Resize animated layer");
|
|
77156
|
+
throw error;
|
|
77157
|
+
}
|
|
77137
77158
|
const scaleRoute = targetAnimations.some((anim) => anim.propertyGroup === "scale");
|
|
77138
77159
|
const selector = selectorFromSelection(selection);
|
|
77139
77160
|
const hasLivePositionTween = selector ? hasNonHoldTweenForElement(
|
|
@@ -79389,6 +79410,13 @@ function dispatchPlainKey(event, key2, cb) {
|
|
|
79389
79410
|
usePlayerStore.getState().setActiveTool("select");
|
|
79390
79411
|
return;
|
|
79391
79412
|
}
|
|
79413
|
+
if ((key2 === "[" || key2 === "]") && !event.shiftKey && !event.altKey) {
|
|
79414
|
+
event.preventDefault();
|
|
79415
|
+
const store = usePlayerStore.getState();
|
|
79416
|
+
if (key2 === "[") store.selectLeftward();
|
|
79417
|
+
else store.selectRightward();
|
|
79418
|
+
return;
|
|
79419
|
+
}
|
|
79392
79420
|
if (key2 === "a" && !event.shiftKey && !event.altKey) {
|
|
79393
79421
|
const { activeTool, setActiveTool } = usePlayerStore.getState();
|
|
79394
79422
|
if (activeTool === "razor") {
|
|
@@ -90149,8 +90177,82 @@ function TimelineHistoryButtons(props) {
|
|
|
90149
90177
|
] });
|
|
90150
90178
|
}
|
|
90151
90179
|
|
|
90180
|
+
// src/components/TimelineToolPicker.tsx
|
|
90181
|
+
import { ArrowLineLeft, ArrowLineRight, CaretDown } from "@phosphor-icons/react";
|
|
90182
|
+
import { jsx as jsx225, jsxs as jsxs179 } from "react/jsx-runtime";
|
|
90183
|
+
function SelectIcon() {
|
|
90184
|
+
return /* @__PURE__ */ jsx225("svg", { width: "16", height: "16", viewBox: "0 0 12 12", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx225("path", { d: "M2 0.5L10 6L6.5 6.5L8.5 11L6.5 11.5L4.5 7L2 9Z" }) });
|
|
90185
|
+
}
|
|
90186
|
+
function TimelineToolPicker() {
|
|
90187
|
+
const activeTool = usePlayerStore((s) => s.activeTool);
|
|
90188
|
+
const store = () => usePlayerStore.getState();
|
|
90189
|
+
const rows = [
|
|
90190
|
+
{
|
|
90191
|
+
label: "Select",
|
|
90192
|
+
shortcut: "V",
|
|
90193
|
+
icon: /* @__PURE__ */ jsx225(SelectIcon, {}),
|
|
90194
|
+
active: activeTool === "select",
|
|
90195
|
+
run: () => store().setActiveTool("select")
|
|
90196
|
+
},
|
|
90197
|
+
{
|
|
90198
|
+
label: "Split",
|
|
90199
|
+
shortcut: "B",
|
|
90200
|
+
icon: /* @__PURE__ */ jsx225(Scissors, { size: 16 }),
|
|
90201
|
+
active: activeTool === "razor",
|
|
90202
|
+
run: () => store().setActiveTool("razor")
|
|
90203
|
+
},
|
|
90204
|
+
{
|
|
90205
|
+
label: "Select leftward",
|
|
90206
|
+
shortcut: "[",
|
|
90207
|
+
icon: /* @__PURE__ */ jsx225(ArrowLineLeft, { size: 16, "aria-hidden": "true" }),
|
|
90208
|
+
active: false,
|
|
90209
|
+
run: () => store().selectLeftward()
|
|
90210
|
+
},
|
|
90211
|
+
{
|
|
90212
|
+
label: "Select rightward",
|
|
90213
|
+
shortcut: "]",
|
|
90214
|
+
icon: /* @__PURE__ */ jsx225(ArrowLineRight, { size: 16, "aria-hidden": "true" }),
|
|
90215
|
+
active: false,
|
|
90216
|
+
run: () => store().selectRightward()
|
|
90217
|
+
}
|
|
90218
|
+
];
|
|
90219
|
+
const current = rows.find((row) => row.active) ?? rows[0];
|
|
90220
|
+
return /* @__PURE__ */ jsx225(
|
|
90221
|
+
Menu,
|
|
90222
|
+
{
|
|
90223
|
+
"aria-label": "Timeline tools",
|
|
90224
|
+
trigger: /* @__PURE__ */ jsxs179(
|
|
90225
|
+
"button",
|
|
90226
|
+
{
|
|
90227
|
+
type: "button",
|
|
90228
|
+
"aria-label": `Timeline tool: ${current.label}`,
|
|
90229
|
+
className: cn(flatIdle, "gap-0.5"),
|
|
90230
|
+
children: [
|
|
90231
|
+
current.icon,
|
|
90232
|
+
/* @__PURE__ */ jsx225(CaretDown, { size: 10, weight: "bold", "aria-hidden": "true" })
|
|
90233
|
+
]
|
|
90234
|
+
}
|
|
90235
|
+
),
|
|
90236
|
+
children: rows.map((row) => /* @__PURE__ */ jsx225(
|
|
90237
|
+
MenuItem,
|
|
90238
|
+
{
|
|
90239
|
+
shortcut: row.shortcut,
|
|
90240
|
+
onClick: row.run,
|
|
90241
|
+
"data-active": row.active || void 0,
|
|
90242
|
+
className: row.active ? "bg-neutral-800 text-white" : void 0,
|
|
90243
|
+
children: /* @__PURE__ */ jsxs179("span", { className: "flex items-center gap-2", children: [
|
|
90244
|
+
row.icon,
|
|
90245
|
+
row.label
|
|
90246
|
+
] })
|
|
90247
|
+
},
|
|
90248
|
+
row.label
|
|
90249
|
+
))
|
|
90250
|
+
}
|
|
90251
|
+
);
|
|
90252
|
+
}
|
|
90253
|
+
|
|
90152
90254
|
// src/components/TimelineToolbar.tsx
|
|
90153
|
-
import { Fragment as Fragment63, jsx as
|
|
90255
|
+
import { Fragment as Fragment63, jsx as jsx226, jsxs as jsxs180 } from "react/jsx-runtime";
|
|
90154
90256
|
var NO_KEYFRAME_TOGGLE = {
|
|
90155
90257
|
state: "none",
|
|
90156
90258
|
isMotionPath: false,
|
|
@@ -90212,8 +90314,6 @@ function TimelineToolbar({
|
|
|
90212
90314
|
showAddBeat = true,
|
|
90213
90315
|
showKeyframes = true
|
|
90214
90316
|
}) {
|
|
90215
|
-
const activeTool = usePlayerStore((s) => s.activeTool);
|
|
90216
|
-
const setActiveTool = usePlayerStore((s) => s.setActiveTool);
|
|
90217
90317
|
const timelineSnapEnabled = usePlayerStore((s) => s.timelineSnapEnabled);
|
|
90218
90318
|
const setTimelineSnapEnabled = usePlayerStore((s) => s.setTimelineSnapEnabled);
|
|
90219
90319
|
const rippleEditEnabled = usePlayerStore((s) => s.rippleEditEnabled);
|
|
@@ -90268,33 +90368,12 @@ function TimelineToolbar({
|
|
|
90268
90368
|
return (
|
|
90269
90369
|
// The "TIMELINE" label is dropped for CapCut-like density — the pane's
|
|
90270
90370
|
// position (tracks right below) makes it self-evident.
|
|
90271
|
-
/* @__PURE__ */
|
|
90272
|
-
/* @__PURE__ */
|
|
90273
|
-
/* @__PURE__ */
|
|
90274
|
-
/* @__PURE__ */
|
|
90275
|
-
|
|
90276
|
-
|
|
90277
|
-
type: "button",
|
|
90278
|
-
onClick: () => setActiveTool("select"),
|
|
90279
|
-
"aria-label": "Selection tool",
|
|
90280
|
-
"aria-pressed": activeTool === "select",
|
|
90281
|
-
className: activeTool === "select" ? flatActive : flatIdle,
|
|
90282
|
-
children: /* @__PURE__ */ jsx225("svg", { width: "16", height: "16", viewBox: "0 0 12 12", fill: "currentColor", children: /* @__PURE__ */ jsx225("path", { d: "M2 0.5L10 6L6.5 6.5L8.5 11L6.5 11.5L4.5 7L2 9Z" }) })
|
|
90283
|
-
}
|
|
90284
|
-
) }),
|
|
90285
|
-
/* @__PURE__ */ jsx225(Tooltip, { label: "Razor tool (B) \u2014 Shift+click splits all tracks", children: /* @__PURE__ */ jsx225(
|
|
90286
|
-
"button",
|
|
90287
|
-
{
|
|
90288
|
-
type: "button",
|
|
90289
|
-
onClick: () => setActiveTool("razor"),
|
|
90290
|
-
"aria-label": "Razor tool",
|
|
90291
|
-
"aria-pressed": activeTool === "razor",
|
|
90292
|
-
className: activeTool === "razor" ? flatActive : flatIdle,
|
|
90293
|
-
children: /* @__PURE__ */ jsx225(Scissors, { size: 16 })
|
|
90294
|
-
}
|
|
90295
|
-
) }),
|
|
90296
|
-
/* @__PURE__ */ jsx225("div", { "aria-hidden": "true", className: "mx-1 h-4 w-px bg-neutral-800" }),
|
|
90297
|
-
/* @__PURE__ */ jsx225(Tooltip, { label: timelineSnapEnabled ? "Snapping on (N)" : "Snapping off (N)", children: /* @__PURE__ */ jsx225(
|
|
90371
|
+
/* @__PURE__ */ jsx226("div", { className: "border-b border-neutral-800/60", children: /* @__PURE__ */ jsxs180("div", { className: "flex items-center justify-between px-2 py-0.5", children: [
|
|
90372
|
+
/* @__PURE__ */ jsxs180("div", { className: "flex items-center gap-0.5", children: [
|
|
90373
|
+
/* @__PURE__ */ jsx226(TimelineHistoryButtons, { ...history2 }),
|
|
90374
|
+
/* @__PURE__ */ jsx226(TimelineToolPicker, {}),
|
|
90375
|
+
/* @__PURE__ */ jsx226("div", { "aria-hidden": "true", className: "mx-1 h-4 w-px bg-neutral-800" }),
|
|
90376
|
+
/* @__PURE__ */ jsx226(Tooltip, { label: timelineSnapEnabled ? "Snapping on (N)" : "Snapping off (N)", children: /* @__PURE__ */ jsx226(
|
|
90298
90377
|
"button",
|
|
90299
90378
|
{
|
|
90300
90379
|
type: "button",
|
|
@@ -90302,14 +90381,14 @@ function TimelineToolbar({
|
|
|
90302
90381
|
"aria-label": "Toggle timeline snapping",
|
|
90303
90382
|
"aria-pressed": timelineSnapEnabled,
|
|
90304
90383
|
className: timelineSnapEnabled ? flatActive : flatIdle,
|
|
90305
|
-
children: /* @__PURE__ */
|
|
90384
|
+
children: /* @__PURE__ */ jsx226(Magnet, { size: 16, weight: "bold", "aria-hidden": "true" })
|
|
90306
90385
|
}
|
|
90307
90386
|
) }),
|
|
90308
|
-
/* @__PURE__ */
|
|
90387
|
+
/* @__PURE__ */ jsx226(
|
|
90309
90388
|
Tooltip,
|
|
90310
90389
|
{
|
|
90311
90390
|
label: rippleEditEnabled ? "Ripple on \u2014 keeps the main track gapless" : "Ripple off \u2014 deleting a main-track clip leaves a gap",
|
|
90312
|
-
children: /* @__PURE__ */
|
|
90391
|
+
children: /* @__PURE__ */ jsx226(
|
|
90313
90392
|
"button",
|
|
90314
90393
|
{
|
|
90315
90394
|
type: "button",
|
|
@@ -90317,12 +90396,12 @@ function TimelineToolbar({
|
|
|
90317
90396
|
"aria-label": "Toggle ripple edit",
|
|
90318
90397
|
"aria-pressed": rippleEditEnabled,
|
|
90319
90398
|
className: rippleEditEnabled ? flatActive : flatIdle,
|
|
90320
|
-
children: /* @__PURE__ */
|
|
90399
|
+
children: /* @__PURE__ */ jsx226(RippleEditIcon, { size: 16 })
|
|
90321
90400
|
}
|
|
90322
90401
|
)
|
|
90323
90402
|
}
|
|
90324
90403
|
),
|
|
90325
|
-
projectHasAudio && /* @__PURE__ */
|
|
90404
|
+
projectHasAudio && /* @__PURE__ */ jsx226(Tooltip, { label: audioMetersVisible ? "Hide audio meters" : "Show audio meters", children: /* @__PURE__ */ jsx226(
|
|
90326
90405
|
"button",
|
|
90327
90406
|
{
|
|
90328
90407
|
type: "button",
|
|
@@ -90330,15 +90409,15 @@ function TimelineToolbar({
|
|
|
90330
90409
|
"aria-label": "Toggle audio meters",
|
|
90331
90410
|
"aria-pressed": audioMetersVisible,
|
|
90332
90411
|
className: audioMetersVisible ? flatActive : flatIdle,
|
|
90333
|
-
children: /* @__PURE__ */
|
|
90412
|
+
children: /* @__PURE__ */ jsx226(AudioMetersIcon, { size: 16 })
|
|
90334
90413
|
}
|
|
90335
90414
|
) }),
|
|
90336
|
-
showKeyframes && /* @__PURE__ */
|
|
90337
|
-
/* @__PURE__ */
|
|
90415
|
+
showKeyframes && /* @__PURE__ */ jsxs180(Fragment63, { children: [
|
|
90416
|
+
/* @__PURE__ */ jsx226(
|
|
90338
90417
|
Tooltip,
|
|
90339
90418
|
{
|
|
90340
90419
|
label: keyframePathEndpoint ? "Motion path endpoints cannot be removed" : !onToggleKeyframe ? "Select an animated element to add keyframes" : keyframeIsMotionPath ? keyframeWillExtend ? "Extend motion path to playhead (K)" : keyframeState === "active" ? "Remove waypoint from motion path (K)" : "Add waypoint to motion path (K)" : keyframeState === "active" ? "Remove keyframe at playhead (K)" : keyframeState === "inactive" ? keyframeWillExtend ? "Add keyframe at playhead, extends animation (K)" : "Add keyframe at playhead (K)" : "Add keyframe (K)",
|
|
90341
|
-
children: /* @__PURE__ */
|
|
90420
|
+
children: /* @__PURE__ */ jsx226(
|
|
90342
90421
|
"button",
|
|
90343
90422
|
{
|
|
90344
90423
|
type: "button",
|
|
@@ -90346,7 +90425,7 @@ function TimelineToolbar({
|
|
|
90346
90425
|
onClick: onToggleKeyframe,
|
|
90347
90426
|
"aria-label": keyframePathEndpoint ? "Motion path endpoint" : keyframeIsMotionPath ? keyframeState === "active" ? "Remove motion path waypoint" : keyframeWillExtend ? "Extend motion path to playhead" : "Add motion path waypoint" : keyframeState === "active" ? "Remove keyframe at playhead" : "Add keyframe at playhead",
|
|
90348
90427
|
className: !onToggleKeyframe ? flatDisabled : `${flatBtn} active:scale-[0.98] hover:bg-white/6 ${keyframeState === "active" ? "text-studio-accent" : keyframeState === "inactive" ? "text-neutral-400 hover:text-studio-accent" : "text-neutral-600 hover:text-neutral-400"}`,
|
|
90349
|
-
children: /* @__PURE__ */
|
|
90428
|
+
children: /* @__PURE__ */ jsx226("svg", { width: "16", height: "16", viewBox: "0 0 10 10", fill: "currentColor", children: keyframeState === "active" ? /* @__PURE__ */ jsx226("path", { d: "M5 0.5L9.5 5L5 9.5L0.5 5Z" }) : /* @__PURE__ */ jsx226(
|
|
90350
90429
|
"path",
|
|
90351
90430
|
{
|
|
90352
90431
|
d: "M5 1.2L8.8 5L5 8.8L1.2 5Z",
|
|
@@ -90359,11 +90438,11 @@ function TimelineToolbar({
|
|
|
90359
90438
|
)
|
|
90360
90439
|
}
|
|
90361
90440
|
),
|
|
90362
|
-
/* @__PURE__ */
|
|
90441
|
+
/* @__PURE__ */ jsx226(
|
|
90363
90442
|
Tooltip,
|
|
90364
90443
|
{
|
|
90365
90444
|
label: autoKeyframeEnabled ? "Auto-record manual edits as keyframes (click to turn off)" : "Manual edits will not be recorded as keyframes (click to turn on)",
|
|
90366
|
-
children: /* @__PURE__ */
|
|
90445
|
+
children: /* @__PURE__ */ jsx226(
|
|
90367
90446
|
"button",
|
|
90368
90447
|
{
|
|
90369
90448
|
type: "button",
|
|
@@ -90371,9 +90450,9 @@ function TimelineToolbar({
|
|
|
90371
90450
|
"aria-label": "Auto-record manual edits as keyframes",
|
|
90372
90451
|
"aria-pressed": autoKeyframeEnabled,
|
|
90373
90452
|
className: `${flatBtn} active:scale-[0.98] hover:bg-white/6 ${autoKeyframeEnabled ? "text-red-400 hover:text-red-300" : "text-neutral-600 hover:text-neutral-400"}`,
|
|
90374
|
-
children: /* @__PURE__ */
|
|
90375
|
-
/* @__PURE__ */
|
|
90376
|
-
/* @__PURE__ */
|
|
90453
|
+
children: /* @__PURE__ */ jsxs180("svg", { width: "16", height: "16", viewBox: "0 0 10 10", fill: "none", children: [
|
|
90454
|
+
/* @__PURE__ */ jsx226("path", { d: "M5 0.7L9.3 5L5 9.3L0.7 5Z", stroke: "currentColor", strokeWidth: "1" }),
|
|
90455
|
+
/* @__PURE__ */ jsx226(
|
|
90377
90456
|
"circle",
|
|
90378
90457
|
{
|
|
90379
90458
|
cx: "5",
|
|
@@ -90394,11 +90473,11 @@ function TimelineToolbar({
|
|
|
90394
90473
|
const el = selectedElementId ? elements.find((e) => (e.key ?? e.id) === selectedElementId) : null;
|
|
90395
90474
|
const splittable = el != null && canSplitElement(el);
|
|
90396
90475
|
const canSplit = splittable && currentTime > el.start && currentTime < el.start + el.duration;
|
|
90397
|
-
return /* @__PURE__ */
|
|
90476
|
+
return /* @__PURE__ */ jsx226(
|
|
90398
90477
|
Tooltip,
|
|
90399
90478
|
{
|
|
90400
90479
|
label: canSplit ? "Split at playhead (S)" : splittable ? "Move the playhead inside the clip to split" : "Select a clip to split",
|
|
90401
|
-
children: /* @__PURE__ */
|
|
90480
|
+
children: /* @__PURE__ */ jsx226(
|
|
90402
90481
|
"button",
|
|
90403
90482
|
{
|
|
90404
90483
|
type: "button",
|
|
@@ -90408,7 +90487,7 @@ function TimelineToolbar({
|
|
|
90408
90487
|
if (canSplit && el) onSplitElement(el, currentTime);
|
|
90409
90488
|
},
|
|
90410
90489
|
className: canSplit ? flatIdle : flatDisabled,
|
|
90411
|
-
children: /* @__PURE__ */
|
|
90490
|
+
children: /* @__PURE__ */ jsxs180(
|
|
90412
90491
|
"svg",
|
|
90413
90492
|
{
|
|
90414
90493
|
width: "16",
|
|
@@ -90421,8 +90500,8 @@ function TimelineToolbar({
|
|
|
90421
90500
|
strokeLinejoin: "round",
|
|
90422
90501
|
"aria-hidden": "true",
|
|
90423
90502
|
children: [
|
|
90424
|
-
/* @__PURE__ */
|
|
90425
|
-
/* @__PURE__ */
|
|
90503
|
+
/* @__PURE__ */ jsx226("path", { d: "M5 3 L7 3 L7 13 L5 13" }),
|
|
90504
|
+
/* @__PURE__ */ jsx226("path", { d: "M11 3 L9 3 L9 13 L11 13" })
|
|
90426
90505
|
]
|
|
90427
90506
|
}
|
|
90428
90507
|
)
|
|
@@ -90434,11 +90513,11 @@ function TimelineToolbar({
|
|
|
90434
90513
|
(() => {
|
|
90435
90514
|
if (!showAddBeat) return null;
|
|
90436
90515
|
const canAdd = beatAnalysisReady && canAddBeatAt(currentTime);
|
|
90437
|
-
return /* @__PURE__ */
|
|
90516
|
+
return /* @__PURE__ */ jsx226(
|
|
90438
90517
|
Tooltip,
|
|
90439
90518
|
{
|
|
90440
90519
|
label: !beatAnalysisReady ? "Add a music track with beat analysis to place beats" : canAdd ? "Add beat at playhead" : "A beat already exists at the playhead",
|
|
90441
|
-
children: /* @__PURE__ */
|
|
90520
|
+
children: /* @__PURE__ */ jsx226(
|
|
90442
90521
|
"button",
|
|
90443
90522
|
{
|
|
90444
90523
|
type: "button",
|
|
@@ -90448,7 +90527,7 @@ function TimelineToolbar({
|
|
|
90448
90527
|
if (canAdd) addBeatAtCompositionTime(currentTime);
|
|
90449
90528
|
},
|
|
90450
90529
|
className: canAdd ? `${flatBtn} text-neutral-400 hover:bg-white/6 hover:text-[#22c55e] active:scale-[0.98]` : flatDisabled,
|
|
90451
|
-
children: /* @__PURE__ */
|
|
90530
|
+
children: /* @__PURE__ */ jsx226("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx226(
|
|
90452
90531
|
"path",
|
|
90453
90532
|
{
|
|
90454
90533
|
d: "M21 10C21 12.2091 16.9706 14 12 14M21 10C21 7.79086 16.9706 6 12 6C7.02944 6 3 7.79086 3 10M21 10V16C21 18.2091 16.9706 20 12 20M12 14C7.02944 14 3 12.2091 3 10M12 14V20M3 10V16C3 18.2091 7.02944 20 12 20M7 19.3264V13.3264M17 19.3264V13.3264M12 10L20 4",
|
|
@@ -90464,12 +90543,12 @@ function TimelineToolbar({
|
|
|
90464
90543
|
);
|
|
90465
90544
|
})()
|
|
90466
90545
|
] }),
|
|
90467
|
-
/* @__PURE__ */
|
|
90468
|
-
/* @__PURE__ */
|
|
90546
|
+
/* @__PURE__ */ jsxs180("div", { className: "flex items-center gap-0.5", children: [
|
|
90547
|
+
/* @__PURE__ */ jsx226(
|
|
90469
90548
|
Tooltip,
|
|
90470
90549
|
{
|
|
90471
90550
|
label: thumbnailsVisible ? "Hide thumbnails \u2014 labels only" : "Show thumbnails \u2014 posters stay visible; richer previews appear on interaction",
|
|
90472
|
-
children: /* @__PURE__ */
|
|
90551
|
+
children: /* @__PURE__ */ jsx226(
|
|
90473
90552
|
"button",
|
|
90474
90553
|
{
|
|
90475
90554
|
type: "button",
|
|
@@ -90477,12 +90556,12 @@ function TimelineToolbar({
|
|
|
90477
90556
|
"aria-pressed": thumbnailsVisible,
|
|
90478
90557
|
onClick: () => setThumbnailMode(thumbnailsVisible ? "hidden" : "adaptive"),
|
|
90479
90558
|
className: `h-7 px-2 rounded-md text-[11px] font-medium transition-colors ${thumbnailsVisible ? "bg-studio-accent/10 text-studio-accent" : "text-neutral-400 hover:bg-white/6 hover:text-neutral-200"}`,
|
|
90480
|
-
children: /* @__PURE__ */
|
|
90559
|
+
children: /* @__PURE__ */ jsx226(Image3, { size: 16, "aria-hidden": "true" })
|
|
90481
90560
|
}
|
|
90482
90561
|
)
|
|
90483
90562
|
}
|
|
90484
90563
|
),
|
|
90485
|
-
/* @__PURE__ */
|
|
90564
|
+
/* @__PURE__ */ jsx226(Tooltip, { label: "Fit timeline to width", children: /* @__PURE__ */ jsx226(
|
|
90486
90565
|
"button",
|
|
90487
90566
|
{
|
|
90488
90567
|
type: "button",
|
|
@@ -90490,10 +90569,10 @@ function TimelineToolbar({
|
|
|
90490
90569
|
"aria-label": "Fit timeline to width",
|
|
90491
90570
|
"aria-pressed": zoomMode === "fit",
|
|
90492
90571
|
className: `h-7 px-2 rounded-md text-[11px] font-medium transition-colors ${zoomMode === "fit" ? "bg-studio-accent/10 text-studio-accent" : "text-neutral-400 hover:bg-white/6 hover:text-neutral-200"}`,
|
|
90493
|
-
children: /* @__PURE__ */
|
|
90572
|
+
children: /* @__PURE__ */ jsx226(ArrowsOutLineHorizontal, { size: 16, "aria-hidden": "true" })
|
|
90494
90573
|
}
|
|
90495
90574
|
) }),
|
|
90496
|
-
/* @__PURE__ */
|
|
90575
|
+
/* @__PURE__ */ jsx226(Tooltip, { label: "Zoom out", children: /* @__PURE__ */ jsx226(
|
|
90497
90576
|
"button",
|
|
90498
90577
|
{
|
|
90499
90578
|
type: "button",
|
|
@@ -90505,10 +90584,10 @@ function TimelineToolbar({
|
|
|
90505
90584
|
);
|
|
90506
90585
|
},
|
|
90507
90586
|
className: flatIdle,
|
|
90508
|
-
children: /* @__PURE__ */
|
|
90587
|
+
children: /* @__PURE__ */ jsx226(MagnifyingGlassMinus, { size: 16, "aria-hidden": "true" })
|
|
90509
90588
|
}
|
|
90510
90589
|
) }),
|
|
90511
|
-
/* @__PURE__ */
|
|
90590
|
+
/* @__PURE__ */ jsx226(
|
|
90512
90591
|
"input",
|
|
90513
90592
|
{
|
|
90514
90593
|
type: "range",
|
|
@@ -90526,7 +90605,7 @@ function TimelineToolbar({
|
|
|
90526
90605
|
className: "mx-1 h-6 w-[96px] cursor-pointer appearance-none bg-transparent [&::-webkit-slider-runnable-track]:h-[2px] [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-neutral-700 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-[10px] [&::-webkit-slider-thumb]:h-[10px] [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:-mt-1 [&::-webkit-slider-thumb]:shadow-[0_0_0_2px_#0a0a0a,0_1px_3px_rgba(0,0,0,0.5)] [&::-webkit-slider-thumb]:cursor-grab [&::-webkit-slider-thumb:active]:cursor-grabbing"
|
|
90527
90606
|
}
|
|
90528
90607
|
),
|
|
90529
|
-
/* @__PURE__ */
|
|
90608
|
+
/* @__PURE__ */ jsx226(Tooltip, { label: "Zoom in", children: /* @__PURE__ */ jsx226(
|
|
90530
90609
|
"button",
|
|
90531
90610
|
{
|
|
90532
90611
|
type: "button",
|
|
@@ -90538,10 +90617,10 @@ function TimelineToolbar({
|
|
|
90538
90617
|
);
|
|
90539
90618
|
},
|
|
90540
90619
|
className: flatIdle,
|
|
90541
|
-
children: /* @__PURE__ */
|
|
90620
|
+
children: /* @__PURE__ */ jsx226(MagnifyingGlassPlus, { size: 16, "aria-hidden": "true" })
|
|
90542
90621
|
}
|
|
90543
90622
|
) }),
|
|
90544
|
-
/* @__PURE__ */
|
|
90623
|
+
/* @__PURE__ */ jsx226(
|
|
90545
90624
|
"span",
|
|
90546
90625
|
{
|
|
90547
90626
|
className: "ml-1 w-[38px] text-right font-mono text-[11px] tabular-nums text-neutral-500 select-none",
|
|
@@ -90555,18 +90634,18 @@ function TimelineToolbar({
|
|
|
90555
90634
|
}
|
|
90556
90635
|
|
|
90557
90636
|
// src/components/StudioSplash.tsx
|
|
90558
|
-
import { jsx as
|
|
90637
|
+
import { jsx as jsx227, jsxs as jsxs181 } from "react/jsx-runtime";
|
|
90559
90638
|
function StudioSplash({ waiting }) {
|
|
90560
|
-
return /* @__PURE__ */
|
|
90561
|
-
/* @__PURE__ */
|
|
90562
|
-
/* @__PURE__ */
|
|
90639
|
+
return /* @__PURE__ */ jsx227("div", { className: "h-full w-full bg-neutral-950 flex items-center justify-center", children: waiting ? /* @__PURE__ */ jsxs181("div", { className: "flex flex-col items-center gap-3 text-center px-6", role: "status", children: [
|
|
90640
|
+
/* @__PURE__ */ jsx227("div", { className: "w-4 h-4 rounded-full border-2 border-neutral-700 border-t-neutral-500 animate-spin motion-reduce:animate-none" }),
|
|
90641
|
+
/* @__PURE__ */ jsxs181("p", { className: "text-xs text-neutral-600", children: [
|
|
90563
90642
|
"Waiting for preview server\u2026 run",
|
|
90564
90643
|
" ",
|
|
90565
|
-
/* @__PURE__ */
|
|
90644
|
+
/* @__PURE__ */ jsx227("code", { className: "text-neutral-500 font-mono", children: "npm run dev" })
|
|
90566
90645
|
] })
|
|
90567
|
-
] }) : /* @__PURE__ */
|
|
90568
|
-
/* @__PURE__ */
|
|
90569
|
-
/* @__PURE__ */
|
|
90646
|
+
] }) : /* @__PURE__ */ jsxs181("div", { className: "flex flex-col items-center gap-3 text-center px-6", role: "status", children: [
|
|
90647
|
+
/* @__PURE__ */ jsx227("div", { className: "w-4 h-4 rounded-full bg-studio-accent animate-pulse motion-reduce:animate-none" }),
|
|
90648
|
+
/* @__PURE__ */ jsx227("p", { className: "text-xs text-neutral-600", children: "Connecting to project\u2026" })
|
|
90570
90649
|
] }) });
|
|
90571
90650
|
}
|
|
90572
90651
|
|
|
@@ -90833,7 +90912,7 @@ function useActiveComposition({
|
|
|
90833
90912
|
}
|
|
90834
90913
|
|
|
90835
90914
|
// src/App.tsx
|
|
90836
|
-
import { Fragment as Fragment64, jsx as
|
|
90915
|
+
import { Fragment as Fragment64, jsx as jsx228, jsxs as jsxs182 } from "react/jsx-runtime";
|
|
90837
90916
|
var getTimelineSelectionSet = () => usePlayerStore.getState().selectedElementIds;
|
|
90838
90917
|
function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
90839
90918
|
const { projectId, resolving, waitingForServer } = useServerConnection();
|
|
@@ -91197,7 +91276,7 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
91197
91276
|
refreshPreviewDocumentVersion
|
|
91198
91277
|
});
|
|
91199
91278
|
const timelineToolbar = useMemo79(
|
|
91200
|
-
() => /* @__PURE__ */
|
|
91279
|
+
() => /* @__PURE__ */ jsx228(
|
|
91201
91280
|
TimelineToolbar,
|
|
91202
91281
|
{
|
|
91203
91282
|
domEditSession,
|
|
@@ -91207,15 +91286,15 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
91207
91286
|
[domEditSession, timelineEditing.handleTimelineElementSplit]
|
|
91208
91287
|
);
|
|
91209
91288
|
if (resolving || waitingForServer || !projectId)
|
|
91210
|
-
return /* @__PURE__ */
|
|
91211
|
-
return /* @__PURE__ */
|
|
91289
|
+
return /* @__PURE__ */ jsx228(StudioSplash, { waiting: waitingForServer });
|
|
91290
|
+
return /* @__PURE__ */ jsx228(StudioShellProvider, { value: studioCtxValue, children: /* @__PURE__ */ jsx228(StudioPlaybackProvider, { value: studioCtxValue, children: /* @__PURE__ */ jsx228(PanelLayoutProvider, { value: layout, children: /* @__PURE__ */ jsx228(FileManagerProvider, { value: fileManager, children: /* @__PURE__ */ jsx228(DomEditProvider, { value: domEditSession, children: /* @__PURE__ */ jsxs182(
|
|
91212
91291
|
"div",
|
|
91213
91292
|
{
|
|
91214
91293
|
className: "flex flex-col h-full w-full bg-neutral-950 relative",
|
|
91215
91294
|
onDragOver: fileDrop.onDragOver,
|
|
91216
91295
|
onDrop: fileDrop.onDrop,
|
|
91217
91296
|
children: [
|
|
91218
|
-
/* @__PURE__ */
|
|
91297
|
+
/* @__PURE__ */ jsx228(
|
|
91219
91298
|
StudioHeader,
|
|
91220
91299
|
{
|
|
91221
91300
|
captureFrameHref: frameCapture.captureFrameHref,
|
|
@@ -91233,23 +91312,23 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
91233
91312
|
}
|
|
91234
91313
|
}
|
|
91235
91314
|
),
|
|
91236
|
-
previewPersistence.domEditSaveQueuePaused && !externalFileChanges.blocked && /* @__PURE__ */
|
|
91315
|
+
previewPersistence.domEditSaveQueuePaused && !externalFileChanges.blocked && /* @__PURE__ */ jsx228(
|
|
91237
91316
|
SaveQueuePausedBanner,
|
|
91238
91317
|
{
|
|
91239
91318
|
message: previewPersistence.domEditSaveQueuePaused,
|
|
91240
91319
|
onRetry: previewPersistence.resetDomEditSaveQueueBreaker
|
|
91241
91320
|
}
|
|
91242
91321
|
),
|
|
91243
|
-
/* @__PURE__ */
|
|
91244
|
-
sdkHandle.unreachableProject && /* @__PURE__ */
|
|
91245
|
-
sdkHandle.compositionMissing && activeCompPath && /* @__PURE__ */
|
|
91246
|
-
/* @__PURE__ */
|
|
91322
|
+
/* @__PURE__ */ jsx228(ExternalFileConflictBanner, { coordinator: externalFileChanges }),
|
|
91323
|
+
sdkHandle.unreachableProject && /* @__PURE__ */ jsx228(ProjectUnreachableBanner, { projectId: sdkHandle.unreachableProject }),
|
|
91324
|
+
sdkHandle.compositionMissing && activeCompPath && /* @__PURE__ */ jsx228(CompositionMissingBanner, { path: activeCompPath }),
|
|
91325
|
+
/* @__PURE__ */ jsx228(
|
|
91247
91326
|
EditorShell,
|
|
91248
91327
|
{
|
|
91249
91328
|
readOnlyPreview,
|
|
91250
91329
|
readOnlyPreviewReason,
|
|
91251
|
-
panels: /* @__PURE__ */
|
|
91252
|
-
/* @__PURE__ */
|
|
91330
|
+
panels: /* @__PURE__ */ jsxs182(Fragment64, { children: [
|
|
91331
|
+
/* @__PURE__ */ jsx228(
|
|
91253
91332
|
StudioLeftPanels,
|
|
91254
91333
|
{
|
|
91255
91334
|
onSelectComposition: handleSelectComposition,
|
|
@@ -91264,7 +91343,7 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
91264
91343
|
onAddCompositionToTimeline: handleAddCompositionAtPlayhead
|
|
91265
91344
|
}
|
|
91266
91345
|
),
|
|
91267
|
-
/* @__PURE__ */
|
|
91346
|
+
/* @__PURE__ */ jsx228(
|
|
91268
91347
|
StudioRightPanels,
|
|
91269
91348
|
{
|
|
91270
91349
|
activeBlockParams,
|
|
@@ -91319,7 +91398,7 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
91319
91398
|
recordingState: gestureState,
|
|
91320
91399
|
onToggleRecording: handleToggleRecording,
|
|
91321
91400
|
blockPreview,
|
|
91322
|
-
gestureOverlay: gestureState === "recording" && previewIframe ? /* @__PURE__ */
|
|
91401
|
+
gestureOverlay: gestureState === "recording" && previewIframe ? /* @__PURE__ */ jsx228(
|
|
91323
91402
|
GestureTrailOverlay,
|
|
91324
91403
|
{
|
|
91325
91404
|
samples: gestureRecording.samplesRef.current,
|
|
@@ -91332,7 +91411,7 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
91332
91411
|
) : void 0
|
|
91333
91412
|
}
|
|
91334
91413
|
),
|
|
91335
|
-
/* @__PURE__ */
|
|
91414
|
+
/* @__PURE__ */ jsx228(
|
|
91336
91415
|
StudioOverlays,
|
|
91337
91416
|
{
|
|
91338
91417
|
projectId,
|
|
@@ -91760,6 +91839,101 @@ function useDomStyleCommit({
|
|
|
91760
91839
|
return { commitStyle, waitForPendingSaves: queue2.waitForIdle };
|
|
91761
91840
|
}
|
|
91762
91841
|
|
|
91842
|
+
// src/hooks/useDomGeometryCommit.ts
|
|
91843
|
+
import { useCallback as useCallback185, useMemo as useMemo81, useRef as useRef183 } from "react";
|
|
91844
|
+
var noop2 = () => {
|
|
91845
|
+
};
|
|
91846
|
+
var NO_SELECTED_ANIMATIONS = [];
|
|
91847
|
+
var noDomBoxSizeRoute = () => Promise.reject(new Error("Resize has no DOM route here"));
|
|
91848
|
+
function useDomGeometryCommit({
|
|
91849
|
+
projectId,
|
|
91850
|
+
iframeRef,
|
|
91851
|
+
writeProjectFile,
|
|
91852
|
+
recordEdit,
|
|
91853
|
+
activeCompPath = null,
|
|
91854
|
+
showToast = noop2,
|
|
91855
|
+
reloadPreview
|
|
91856
|
+
}) {
|
|
91857
|
+
const projectIdRef = useRef183(projectId);
|
|
91858
|
+
projectIdRef.current = projectId;
|
|
91859
|
+
const pending2 = useRef183(/* @__PURE__ */ new Set()).current;
|
|
91860
|
+
const editHistory = useMemo81(() => ({ recordEdit }), [recordEdit]);
|
|
91861
|
+
const reload = useCallback185(
|
|
91862
|
+
() => reloadPreview ? reloadPreview() : iframeRef.current?.contentWindow?.location.reload(),
|
|
91863
|
+
[reloadPreview, iframeRef]
|
|
91864
|
+
);
|
|
91865
|
+
const { bump: bumpGsapCache } = useGsapCacheVersion();
|
|
91866
|
+
const gsap3 = useGsapScriptCommits({
|
|
91867
|
+
projectIdRef,
|
|
91868
|
+
activeCompPath,
|
|
91869
|
+
previewIframeRef: iframeRef,
|
|
91870
|
+
editHistory,
|
|
91871
|
+
reloadPreview: reload,
|
|
91872
|
+
onCacheInvalidate: bumpGsapCache,
|
|
91873
|
+
showToast,
|
|
91874
|
+
writeProjectFile
|
|
91875
|
+
});
|
|
91876
|
+
const makeFetchFallback = useGsapAnimationFetchFallback(projectId);
|
|
91877
|
+
const trackGsapInteractionFailure = useGsapInteractionFailureTelemetry(activeCompPath, showToast);
|
|
91878
|
+
const {
|
|
91879
|
+
handleGsapAwarePathOffsetCommit,
|
|
91880
|
+
handleGsapAwareGroupPathOffsetCommit,
|
|
91881
|
+
handleGsapAwareBoxSizeCommit,
|
|
91882
|
+
handleGsapAwareRotationCommit
|
|
91883
|
+
} = useGsapAwareEditing({
|
|
91884
|
+
// The host owns selection, so every gesture reads its element's animations from the server.
|
|
91885
|
+
domEditSelection: null,
|
|
91886
|
+
selectedGsapAnimations: NO_SELECTED_ANIMATIONS,
|
|
91887
|
+
gsapCommitMutation: gsap3.commitMutation,
|
|
91888
|
+
previewIframeRef: iframeRef,
|
|
91889
|
+
showToast,
|
|
91890
|
+
bumpGsapCache,
|
|
91891
|
+
makeFetchFallback,
|
|
91892
|
+
trackGsapInteractionFailure,
|
|
91893
|
+
handleDomBoxSizeCommit: noDomBoxSizeRoute,
|
|
91894
|
+
addGsapAnimation: gsap3.addGsapAnimation,
|
|
91895
|
+
convertToKeyframes: gsap3.convertToKeyframes,
|
|
91896
|
+
setArcPath: gsap3.setArcPath,
|
|
91897
|
+
updateArcSegment: gsap3.updateArcSegment
|
|
91898
|
+
});
|
|
91899
|
+
const saved2 = useCallback185(
|
|
91900
|
+
async (commit, restore = noop2) => {
|
|
91901
|
+
const refusal2 = !projectIdRef.current ? "No project is open" : !isPreviewBooted(projectIdRef.current) ? "The preview for this project has not loaded yet" : null;
|
|
91902
|
+
if (refusal2) {
|
|
91903
|
+
restore();
|
|
91904
|
+
showToast(refusal2, "error");
|
|
91905
|
+
throw new Error(refusal2);
|
|
91906
|
+
}
|
|
91907
|
+
const run = commit();
|
|
91908
|
+
pending2.add(run);
|
|
91909
|
+
try {
|
|
91910
|
+
await run;
|
|
91911
|
+
} finally {
|
|
91912
|
+
pending2.delete(run);
|
|
91913
|
+
}
|
|
91914
|
+
return { ok: true };
|
|
91915
|
+
},
|
|
91916
|
+
[pending2, showToast]
|
|
91917
|
+
);
|
|
91918
|
+
return useMemo81(
|
|
91919
|
+
() => ({
|
|
91920
|
+
commitPathOffset: (selection, next, modifiers) => saved2(() => handleGsapAwarePathOffsetCommit(selection, next, modifiers)),
|
|
91921
|
+
commitGroupPathOffset: (updates) => saved2(() => handleGsapAwareGroupPathOffsetCommit(updates)),
|
|
91922
|
+
commitBoxSize: (selection, next, offset, restore) => saved2(() => handleGsapAwareBoxSizeCommit(selection, next, offset, restore), restore),
|
|
91923
|
+
commitRotation: (selection, next) => saved2(() => handleGsapAwareRotationCommit(selection, next)),
|
|
91924
|
+
waitForPendingSaves: () => Promise.allSettled([...pending2]).then(noop2)
|
|
91925
|
+
}),
|
|
91926
|
+
[
|
|
91927
|
+
saved2,
|
|
91928
|
+
pending2,
|
|
91929
|
+
handleGsapAwarePathOffsetCommit,
|
|
91930
|
+
handleGsapAwareGroupPathOffsetCommit,
|
|
91931
|
+
handleGsapAwareBoxSizeCommit,
|
|
91932
|
+
handleGsapAwareRotationCommit
|
|
91933
|
+
]
|
|
91934
|
+
);
|
|
91935
|
+
}
|
|
91936
|
+
|
|
91763
91937
|
// src/index.ts
|
|
91764
91938
|
import {
|
|
91765
91939
|
playSeamTransitionLoop
|
|
@@ -91869,6 +92043,7 @@ export {
|
|
|
91869
92043
|
useCompositionStack,
|
|
91870
92044
|
useDomEditSelectionContext,
|
|
91871
92045
|
useDomEditSession,
|
|
92046
|
+
useDomGeometryCommit,
|
|
91872
92047
|
useDomStyleCommit,
|
|
91873
92048
|
useEditHistoryActions,
|
|
91874
92049
|
useElementPicker,
|