@hyperframes/studio 0.8.46 → 0.8.48
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-CtVX6jL_.js +464 -0
- package/dist/assets/{index-CbchRscN.js → index-B3-orIjW.js} +1 -1
- package/dist/assets/index-B9LfWNyM.css +1 -0
- package/dist/assets/index-C9gJKpqQ.js +441 -0
- package/dist/assets/{index-BywY2OM3.js → index-D_j-0PD3.js} +1 -1
- package/dist/index.d.ts +83 -26
- package/dist/index.html +2 -2
- package/dist/index.js +1118 -661
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/App.tsx +17 -26
- package/src/components/AskAgentModal.tsx +9 -7
- package/src/components/TimelineToolbar.tsx +26 -1
- package/src/components/editor/PropertyPanelFlat.tsx +8 -8
- package/src/components/editor/domEditing.ts +7 -1
- package/src/components/editor/domEditingAgentPrompt.test.ts +199 -0
- package/src/components/editor/domEditingAgentPrompt.ts +136 -34
- package/src/components/editor/manualEditingAvailability.test.ts +19 -0
- package/src/components/editor/manualEditingAvailability.ts +9 -5
- package/src/components/editor/propertyPanelAutomation.test.ts +82 -1
- package/src/components/editor/propertyPanelAutomation.ts +15 -0
- package/src/components/editor/propertyPanelFlatMediaSection.test.tsx +35 -0
- package/src/components/editor/propertyPanelFlatMediaSection.tsx +23 -9
- package/src/components/editor/useVolumeAutomation.test.tsx +81 -10
- package/src/components/editor/useVolumeAutomation.ts +23 -2
- package/src/components/panels/VariablesPanel.tsx +5 -8
- package/src/components/sidebar/CompositionsTab.rootBadge.test.tsx +59 -0
- package/src/components/sidebar/CompositionsTab.tsx +15 -0
- package/src/components/sidebar/LeftSidebar.masterComposition.test.tsx +47 -0
- package/src/components/sidebar/LeftSidebar.tsx +7 -0
- package/src/contexts/FileManagerContext.tsx +0 -3
- package/src/hooks/appHotkeysDispatch.ts +256 -0
- package/src/hooks/domEditDeleteMembers.test.ts +30 -0
- package/src/hooks/domEditDeleteMembers.ts +19 -0
- package/src/hooks/useActiveComposition.ts +69 -0
- package/src/hooks/useAppHotkeys.test.ts +23 -1
- package/src/hooks/useAppHotkeys.ts +6 -239
- package/src/hooks/useAutoOpenRootComposition.test.tsx +151 -0
- package/src/hooks/useAutoOpenRootComposition.ts +33 -0
- package/src/hooks/useDomEditCommits.ts +13 -15
- package/src/hooks/useDomEditSession.test.tsx +90 -1
- package/src/hooks/useDomEditSession.ts +31 -34
- package/src/hooks/useDomSelectionTypes.ts +7 -2
- package/src/hooks/useElementLifecycleOps.ts +0 -8
- package/src/hooks/useFileManager.projectOwnership.test.tsx +0 -1
- package/src/hooks/useFileManager.ts +0 -2
- package/src/hooks/useFileTree.test.tsx +214 -0
- package/src/hooks/useFileTree.ts +66 -24
- package/src/hooks/useGroupCommits.test.ts +98 -0
- package/src/hooks/useGroupCommits.ts +66 -9
- package/src/hooks/useResetSelectionOnProjectSwitch.test.tsx +234 -0
- package/src/hooks/useResetSelectionOnProjectSwitch.ts +34 -0
- package/src/hooks/useSdkSession.lifecycle.test.tsx +76 -0
- package/src/hooks/useSdkSession.ts +21 -3
- package/src/hooks/useTimelineAssetDropOps.test.tsx +72 -0
- package/src/hooks/useTimelineAssetDropOps.ts +20 -16
- package/src/hooks/useTimelineDeleteOps.test.tsx +119 -0
- package/src/hooks/useTimelineDeleteOps.ts +103 -9
- package/src/hooks/useTimelineEditing.ts +1 -0
- package/src/hooks/useTimelineGroupEditing.test.tsx +74 -0
- package/src/hooks/useTimelineGroupEditing.ts +19 -5
- package/src/index.ts +10 -0
- package/src/player/components/Timeline.test.ts +0 -4
- package/src/player/components/Timeline.tsx +0 -1
- package/src/player/components/TimelineAutomationLaneSlot.tsx +4 -2
- package/src/player/components/TimelineClipDiamonds.test.tsx +13 -1
- package/src/player/components/TimelineDiamondConnectors.test.ts +16 -0
- package/src/player/components/TimelineDiamondConnectors.tsx +17 -1
- package/src/player/components/TimelinePropertyLanes.test.tsx +1 -1
- package/src/player/components/automationLaneData.test.ts +11 -3
- package/src/player/components/automationLaneData.ts +5 -4
- package/src/player/components/automationLaneGeometry.ts +15 -0
- package/src/player/components/timelineDragDrop.test.tsx +21 -4
- package/src/player/components/timelineDragDrop.ts +9 -25
- package/src/player/components/timelineGapCommit.test.ts +96 -0
- package/src/player/components/timelineGapCommit.ts +56 -11
- package/src/player/components/timelineGaps.ts +2 -2
- package/src/player/components/timelineLayout.test.ts +0 -1
- package/src/player/components/timelineLayout.ts +1 -6
- package/src/player/components/timelineZones.test.ts +20 -1
- package/src/player/components/timelineZones.ts +10 -3
- package/src/player/components/useAutomationLaneGestures.ts +2 -10
- package/src/player/components/useTimelineTrackLayout.ts +7 -6
- package/src/player/hooks/usePlaybackKeyboard.test.ts +34 -0
- package/src/player/hooks/usePlaybackKeyboard.ts +13 -0
- package/src/player/hooks/useTimelinePlayer.ts +9 -4
- package/src/player/hooks/useTimelineSyncCallbacks.ts +7 -4
- package/src/player/lib/timelineIframeHelpers.test.ts +22 -0
- package/src/player/lib/timelineIframeHelpers.ts +1 -0
- package/src/player/store/playerStore.test.ts +42 -0
- package/src/player/store/playerStore.ts +25 -28
- package/src/player/store/readinessSlice.ts +42 -0
- package/src/utils/razorSplitTransaction.test.ts +10 -0
- package/src/utils/razorSplitTransaction.ts +5 -0
- package/src/utils/sdkCutover.gate.test.ts +5 -4
- package/src/utils/sdkCutover.test.ts +93 -0
- package/src/utils/sdkCutover.ts +46 -25
- package/src/utils/sdkCutoverEligibility.ts +21 -0
- package/src/utils/sdkCutoverPolicy.test.ts +11 -2
- package/src/utils/sdkCutoverPolicy.ts +5 -3
- package/src/utils/sdkEditTransaction.decline.test.ts +46 -0
- package/src/utils/sdkEditTransaction.ts +22 -1
- package/src/utils/sdkResolverShadow.ts +10 -1
- package/src/utils/studioHelpers.test.ts +18 -0
- package/src/utils/studioHelpers.ts +41 -5
- package/src/utils/studioUiPreferences.test.ts +14 -0
- package/src/utils/studioUiPreferences.ts +6 -0
- package/src/utils/studioUrlState.ts +15 -7
- package/src/utils/timelineInspector.ts +10 -0
- package/dist/assets/hyperframes-player-CsV2rywT.js +0 -464
- package/dist/assets/index-DCblmTX3.js +0 -441
- package/dist/assets/index-DnRfAiK2.css +0 -1
package/dist/index.js
CHANGED
|
@@ -1338,6 +1338,9 @@ function readStorage(storage) {
|
|
|
1338
1338
|
if (typeof parsed.timelineSnapEnabled === "boolean") {
|
|
1339
1339
|
preferences.timelineSnapEnabled = parsed.timelineSnapEnabled;
|
|
1340
1340
|
}
|
|
1341
|
+
if (typeof parsed.rippleEditEnabled === "boolean") {
|
|
1342
|
+
preferences.rippleEditEnabled = parsed.rippleEditEnabled;
|
|
1343
|
+
}
|
|
1341
1344
|
if (parsed.timeDisplayMode === "time" || parsed.timeDisplayMode === "frame") {
|
|
1342
1345
|
preferences.timeDisplayMode = parsed.timeDisplayMode;
|
|
1343
1346
|
}
|
|
@@ -1594,6 +1597,30 @@ function createThumbnailSlice(set) {
|
|
|
1594
1597
|
};
|
|
1595
1598
|
}
|
|
1596
1599
|
|
|
1600
|
+
// src/player/store/readinessSlice.ts
|
|
1601
|
+
import { settleCompositionReadiness } from "@hyperframes/core/composition-readiness";
|
|
1602
|
+
var timelineReadyGeneration = 0;
|
|
1603
|
+
function resetPlaybackReadinessState() {
|
|
1604
|
+
timelineReadyGeneration++;
|
|
1605
|
+
return { timelineReady: false };
|
|
1606
|
+
}
|
|
1607
|
+
function createPlaybackReadinessSlice(set) {
|
|
1608
|
+
return {
|
|
1609
|
+
timelineReady: false,
|
|
1610
|
+
setTimelineReady: (ready) => {
|
|
1611
|
+
timelineReadyGeneration++;
|
|
1612
|
+
set({ timelineReady: ready });
|
|
1613
|
+
},
|
|
1614
|
+
requestTimelineReady: (doc) => {
|
|
1615
|
+
const generation = ++timelineReadyGeneration;
|
|
1616
|
+
if (!doc) return set({ timelineReady: true });
|
|
1617
|
+
settleCompositionReadiness(doc, () => {
|
|
1618
|
+
if (generation === timelineReadyGeneration) set({ timelineReady: true });
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1597
1624
|
// src/player/store/liveTime.ts
|
|
1598
1625
|
var timeListeners = /* @__PURE__ */ new Set();
|
|
1599
1626
|
var liveTime = {
|
|
@@ -1623,7 +1650,7 @@ function createTimelineResetState() {
|
|
|
1623
1650
|
isPlaying: false,
|
|
1624
1651
|
currentTime: 0,
|
|
1625
1652
|
duration: 0,
|
|
1626
|
-
|
|
1653
|
+
...resetPlaybackReadinessState(),
|
|
1627
1654
|
beatDragging: false,
|
|
1628
1655
|
elements: [],
|
|
1629
1656
|
selectedElementId: null,
|
|
@@ -1666,7 +1693,6 @@ var usePlayerStore = create2((set, get) => ({
|
|
|
1666
1693
|
isPlaying: false,
|
|
1667
1694
|
currentTime: 0,
|
|
1668
1695
|
duration: 0,
|
|
1669
|
-
timelineReady: false,
|
|
1670
1696
|
timelineSessionEpoch: 0,
|
|
1671
1697
|
timelineProjectId: null,
|
|
1672
1698
|
beatDragging: false,
|
|
@@ -1692,6 +1718,7 @@ var usePlayerStore = create2((set, get) => ({
|
|
|
1692
1718
|
...createThumbnailSlice(set),
|
|
1693
1719
|
...createAutomationSelectionSlice(set),
|
|
1694
1720
|
...createEditingModeSlice(set),
|
|
1721
|
+
...createPlaybackReadinessSlice(set),
|
|
1695
1722
|
activeKeyframePct: null,
|
|
1696
1723
|
setActiveKeyframePct: (pct) => set({ activeKeyframePct: pct }),
|
|
1697
1724
|
selectedElementIds: /* @__PURE__ */ new Set(),
|
|
@@ -1813,6 +1840,12 @@ var usePlayerStore = create2((set, get) => ({
|
|
|
1813
1840
|
writeStudioUiPreferences({ timelineSnapEnabled: enabled });
|
|
1814
1841
|
set({ timelineSnapEnabled: enabled });
|
|
1815
1842
|
},
|
|
1843
|
+
rippleEditEnabled: readStudioUiPreferences().rippleEditEnabled ?? true,
|
|
1844
|
+
// default on
|
|
1845
|
+
setRippleEditEnabled: (enabled) => {
|
|
1846
|
+
writeStudioUiPreferences({ rippleEditEnabled: enabled });
|
|
1847
|
+
set({ rippleEditEnabled: enabled });
|
|
1848
|
+
},
|
|
1816
1849
|
timeDisplayMode: readStudioUiPreferences().timeDisplayMode ?? "time",
|
|
1817
1850
|
setTimeDisplayMode: (mode) => {
|
|
1818
1851
|
writeStudioUiPreferences({ timeDisplayMode: mode });
|
|
@@ -1856,7 +1889,6 @@ var usePlayerStore = create2((set, get) => ({
|
|
|
1856
1889
|
bumpZEditVersion: () => set((state) => ({ zEditVersion: state.zEditVersion + 1 })),
|
|
1857
1890
|
setCurrentTime: (time) => set({ currentTime: Number.isFinite(time) ? time : 0 }),
|
|
1858
1891
|
setDuration: (duration) => set({ duration: Number.isFinite(duration) ? duration : 0 }),
|
|
1859
|
-
setTimelineReady: (ready) => set({ timelineReady: ready }),
|
|
1860
1892
|
setBeatDragging: (dragging) => set({ beatDragging: dragging }),
|
|
1861
1893
|
setElements: (elements) => set({ elements }),
|
|
1862
1894
|
// A genuine single selection: always collapse the set to just this element. User
|
|
@@ -3029,6 +3061,10 @@ function isAudioTimelineElement(element) {
|
|
|
3029
3061
|
if (AUDIO_TIMELINE_TAGS.has(tag)) return true;
|
|
3030
3062
|
return Boolean(element.src && AUDIO_SOURCE_EXT_RE.test(element.src));
|
|
3031
3063
|
}
|
|
3064
|
+
function isAudioOrVideoTimelineElement(element) {
|
|
3065
|
+
if (!element) return false;
|
|
3066
|
+
return isAudioTimelineElement(element) || element.tag.trim().toLowerCase() === "video";
|
|
3067
|
+
}
|
|
3032
3068
|
function isMusicTrack(element) {
|
|
3033
3069
|
if (!element) return false;
|
|
3034
3070
|
if (!isAudioTimelineElement(element)) return false;
|
|
@@ -3104,7 +3140,6 @@ function FileManagerProvider({
|
|
|
3104
3140
|
projectDir,
|
|
3105
3141
|
fileTree,
|
|
3106
3142
|
fileTreeLoaded,
|
|
3107
|
-
setFileTree,
|
|
3108
3143
|
editingPathRef,
|
|
3109
3144
|
projectIdRef,
|
|
3110
3145
|
saveRafRef,
|
|
@@ -3145,7 +3180,6 @@ function FileManagerProvider({
|
|
|
3145
3180
|
projectDir,
|
|
3146
3181
|
fileTree,
|
|
3147
3182
|
fileTreeLoaded,
|
|
3148
|
-
setFileTree,
|
|
3149
3183
|
editingPathRef,
|
|
3150
3184
|
projectIdRef,
|
|
3151
3185
|
saveRafRef,
|
|
@@ -3183,7 +3217,6 @@ function FileManagerProvider({
|
|
|
3183
3217
|
projectDir,
|
|
3184
3218
|
fileTree,
|
|
3185
3219
|
fileTreeLoaded,
|
|
3186
|
-
setFileTree,
|
|
3187
3220
|
editingPathRef,
|
|
3188
3221
|
projectIdRef,
|
|
3189
3222
|
saveRafRef,
|
|
@@ -3939,6 +3972,7 @@ function buildMissingCompositionEntry(params) {
|
|
|
3939
3972
|
start: window2.start,
|
|
3940
3973
|
duration: window2.duration,
|
|
3941
3974
|
track: timing.trackIndex,
|
|
3975
|
+
authoredTrack: timing.trackIndex,
|
|
3942
3976
|
domId: optionalNonEmpty(element.id),
|
|
3943
3977
|
hfId: optionalNonEmpty(element.getAttribute("data-hf-id")),
|
|
3944
3978
|
selector,
|
|
@@ -5214,10 +5248,7 @@ function resolveTimelineAssetDrop(input, clientX, clientY) {
|
|
|
5214
5248
|
});
|
|
5215
5249
|
const contentY = clientY - input.rectTop + input.scrollTop;
|
|
5216
5250
|
const pointerStart = Math.round(x / Math.max(input.pixelsPerSecond, 1) * 100) / 100;
|
|
5217
|
-
const start = Math.max(
|
|
5218
|
-
0,
|
|
5219
|
-
input.clampStartToDuration === false ? pointerStart : Math.min(input.duration, pointerStart)
|
|
5220
|
-
);
|
|
5251
|
+
const start = Math.max(0, pointerStart);
|
|
5221
5252
|
const rowIndex = Math.floor(getTimelineRowFromY(contentY, input.rowHeights));
|
|
5222
5253
|
return {
|
|
5223
5254
|
start,
|
|
@@ -6579,10 +6610,6 @@ function invokeDropCallback(callback) {
|
|
|
6579
6610
|
} catch {
|
|
6580
6611
|
}
|
|
6581
6612
|
}
|
|
6582
|
-
function resolveDropStart(usePointerStart, pointerStart) {
|
|
6583
|
-
if (usePointerStart) return pointerStart;
|
|
6584
|
-
return Math.max(0, usePlayerStore.getState().currentTime);
|
|
6585
|
-
}
|
|
6586
6613
|
function applyFileDrop(transfer, onFileDrop, placement) {
|
|
6587
6614
|
if (!onFileDrop || transfer.files.length === 0) return false;
|
|
6588
6615
|
invokeDropCallback(() => onFileDrop(Array.from(transfer.files), placement));
|
|
@@ -6602,7 +6629,6 @@ function applyTypedJsonDrop(transfer, mime, field, apply, placement) {
|
|
|
6602
6629
|
function useTimelineAssetDrop({
|
|
6603
6630
|
scrollRef,
|
|
6604
6631
|
ppsRef,
|
|
6605
|
-
durationRef,
|
|
6606
6632
|
trackOrderRef,
|
|
6607
6633
|
rowGeometryRef,
|
|
6608
6634
|
contentOrigin,
|
|
@@ -6683,10 +6709,10 @@ function useTimelineAssetDrop({
|
|
|
6683
6709
|
[clearDropPreview]
|
|
6684
6710
|
);
|
|
6685
6711
|
const resolveDropPlacement2 = useCallback7(
|
|
6686
|
-
(clientX, clientY
|
|
6712
|
+
(clientX, clientY) => {
|
|
6687
6713
|
const scroll = scrollRef.current;
|
|
6688
6714
|
const rect = scroll?.getBoundingClientRect();
|
|
6689
|
-
|
|
6715
|
+
return resolveTimelineAssetDrop(
|
|
6690
6716
|
{
|
|
6691
6717
|
rectLeft: rect?.left ?? 0,
|
|
6692
6718
|
rectTop: rect?.top ?? 0,
|
|
@@ -6694,20 +6720,14 @@ function useTimelineAssetDrop({
|
|
|
6694
6720
|
scrollTop: scroll?.scrollTop ?? 0,
|
|
6695
6721
|
contentOrigin,
|
|
6696
6722
|
pixelsPerSecond: ppsRef.current,
|
|
6697
|
-
duration: durationRef.current,
|
|
6698
|
-
clampStartToDuration: !usePointerStart,
|
|
6699
6723
|
rowHeights: rowGeometryRef.current.rowHeights,
|
|
6700
6724
|
trackOrder: trackOrderRef.current
|
|
6701
6725
|
},
|
|
6702
6726
|
clientX,
|
|
6703
6727
|
clientY
|
|
6704
6728
|
);
|
|
6705
|
-
return {
|
|
6706
|
-
start: resolveDropStart(usePointerStart, pointer.start),
|
|
6707
|
-
track: pointer.track
|
|
6708
|
-
};
|
|
6709
6729
|
},
|
|
6710
|
-
[scrollRef, ppsRef,
|
|
6730
|
+
[scrollRef, ppsRef, trackOrderRef, rowGeometryRef, contentOrigin]
|
|
6711
6731
|
);
|
|
6712
6732
|
const handleAssetDrop = useCallback7(
|
|
6713
6733
|
(e) => {
|
|
@@ -6715,15 +6735,14 @@ function useTimelineAssetDrop({
|
|
|
6715
6735
|
const canCommit = activeDropEpochRef.current === sessionEpoch;
|
|
6716
6736
|
clearDropPreview();
|
|
6717
6737
|
if (!canCommit) return;
|
|
6738
|
+
const placement = resolveDropPlacement2(e.clientX, e.clientY);
|
|
6718
6739
|
const compositionPayload = parseTimelineCompositionPayload(
|
|
6719
6740
|
e.dataTransfer.getData(TIMELINE_COMPOSITION_MIME)
|
|
6720
6741
|
);
|
|
6721
6742
|
if (compositionPayload && onCompositionDrop) {
|
|
6722
|
-
|
|
6723
|
-
invokeDropCallback(() => onCompositionDrop(compositionPayload.sourcePath, placement2));
|
|
6743
|
+
invokeDropCallback(() => onCompositionDrop(compositionPayload.sourcePath, placement));
|
|
6724
6744
|
return;
|
|
6725
6745
|
}
|
|
6726
|
-
const placement = resolveDropPlacement2(e.clientX, e.clientY);
|
|
6727
6746
|
if (applyFileDrop(e.dataTransfer, onFileDrop, placement)) return;
|
|
6728
6747
|
if (applyTypedJsonDrop(e.dataTransfer, TIMELINE_ASSET_MIME, "path", onAssetDrop, placement)) {
|
|
6729
6748
|
return;
|
|
@@ -9042,6 +9061,11 @@ function keyframeTarget(keyframe) {
|
|
|
9042
9061
|
|
|
9043
9062
|
// src/player/components/TimelineDiamondConnectors.tsx
|
|
9044
9063
|
import { Fragment as Fragment10, jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
9064
|
+
var EASE_BUTTON_PX = 16;
|
|
9065
|
+
var EASE_BUTTON_REST_GAP_PX = 4;
|
|
9066
|
+
function hasRoomForRestingEase(connectorWidth) {
|
|
9067
|
+
return connectorWidth >= EASE_BUTTON_PX + EASE_BUTTON_REST_GAP_PX * 2;
|
|
9068
|
+
}
|
|
9045
9069
|
function TimelineDiamondConnectors({
|
|
9046
9070
|
markers,
|
|
9047
9071
|
centerY,
|
|
@@ -9100,6 +9124,7 @@ function TimelineDiamondConnectors({
|
|
|
9100
9124
|
previous.keyframe.percentage
|
|
9101
9125
|
),
|
|
9102
9126
|
roomForFullTarget: connectorWidth >= 24,
|
|
9127
|
+
restingVisible: hasRoomForRestingEase(connectorWidth),
|
|
9103
9128
|
onSelectSegment
|
|
9104
9129
|
}
|
|
9105
9130
|
)
|
|
@@ -9119,6 +9144,7 @@ function SegmentEaseControl({
|
|
|
9119
9144
|
rovingTargetId,
|
|
9120
9145
|
afterLabel,
|
|
9121
9146
|
roomForFullTarget,
|
|
9147
|
+
restingVisible,
|
|
9122
9148
|
onSelectSegment
|
|
9123
9149
|
}) {
|
|
9124
9150
|
const pressXRef = useRef12(null);
|
|
@@ -9151,7 +9177,7 @@ function SegmentEaseControl({
|
|
|
9151
9177
|
tabIndex: focusId === rovingTargetId ? 0 : -1,
|
|
9152
9178
|
"aria-label": `Edit ${ease} easing after ${afterLabel}`,
|
|
9153
9179
|
title: `Edit ${ease} easing`,
|
|
9154
|
-
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-['']" : ""}`,
|
|
9180
|
+
className: `absolute flex items-center justify-center rounded ${restingVisible ? "opacity-40" : "opacity-0"} transition-opacity hover:opacity-100 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-['']" : ""}`,
|
|
9155
9181
|
style: {
|
|
9156
9182
|
left: "50%",
|
|
9157
9183
|
top: "50%",
|
|
@@ -10896,6 +10922,11 @@ import {
|
|
|
10896
10922
|
} from "@hyperframes/core/audio-automation";
|
|
10897
10923
|
import { getAudioFxDef } from "@hyperframes/core/audio-fx";
|
|
10898
10924
|
var POINT_MERGE_SEC = 0.02;
|
|
10925
|
+
function mergeInsertPoint(points, t, v) {
|
|
10926
|
+
const kept = points.filter((p) => Math.abs(p.t - t) > POINT_MERGE_SEC);
|
|
10927
|
+
const seeded = points.length === 0 && t > POINT_MERGE_SEC ? [{ t: 0, v }] : [];
|
|
10928
|
+
return [...seeded, ...kept, { t, v }].sort((a, b) => a.t - b.t);
|
|
10929
|
+
}
|
|
10899
10930
|
var MIN_POINT_GAP_SEC = 1e-3;
|
|
10900
10931
|
var GRAB_PX = 7;
|
|
10901
10932
|
var SEGMENT_GRAB_PX = 5;
|
|
@@ -11794,12 +11825,7 @@ function useAutomationLaneGestures({
|
|
|
11794
11825
|
return;
|
|
11795
11826
|
}
|
|
11796
11827
|
const { t, v } = pointAt(e.clientX, e.clientY);
|
|
11797
|
-
|
|
11798
|
-
const seeded = lane.points.length === 0 && t > POINT_MERGE_SEC ? [{ t: 0, v }] : [];
|
|
11799
|
-
commitPoints(
|
|
11800
|
-
[...seeded, ...kept, { t, v }].sort((a, b) => a.t - b.t),
|
|
11801
|
-
true
|
|
11802
|
-
);
|
|
11828
|
+
commitPoints(mergeInsertPoint(lane.points, t, v), true);
|
|
11803
11829
|
},
|
|
11804
11830
|
[lane, pointAt, commitPoints, readOnly, hitIndex, segmentIndex]
|
|
11805
11831
|
);
|
|
@@ -12522,7 +12548,7 @@ function laneGroupKey(target, chain) {
|
|
|
12522
12548
|
function groupAutomationLanes(elements) {
|
|
12523
12549
|
const groups = /* @__PURE__ */ new Map();
|
|
12524
12550
|
for (const element of elements) {
|
|
12525
|
-
if (!
|
|
12551
|
+
if (!isAudioOrVideoTimelineElement(element)) continue;
|
|
12526
12552
|
const chain = elementFxChain(element);
|
|
12527
12553
|
for (const lane of elementAutomationLanes(element)) {
|
|
12528
12554
|
const key2 = laneGroupKey(lane.target, chain);
|
|
@@ -12619,7 +12645,7 @@ function TimelineAutomationLaneSlot({
|
|
|
12619
12645
|
currentTime,
|
|
12620
12646
|
beatTimes
|
|
12621
12647
|
}) {
|
|
12622
|
-
const clips = elements.filter(
|
|
12648
|
+
const clips = elements.filter(isAudioOrVideoTimelineElement);
|
|
12623
12649
|
const rowsByClip = /* @__PURE__ */ new Map();
|
|
12624
12650
|
groupAutomationLanes(clips).forEach((group, rowIndex) => {
|
|
12625
12651
|
for (const entry2 of group.entries) {
|
|
@@ -13051,6 +13077,10 @@ function matchesByDomId(selection, element, selectionSourceFile) {
|
|
|
13051
13077
|
if (!selection.id) return false;
|
|
13052
13078
|
return element.domId === selection.id && (element.sourceFile || "index.html") === selectionSourceFile;
|
|
13053
13079
|
}
|
|
13080
|
+
function matchesByHfId(selection, element, selectionSourceFile) {
|
|
13081
|
+
if (!selection.hfId) return false;
|
|
13082
|
+
return element.hfId === selection.hfId && (element.sourceFile || "index.html") === selectionSourceFile;
|
|
13083
|
+
}
|
|
13054
13084
|
function matchesByCompositionHost(selection, element) {
|
|
13055
13085
|
if (!selection.isCompositionHost || !selection.compositionSrc) return false;
|
|
13056
13086
|
return element.compositionSrc === selection.compositionSrc;
|
|
@@ -13063,6 +13093,8 @@ function findMatchingTimelineElementId(selection, elements) {
|
|
|
13063
13093
|
const selectionSourceFile = selection.sourceFile || "index.html";
|
|
13064
13094
|
const byId = selection.id ? elements.find((el) => matchesByDomId(selection, el, selectionSourceFile)) : void 0;
|
|
13065
13095
|
if (byId) return byId.key ?? byId.id;
|
|
13096
|
+
const byHfId = selection.hfId ? elements.find((el) => matchesByHfId(selection, el, selectionSourceFile)) : void 0;
|
|
13097
|
+
if (byHfId) return byHfId.key ?? byHfId.id;
|
|
13066
13098
|
const bySelector = selection.selector ? elements.find((el) => matchesBySelector(selection, el)) : void 0;
|
|
13067
13099
|
if (bySelector) return bySelector.key ?? bySelector.id;
|
|
13068
13100
|
const byHost = elements.find((el) => matchesByCompositionHost(selection, el));
|
|
@@ -13072,6 +13104,11 @@ function findMatchingTimelineElementId(selection, elements) {
|
|
|
13072
13104
|
}
|
|
13073
13105
|
return null;
|
|
13074
13106
|
}
|
|
13107
|
+
function resolveElementTrack(element) {
|
|
13108
|
+
return Math.round(
|
|
13109
|
+
Number.isFinite(element.authoredTrack) ? element.authoredTrack : element.track
|
|
13110
|
+
);
|
|
13111
|
+
}
|
|
13075
13112
|
function findTimelineIdByAncestor(element, elements, sourceFile) {
|
|
13076
13113
|
let ancestor = element?.parentElement ?? null;
|
|
13077
13114
|
while (ancestor) {
|
|
@@ -15647,7 +15684,7 @@ function trackShowsBeatStrip(els, beatTimes, ctx3) {
|
|
|
15647
15684
|
return ctx3.selectedElementId ? els.some((e) => (e.key ?? e.id) === ctx3.selectedElementId) : els.some((e) => ctx3.isMusicTrack(e));
|
|
15648
15685
|
}
|
|
15649
15686
|
function automationLaneCountOf(element) {
|
|
15650
|
-
return
|
|
15687
|
+
return isAudioOrVideoTimelineElement(element) ? elementAutomationLanes(element).length : 0;
|
|
15651
15688
|
}
|
|
15652
15689
|
function trackAutomationLaneCount(elements) {
|
|
15653
15690
|
return groupAutomationLanes(elements).length;
|
|
@@ -19146,6 +19183,9 @@ import { useRef as useRef29, useState as useState17, useCallback as useCallback1
|
|
|
19146
19183
|
function classifyZone(el) {
|
|
19147
19184
|
return isAudioTimelineElement(el) ? "audio" : "visual";
|
|
19148
19185
|
}
|
|
19186
|
+
function isMainTrackElement(el) {
|
|
19187
|
+
return el.track === 0 && classifyZone(el) === "visual" && el.expandedParentStart == null;
|
|
19188
|
+
}
|
|
19149
19189
|
var keyOf = (el) => el.key ?? el.id;
|
|
19150
19190
|
var EPS = 1e-6;
|
|
19151
19191
|
function overlaps2(a, b) {
|
|
@@ -21939,20 +21979,23 @@ function resolveCloseGapShifts(elements, gap) {
|
|
|
21939
21979
|
// src/player/components/timelineGapCommit.ts
|
|
21940
21980
|
var keyOf5 = (e) => e.key ?? e.id;
|
|
21941
21981
|
var gapCloseGestureSeq = 0;
|
|
21942
|
-
function
|
|
21943
|
-
const byKey = new Map(
|
|
21944
|
-
return shifts.
|
|
21982
|
+
function resolveShiftedElements(elements, shifts) {
|
|
21983
|
+
const byKey = new Map(elements.map((e) => [keyOf5(e), e]));
|
|
21984
|
+
return shifts.flatMap((s) => {
|
|
21945
21985
|
const element = byKey.get(s.key);
|
|
21946
|
-
return element
|
|
21986
|
+
return element ? [{ element, start: s.newStart }] : [];
|
|
21947
21987
|
});
|
|
21948
21988
|
}
|
|
21989
|
+
function canShiftTrackGapClips(laneElements, shifts) {
|
|
21990
|
+
const resolved2 = resolveShiftedElements(laneElements, shifts);
|
|
21991
|
+
return resolved2.length === shifts.length && resolved2.every((r) => getTimelineEditCapabilities(r.element).canMove);
|
|
21992
|
+
}
|
|
21949
21993
|
function buildShiftEdits(laneElements, shifts) {
|
|
21950
21994
|
if (shifts.length === 0 || !canShiftTrackGapClips(laneElements, shifts)) return null;
|
|
21951
|
-
|
|
21952
|
-
|
|
21953
|
-
|
|
21954
|
-
|
|
21955
|
-
});
|
|
21995
|
+
return resolveShiftedElements(laneElements, shifts).map(({ element, start }) => ({
|
|
21996
|
+
element,
|
|
21997
|
+
updates: { start, track: element.track }
|
|
21998
|
+
}));
|
|
21956
21999
|
}
|
|
21957
22000
|
function commitShifts(laneElements, shifts, deps) {
|
|
21958
22001
|
const edits = buildShiftEdits(laneElements, shifts);
|
|
@@ -21972,6 +22015,22 @@ function commitCloseAllTrackGaps(laneElements, deps) {
|
|
|
21972
22015
|
deps
|
|
21973
22016
|
);
|
|
21974
22017
|
}
|
|
22018
|
+
function resolveMainTrackDeleteRippleShifts(survivingElements, deletedElements, rippleEnabled) {
|
|
22019
|
+
const deletedMainTrack = deletedElements.filter(isMainTrackElement);
|
|
22020
|
+
if (!rippleEnabled || deletedMainTrack.length === 0) return null;
|
|
22021
|
+
const survivors = survivingElements.filter(isMainTrackElement);
|
|
22022
|
+
const shifts = [];
|
|
22023
|
+
for (const survivor of survivors) {
|
|
22024
|
+
const width = deletedMainTrack.filter((d) => d.start < survivor.start).reduce((sum, d) => sum + d.duration, 0);
|
|
22025
|
+
if (width <= 0) continue;
|
|
22026
|
+
const newStart = round32(Math.max(laneGapFloor(survivors), survivor.start - width));
|
|
22027
|
+
if (Math.abs(newStart - survivor.start) > TRACK_GAP_EPSILON_S) {
|
|
22028
|
+
shifts.push({ key: keyOf5(survivor), newStart });
|
|
22029
|
+
}
|
|
22030
|
+
}
|
|
22031
|
+
if (shifts.length === 0 || !canShiftTrackGapClips(survivors, shifts)) return null;
|
|
22032
|
+
return shifts;
|
|
22033
|
+
}
|
|
21975
22034
|
|
|
21976
22035
|
// src/player/components/useTrackGapMenu.ts
|
|
21977
22036
|
function useTrackGapMenu({
|
|
@@ -23179,7 +23238,6 @@ var Timeline = memo16(function Timeline2({
|
|
|
23179
23238
|
const assetDrop = useTimelineAssetDrop({
|
|
23180
23239
|
scrollRef,
|
|
23181
23240
|
ppsRef,
|
|
23182
|
-
durationRef,
|
|
23183
23241
|
trackOrderRef,
|
|
23184
23242
|
rowGeometryRef,
|
|
23185
23243
|
contentOrigin,
|
|
@@ -24661,6 +24719,9 @@ function canvasNudgeKeysClaimed() {
|
|
|
24661
24719
|
}
|
|
24662
24720
|
|
|
24663
24721
|
// src/player/hooks/usePlaybackKeyboard.ts
|
|
24722
|
+
function shouldRazorClaimPlainA(e) {
|
|
24723
|
+
return !e.shiftKey && !e.altKey && usePlayerStore.getState().activeTool === "razor";
|
|
24724
|
+
}
|
|
24664
24725
|
function usePlaybackKeyboard({
|
|
24665
24726
|
iframeRef,
|
|
24666
24727
|
shuttleDirectionRef,
|
|
@@ -24790,6 +24851,7 @@ function usePlaybackKeyboard({
|
|
|
24790
24851
|
return;
|
|
24791
24852
|
}
|
|
24792
24853
|
if (key2 === "a") {
|
|
24854
|
+
if (shouldRazorClaimPlainA(e)) return;
|
|
24793
24855
|
e.preventDefault();
|
|
24794
24856
|
seek(usePlayerStore.getState().inPoint ?? 0, { keepPlaying: true });
|
|
24795
24857
|
return;
|
|
@@ -25080,7 +25142,7 @@ function useTimelineSyncCallbacks({
|
|
|
25080
25142
|
syncTimelineElements,
|
|
25081
25143
|
setDuration,
|
|
25082
25144
|
setCurrentTime,
|
|
25083
|
-
|
|
25145
|
+
requestTimelineReady,
|
|
25084
25146
|
setIsPlaying,
|
|
25085
25147
|
attachIframeShortcutListeners,
|
|
25086
25148
|
applyPreviewAudioState
|
|
@@ -25152,7 +25214,7 @@ function useTimelineSyncCallbacks({
|
|
|
25152
25214
|
syncAdapterDuration(adapter, setDuration);
|
|
25153
25215
|
setCurrentTime(startTime);
|
|
25154
25216
|
if (!isRefreshingRef.current) {
|
|
25155
|
-
|
|
25217
|
+
requestTimelineReady(safeContentDocument(iframeRef.current));
|
|
25156
25218
|
}
|
|
25157
25219
|
isRefreshingRef.current = false;
|
|
25158
25220
|
setIsPlaying(false);
|
|
@@ -25170,7 +25232,7 @@ function useTimelineSyncCallbacks({
|
|
|
25170
25232
|
getAdapter,
|
|
25171
25233
|
setDuration,
|
|
25172
25234
|
setCurrentTime,
|
|
25173
|
-
|
|
25235
|
+
requestTimelineReady,
|
|
25174
25236
|
setIsPlaying,
|
|
25175
25237
|
processTimelineMessage,
|
|
25176
25238
|
enrichMissingCompositions,
|
|
@@ -25641,7 +25703,7 @@ function useTimelinePlayer() {
|
|
|
25641
25703
|
const lastTimelineMessageRef = useRef44(0);
|
|
25642
25704
|
const staticSeekAdapterRef = useRef44(null);
|
|
25643
25705
|
const staticSeekWarnedRef = useRef44(false);
|
|
25644
|
-
const { setIsPlaying, setCurrentTime, setDuration,
|
|
25706
|
+
const { setIsPlaying, setCurrentTime, setDuration, requestTimelineReady, setElements } = usePlayerStore.getState();
|
|
25645
25707
|
const syncTimelineElements = useCallback36(
|
|
25646
25708
|
// The lease guard adds one deliberate branch at the shared synchronization boundary.
|
|
25647
25709
|
// fallow-ignore-next-line complexity
|
|
@@ -25667,7 +25729,7 @@ function useTimelinePlayer() {
|
|
|
25667
25729
|
setDuration(nextDuration ?? 0);
|
|
25668
25730
|
}
|
|
25669
25731
|
if (!state.timelineReady) {
|
|
25670
|
-
|
|
25732
|
+
requestTimelineReady(safeContentDocument(iframeRef.current));
|
|
25671
25733
|
}
|
|
25672
25734
|
void probeMissingSourceDurations(
|
|
25673
25735
|
mergedElements,
|
|
@@ -25683,7 +25745,7 @@ function useTimelinePlayer() {
|
|
|
25683
25745
|
}
|
|
25684
25746
|
);
|
|
25685
25747
|
},
|
|
25686
|
-
[setElements,
|
|
25748
|
+
[setElements, requestTimelineReady, setDuration]
|
|
25687
25749
|
);
|
|
25688
25750
|
const getAdapter = useCallback36(() => {
|
|
25689
25751
|
try {
|
|
@@ -25953,7 +26015,7 @@ function useTimelinePlayer() {
|
|
|
25953
26015
|
syncTimelineElements,
|
|
25954
26016
|
setDuration,
|
|
25955
26017
|
setCurrentTime,
|
|
25956
|
-
|
|
26018
|
+
requestTimelineReady,
|
|
25957
26019
|
setIsPlaying,
|
|
25958
26020
|
attachIframeShortcutListeners,
|
|
25959
26021
|
applyPreviewAudioState
|
|
@@ -28524,6 +28586,13 @@ function pauseStudioPreviewPlayback(iframe) {
|
|
|
28524
28586
|
}
|
|
28525
28587
|
|
|
28526
28588
|
// src/components/editor/domEditingAgentPrompt.ts
|
|
28589
|
+
var GUARDRAIL_LINES = [
|
|
28590
|
+
"Guardrails:",
|
|
28591
|
+
"- Make a targeted change to this element only.",
|
|
28592
|
+
"- Preserve the rest of the composition and its timing.",
|
|
28593
|
+
"- Do not modify other elements' data-* attributes or positioning.",
|
|
28594
|
+
"- Prefer existing inline styles or existing CSS rules for this element over adding unrelated selectors."
|
|
28595
|
+
];
|
|
28527
28596
|
function formatBoundingBox(bounds) {
|
|
28528
28597
|
return `x=${Math.round(bounds.x)}, y=${Math.round(bounds.y)}, width=${Math.round(bounds.width)}, height=${Math.round(bounds.height)}`;
|
|
28529
28598
|
}
|
|
@@ -28535,6 +28604,35 @@ function formatTextFields(fields) {
|
|
|
28535
28604
|
(field) => `- key=${field.key}; tag=<${field.tagName}>; source=${field.source}; text=${JSON.stringify(field.value)}`
|
|
28536
28605
|
).join("\n");
|
|
28537
28606
|
}
|
|
28607
|
+
function formatSelectorTagLine(info) {
|
|
28608
|
+
return `Selector: ${info.selector ?? "(none)"} Tag: <${info.tagName}>`;
|
|
28609
|
+
}
|
|
28610
|
+
function formatTextLine(textContent) {
|
|
28611
|
+
return textContent ? `Text: ${textContent}` : "";
|
|
28612
|
+
}
|
|
28613
|
+
function buildElementInfoLines(info) {
|
|
28614
|
+
const lines = [
|
|
28615
|
+
`DOM id: ${info.id ?? "(none)"}`,
|
|
28616
|
+
`Selector: ${info.selector ?? "(none)"}`,
|
|
28617
|
+
`Selector index: ${info.selectorIndex ?? 0}`,
|
|
28618
|
+
`Tag: <${info.tagName}>`
|
|
28619
|
+
];
|
|
28620
|
+
if (info.label) lines.push(`Label: ${info.label}`);
|
|
28621
|
+
lines.push(`Bounds: ${formatBoundingBox(info.boundingBox)}`);
|
|
28622
|
+
if (info.src) lines.push(`Source (media): ${info.src}`);
|
|
28623
|
+
if (info.textContent) lines.push(`Text: ${info.textContent}`);
|
|
28624
|
+
return lines;
|
|
28625
|
+
}
|
|
28626
|
+
function buildElementDetailLines(info) {
|
|
28627
|
+
const lines = [];
|
|
28628
|
+
const textFieldsBlock = info.textFields ? formatTextFields(info.textFields) : "";
|
|
28629
|
+
if (textFieldsBlock) lines.push("", "Text fields:", textFieldsBlock);
|
|
28630
|
+
const inlineStyleBlock = info.inlineStyles ? formatStyleBlock(info.inlineStyles) : "";
|
|
28631
|
+
if (inlineStyleBlock) lines.push("", "Inline styles:", inlineStyleBlock);
|
|
28632
|
+
const computedStyleBlock = info.computedStyles ? formatStyleBlock(info.computedStyles) : "";
|
|
28633
|
+
if (computedStyleBlock) lines.push("", "Computed styles (browser-resolved):", computedStyleBlock);
|
|
28634
|
+
return lines;
|
|
28635
|
+
}
|
|
28538
28636
|
function buildElementAgentPrompt({
|
|
28539
28637
|
selection,
|
|
28540
28638
|
currentTime,
|
|
@@ -28544,6 +28642,17 @@ function buildElementAgentPrompt({
|
|
|
28544
28642
|
sourceFilePath
|
|
28545
28643
|
}) {
|
|
28546
28644
|
const displayedSourceFile = sourceFilePath?.trim() || selection.sourceFile;
|
|
28645
|
+
const info = {
|
|
28646
|
+
id: selection.id ?? null,
|
|
28647
|
+
selector: selection.selector,
|
|
28648
|
+
selectorIndex: selection.selectorIndex,
|
|
28649
|
+
tagName: selection.tagName,
|
|
28650
|
+
boundingBox: selection.boundingBox,
|
|
28651
|
+
textContent: selection.textContent,
|
|
28652
|
+
textFields: selection.textFields,
|
|
28653
|
+
inlineStyles: selection.inlineStyles,
|
|
28654
|
+
computedStyles: selection.computedStyles
|
|
28655
|
+
};
|
|
28547
28656
|
const lines = [
|
|
28548
28657
|
"## HyperFrames element edit request v1",
|
|
28549
28658
|
"Schema version: 1",
|
|
@@ -28553,52 +28662,62 @@ function buildElementAgentPrompt({
|
|
|
28553
28662
|
`Composition: ${selection.compositionPath}`,
|
|
28554
28663
|
`Playback time: ${formatTime(currentTime)}`,
|
|
28555
28664
|
`Source file: ${displayedSourceFile}`,
|
|
28556
|
-
|
|
28557
|
-
`Selector: ${selection.selector ?? "(none)"}`,
|
|
28558
|
-
`Selector index: ${selection.selectorIndex ?? 0}`,
|
|
28559
|
-
`Tag: <${selection.tagName}>`,
|
|
28560
|
-
`Bounds: ${formatBoundingBox(selection.boundingBox)}`
|
|
28665
|
+
...buildElementInfoLines(info)
|
|
28561
28666
|
];
|
|
28562
|
-
if (selection.textContent) {
|
|
28563
|
-
lines.push(`Text: ${selection.textContent}`);
|
|
28564
|
-
}
|
|
28565
28667
|
const trimmedSelectionContext = selectionContext?.trim();
|
|
28566
28668
|
if (trimmedSelectionContext) {
|
|
28567
28669
|
lines.push("", "Selection context:", trimmedSelectionContext);
|
|
28568
28670
|
}
|
|
28569
|
-
|
|
28570
|
-
if (textFieldsBlock) {
|
|
28571
|
-
lines.push("", "Text fields:", textFieldsBlock);
|
|
28572
|
-
}
|
|
28573
|
-
const inlineStyleBlock = formatStyleBlock(selection.inlineStyles);
|
|
28574
|
-
if (inlineStyleBlock) {
|
|
28575
|
-
lines.push("", "Inline styles:", inlineStyleBlock);
|
|
28576
|
-
}
|
|
28577
|
-
const computedStyleBlock = formatStyleBlock(selection.computedStyles);
|
|
28578
|
-
if (computedStyleBlock) {
|
|
28579
|
-
lines.push("", "Computed styles (browser-resolved):", computedStyleBlock);
|
|
28580
|
-
}
|
|
28671
|
+
lines.push(...buildElementDetailLines(info));
|
|
28581
28672
|
if (tagSnippet) {
|
|
28582
28673
|
lines.push("", "Target HTML:", tagSnippet);
|
|
28583
28674
|
}
|
|
28584
|
-
lines.push(
|
|
28585
|
-
"",
|
|
28586
|
-
"Guardrails:",
|
|
28587
|
-
"- Make a targeted change to this element only.",
|
|
28588
|
-
"- Preserve the rest of the composition and its timing.",
|
|
28589
|
-
"- Do not modify other elements' data-* attributes or positioning.",
|
|
28590
|
-
"- Prefer existing inline styles or existing CSS rules for this element over adding unrelated selectors."
|
|
28591
|
-
);
|
|
28675
|
+
lines.push("", ...GUARDRAIL_LINES);
|
|
28592
28676
|
return lines.join("\n");
|
|
28593
28677
|
}
|
|
28678
|
+
function buildSelectorAndTextLines(info) {
|
|
28679
|
+
return [formatSelectorTagLine(info), formatTextLine(info.textContent)];
|
|
28680
|
+
}
|
|
28594
28681
|
function buildAgentContextPreview(selection, activeCompPath) {
|
|
28595
28682
|
return [
|
|
28596
28683
|
`Composition: ${selection.compositionPath}`,
|
|
28597
28684
|
`Source: ${selection.sourceFile || activeCompPath || "index.html"}`,
|
|
28598
|
-
|
|
28599
|
-
selection.textContent ? `Text: ${selection.textContent}` : ""
|
|
28685
|
+
...buildSelectorAndTextLines(selection)
|
|
28600
28686
|
].filter(Boolean).join("\n");
|
|
28601
28687
|
}
|
|
28688
|
+
function buildPickerAgentPrompt({
|
|
28689
|
+
selection,
|
|
28690
|
+
userInstruction
|
|
28691
|
+
}) {
|
|
28692
|
+
const lines = [
|
|
28693
|
+
"## HyperFrames element edit request v1",
|
|
28694
|
+
"Schema version: 1",
|
|
28695
|
+
"",
|
|
28696
|
+
userInstruction?.trim() || "Edit this selected HyperFrames element."
|
|
28697
|
+
];
|
|
28698
|
+
if (!selection) return lines.join("\n");
|
|
28699
|
+
const info = {
|
|
28700
|
+
id: selection.id,
|
|
28701
|
+
selector: selection.selector,
|
|
28702
|
+
tagName: selection.tagName,
|
|
28703
|
+
label: selection.label,
|
|
28704
|
+
boundingBox: selection.boundingBox,
|
|
28705
|
+
textContent: selection.textContent,
|
|
28706
|
+
src: selection.src
|
|
28707
|
+
};
|
|
28708
|
+
lines.push(
|
|
28709
|
+
"",
|
|
28710
|
+
...buildElementInfoLines(info),
|
|
28711
|
+
...buildElementDetailLines(info),
|
|
28712
|
+
"",
|
|
28713
|
+
...GUARDRAIL_LINES
|
|
28714
|
+
);
|
|
28715
|
+
return lines.join("\n");
|
|
28716
|
+
}
|
|
28717
|
+
function buildPickerAgentContextPreview(selection) {
|
|
28718
|
+
if (!selection) return "";
|
|
28719
|
+
return buildSelectorAndTextLines(selection).filter(Boolean).join("\n");
|
|
28720
|
+
}
|
|
28602
28721
|
|
|
28603
28722
|
// src/components/editor/domEditOverlayBasis.ts
|
|
28604
28723
|
function readPositiveDimension(value) {
|
|
@@ -38233,7 +38352,7 @@ var STUDIO_SDK_OPERATION_FAMILIES = [
|
|
|
38233
38352
|
function resolveEnabledSdkFamilies(env2, masterEnabled) {
|
|
38234
38353
|
if (!masterEnabled) return /* @__PURE__ */ new Set();
|
|
38235
38354
|
const raw = env2["VITE_STUDIO_SDK_CUTOVER_FAMILIES"];
|
|
38236
|
-
if (typeof raw !== "string" || raw.trim() === "") return
|
|
38355
|
+
if (typeof raw !== "string" || raw.trim() === "") return new Set(STUDIO_SDK_OPERATION_FAMILIES);
|
|
38237
38356
|
const requested = raw.split(",").map((family) => family.trim()).filter(Boolean);
|
|
38238
38357
|
const known = new Set(STUDIO_SDK_OPERATION_FAMILIES);
|
|
38239
38358
|
const unknown = requested.filter((family) => !known.has(family));
|
|
@@ -38266,7 +38385,7 @@ var env = { ...import.meta.env ?? {}, ...runtimeEnv };
|
|
|
38266
38385
|
var STUDIO_SDK_CUTOVER_ENABLED = resolveStudioBooleanEnvFlag(
|
|
38267
38386
|
env,
|
|
38268
38387
|
["VITE_STUDIO_SDK_CUTOVER_ENABLED"],
|
|
38269
|
-
|
|
38388
|
+
true
|
|
38270
38389
|
);
|
|
38271
38390
|
var STUDIO_SDK_CUTOVER_FAMILIES = resolveEnabledSdkFamilies(
|
|
38272
38391
|
env,
|
|
@@ -38759,6 +38878,13 @@ function shouldDeclineTextCutoverForTarget(target, ops) {
|
|
|
38759
38878
|
const tag = elementTag(children[0]);
|
|
38760
38879
|
return tag !== null && NON_HTML_CHILD_TAGS.has(tag);
|
|
38761
38880
|
}
|
|
38881
|
+
function isResolverDisagreement(session, hfId) {
|
|
38882
|
+
try {
|
|
38883
|
+
return resolveSnapshot(session, hfId) !== null;
|
|
38884
|
+
} catch {
|
|
38885
|
+
return false;
|
|
38886
|
+
}
|
|
38887
|
+
}
|
|
38762
38888
|
function shouldUseSdkCutover(flagEnabled, hasSession, hfId, ops) {
|
|
38763
38889
|
return flagEnabled && hasSession && !!hfId && ops.length > 0 && ops.every((o) => CUTOVER_OP_TYPES.has(o.type)) && // SDK edit ops target only the element hfId; child-scoped patch ops need the server path.
|
|
38764
38890
|
!hasChildScopedOp(ops) && !ops.some(mapsToReservedAttr) && !hasUnsafeHtmlAttributeOp(ops);
|
|
@@ -38800,7 +38926,12 @@ function isSelfWriteEcho(path, content, now2 = Date.now()) {
|
|
|
38800
38926
|
}
|
|
38801
38927
|
|
|
38802
38928
|
// src/utils/sdkEditTransaction.ts
|
|
38803
|
-
function declinedCutover(reason) {
|
|
38929
|
+
function declinedCutover(reason, family, resolverDisagreement) {
|
|
38930
|
+
trackStudioEvent("sdk_cutover_declined", {
|
|
38931
|
+
reason,
|
|
38932
|
+
family: family ?? null,
|
|
38933
|
+
...resolverDisagreement ? { resolverDisagreement: true } : {}
|
|
38934
|
+
});
|
|
38804
38935
|
return { status: "declined", reason };
|
|
38805
38936
|
}
|
|
38806
38937
|
function asCutoverError(error) {
|
|
@@ -38967,15 +39098,17 @@ function gsapReadSource(deps, targetPath) {
|
|
|
38967
39098
|
}
|
|
38968
39099
|
async function sdkCutoverPersist(selection, ops, originalContent, targetPath, sdkSession, deps, options) {
|
|
38969
39100
|
if (!shouldUseSdkCutover(sdkFamilyEnabled("dom"), !!sdkSession, selection.hfId, ops))
|
|
38970
|
-
return declinedCutover("ineligible_operation");
|
|
38971
|
-
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
39101
|
+
return declinedCutover("ineligible_operation", "dom");
|
|
39102
|
+
if (!sdkSession) return declinedCutover("session_unavailable", "dom");
|
|
38972
39103
|
const hfId = selection.hfId;
|
|
38973
|
-
if (!hfId) return declinedCutover("target_unaddressable");
|
|
39104
|
+
if (!hfId) return declinedCutover("target_unaddressable", "dom");
|
|
38974
39105
|
const target = sdkSession.getElement(hfId);
|
|
38975
|
-
if (!target)
|
|
39106
|
+
if (!target)
|
|
39107
|
+
return declinedCutover("target_not_found", "dom", isResolverDisagreement(sdkSession, hfId));
|
|
38976
39108
|
if (shouldDeclineTextCutoverForTarget(target, ops))
|
|
38977
|
-
return declinedCutover("unsupported_text_target");
|
|
38978
|
-
if (wrongCompositionFile(deps, targetPath))
|
|
39109
|
+
return declinedCutover("unsupported_text_target", "dom");
|
|
39110
|
+
if (wrongCompositionFile(deps, targetPath))
|
|
39111
|
+
return declinedCutover("wrong_composition_file", "dom");
|
|
38979
39112
|
const result = await persistSdkCandidateMutation(
|
|
38980
39113
|
sdkSession,
|
|
38981
39114
|
targetPath,
|
|
@@ -38998,10 +39131,12 @@ async function sdkTimingPersist(hfId, targetPath, timingUpdate, sdkSession, deps
|
|
|
38998
39131
|
timingSrc ? () => timingSrc(targetPath) : void 0,
|
|
38999
39132
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
39000
39133
|
);
|
|
39001
|
-
if (!sdkFamilyEnabled("timing")) return declinedCutover("feature_disabled");
|
|
39002
|
-
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
39003
|
-
if (!sdkSession.getElement(hfId))
|
|
39004
|
-
|
|
39134
|
+
if (!sdkFamilyEnabled("timing")) return declinedCutover("feature_disabled", "timing");
|
|
39135
|
+
if (!sdkSession) return declinedCutover("session_unavailable", "timing");
|
|
39136
|
+
if (!sdkSession.getElement(hfId))
|
|
39137
|
+
return declinedCutover("target_not_found", "timing", isResolverDisagreement(sdkSession, hfId));
|
|
39138
|
+
if (wrongCompositionFile(deps, targetPath))
|
|
39139
|
+
return declinedCutover("wrong_composition_file", "timing");
|
|
39005
39140
|
try {
|
|
39006
39141
|
const serializedBefore = sdkSession.serialize();
|
|
39007
39142
|
const result = await persistSdkCandidateMutation(
|
|
@@ -39032,11 +39167,17 @@ async function sdkTimingBatchPersist(changes, targetPath, sdkSession, deps, opti
|
|
|
39032
39167
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
39033
39168
|
);
|
|
39034
39169
|
}
|
|
39035
|
-
if (!sdkFamilyEnabled("timing")) return declinedCutover("feature_disabled");
|
|
39036
|
-
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
39037
|
-
if (wrongCompositionFile(deps, targetPath))
|
|
39038
|
-
|
|
39039
|
-
|
|
39170
|
+
if (!sdkFamilyEnabled("timing")) return declinedCutover("feature_disabled", "timing");
|
|
39171
|
+
if (!sdkSession) return declinedCutover("session_unavailable", "timing");
|
|
39172
|
+
if (wrongCompositionFile(deps, targetPath))
|
|
39173
|
+
return declinedCutover("wrong_composition_file", "timing");
|
|
39174
|
+
const unresolved = changes.find((change) => !sdkSession.getElement(change.hfId));
|
|
39175
|
+
if (unresolved)
|
|
39176
|
+
return declinedCutover(
|
|
39177
|
+
"target_not_found",
|
|
39178
|
+
"timing",
|
|
39179
|
+
isResolverDisagreement(sdkSession, unresolved.hfId)
|
|
39180
|
+
);
|
|
39040
39181
|
try {
|
|
39041
39182
|
const serializedBefore = sdkSession.serialize();
|
|
39042
39183
|
const result = await persistSdkCandidateMutation(
|
|
@@ -39091,9 +39232,9 @@ function sdkGsapTweenPersist(targetPath, op, sdkSession, deps, options) {
|
|
|
39091
39232
|
);
|
|
39092
39233
|
}
|
|
39093
39234
|
if (!sdkFamilyEnabled("gsap-animation"))
|
|
39094
|
-
return Promise.resolve(declinedCutover("feature_disabled"));
|
|
39235
|
+
return Promise.resolve(declinedCutover("feature_disabled", "gsap-animation"));
|
|
39095
39236
|
if (op.kind === "add" && sdkSession && !sdkSession.getElement(op.target))
|
|
39096
|
-
return Promise.resolve(declinedCutover("target_not_found"));
|
|
39237
|
+
return Promise.resolve(declinedCutover("target_not_found", "gsap-animation"));
|
|
39097
39238
|
return dispatchGsapOpAndPersist("gsap-animation", targetPath, sdkSession, deps, options, (s) => {
|
|
39098
39239
|
s.batch(() => {
|
|
39099
39240
|
if (op.kind === "add") {
|
|
@@ -39116,9 +39257,10 @@ async function dispatchGsapOpAndPersist(family, targetPath, sdkSession, deps, op
|
|
|
39116
39257
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
39117
39258
|
);
|
|
39118
39259
|
}
|
|
39119
|
-
if (!sdkFamilyEnabled(family)) return declinedCutover("feature_disabled");
|
|
39120
|
-
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
39121
|
-
if (wrongCompositionFile(deps, targetPath))
|
|
39260
|
+
if (!sdkFamilyEnabled(family)) return declinedCutover("feature_disabled", family);
|
|
39261
|
+
if (!sdkSession) return declinedCutover("session_unavailable", family);
|
|
39262
|
+
if (wrongCompositionFile(deps, targetPath))
|
|
39263
|
+
return declinedCutover("wrong_composition_file", family);
|
|
39122
39264
|
const session = sdkSession;
|
|
39123
39265
|
try {
|
|
39124
39266
|
const serializedBefore = session.serialize();
|
|
@@ -39271,10 +39413,16 @@ async function sdkDeletePersist(hfId, originalContent, targetPath, sdkSession, d
|
|
|
39271
39413
|
() => Promise.resolve(originalContent),
|
|
39272
39414
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
39273
39415
|
);
|
|
39274
|
-
if (!sdkFamilyEnabled("lifecycle")) return declinedCutover("feature_disabled");
|
|
39275
|
-
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
39276
|
-
if (!sdkSession.getElement(hfId))
|
|
39277
|
-
|
|
39416
|
+
if (!sdkFamilyEnabled("lifecycle")) return declinedCutover("feature_disabled", "lifecycle");
|
|
39417
|
+
if (!sdkSession) return declinedCutover("session_unavailable", "lifecycle");
|
|
39418
|
+
if (!sdkSession.getElement(hfId))
|
|
39419
|
+
return declinedCutover(
|
|
39420
|
+
"target_not_found",
|
|
39421
|
+
"lifecycle",
|
|
39422
|
+
isResolverDisagreement(sdkSession, hfId)
|
|
39423
|
+
);
|
|
39424
|
+
if (wrongCompositionFile(deps, targetPath))
|
|
39425
|
+
return declinedCutover("wrong_composition_file", "lifecycle");
|
|
39278
39426
|
const result = await persistSdkCandidateMutation(
|
|
39279
39427
|
sdkSession,
|
|
39280
39428
|
targetPath,
|
|
@@ -39518,14 +39666,7 @@ function useElementLifecycleOps({
|
|
|
39518
39666
|
},
|
|
39519
39667
|
[commitDomEditPatchBatches, onReorderShadow]
|
|
39520
39668
|
);
|
|
39521
|
-
const handleDomEditElementDelete = useCallback54(
|
|
39522
|
-
async (selection) => {
|
|
39523
|
-
await handleDomEditElementsDelete([selection]);
|
|
39524
|
-
},
|
|
39525
|
-
[handleDomEditElementsDelete]
|
|
39526
|
-
);
|
|
39527
39669
|
return {
|
|
39528
|
-
handleDomEditElementDelete,
|
|
39529
39670
|
handleDomEditElementsDelete,
|
|
39530
39671
|
handleDomZIndexReorderCommit
|
|
39531
39672
|
};
|
|
@@ -54076,6 +54217,10 @@ function withLane2(automation, lane) {
|
|
|
54076
54217
|
lanes: [...automation.lanes.filter((l) => l.target !== lane.target), lane]
|
|
54077
54218
|
};
|
|
54078
54219
|
}
|
|
54220
|
+
function withPointAt(automation, target, t, v) {
|
|
54221
|
+
const points = automation.lanes.find((lane) => lane.target === target)?.points ?? [];
|
|
54222
|
+
return withLane2(automation, { target, points: mergeInsertPoint(points, t, v) });
|
|
54223
|
+
}
|
|
54079
54224
|
function automationAttrValue(automation) {
|
|
54080
54225
|
return automation.lanes.length > 0 ? serializeAutomation2(automation) : "";
|
|
54081
54226
|
}
|
|
@@ -56939,24 +57084,33 @@ function AudioFxGroup({
|
|
|
56939
57084
|
}
|
|
56940
57085
|
|
|
56941
57086
|
// src/components/editor/useVolumeAutomation.ts
|
|
56942
|
-
import {
|
|
56943
|
-
|
|
57087
|
+
import {
|
|
57088
|
+
HF_AUDIO_AUTOMATION_DATA_KEY as HF_AUDIO_AUTOMATION_DATA_KEY2,
|
|
57089
|
+
sampleAutomationLane as sampleAutomationLane9,
|
|
57090
|
+
VOLUME_TARGET as VOLUME_TARGET2
|
|
57091
|
+
} from "@hyperframes/core/audio-automation";
|
|
57092
|
+
function useVolumeAutomation(element, currentTime, onSetAttributeQuiet) {
|
|
56944
57093
|
const automation = readPanelAutomation(
|
|
56945
57094
|
element.dataAttributes?.[HF_AUDIO_AUTOMATION_DATA_KEY2],
|
|
56946
57095
|
void 0
|
|
56947
57096
|
);
|
|
57097
|
+
const { start: elStart, duration: elDuration } = deriveElementTiming(element);
|
|
57098
|
+
const clipTimeSec = clampNumber(currentTime - elStart, 0, elDuration > 0 ? elDuration : Infinity);
|
|
56948
57099
|
const write = (next) => {
|
|
56949
57100
|
void onSetAttributeQuiet(HF_AUDIO_AUTOMATION_ATTR3, automationAttrValue(next) || null);
|
|
56950
57101
|
};
|
|
56951
57102
|
const raw = element.dataAttributes?.["volume"];
|
|
56952
57103
|
const parsed = raw ? Number(raw) : 1;
|
|
56953
57104
|
const current = Number.isFinite(parsed) ? parsed : 1;
|
|
57105
|
+
const volumeLane = automation.lanes.find((lane) => lane.target === VOLUME_TARGET2);
|
|
56954
57106
|
return {
|
|
56955
|
-
volumeAutomated:
|
|
57107
|
+
volumeAutomated: volumeLane !== void 0,
|
|
57108
|
+
automatedVolumeValue: volumeLane ? sampleAutomationLane9(volumeLane, clipTimeSec) : void 0,
|
|
56956
57109
|
// Seeded at the level the slider already shows, so automating the track does
|
|
56957
57110
|
// not change how loud it is.
|
|
56958
57111
|
onAutomateVolume: () => write(withSeededLane(automation, VOLUME_TARGET2, Number.isFinite(current) ? current : 1)),
|
|
56959
|
-
onRemoveVolumeAutomation: () => write(withoutLane(automation, VOLUME_TARGET2))
|
|
57112
|
+
onRemoveVolumeAutomation: () => write(withoutLane(automation, VOLUME_TARGET2)),
|
|
57113
|
+
onCommitVolumeAt: (v) => write(withPointAt(automation, VOLUME_TARGET2, clipTimeSec, v))
|
|
56960
57114
|
};
|
|
56961
57115
|
}
|
|
56962
57116
|
|
|
@@ -57049,7 +57203,9 @@ function FlatMediaSection({
|
|
|
57049
57203
|
onRemoveBackground,
|
|
57050
57204
|
volumeAutomated,
|
|
57051
57205
|
onAutomateVolume,
|
|
57052
|
-
onRemoveVolumeAutomation
|
|
57206
|
+
onRemoveVolumeAutomation,
|
|
57207
|
+
onCommitVolumeAt,
|
|
57208
|
+
automatedVolumeValue
|
|
57053
57209
|
}) {
|
|
57054
57210
|
const track2 = useTrackDesignInput();
|
|
57055
57211
|
const isVideo = element.tagName === "video";
|
|
@@ -57057,7 +57213,7 @@ function FlatMediaSection({
|
|
|
57057
57213
|
const isImage = element.tagName === "img";
|
|
57058
57214
|
const isVisualMedia = isVideo || isImage;
|
|
57059
57215
|
const el = element.element;
|
|
57060
|
-
const volume = parseNumericValue(element.dataAttributes.volume ?? "") ?? 1;
|
|
57216
|
+
const volume = volumeAutomated && automatedVolumeValue !== void 0 ? automatedVolumeValue : parseNumericValue(element.dataAttributes.volume ?? "") ?? 1;
|
|
57061
57217
|
const volumeFaderPosition = audioGainToFaderPosition2(volume);
|
|
57062
57218
|
const mediaStart = Number.parseFloat(
|
|
57063
57219
|
element.dataAttributes["media-start"] ?? element.dataAttributes["playback-start"] ?? "0"
|
|
@@ -57206,9 +57362,15 @@ function FlatMediaSection({
|
|
|
57206
57362
|
max: AUDIO_GAIN_FADER_MAX2,
|
|
57207
57363
|
tier: volume === 1 ? "default" : "explicitCustom",
|
|
57208
57364
|
displayValue: audioGainToText2(volume),
|
|
57209
|
-
disabled: volumeAutomated,
|
|
57210
57365
|
centerTick: true,
|
|
57211
|
-
onCommit: (next) =>
|
|
57366
|
+
onCommit: (next) => {
|
|
57367
|
+
const gain = audioFaderPositionToGain2(next);
|
|
57368
|
+
if (volumeAutomated) {
|
|
57369
|
+
onCommitVolumeAt?.(gain);
|
|
57370
|
+
} else {
|
|
57371
|
+
void onSetAttribute("volume", formatAudioGain2(gain));
|
|
57372
|
+
}
|
|
57373
|
+
}
|
|
57212
57374
|
}
|
|
57213
57375
|
) }),
|
|
57214
57376
|
/* @__PURE__ */ jsx142(
|
|
@@ -60887,7 +61049,11 @@ function PropertyPanelFlat({
|
|
|
60887
61049
|
const audioSelection = isAudioDomElement(element.element);
|
|
60888
61050
|
const showMotionEffects = gsapEffectHandlers !== null && !audioSelection;
|
|
60889
61051
|
const showMotionGroup = showMotionTiming || showMotionEffects;
|
|
60890
|
-
const volumeAutomation = useVolumeAutomation(
|
|
61052
|
+
const volumeAutomation = useVolumeAutomation(
|
|
61053
|
+
element,
|
|
61054
|
+
currentTime,
|
|
61055
|
+
onSetAttributeQuiet ?? onSetAttributeLive
|
|
61056
|
+
);
|
|
60891
61057
|
const audioGroupLabel = useMemo52(() => {
|
|
60892
61058
|
const doc = element.element?.ownerDocument;
|
|
60893
61059
|
const id = element.id;
|
|
@@ -62730,7 +62896,7 @@ var FileTree = memo34(function FileTree2({
|
|
|
62730
62896
|
});
|
|
62731
62897
|
|
|
62732
62898
|
// src/App.tsx
|
|
62733
|
-
import { useState as
|
|
62899
|
+
import { useState as useState157, useCallback as useCallback176, useRef as useRef175, useMemo as useMemo78, useLayoutEffect as useLayoutEffect11 } from "react";
|
|
62734
62900
|
|
|
62735
62901
|
// src/components/renders/useRenderQueue.ts
|
|
62736
62902
|
import { useState as useState95, useEffect as useEffect89, useCallback as useCallback80, useRef as useRef104, useMemo as useMemo56 } from "react";
|
|
@@ -65147,45 +65313,70 @@ function usePanelLayout(initialState2) {
|
|
|
65147
65313
|
}
|
|
65148
65314
|
|
|
65149
65315
|
// src/hooks/useFileManager.ts
|
|
65150
|
-
import { useState as useState103, useCallback as useCallback88, useMemo as useMemo59, useRef as
|
|
65316
|
+
import { useState as useState103, useCallback as useCallback88, useMemo as useMemo59, useRef as useRef115 } from "react";
|
|
65151
65317
|
|
|
65152
65318
|
// src/hooks/useFileTree.ts
|
|
65153
|
-
import { useState as useState102, useCallback as useCallback86, useEffect as useEffect94, useMemo as useMemo58 } from "react";
|
|
65319
|
+
import { useState as useState102, useCallback as useCallback86, useEffect as useEffect94, useMemo as useMemo58, useRef as useRef113 } from "react";
|
|
65320
|
+
var EMPTY_FILE_LIST = [];
|
|
65154
65321
|
function useFileTree({ projectId, projectIdRef }) {
|
|
65155
|
-
const [
|
|
65156
|
-
const
|
|
65157
|
-
const
|
|
65158
|
-
const
|
|
65322
|
+
const [fetched, setFetched] = useState102(null);
|
|
65323
|
+
const current = fetched?.projectId === projectId ? fetched : null;
|
|
65324
|
+
const fileTree = current?.fileTree ?? EMPTY_FILE_LIST;
|
|
65325
|
+
const compositionPaths = current?.compositionPaths ?? EMPTY_FILE_LIST;
|
|
65326
|
+
const projectDir = current?.projectDir ?? null;
|
|
65327
|
+
const fileTreeLoaded = current?.loaded ?? false;
|
|
65159
65328
|
useEffect94(() => {
|
|
65160
|
-
if (!projectId)
|
|
65161
|
-
setFileTreeLoaded(false);
|
|
65162
|
-
return;
|
|
65163
|
-
}
|
|
65329
|
+
if (!projectId) return;
|
|
65164
65330
|
let cancelled = false;
|
|
65165
|
-
|
|
65331
|
+
setFetched({ projectId, loaded: false, fileTree: [], compositionPaths: [], projectDir: null });
|
|
65166
65332
|
fetch(buildProjectApiPath(projectId)).then((r) => r.json()).then((data) => {
|
|
65167
65333
|
if (cancelled) return;
|
|
65168
|
-
|
|
65169
|
-
|
|
65170
|
-
|
|
65334
|
+
setFetched({
|
|
65335
|
+
projectId,
|
|
65336
|
+
loaded: true,
|
|
65337
|
+
fileTree: data.files ?? [],
|
|
65338
|
+
compositionPaths: data.compositions ?? [],
|
|
65339
|
+
projectDir: typeof data.dir === "string" ? data.dir : null
|
|
65340
|
+
});
|
|
65171
65341
|
void captureProjectProvenance(projectId, data.files ?? [], data.compositions ?? []);
|
|
65172
65342
|
}).catch(() => {
|
|
65173
|
-
if (!cancelled)
|
|
65174
|
-
|
|
65175
|
-
|
|
65343
|
+
if (!cancelled) {
|
|
65344
|
+
setFetched((prev) => prev?.projectId === projectId ? { ...prev, loaded: true } : prev);
|
|
65345
|
+
}
|
|
65176
65346
|
});
|
|
65177
65347
|
return () => {
|
|
65178
65348
|
cancelled = true;
|
|
65179
65349
|
};
|
|
65180
65350
|
}, [projectId]);
|
|
65351
|
+
const refreshRequestRef = useRef113(0);
|
|
65352
|
+
const refreshAbortRef = useRef113(null);
|
|
65181
65353
|
const refreshFileTree = useCallback86(async () => {
|
|
65182
65354
|
const pid = projectIdRef.current;
|
|
65183
65355
|
if (!pid) return;
|
|
65184
|
-
|
|
65185
|
-
const
|
|
65186
|
-
|
|
65356
|
+
refreshAbortRef.current?.abort();
|
|
65357
|
+
const requestId = ++refreshRequestRef.current;
|
|
65358
|
+
const controller = new AbortController();
|
|
65359
|
+
refreshAbortRef.current = controller;
|
|
65360
|
+
let data;
|
|
65361
|
+
try {
|
|
65362
|
+
const res = await fetch(buildProjectApiPath(pid), { signal: controller.signal });
|
|
65363
|
+
data = await res.json();
|
|
65364
|
+
} catch (err) {
|
|
65365
|
+
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
65366
|
+
throw err;
|
|
65367
|
+
}
|
|
65368
|
+
if (data.files && requestId === refreshRequestRef.current) {
|
|
65369
|
+
setFetched(
|
|
65370
|
+
(prev) => prev?.projectId === pid ? {
|
|
65371
|
+
...prev,
|
|
65372
|
+
fileTree: data.files ?? prev.fileTree,
|
|
65373
|
+
// A response that omits `compositions` must not wipe out a
|
|
65374
|
+
// known-good list — only replace it when the field is present.
|
|
65375
|
+
compositionPaths: data.compositions ?? prev.compositionPaths
|
|
65376
|
+
} : prev
|
|
65377
|
+
);
|
|
65378
|
+
}
|
|
65187
65379
|
}, [projectIdRef]);
|
|
65188
|
-
const compositions = compositionPaths;
|
|
65189
65380
|
const assets = useMemo58(
|
|
65190
65381
|
() => fileTree.filter((f) => !f.endsWith(".html") && !f.endsWith(".md") && !f.endsWith(".json")),
|
|
65191
65382
|
[fileTree]
|
|
@@ -65201,17 +65392,16 @@ function useFileTree({ projectId, projectIdRef }) {
|
|
|
65201
65392
|
return {
|
|
65202
65393
|
projectDir,
|
|
65203
65394
|
fileTree,
|
|
65204
|
-
setFileTree,
|
|
65205
65395
|
fileTreeLoaded,
|
|
65206
65396
|
refreshFileTree,
|
|
65207
|
-
compositions,
|
|
65397
|
+
compositions: compositionPaths,
|
|
65208
65398
|
assets,
|
|
65209
65399
|
fontAssets
|
|
65210
65400
|
};
|
|
65211
65401
|
}
|
|
65212
65402
|
|
|
65213
65403
|
// src/hooks/useEditorSave.ts
|
|
65214
|
-
import { useCallback as useCallback87, useRef as
|
|
65404
|
+
import { useCallback as useCallback87, useRef as useRef114 } from "react";
|
|
65215
65405
|
var FAILURE_BURST_MS = 5e3;
|
|
65216
65406
|
function useEditorSave({
|
|
65217
65407
|
editingPathRef,
|
|
@@ -65222,13 +65412,13 @@ function useEditorSave({
|
|
|
65222
65412
|
setRefreshKey,
|
|
65223
65413
|
showToast
|
|
65224
65414
|
}) {
|
|
65225
|
-
const saveRafRef =
|
|
65226
|
-
const refreshRafRef =
|
|
65227
|
-
const lastFailureToastAtRef =
|
|
65228
|
-
const lastFailureReportRef =
|
|
65229
|
-
const pendingCandidateRef =
|
|
65230
|
-
const inFlightRef =
|
|
65231
|
-
const inFlightCandidateRef =
|
|
65415
|
+
const saveRafRef = useRef114(null);
|
|
65416
|
+
const refreshRafRef = useRef114(null);
|
|
65417
|
+
const lastFailureToastAtRef = useRef114(null);
|
|
65418
|
+
const lastFailureReportRef = useRef114(null);
|
|
65419
|
+
const pendingCandidateRef = useRef114(null);
|
|
65420
|
+
const inFlightRef = useRef114(null);
|
|
65421
|
+
const inFlightCandidateRef = useRef114(null);
|
|
65232
65422
|
const reportFailure = useCallback87(
|
|
65233
65423
|
(path, error) => {
|
|
65234
65424
|
const now2 = Date.now();
|
|
@@ -65344,11 +65534,11 @@ function useFileManager({
|
|
|
65344
65534
|
}) {
|
|
65345
65535
|
const [editingFile, setEditingFile] = useState103(null);
|
|
65346
65536
|
const [revealSourceOffset, setRevealSourceOffset] = useState103(null);
|
|
65347
|
-
const editingPathRef =
|
|
65537
|
+
const editingPathRef = useRef115(editingFile?.path);
|
|
65348
65538
|
editingPathRef.current = editingFile?.path;
|
|
65349
|
-
const projectIdRef =
|
|
65539
|
+
const projectIdRef = useRef115(projectId);
|
|
65350
65540
|
projectIdRef.current = projectId;
|
|
65351
|
-
const importedFontAssetsRef =
|
|
65541
|
+
const importedFontAssetsRef = useRef115([]);
|
|
65352
65542
|
const fileVersionScope = useMemo59(
|
|
65353
65543
|
() => ({ projectId, versions: /* @__PURE__ */ new Map() }),
|
|
65354
65544
|
[projectId]
|
|
@@ -65363,7 +65553,6 @@ function useFileManager({
|
|
|
65363
65553
|
const {
|
|
65364
65554
|
projectDir,
|
|
65365
65555
|
fileTree,
|
|
65366
|
-
setFileTree,
|
|
65367
65556
|
fileTreeLoaded,
|
|
65368
65557
|
refreshFileTree,
|
|
65369
65558
|
compositions,
|
|
@@ -65498,8 +65687,8 @@ function useFileManager({
|
|
|
65498
65687
|
},
|
|
65499
65688
|
[fileVersions, updateEditingFileContent, writeProjectFile]
|
|
65500
65689
|
);
|
|
65501
|
-
const revealRequestIdRef =
|
|
65502
|
-
const revealAbortRef =
|
|
65690
|
+
const revealRequestIdRef = useRef115(0);
|
|
65691
|
+
const revealAbortRef = useRef115(null);
|
|
65503
65692
|
const handleFileSelect = useCallback88(
|
|
65504
65693
|
(path) => {
|
|
65505
65694
|
const pid = projectIdRef.current;
|
|
@@ -65747,7 +65936,6 @@ function useFileManager({
|
|
|
65747
65936
|
projectDir,
|
|
65748
65937
|
fileTree,
|
|
65749
65938
|
fileTreeLoaded,
|
|
65750
|
-
setFileTree,
|
|
65751
65939
|
// Refs
|
|
65752
65940
|
editingPathRef,
|
|
65753
65941
|
projectIdRef,
|
|
@@ -65787,7 +65975,7 @@ function useFileManager({
|
|
|
65787
65975
|
}
|
|
65788
65976
|
|
|
65789
65977
|
// src/hooks/usePreviewPersistence.ts
|
|
65790
|
-
import { useCallback as useCallback89, useRef as
|
|
65978
|
+
import { useCallback as useCallback89, useRef as useRef116, useState as useState104 } from "react";
|
|
65791
65979
|
|
|
65792
65980
|
// src/utils/gsapUndoRestore.ts
|
|
65793
65981
|
function elementIdentityKey(el) {
|
|
@@ -66023,11 +66211,11 @@ function usePreviewPersistence({
|
|
|
66023
66211
|
}) {
|
|
66024
66212
|
void _recordEdit;
|
|
66025
66213
|
const [domEditSaveQueuePaused, setDomEditSaveQueuePaused] = useState104(null);
|
|
66026
|
-
const domTextCommitVersionRef =
|
|
66027
|
-
const showToastRef =
|
|
66214
|
+
const domTextCommitVersionRef = useRef116(0);
|
|
66215
|
+
const showToastRef = useRef116(showToast);
|
|
66028
66216
|
showToastRef.current = showToast;
|
|
66029
|
-
const domEditSaveQueueRef =
|
|
66030
|
-
const applyStudioManualEditsToPreviewRef =
|
|
66217
|
+
const domEditSaveQueueRef = useRef116(null);
|
|
66218
|
+
const applyStudioManualEditsToPreviewRef = useRef116(async () => {
|
|
66031
66219
|
});
|
|
66032
66220
|
if (!domEditSaveQueueRef.current) {
|
|
66033
66221
|
domEditSaveQueueRef.current = createDomEditSaveQueue({
|
|
@@ -66120,10 +66308,10 @@ function usePreviewPersistence({
|
|
|
66120
66308
|
}
|
|
66121
66309
|
|
|
66122
66310
|
// src/hooks/usePreviewDocumentVersion.ts
|
|
66123
|
-
import { useCallback as useCallback90, useEffect as useEffect95, useRef as
|
|
66311
|
+
import { useCallback as useCallback90, useEffect as useEffect95, useRef as useRef117, useState as useState105 } from "react";
|
|
66124
66312
|
function usePreviewDocumentVersion() {
|
|
66125
66313
|
const [previewDocumentVersion, setPreviewDocumentVersion] = useState105(0);
|
|
66126
|
-
const refreshTimersRef =
|
|
66314
|
+
const refreshTimersRef = useRef117([]);
|
|
66127
66315
|
const refresh = useCallback90(() => {
|
|
66128
66316
|
for (const id of refreshTimersRef.current) clearTimeout(id);
|
|
66129
66317
|
refreshTimersRef.current = [];
|
|
@@ -66143,10 +66331,10 @@ function usePreviewDocumentVersion() {
|
|
|
66143
66331
|
}
|
|
66144
66332
|
|
|
66145
66333
|
// src/hooks/useTimelineEditing.ts
|
|
66146
|
-
import { useCallback as useCallback100, useRef as
|
|
66334
|
+
import { useCallback as useCallback100, useRef as useRef121 } from "react";
|
|
66147
66335
|
|
|
66148
66336
|
// src/hooks/useRazorSplit.ts
|
|
66149
|
-
import { useCallback as useCallback91, useRef as
|
|
66337
|
+
import { useCallback as useCallback91, useRef as useRef118 } from "react";
|
|
66150
66338
|
|
|
66151
66339
|
// src/utils/razorSplitTransaction.ts
|
|
66152
66340
|
function targetIdentity(path, target) {
|
|
@@ -66164,7 +66352,10 @@ function buildCutTarget(element, target, splitTime) {
|
|
|
66164
66352
|
elementDuration: element.duration,
|
|
66165
66353
|
...element.playbackStart != null ? { playbackStart: element.playbackStart } : {},
|
|
66166
66354
|
...element.playbackRate != null ? { playbackRate: element.playbackRate } : {},
|
|
66167
|
-
...element.kind === "composition" ? { isComposition: true } : {}
|
|
66355
|
+
...element.kind === "composition" ? { isComposition: true } : {},
|
|
66356
|
+
// Pin both halves to the current track: unstamped, the runtime's positional
|
|
66357
|
+
// fallback (parseAuthoredTrack) renumbers the new sibling onto a new row.
|
|
66358
|
+
track: resolveElementTrack(element)
|
|
66168
66359
|
};
|
|
66169
66360
|
}
|
|
66170
66361
|
function buildAtomicCutIntents(elements, splitTime, activeCompPath) {
|
|
@@ -66278,7 +66469,7 @@ function useRazorSplit({
|
|
|
66278
66469
|
forceReloadSdkSession,
|
|
66279
66470
|
isRecordingRef
|
|
66280
66471
|
}) {
|
|
66281
|
-
const projectIdRef =
|
|
66472
|
+
const projectIdRef = useRef118(projectId);
|
|
66282
66473
|
projectIdRef.current = projectId;
|
|
66283
66474
|
const synchronize = useCallback91(() => {
|
|
66284
66475
|
let failure;
|
|
@@ -66479,22 +66670,25 @@ function useTimelineAssetDropOps({
|
|
|
66479
66670
|
(te) => (te.sourceFile || activeCompPath || "index.html") === resolvedTargetPath
|
|
66480
66671
|
);
|
|
66481
66672
|
const newElementZIndex = Math.max(1, relevantElements.length + 1);
|
|
66482
|
-
const patchedContent =
|
|
66483
|
-
|
|
66484
|
-
|
|
66485
|
-
|
|
66486
|
-
|
|
66487
|
-
|
|
66488
|
-
|
|
66489
|
-
|
|
66490
|
-
|
|
66491
|
-
|
|
66492
|
-
|
|
66493
|
-
|
|
66494
|
-
|
|
66495
|
-
|
|
66496
|
-
|
|
66497
|
-
|
|
66673
|
+
const patchedContent = extendRootDurationInSource(
|
|
66674
|
+
insertTimelineAssetIntoSource(
|
|
66675
|
+
originalContent,
|
|
66676
|
+
buildTimelineAssetInsertHtml({
|
|
66677
|
+
id: newId,
|
|
66678
|
+
hfId: `hf-${generateId()}`,
|
|
66679
|
+
assetPath: resolvedAssetSrc,
|
|
66680
|
+
kind,
|
|
66681
|
+
start: normalizedStart,
|
|
66682
|
+
duration: normalizedDuration,
|
|
66683
|
+
track: placement.track,
|
|
66684
|
+
zIndex: newElementZIndex,
|
|
66685
|
+
geometry: fitTimelineAssetGeometry(
|
|
66686
|
+
null,
|
|
66687
|
+
resolveTimelineAssetCompositionSize(originalContent)
|
|
66688
|
+
)
|
|
66689
|
+
})
|
|
66690
|
+
),
|
|
66691
|
+
normalizedStart + normalizedDuration
|
|
66498
66692
|
);
|
|
66499
66693
|
await saveProjectFilesWithHistory({
|
|
66500
66694
|
projectId: pid,
|
|
@@ -66835,7 +67029,16 @@ function useSetElementAttribute({
|
|
|
66835
67029
|
}
|
|
66836
67030
|
|
|
66837
67031
|
// src/hooks/useTimelineDeleteOps.ts
|
|
66838
|
-
import { useCallback as useCallback95 } from "react";
|
|
67032
|
+
import { useCallback as useCallback95, useRef as useRef119 } from "react";
|
|
67033
|
+
function applyRippleShifts(survivors, changes) {
|
|
67034
|
+
if (!changes) return survivors;
|
|
67035
|
+
const newStartByElement = new Map(changes.map((c) => [c.element, c.start]));
|
|
67036
|
+
return survivors.map((te) => {
|
|
67037
|
+
const newStart = newStartByElement.get(te);
|
|
67038
|
+
return newStart != null ? { ...te, start: newStart } : te;
|
|
67039
|
+
});
|
|
67040
|
+
}
|
|
67041
|
+
var deleteGestureSeq = 0;
|
|
66839
67042
|
function useTimelineDeleteOps({
|
|
66840
67043
|
projectIdRef,
|
|
66841
67044
|
activeCompPath,
|
|
@@ -66846,8 +67049,10 @@ function useTimelineDeleteOps({
|
|
|
66846
67049
|
reloadPreview,
|
|
66847
67050
|
isRecordingRef,
|
|
66848
67051
|
forceReloadSdkSession,
|
|
66849
|
-
previewIframeRef
|
|
67052
|
+
previewIframeRef,
|
|
67053
|
+
handleTimelineGroupMove
|
|
66850
67054
|
}) {
|
|
67055
|
+
const rippleNoticeShownRef = useRef119(false);
|
|
66851
67056
|
const handleTimelineElementsDelete = useCallback95(
|
|
66852
67057
|
// fallow-ignore-next-line complexity
|
|
66853
67058
|
async (selection) => {
|
|
@@ -66895,11 +67100,14 @@ function useTimelineDeleteOps({
|
|
|
66895
67100
|
if (deleteContentEnd > 0 && targetPath === (activeCompPath || "index.html")) {
|
|
66896
67101
|
usePlayerStore.getState().setDuration(deleteContentEnd);
|
|
66897
67102
|
}
|
|
67103
|
+
const coalesceKey = `main-track-ripple-delete:${deleteGestureSeq++}`;
|
|
67104
|
+
const deleteHistoryLabel = "Delete timeline clip";
|
|
66898
67105
|
try {
|
|
66899
67106
|
await saveProjectFilesWithHistory({
|
|
66900
67107
|
projectId: pid,
|
|
66901
|
-
label:
|
|
67108
|
+
label: deleteHistoryLabel,
|
|
66902
67109
|
kind: "timeline",
|
|
67110
|
+
coalesceKey,
|
|
66903
67111
|
files: { [targetPath]: patchedContent },
|
|
66904
67112
|
readFile: async () => originalContent,
|
|
66905
67113
|
// remove-element already wrote the removal, so disk holds THAT — not the
|
|
@@ -66913,15 +67121,53 @@ function useTimelineDeleteOps({
|
|
|
66913
67121
|
throw error;
|
|
66914
67122
|
}
|
|
66915
67123
|
const deletedKeys = new Set(sameFile.map((te) => te.key ?? te.id));
|
|
66916
|
-
|
|
67124
|
+
const survivors = timelineElements.filter((te) => !deletedKeys.has(te.key ?? te.id));
|
|
67125
|
+
const rippleShifts = resolveMainTrackDeleteRippleShifts(
|
|
67126
|
+
survivors,
|
|
67127
|
+
sameFile,
|
|
67128
|
+
usePlayerStore.getState().rippleEditEnabled
|
|
67129
|
+
);
|
|
67130
|
+
let rippleApplied = null;
|
|
67131
|
+
let rippleFailed = false;
|
|
67132
|
+
if (rippleShifts) {
|
|
67133
|
+
const rippleChanges = resolveShiftedElements(survivors, rippleShifts);
|
|
67134
|
+
try {
|
|
67135
|
+
await handleTimelineGroupMove(rippleChanges, {
|
|
67136
|
+
coalesceKey,
|
|
67137
|
+
coalesceMs: Number.POSITIVE_INFINITY,
|
|
67138
|
+
// Coalescing keeps the LAST entry's label; without this the undo
|
|
67139
|
+
// toast reads "Undid Move timeline clips" after a delete, naming
|
|
67140
|
+
// the ripple's mechanics instead of what the user actually did.
|
|
67141
|
+
label: deleteHistoryLabel,
|
|
67142
|
+
// This call gets its own, more specific failure toast below —
|
|
67143
|
+
// the generic one would tell the user about one action twice.
|
|
67144
|
+
suppressFailureToast: true
|
|
67145
|
+
});
|
|
67146
|
+
rippleApplied = rippleChanges;
|
|
67147
|
+
} catch (error) {
|
|
67148
|
+
rippleFailed = true;
|
|
67149
|
+
console.error("[Timeline] ripple-edit failed to persist after delete", error);
|
|
67150
|
+
showToast("Clip deleted, but the gap could not be closed.", "error");
|
|
67151
|
+
}
|
|
67152
|
+
}
|
|
67153
|
+
usePlayerStore.getState().setElements(applyRippleShifts(survivors, rippleApplied));
|
|
66917
67154
|
usePlayerStore.getState().setSelectedElementId(null);
|
|
66918
67155
|
usePlayerStore.getState().setSelectedElementIds(/* @__PURE__ */ new Set());
|
|
66919
67156
|
forceReloadSdkSession?.();
|
|
66920
67157
|
reloadPreview();
|
|
66921
|
-
|
|
66922
|
-
|
|
66923
|
-
|
|
66924
|
-
|
|
67158
|
+
if (!rippleFailed) {
|
|
67159
|
+
showToast(
|
|
67160
|
+
`Deleted ${label}. Use Undo to restore ${sameFile.length === 1 ? "it" : "them"}.`,
|
|
67161
|
+
"info"
|
|
67162
|
+
);
|
|
67163
|
+
}
|
|
67164
|
+
if (rippleApplied && !rippleNoticeShownRef.current) {
|
|
67165
|
+
rippleNoticeShownRef.current = true;
|
|
67166
|
+
showToast(
|
|
67167
|
+
"Ripple closed the gap on the main track. Undo (\u2318Z) restores it, or turn off Ripple in the timeline toolbar.",
|
|
67168
|
+
"info"
|
|
67169
|
+
);
|
|
67170
|
+
}
|
|
66925
67171
|
} catch (error) {
|
|
66926
67172
|
const message = error instanceof Error ? error.message : "Failed to delete timeline clip";
|
|
66927
67173
|
showToast(message);
|
|
@@ -66937,7 +67183,8 @@ function useTimelineDeleteOps({
|
|
|
66937
67183
|
reloadPreview,
|
|
66938
67184
|
isRecordingRef,
|
|
66939
67185
|
forceReloadSdkSession,
|
|
66940
|
-
previewIframeRef
|
|
67186
|
+
previewIframeRef,
|
|
67187
|
+
handleTimelineGroupMove
|
|
66941
67188
|
]
|
|
66942
67189
|
);
|
|
66943
67190
|
const handleTimelineElementDelete = useCallback95(
|
|
@@ -67541,21 +67788,22 @@ function useTimelineGroupEditing({
|
|
|
67541
67788
|
syncPreviewContentDuration(previewIframeRef.current);
|
|
67542
67789
|
const coalesceKey = options?.coalesceKey ?? moveCoalesceKey(changes);
|
|
67543
67790
|
const coalesceMs = options?.coalesceMs;
|
|
67544
|
-
|
|
67791
|
+
const label = options?.label ?? "Move timeline clips";
|
|
67792
|
+
return enqueueGroupOperation(label, async (projectId) => {
|
|
67545
67793
|
await options?.beforeTiming;
|
|
67546
67794
|
const handledBySdk = await trySdkBatchPersist({
|
|
67547
67795
|
changes,
|
|
67548
67796
|
sdkChanges: toSdkTimingChanges(changes, (change) => ({ start: change.start })),
|
|
67549
67797
|
eligible: changes.every((change) => change.track == null),
|
|
67550
67798
|
needsExtension,
|
|
67551
|
-
label
|
|
67799
|
+
label,
|
|
67552
67800
|
coalesceKey,
|
|
67553
67801
|
coalesceMs
|
|
67554
67802
|
});
|
|
67555
67803
|
if (!handledBySdk) {
|
|
67556
67804
|
await persistServerBatch(
|
|
67557
67805
|
projectId,
|
|
67558
|
-
|
|
67806
|
+
label,
|
|
67559
67807
|
changes.map((change) => ({
|
|
67560
67808
|
element: change.element,
|
|
67561
67809
|
buildPatches: (original, target) => buildTimelineMoveTimingPatch(
|
|
@@ -67576,7 +67824,7 @@ function useTimelineGroupEditing({
|
|
|
67576
67824
|
projectId,
|
|
67577
67825
|
iframe: previewIframeRef.current,
|
|
67578
67826
|
reloadPreview,
|
|
67579
|
-
label
|
|
67827
|
+
label,
|
|
67580
67828
|
errorLabel: "Failed to shift GSAP positions",
|
|
67581
67829
|
coalesceKey,
|
|
67582
67830
|
recordEdit,
|
|
@@ -67595,7 +67843,11 @@ function useTimelineGroupEditing({
|
|
|
67595
67843
|
}
|
|
67596
67844
|
}).catch((error) => {
|
|
67597
67845
|
rollbackDuration();
|
|
67598
|
-
|
|
67846
|
+
if (options?.suppressFailureToast) {
|
|
67847
|
+
console.error("[Timeline] group move failed to persist", error);
|
|
67848
|
+
} else {
|
|
67849
|
+
showToast(getStudioSaveErrorMessage(error), "error");
|
|
67850
|
+
}
|
|
67599
67851
|
throw error;
|
|
67600
67852
|
});
|
|
67601
67853
|
},
|
|
@@ -67713,10 +67965,10 @@ function useTimelineGroupEditing({
|
|
|
67713
67965
|
}
|
|
67714
67966
|
|
|
67715
67967
|
// src/hooks/useBlockedTimelineEditToast.ts
|
|
67716
|
-
import { useCallback as useCallback99, useRef as
|
|
67968
|
+
import { useCallback as useCallback99, useRef as useRef120 } from "react";
|
|
67717
67969
|
var BLOCKED_TOAST_INTERVAL_MS = 1500;
|
|
67718
67970
|
function useBlockedTimelineEditToast(showToast) {
|
|
67719
|
-
const lastAtRef =
|
|
67971
|
+
const lastAtRef = useRef120(0);
|
|
67720
67972
|
return useCallback99(
|
|
67721
67973
|
(_element) => {
|
|
67722
67974
|
const now2 = Date.now();
|
|
@@ -67748,9 +68000,9 @@ function useTimelineEditing({
|
|
|
67748
68000
|
invalidateGsapCache,
|
|
67749
68001
|
handleDomZIndexReorderCommitRef
|
|
67750
68002
|
}) {
|
|
67751
|
-
const projectIdRef =
|
|
68003
|
+
const projectIdRef = useRef121(projectId);
|
|
67752
68004
|
projectIdRef.current = projectId;
|
|
67753
|
-
const editQueueRef =
|
|
68005
|
+
const editQueueRef = useRef121(Promise.resolve());
|
|
67754
68006
|
const enqueueEdit = useCallback100(
|
|
67755
68007
|
(element, label, buildPatches, coalesceKey) => {
|
|
67756
68008
|
if (isRecordingRef?.current) {
|
|
@@ -68052,7 +68304,8 @@ function useTimelineEditing({
|
|
|
68052
68304
|
reloadPreview,
|
|
68053
68305
|
isRecordingRef,
|
|
68054
68306
|
forceReloadSdkSession,
|
|
68055
|
-
previewIframeRef
|
|
68307
|
+
previewIframeRef,
|
|
68308
|
+
handleTimelineGroupMove: groupEditing.handleTimelineGroupMove
|
|
68056
68309
|
});
|
|
68057
68310
|
const { handleTimelineAssetDrop, handleTimelineFileDrop, handleTimelineCompositionDrop } = useTimelineAssetDropOps({
|
|
68058
68311
|
projectIdRef,
|
|
@@ -68120,7 +68373,7 @@ function persistTimelineMoveEditsAtomically(edits, coalesceKey, operation, deps,
|
|
|
68120
68373
|
import { useCallback as useCallback123 } from "react";
|
|
68121
68374
|
|
|
68122
68375
|
// src/hooks/useAskAgentModal.ts
|
|
68123
|
-
import { useState as useState106, useCallback as useCallback101, useRef as
|
|
68376
|
+
import { useState as useState106, useCallback as useCallback101, useRef as useRef122, useEffect as useEffect96 } from "react";
|
|
68124
68377
|
function useAskAgentModal({
|
|
68125
68378
|
activeCompPath,
|
|
68126
68379
|
projectDir,
|
|
@@ -68136,7 +68389,7 @@ function useAskAgentModal({
|
|
|
68136
68389
|
);
|
|
68137
68390
|
const [copiedAgentPrompt, setCopiedAgentPrompt] = useState106(false);
|
|
68138
68391
|
const [agentModalOpen, setAgentModalOpen] = useState106(false);
|
|
68139
|
-
const copiedAgentTimerRef =
|
|
68392
|
+
const copiedAgentTimerRef = useRef122(null);
|
|
68140
68393
|
const preloadAgentPromptSnippet = useCallback101(
|
|
68141
68394
|
async (selection) => {
|
|
68142
68395
|
const pid = projectIdRef.current;
|
|
@@ -68231,7 +68484,7 @@ function useAskAgentModal({
|
|
|
68231
68484
|
}
|
|
68232
68485
|
|
|
68233
68486
|
// src/hooks/useDomSelection.ts
|
|
68234
|
-
import { useState as useState107, useCallback as useCallback102, useRef as
|
|
68487
|
+
import { useState as useState107, useCallback as useCallback102, useRef as useRef123, useEffect as useEffect98 } from "react";
|
|
68235
68488
|
|
|
68236
68489
|
// src/utils/domEditHelpers.ts
|
|
68237
68490
|
function domEditSelectionsTargetSame(a, b) {
|
|
@@ -68458,14 +68711,14 @@ function useDomSelection({
|
|
|
68458
68711
|
const [domEditGroupSelections, setDomEditGroupSelections] = useState107([]);
|
|
68459
68712
|
const [domEditHoverSelection, setDomEditHoverSelection] = useState107(null);
|
|
68460
68713
|
const [activeGroupElement, setActiveGroupElementState] = useState107(null);
|
|
68461
|
-
const rightPanelTabRef =
|
|
68714
|
+
const rightPanelTabRef = useRef123(rightPanelTab);
|
|
68462
68715
|
rightPanelTabRef.current = rightPanelTab;
|
|
68463
|
-
const domEditSelectionRef =
|
|
68464
|
-
const domEditGroupSelectionsRef =
|
|
68465
|
-
const domEditHoverSelectionRef =
|
|
68466
|
-
const activeGroupElementRef =
|
|
68467
|
-
const compositionIdentityRef =
|
|
68468
|
-
const timelineSelectSeqRef =
|
|
68716
|
+
const domEditSelectionRef = useRef123(domEditSelection);
|
|
68717
|
+
const domEditGroupSelectionsRef = useRef123(domEditGroupSelections);
|
|
68718
|
+
const domEditHoverSelectionRef = useRef123(domEditHoverSelection);
|
|
68719
|
+
const activeGroupElementRef = useRef123(activeGroupElement);
|
|
68720
|
+
const compositionIdentityRef = useRef123({ activeCompPath, projectId });
|
|
68721
|
+
const timelineSelectSeqRef = useRef123(0);
|
|
68469
68722
|
domEditSelectionRef.current = domEditSelection;
|
|
68470
68723
|
domEditGroupSelectionsRef.current = domEditGroupSelections;
|
|
68471
68724
|
domEditHoverSelectionRef.current = domEditHoverSelection;
|
|
@@ -68660,7 +68913,7 @@ function useDomSelection({
|
|
|
68660
68913
|
},
|
|
68661
68914
|
[applyDomSelection, buildDomSelectionForTimelineElement]
|
|
68662
68915
|
);
|
|
68663
|
-
const refreshDomEditGroupSelectionsFromPreviewRef =
|
|
68916
|
+
const refreshDomEditGroupSelectionsFromPreviewRef = useRef123(async () => {
|
|
68664
68917
|
});
|
|
68665
68918
|
const refreshDomEditSelectionFromPreview = useCallback102(
|
|
68666
68919
|
// fallow-ignore-next-line complexity
|
|
@@ -68818,7 +69071,7 @@ function useDomSelection({
|
|
|
68818
69071
|
}
|
|
68819
69072
|
|
|
68820
69073
|
// src/hooks/usePreviewInteraction.ts
|
|
68821
|
-
import { useCallback as useCallback103, useRef as
|
|
69074
|
+
import { useCallback as useCallback103, useRef as useRef124 } from "react";
|
|
68822
69075
|
var CYCLE_RADIUS_PX = 6;
|
|
68823
69076
|
var CYCLE_WINDOW_MS = 600;
|
|
68824
69077
|
var DOUBLE_CLICK_MS = 400;
|
|
@@ -68835,8 +69088,8 @@ function usePreviewInteraction({
|
|
|
68835
69088
|
setActiveGroupElement,
|
|
68836
69089
|
onClickToSource
|
|
68837
69090
|
}) {
|
|
68838
|
-
const cycleRef =
|
|
68839
|
-
const lastDownRef =
|
|
69091
|
+
const cycleRef = useRef124(null);
|
|
69092
|
+
const lastDownRef = useRef124(null);
|
|
68840
69093
|
const pausePreviewPlayback = useCallback103(() => {
|
|
68841
69094
|
const pausedTime = pauseStudioPreviewPlayback(previewIframeRef.current);
|
|
68842
69095
|
const playerStore = usePlayerStore.getState();
|
|
@@ -68994,7 +69247,7 @@ function usePreviewInteraction({
|
|
|
68994
69247
|
}
|
|
68995
69248
|
|
|
68996
69249
|
// src/hooks/useDomEditCommits.ts
|
|
68997
|
-
import { useCallback as useCallback108, useRef as
|
|
69250
|
+
import { useCallback as useCallback108, useRef as useRef127 } from "react";
|
|
68998
69251
|
import { findUnsafeDomPatchValues as findUnsafeDomPatchValues2 } from "@hyperframes/core/studio-api/finite-mutation";
|
|
68999
69252
|
|
|
69000
69253
|
// src/utils/studioFontHelpers.ts
|
|
@@ -69155,7 +69408,7 @@ function useDomEditPositionPatchCommit({
|
|
|
69155
69408
|
}
|
|
69156
69409
|
|
|
69157
69410
|
// src/hooks/useDomEditTextCommits.ts
|
|
69158
|
-
import { useCallback as useCallback106, useRef as
|
|
69411
|
+
import { useCallback as useCallback106, useRef as useRef126 } from "react";
|
|
69159
69412
|
|
|
69160
69413
|
// src/hooks/domEditTextFieldCommitOps.ts
|
|
69161
69414
|
function hasSameKeysInSamePositions(originalFields, nextFields) {
|
|
@@ -69210,7 +69463,7 @@ function planDomTextCommit(originalTextFields, nextTextFields, plainTextContent)
|
|
|
69210
69463
|
}
|
|
69211
69464
|
|
|
69212
69465
|
// src/hooks/useDomEditAttributeCommits.ts
|
|
69213
|
-
import { useCallback as useCallback105, useRef as
|
|
69466
|
+
import { useCallback as useCallback105, useRef as useRef125 } from "react";
|
|
69214
69467
|
import { HF_AUDIO_GROUP_ATTR as HF_AUDIO_GROUP_ATTR5, HF_AUDIO_GROUP_TAG as HF_AUDIO_GROUP_TAG8 } from "@hyperframes/core/audio-groups";
|
|
69215
69468
|
function resolveFullAttrName(attr, prefixData) {
|
|
69216
69469
|
return prefixData && !attr.startsWith("data-") ? `data-${attr}` : attr;
|
|
@@ -69250,7 +69503,7 @@ function useDomEditAttributeCommits({
|
|
|
69250
69503
|
refreshDomEditSelectionFromPreview,
|
|
69251
69504
|
persistDomEditOperations
|
|
69252
69505
|
}) {
|
|
69253
|
-
const domAttributeCommitVersionRef =
|
|
69506
|
+
const domAttributeCommitVersionRef = useRef125(/* @__PURE__ */ new Map());
|
|
69254
69507
|
const commitDataAttribute = useCallback105(
|
|
69255
69508
|
async (attr, value, options) => {
|
|
69256
69509
|
if (!domEditSelection) return;
|
|
@@ -69532,8 +69785,8 @@ function useDomEditTextCommits({
|
|
|
69532
69785
|
persistDomEditOperations,
|
|
69533
69786
|
resolveImportedFontAsset
|
|
69534
69787
|
}) {
|
|
69535
|
-
const domTextCommitVersionRef =
|
|
69536
|
-
const domStyleCommitVersionRef =
|
|
69788
|
+
const domTextCommitVersionRef = useRef126(/* @__PURE__ */ new Map());
|
|
69789
|
+
const domStyleCommitVersionRef = useRef126(/* @__PURE__ */ new Map());
|
|
69537
69790
|
const {
|
|
69538
69791
|
handleDomAttributeCommit,
|
|
69539
69792
|
handleDomAttributeLiveCommit,
|
|
@@ -70444,7 +70697,7 @@ function useDomEditCommits({
|
|
|
70444
70697
|
},
|
|
70445
70698
|
[fileTree, projectId, importedFontAssetsRef]
|
|
70446
70699
|
);
|
|
70447
|
-
const reportedUnresolvableRef =
|
|
70700
|
+
const reportedUnresolvableRef = useRef127(/* @__PURE__ */ new Set());
|
|
70448
70701
|
const performPersistDomEditOperations = useCallback108(
|
|
70449
70702
|
// fallow-ignore-next-line complexity
|
|
70450
70703
|
async (selection, operations, options, expectedProjectId) => {
|
|
@@ -70689,7 +70942,7 @@ function useDomEditCommits({
|
|
|
70689
70942
|
showToast,
|
|
70690
70943
|
commitPositionPatchToHtml
|
|
70691
70944
|
});
|
|
70692
|
-
const {
|
|
70945
|
+
const { handleDomEditElementsDelete, handleDomZIndexReorderCommit } = useElementLifecycleOps({
|
|
70693
70946
|
activeCompPath,
|
|
70694
70947
|
showToast,
|
|
70695
70948
|
writeProjectFile,
|
|
@@ -70722,7 +70975,6 @@ function useDomEditCommits({
|
|
|
70722
70975
|
handleDomBoxSizeCommit,
|
|
70723
70976
|
handleDomRotationCommit,
|
|
70724
70977
|
handleDomManualEditsReset,
|
|
70725
|
-
handleDomEditElementDelete,
|
|
70726
70978
|
handleDomEditElementsDelete,
|
|
70727
70979
|
handleDomZIndexReorderCommit
|
|
70728
70980
|
};
|
|
@@ -70730,13 +70982,21 @@ function useDomEditCommits({
|
|
|
70730
70982
|
|
|
70731
70983
|
// src/hooks/useGroupCommits.ts
|
|
70732
70984
|
import { useCallback as useCallback109 } from "react";
|
|
70733
|
-
function
|
|
70985
|
+
function resolveAuthoredTrack(selection, timelineElements) {
|
|
70986
|
+
const id = findMatchingTimelineElementId(selection, timelineElements);
|
|
70987
|
+
if (!id) return void 0;
|
|
70988
|
+
const match = timelineElements.find((el) => (el.key ?? el.id) === id);
|
|
70989
|
+
if (!match) return void 0;
|
|
70990
|
+
return resolveElementTrack(match);
|
|
70991
|
+
}
|
|
70992
|
+
function computeGroupGeometry(members, timelineElements) {
|
|
70734
70993
|
const boxes = members.map((m) => ({
|
|
70735
70994
|
target: buildDomEditPatchTarget(m),
|
|
70736
70995
|
left: m.element.offsetLeft,
|
|
70737
70996
|
top: m.element.offsetTop,
|
|
70738
70997
|
right: m.element.offsetLeft + m.element.offsetWidth,
|
|
70739
|
-
bottom: m.element.offsetTop + m.element.offsetHeight
|
|
70998
|
+
bottom: m.element.offsetTop + m.element.offsetHeight,
|
|
70999
|
+
track: resolveAuthoredTrack(m, timelineElements)
|
|
70740
71000
|
}));
|
|
70741
71001
|
const left = Math.min(...boxes.map((b) => b.left));
|
|
70742
71002
|
const top = Math.min(...boxes.map((b) => b.top));
|
|
@@ -70745,9 +71005,29 @@ function computeGroupGeometry(members) {
|
|
|
70745
71005
|
return {
|
|
70746
71006
|
bbox: { left, top, width, height },
|
|
70747
71007
|
targets: boxes.map((b) => b.target),
|
|
70748
|
-
rebases: boxes.map((b) => ({
|
|
71008
|
+
rebases: boxes.map((b) => ({
|
|
71009
|
+
target: b.target,
|
|
71010
|
+
left: b.left - left,
|
|
71011
|
+
top: b.top - top,
|
|
71012
|
+
track: b.track
|
|
71013
|
+
}))
|
|
70749
71014
|
};
|
|
70750
71015
|
}
|
|
71016
|
+
function resolveGroupChildTracks(group, timelineElements) {
|
|
71017
|
+
const sourceFile = group.sourceFile || "index.html";
|
|
71018
|
+
const result = [];
|
|
71019
|
+
for (const child of Array.from(group.element.children)) {
|
|
71020
|
+
const id = child.id || void 0;
|
|
71021
|
+
const hfId = readHfId(child);
|
|
71022
|
+
if (!id && !hfId) continue;
|
|
71023
|
+
const track2 = resolveAuthoredTrack(
|
|
71024
|
+
{ id, hfId, sourceFile, isCompositionHost: false },
|
|
71025
|
+
timelineElements
|
|
71026
|
+
);
|
|
71027
|
+
result.push({ target: buildDomEditPatchTarget({ id, hfId }), track: track2 });
|
|
71028
|
+
}
|
|
71029
|
+
return result;
|
|
71030
|
+
}
|
|
70751
71031
|
async function commitStructuralMutation(pid, targetPath, route, body, label, deps) {
|
|
70752
71032
|
const originalContent = await readProjectFileContent(pid, targetPath);
|
|
70753
71033
|
const mutateResponse = await fetch(
|
|
@@ -70779,7 +71059,7 @@ async function commitStructuralMutation(pid, targetPath, route, body, label, dep
|
|
|
70779
71059
|
return mutateData;
|
|
70780
71060
|
}
|
|
70781
71061
|
function useGroupCommits(params) {
|
|
70782
|
-
const { activeCompPath, showToast, projectIdRef } = params;
|
|
71062
|
+
const { activeCompPath, showToast, projectIdRef, timelineElements } = params;
|
|
70783
71063
|
const groupSelection = useCallback109(
|
|
70784
71064
|
async (members) => {
|
|
70785
71065
|
const pid = projectIdRef.current;
|
|
@@ -70791,7 +71071,7 @@ function useGroupCommits(params) {
|
|
|
70791
71071
|
}
|
|
70792
71072
|
const doc = members[0].element.ownerDocument;
|
|
70793
71073
|
const groupId = `Group ${doc.querySelectorAll("[data-hf-group]").length + 1}`;
|
|
70794
|
-
const { bbox, targets, rebases } = computeGroupGeometry(members);
|
|
71074
|
+
const { bbox, targets, rebases } = computeGroupGeometry(members, timelineElements);
|
|
70795
71075
|
try {
|
|
70796
71076
|
const data = await commitStructuralMutation(
|
|
70797
71077
|
pid,
|
|
@@ -70807,19 +71087,20 @@ function useGroupCommits(params) {
|
|
|
70807
71087
|
return null;
|
|
70808
71088
|
}
|
|
70809
71089
|
},
|
|
70810
|
-
[activeCompPath, projectIdRef, showToast, params]
|
|
71090
|
+
[activeCompPath, projectIdRef, showToast, params, timelineElements]
|
|
70811
71091
|
);
|
|
70812
71092
|
const ungroupSelection = useCallback109(
|
|
70813
71093
|
async (group) => {
|
|
70814
71094
|
const pid = projectIdRef.current;
|
|
70815
71095
|
if (!pid) return;
|
|
70816
71096
|
const targetPath = group.sourceFile || activeCompPath || "index.html";
|
|
71097
|
+
const childTracks = resolveGroupChildTracks(group, timelineElements);
|
|
70817
71098
|
try {
|
|
70818
71099
|
await commitStructuralMutation(
|
|
70819
71100
|
pid,
|
|
70820
71101
|
targetPath,
|
|
70821
71102
|
"unwrap-elements",
|
|
70822
|
-
{ target: buildDomEditPatchTarget(group) },
|
|
71103
|
+
{ target: buildDomEditPatchTarget(group), childTracks },
|
|
70823
71104
|
"Ungroup elements",
|
|
70824
71105
|
params
|
|
70825
71106
|
);
|
|
@@ -70827,13 +71108,13 @@ function useGroupCommits(params) {
|
|
|
70827
71108
|
showToast(error instanceof Error ? error.message : "Failed to ungroup elements", "error");
|
|
70828
71109
|
}
|
|
70829
71110
|
},
|
|
70830
|
-
[activeCompPath, projectIdRef, showToast, params]
|
|
71111
|
+
[activeCompPath, projectIdRef, showToast, params, timelineElements]
|
|
70831
71112
|
);
|
|
70832
71113
|
return { groupSelection, ungroupSelection };
|
|
70833
71114
|
}
|
|
70834
71115
|
|
|
70835
71116
|
// src/hooks/useGsapScriptCommits.ts
|
|
70836
|
-
import { useCallback as useCallback115, useMemo as useMemo60, useRef as
|
|
71117
|
+
import { useCallback as useCallback115, useMemo as useMemo60, useRef as useRef129 } from "react";
|
|
70837
71118
|
import { findUnsafeMutationValues } from "@hyperframes/core/studio-api/finite-mutation";
|
|
70838
71119
|
|
|
70839
71120
|
// src/hooks/gsapRuntimePatch.ts
|
|
@@ -71628,7 +71909,7 @@ function useGsapKeyframeOps({
|
|
|
71628
71909
|
}
|
|
71629
71910
|
|
|
71630
71911
|
// src/hooks/useGsapPropertyDebounce.ts
|
|
71631
|
-
import { useCallback as useCallback113, useEffect as useEffect99, useRef as
|
|
71912
|
+
import { useCallback as useCallback113, useEffect as useEffect99, useRef as useRef128 } from "react";
|
|
71632
71913
|
import { parseGsapScriptAcorn } from "@hyperframes/core/gsap-parser-acorn";
|
|
71633
71914
|
var DEBOUNCE_MS = 150;
|
|
71634
71915
|
function mergeTweenProperties(sdkSession, animationId, edited, kind) {
|
|
@@ -71644,9 +71925,9 @@ function mergeTweenProperties(sdkSession, animationId, edited, kind) {
|
|
|
71644
71925
|
}
|
|
71645
71926
|
}
|
|
71646
71927
|
function useGsapPropertyDebounce(commitMutationSafely, sdk) {
|
|
71647
|
-
const pendingPropertyEditRef =
|
|
71648
|
-
const debounceTimerRef =
|
|
71649
|
-
const sdkRef =
|
|
71928
|
+
const pendingPropertyEditRef = useRef128(null);
|
|
71929
|
+
const debounceTimerRef = useRef128(null);
|
|
71930
|
+
const sdkRef = useRef128(sdk);
|
|
71650
71931
|
sdkRef.current = sdk;
|
|
71651
71932
|
const flushPendingPropertyEdit = useCallback113(async () => {
|
|
71652
71933
|
const pending2 = pendingPropertyEditRef.current;
|
|
@@ -72077,9 +72358,9 @@ function instantPatchesFor(options) {
|
|
|
72077
72358
|
}
|
|
72078
72359
|
function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef, editHistory, reloadPreview, onCacheInvalidate, onFileContentChanged, showToast, sdkSession, publishSdkSession, writeProjectFile, forceReloadSdkSession }) {
|
|
72079
72360
|
const activeProjectId = projectIdRef.current;
|
|
72080
|
-
const activeCompPathRef =
|
|
72361
|
+
const activeCompPathRef = useRef129(activeCompPath);
|
|
72081
72362
|
activeCompPathRef.current = activeCompPath;
|
|
72082
|
-
const serializerRef =
|
|
72363
|
+
const serializerRef = useRef129(createKeyedSerializer());
|
|
72083
72364
|
const recordMutationEdit = useCallback115(async (targetPath, result, options) => {
|
|
72084
72365
|
if (result.before == null || result.after == null) return;
|
|
72085
72366
|
await editHistory.recordEdit({
|
|
@@ -72260,10 +72541,10 @@ function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef,
|
|
|
72260
72541
|
}
|
|
72261
72542
|
|
|
72262
72543
|
// src/hooks/useDomEditWiring.ts
|
|
72263
|
-
import { useCallback as useCallback119, useEffect as useEffect101, useRef as
|
|
72544
|
+
import { useCallback as useCallback119, useEffect as useEffect101, useRef as useRef132 } from "react";
|
|
72264
72545
|
|
|
72265
72546
|
// src/hooks/useDomEditPreviewSync.ts
|
|
72266
|
-
import { useEffect as useEffect100, useRef as
|
|
72547
|
+
import { useEffect as useEffect100, useRef as useRef130 } from "react";
|
|
72267
72548
|
function useDomEditPreviewSync({
|
|
72268
72549
|
previewIframe,
|
|
72269
72550
|
activeCompPath,
|
|
@@ -72342,7 +72623,7 @@ function useDomEditPreviewSync({
|
|
|
72342
72623
|
applyStudioManualEditsToPreviewRef,
|
|
72343
72624
|
gsapCacheVersion
|
|
72344
72625
|
]);
|
|
72345
|
-
const openSourceRef =
|
|
72626
|
+
const openSourceRef = useRef130(openSourceForSelection);
|
|
72346
72627
|
openSourceRef.current = openSourceForSelection;
|
|
72347
72628
|
useEffect100(
|
|
72348
72629
|
// fallow-ignore-next-line complexity
|
|
@@ -72440,7 +72721,7 @@ function useGsapInteractionFailureTelemetry(activeCompPath, showToast) {
|
|
|
72440
72721
|
}
|
|
72441
72722
|
|
|
72442
72723
|
// src/hooks/useGsapSelectionHandlers.ts
|
|
72443
|
-
import { useCallback as useCallback118, useRef as
|
|
72724
|
+
import { useCallback as useCallback118, useRef as useRef131 } from "react";
|
|
72444
72725
|
function useGsapSelectionHandlers({
|
|
72445
72726
|
domEditSelection,
|
|
72446
72727
|
updateGsapProperty,
|
|
@@ -72464,7 +72745,7 @@ function useGsapSelectionHandlers({
|
|
|
72464
72745
|
selectedGsapAnimations,
|
|
72465
72746
|
showToast
|
|
72466
72747
|
}) {
|
|
72467
|
-
const lastSelectionRef =
|
|
72748
|
+
const lastSelectionRef = useRef131(null);
|
|
72468
72749
|
if (domEditSelection) lastSelectionRef.current = domEditSelection;
|
|
72469
72750
|
const resolveWriteSelection2 = useCallback118(
|
|
72470
72751
|
(selectionOverride) => selectionOverride === void 0 ? domEditSelection ?? lastSelectionRef.current : selectionOverride,
|
|
@@ -72808,7 +73089,7 @@ function useDomEditWiring({
|
|
|
72808
73089
|
const key2 = matchKey ? matchKey.key ?? matchKey.id : null;
|
|
72809
73090
|
if (key2 && key2 !== selectedElementId) setSelectedElementId(key2);
|
|
72810
73091
|
}, [domEditSelection?.id]);
|
|
72811
|
-
const prevRefreshKeyRef =
|
|
73092
|
+
const prevRefreshKeyRef = useRef132(refreshKey);
|
|
72812
73093
|
useEffect101(() => {
|
|
72813
73094
|
if (refreshKey !== prevRefreshKeyRef.current) {
|
|
72814
73095
|
prevRefreshKeyRef.current = refreshKey;
|
|
@@ -73909,7 +74190,7 @@ function useGsapAwareEditing({
|
|
|
73909
74190
|
}
|
|
73910
74191
|
|
|
73911
74192
|
// src/hooks/useStudioSelectionPublisher.ts
|
|
73912
|
-
import { useEffect as useEffect102, useRef as
|
|
74193
|
+
import { useEffect as useEffect102, useRef as useRef133 } from "react";
|
|
73913
74194
|
|
|
73914
74195
|
// src/utils/studioSelectionSnapshot.ts
|
|
73915
74196
|
function round34(value) {
|
|
@@ -74000,8 +74281,8 @@ function useStudioSelectionPublisher({
|
|
|
74000
74281
|
previewDocumentVersion,
|
|
74001
74282
|
refreshDomEditSelectionFromPreview
|
|
74002
74283
|
}) {
|
|
74003
|
-
const lastSelectionRefreshKeyRef =
|
|
74004
|
-
const pendingSelectionRefreshKeyRef =
|
|
74284
|
+
const lastSelectionRefreshKeyRef = useRef133(refreshKey);
|
|
74285
|
+
const pendingSelectionRefreshKeyRef = useRef133(null);
|
|
74005
74286
|
useEffect102(() => {
|
|
74006
74287
|
if (!projectId) return;
|
|
74007
74288
|
const selection = domEditSelection?.element.isConnected ? buildStudioSelectionSnapshot({
|
|
@@ -74104,6 +74385,16 @@ function useKeyframeEaseCommits({
|
|
|
74104
74385
|
function membersForDelete(selection, group, options) {
|
|
74105
74386
|
return options?.expandGroup && group.length > 0 ? group : [selection];
|
|
74106
74387
|
}
|
|
74388
|
+
function timelineElementsForDelete(members, elements) {
|
|
74389
|
+
const matches = [];
|
|
74390
|
+
for (const member of members) {
|
|
74391
|
+
const id = findMatchingTimelineElementId(member, elements);
|
|
74392
|
+
const match = id ? elements.find((el) => (el.key ?? el.id) === id) : void 0;
|
|
74393
|
+
if (!match) return null;
|
|
74394
|
+
matches.push(match);
|
|
74395
|
+
}
|
|
74396
|
+
return matches;
|
|
74397
|
+
}
|
|
74107
74398
|
|
|
74108
74399
|
// src/hooks/useDomEditSession.ts
|
|
74109
74400
|
function useDomEditSession({
|
|
@@ -74144,7 +74435,8 @@ function useDomEditSession({
|
|
|
74144
74435
|
getSidebarTab,
|
|
74145
74436
|
sdkSession,
|
|
74146
74437
|
publishSdkSession,
|
|
74147
|
-
forceReloadSdkSession
|
|
74438
|
+
forceReloadSdkSession,
|
|
74439
|
+
handleTimelineElementsDelete
|
|
74148
74440
|
}) {
|
|
74149
74441
|
const isMasterView = !activeCompPath || activeCompPath === "index.html";
|
|
74150
74442
|
void _setRefreshKey;
|
|
@@ -74314,9 +74606,8 @@ function useDomEditSession({
|
|
|
74314
74606
|
readProjectFile,
|
|
74315
74607
|
publishSession: publishSdkSession
|
|
74316
74608
|
}) : void 0,
|
|
74317
|
-
//
|
|
74318
|
-
//
|
|
74319
|
-
// the SDK resolves each reordered element (the reorderElements op's targets).
|
|
74609
|
+
// Z-index reorder takes the server path (no SDK persist); this decoupled
|
|
74610
|
+
// tripwire still records whether the SDK resolves each reordered target.
|
|
74320
74611
|
onReorderShadow: sdkSession ? (targets) => {
|
|
74321
74612
|
let reorderSrcPromise;
|
|
74322
74613
|
const reorderSrc = activeCompPath ? () => reorderSrcPromise ??= readProjectFile(activeCompPath) : void 0;
|
|
@@ -74332,7 +74623,8 @@ function useDomEditSession({
|
|
|
74332
74623
|
projectIdRef,
|
|
74333
74624
|
reloadPreview,
|
|
74334
74625
|
clearDomSelection,
|
|
74335
|
-
forceReloadSdkSession
|
|
74626
|
+
forceReloadSdkSession,
|
|
74627
|
+
timelineElements
|
|
74336
74628
|
});
|
|
74337
74629
|
const handleDomEditElementDelete = useCallback123(
|
|
74338
74630
|
async (selection, options) => {
|
|
@@ -74341,9 +74633,21 @@ function useDomEditSession({
|
|
|
74341
74633
|
return;
|
|
74342
74634
|
}
|
|
74343
74635
|
const members = membersForDelete(selection, domEditGroupSelectionsRef.current, options);
|
|
74636
|
+
const timelineTargets = timelineElementsForDelete(members, timelineElements);
|
|
74637
|
+
if (timelineTargets) {
|
|
74638
|
+
await handleTimelineElementsDelete(timelineTargets);
|
|
74639
|
+
return;
|
|
74640
|
+
}
|
|
74344
74641
|
await handleDomEditElementsDelete(members);
|
|
74345
74642
|
},
|
|
74346
|
-
[
|
|
74643
|
+
[
|
|
74644
|
+
domEditGroupSelectionsRef,
|
|
74645
|
+
handleDomEditElementsDelete,
|
|
74646
|
+
handleTimelineElementsDelete,
|
|
74647
|
+
isRecordingRef,
|
|
74648
|
+
showToast,
|
|
74649
|
+
timelineElements
|
|
74650
|
+
]
|
|
74347
74651
|
);
|
|
74348
74652
|
const handleGroupSelection = useCallback123(() => {
|
|
74349
74653
|
const group = domEditGroupSelectionsRef.current;
|
|
@@ -74594,7 +74898,7 @@ function useSdkSelectionSync(session, domEditSelection, domEditGroupSelections)
|
|
|
74594
74898
|
import { useEffect as useEffect105 } from "react";
|
|
74595
74899
|
|
|
74596
74900
|
// src/hooks/useSdkSession.ts
|
|
74597
|
-
import { useState as useState108, useEffect as useEffect104, useCallback as useCallback124, useRef as
|
|
74901
|
+
import { useState as useState108, useEffect as useEffect104, useCallback as useCallback124, useRef as useRef134 } from "react";
|
|
74598
74902
|
import { openComposition as openComposition3 } from "@hyperframes/sdk";
|
|
74599
74903
|
|
|
74600
74904
|
// src/hooks/externalFileReloadBus.ts
|
|
@@ -74644,15 +74948,15 @@ function disposeSdkSession(session) {
|
|
|
74644
74948
|
}
|
|
74645
74949
|
function useSdkSession(projectId, activeCompPath) {
|
|
74646
74950
|
const [ownedSession, setOwnedSession] = useState108(null);
|
|
74647
|
-
const ownedSessionRef =
|
|
74648
|
-
const sessionOwnersRef =
|
|
74649
|
-
const generationRef =
|
|
74650
|
-
const projectIdRef =
|
|
74951
|
+
const ownedSessionRef = useRef134(null);
|
|
74952
|
+
const sessionOwnersRef = useRef134(/* @__PURE__ */ new WeakMap());
|
|
74953
|
+
const generationRef = useRef134(0);
|
|
74954
|
+
const projectIdRef = useRef134(projectId);
|
|
74651
74955
|
projectIdRef.current = projectId;
|
|
74652
|
-
const activeCompPathRef =
|
|
74956
|
+
const activeCompPathRef = useRef134(activeCompPath);
|
|
74653
74957
|
activeCompPathRef.current = activeCompPath;
|
|
74654
74958
|
const [reloadToken, setReloadToken] = useState108(0);
|
|
74655
|
-
const reloadTokenRef =
|
|
74959
|
+
const reloadTokenRef = useRef134(reloadToken);
|
|
74656
74960
|
reloadTokenRef.current = reloadToken;
|
|
74657
74961
|
useEffect104(
|
|
74658
74962
|
() => addExternalFileReloadListener((changedPath) => {
|
|
@@ -74679,7 +74983,11 @@ function useSdkSession(projectId, activeCompPath) {
|
|
|
74679
74983
|
generation
|
|
74680
74984
|
};
|
|
74681
74985
|
readProjectFileOptional(projectId, activeCompPath).then(async (content) => {
|
|
74682
|
-
if (cancelled
|
|
74986
|
+
if (cancelled) return;
|
|
74987
|
+
if (typeof content !== "string") {
|
|
74988
|
+
trackStudioEvent("sdk_session_unavailable", { stage: "read" });
|
|
74989
|
+
return;
|
|
74990
|
+
}
|
|
74683
74991
|
const comp = await openComposition3(content, { history: false });
|
|
74684
74992
|
if (cancelled) {
|
|
74685
74993
|
disposeSdkSession(comp);
|
|
@@ -74693,6 +75001,7 @@ function useSdkSession(projectId, activeCompPath) {
|
|
|
74693
75001
|
reloadTokenRef.current
|
|
74694
75002
|
)) {
|
|
74695
75003
|
disposeSdkSession(comp);
|
|
75004
|
+
trackStudioEvent("sdk_session_unavailable", { stage: "ownership" });
|
|
74696
75005
|
return;
|
|
74697
75006
|
}
|
|
74698
75007
|
const displaced = ownedSessionRef.current;
|
|
@@ -74701,8 +75010,14 @@ function useSdkSession(projectId, activeCompPath) {
|
|
|
74701
75010
|
ownedSessionRef.current = installed;
|
|
74702
75011
|
setOwnedSession(installed);
|
|
74703
75012
|
if (displaced && displaced.session !== comp) disposeSdkSession(displaced.session);
|
|
74704
|
-
}).catch(() => {
|
|
74705
|
-
if (!cancelled && generationRef.current === generation)
|
|
75013
|
+
}).catch((error) => {
|
|
75014
|
+
if (!cancelled && generationRef.current === generation) {
|
|
75015
|
+
setOwnedSession(null);
|
|
75016
|
+
trackStudioEvent("sdk_session_unavailable", {
|
|
75017
|
+
stage: "open",
|
|
75018
|
+
error: error instanceof Error ? error.message : String(error)
|
|
75019
|
+
});
|
|
75020
|
+
}
|
|
74706
75021
|
});
|
|
74707
75022
|
return () => {
|
|
74708
75023
|
cancelled = true;
|
|
@@ -74852,7 +75167,7 @@ async function deleteExternalConflictSnapshot(projectId, filePath) {
|
|
|
74852
75167
|
}
|
|
74853
75168
|
|
|
74854
75169
|
// src/hooks/useExternalFileChangeCoordinator.ts
|
|
74855
|
-
import { useCallback as useCallback125, useEffect as useEffect106, useRef as
|
|
75170
|
+
import { useCallback as useCallback125, useEffect as useEffect106, useRef as useRef135, useState as useState109 } from "react";
|
|
74856
75171
|
function testHotAdapter() {
|
|
74857
75172
|
const value = globalThis.__HF_STUDIO_HOT_TEST_ADAPTER__;
|
|
74858
75173
|
if (!value || typeof value !== "object") return null;
|
|
@@ -74904,13 +75219,13 @@ function useExternalFileChangeCoordinator({
|
|
|
74904
75219
|
onAcceptedPersistedFileChange
|
|
74905
75220
|
}) {
|
|
74906
75221
|
const [blocked, setBlocked] = useState109(null);
|
|
74907
|
-
const generationRef =
|
|
74908
|
-
const mountedRef =
|
|
74909
|
-
const lastEventIdentityRef =
|
|
74910
|
-
const blockedRef =
|
|
74911
|
-
const snapshotWriteTailRef =
|
|
74912
|
-
const drainingRef =
|
|
74913
|
-
const pendingPayloadRef =
|
|
75222
|
+
const generationRef = useRef135(0);
|
|
75223
|
+
const mountedRef = useRef135(true);
|
|
75224
|
+
const lastEventIdentityRef = useRef135(null);
|
|
75225
|
+
const blockedRef = useRef135(blocked);
|
|
75226
|
+
const snapshotWriteTailRef = useRef135(Promise.resolve());
|
|
75227
|
+
const drainingRef = useRef135(false);
|
|
75228
|
+
const pendingPayloadRef = useRef135(null);
|
|
74914
75229
|
blockedRef.current = blocked;
|
|
74915
75230
|
useEffect106(() => {
|
|
74916
75231
|
mountedRef.current = true;
|
|
@@ -75267,7 +75582,7 @@ function useStudioExternalFileChanges({
|
|
|
75267
75582
|
}
|
|
75268
75583
|
|
|
75269
75584
|
// src/hooks/useBlockHandlers.ts
|
|
75270
|
-
import { useCallback as useCallback127, useMemo as useMemo61, useRef as
|
|
75585
|
+
import { useCallback as useCallback127, useMemo as useMemo61, useRef as useRef136, useState as useState110 } from "react";
|
|
75271
75586
|
|
|
75272
75587
|
// src/utils/blockInstaller.ts
|
|
75273
75588
|
function getMaxZIndexFromIframe(iframe) {
|
|
@@ -75476,7 +75791,7 @@ function useBlockHandlers({
|
|
|
75476
75791
|
blockCtxDeps.showToast
|
|
75477
75792
|
]
|
|
75478
75793
|
);
|
|
75479
|
-
const installingBlockRef =
|
|
75794
|
+
const installingBlockRef = useRef136(false);
|
|
75480
75795
|
const runBlockInstall = useCallback127(
|
|
75481
75796
|
async (blockName, install) => {
|
|
75482
75797
|
if (installingBlockRef.current) {
|
|
@@ -75587,26 +75902,9 @@ function useBlockHandlers({
|
|
|
75587
75902
|
}
|
|
75588
75903
|
|
|
75589
75904
|
// src/hooks/useAppHotkeys.ts
|
|
75590
|
-
import { useCallback as useCallback128, useEffect as useEffect107, useRef as
|
|
75591
|
-
|
|
75592
|
-
|
|
75593
|
-
return iframe?.contentWindow ?? null;
|
|
75594
|
-
} catch {
|
|
75595
|
-
return null;
|
|
75596
|
-
}
|
|
75597
|
-
}
|
|
75598
|
-
function safeAddListener(t, type, h, capture = false) {
|
|
75599
|
-
try {
|
|
75600
|
-
t?.addEventListener(type, h, capture);
|
|
75601
|
-
} catch {
|
|
75602
|
-
}
|
|
75603
|
-
}
|
|
75604
|
-
function safeRemoveListener(t, type, h) {
|
|
75605
|
-
try {
|
|
75606
|
-
t?.removeEventListener(type, h);
|
|
75607
|
-
} catch {
|
|
75608
|
-
}
|
|
75609
|
-
}
|
|
75905
|
+
import { useCallback as useCallback128, useEffect as useEffect107, useRef as useRef137 } from "react";
|
|
75906
|
+
|
|
75907
|
+
// src/hooks/appHotkeysDispatch.ts
|
|
75610
75908
|
function handleUndoRedoKey(event, onUndo, onRedo) {
|
|
75611
75909
|
const key2 = event.key.toLowerCase();
|
|
75612
75910
|
if (key2 === "z" && !event.shiftKey) {
|
|
@@ -75621,18 +75919,6 @@ function handleUndoRedoKey(event, onUndo, onRedo) {
|
|
|
75621
75919
|
}
|
|
75622
75920
|
return false;
|
|
75623
75921
|
}
|
|
75624
|
-
function tryApplyBeatHistory(direction, fileState, showToast) {
|
|
75625
|
-
const ps = usePlayerStore.getState();
|
|
75626
|
-
const beatStack = direction === "undo" ? ps.beatUndo : ps.beatRedo;
|
|
75627
|
-
const beatAt = beatStack[beatStack.length - 1]?.at ?? null;
|
|
75628
|
-
if (beatAt === null) return false;
|
|
75629
|
-
const fileStack = fileState[direction];
|
|
75630
|
-
const fileAt = fileStack[fileStack.length - 1]?.createdAt ?? null;
|
|
75631
|
-
if (fileAt !== null && (direction === "undo" ? beatAt < fileAt : beatAt > fileAt)) return false;
|
|
75632
|
-
const label = direction === "undo" ? ps.undoBeatEdits() : ps.redoBeatEdits();
|
|
75633
|
-
if (label) showToast(`${direction === "undo" ? "Undid" : "Redid"} ${label}`, "info");
|
|
75634
|
-
return true;
|
|
75635
|
-
}
|
|
75636
75922
|
function dispatchModifierKey(event, key2, cb) {
|
|
75637
75923
|
if (!shouldIgnoreHistoryShortcut(event.target) && handleUndoRedoKey(
|
|
75638
75924
|
event,
|
|
@@ -75724,6 +76010,14 @@ function dispatchPlainKey(event, key2, cb) {
|
|
|
75724
76010
|
usePlayerStore.getState().setActiveTool("select");
|
|
75725
76011
|
return;
|
|
75726
76012
|
}
|
|
76013
|
+
if (key2 === "a" && !event.shiftKey && !event.altKey) {
|
|
76014
|
+
const { activeTool, setActiveTool } = usePlayerStore.getState();
|
|
76015
|
+
if (activeTool === "razor") {
|
|
76016
|
+
event.preventDefault();
|
|
76017
|
+
setActiveTool("select");
|
|
76018
|
+
return;
|
|
76019
|
+
}
|
|
76020
|
+
}
|
|
75727
76021
|
if (event.key === "Escape") {
|
|
75728
76022
|
const { activeTool, selectedElementId, setActiveTool, setSelectedElementId } = usePlayerStore.getState();
|
|
75729
76023
|
if (activeTool === "razor") {
|
|
@@ -75769,6 +76063,39 @@ function dispatchPlainKey(event, key2, cb) {
|
|
|
75769
76063
|
cb.onToggleRecording();
|
|
75770
76064
|
}
|
|
75771
76065
|
}
|
|
76066
|
+
|
|
76067
|
+
// src/hooks/useAppHotkeys.ts
|
|
76068
|
+
function iframeContentWindow(iframe) {
|
|
76069
|
+
try {
|
|
76070
|
+
return iframe?.contentWindow ?? null;
|
|
76071
|
+
} catch {
|
|
76072
|
+
return null;
|
|
76073
|
+
}
|
|
76074
|
+
}
|
|
76075
|
+
function safeAddListener(t, type, h, capture = false) {
|
|
76076
|
+
try {
|
|
76077
|
+
t?.addEventListener(type, h, capture);
|
|
76078
|
+
} catch {
|
|
76079
|
+
}
|
|
76080
|
+
}
|
|
76081
|
+
function safeRemoveListener(t, type, h) {
|
|
76082
|
+
try {
|
|
76083
|
+
t?.removeEventListener(type, h);
|
|
76084
|
+
} catch {
|
|
76085
|
+
}
|
|
76086
|
+
}
|
|
76087
|
+
function tryApplyBeatHistory(direction, fileState, showToast) {
|
|
76088
|
+
const ps = usePlayerStore.getState();
|
|
76089
|
+
const beatStack = direction === "undo" ? ps.beatUndo : ps.beatRedo;
|
|
76090
|
+
const beatAt = beatStack[beatStack.length - 1]?.at ?? null;
|
|
76091
|
+
if (beatAt === null) return false;
|
|
76092
|
+
const fileStack = fileState[direction];
|
|
76093
|
+
const fileAt = fileStack[fileStack.length - 1]?.createdAt ?? null;
|
|
76094
|
+
if (fileAt !== null && (direction === "undo" ? beatAt < fileAt : beatAt > fileAt)) return false;
|
|
76095
|
+
const label = direction === "undo" ? ps.undoBeatEdits() : ps.redoBeatEdits();
|
|
76096
|
+
if (label) showToast(`${direction === "undo" ? "Undid" : "Redid"} ${label}`, "info");
|
|
76097
|
+
return true;
|
|
76098
|
+
}
|
|
75772
76099
|
function useAppHotkeys({
|
|
75773
76100
|
handleTimelineElementsDelete,
|
|
75774
76101
|
handleTimelineElementSplit,
|
|
@@ -75794,7 +76121,7 @@ function useAppHotkeys({
|
|
|
75794
76121
|
activeCompPath,
|
|
75795
76122
|
forceReloadSdkSession
|
|
75796
76123
|
}) {
|
|
75797
|
-
const previewHistoryCleanupRef =
|
|
76124
|
+
const previewHistoryCleanupRef = useRef137(null);
|
|
75798
76125
|
const readHistoryFile = useCallback128(
|
|
75799
76126
|
(path) => path === STUDIO_MOTION_PATH ? readOptionalProjectFile(path) : readProjectFile(path),
|
|
75800
76127
|
[readOptionalProjectFile, readProjectFile]
|
|
@@ -75858,7 +76185,7 @@ function useAppHotkeys({
|
|
|
75858
76185
|
);
|
|
75859
76186
|
const handleUndo = useCallback128(() => applyHistory("undo"), [applyHistory]);
|
|
75860
76187
|
const handleRedo = useCallback128(() => applyHistory("redo"), [applyHistory]);
|
|
75861
|
-
const cbRef =
|
|
76188
|
+
const cbRef = useRef137(null);
|
|
75862
76189
|
cbRef.current = {
|
|
75863
76190
|
handleTimelineElementsDelete,
|
|
75864
76191
|
handleTimelineElementSplit,
|
|
@@ -75938,7 +76265,7 @@ function useAppHotkeys({
|
|
|
75938
76265
|
}
|
|
75939
76266
|
|
|
75940
76267
|
// src/hooks/useClipboard.ts
|
|
75941
|
-
import { useCallback as useCallback129, useRef as
|
|
76268
|
+
import { useCallback as useCallback129, useRef as useRef138 } from "react";
|
|
75942
76269
|
|
|
75943
76270
|
// src/utils/clipboardPayload.ts
|
|
75944
76271
|
function insertAsSibling(source, newHtml, selector, selectorIndex) {
|
|
@@ -76044,8 +76371,8 @@ function useClipboard({
|
|
|
76044
76371
|
handleDomEditElementDelete,
|
|
76045
76372
|
previewIframeRef
|
|
76046
76373
|
}) {
|
|
76047
|
-
const clipboardRef =
|
|
76048
|
-
const projectIdRef =
|
|
76374
|
+
const clipboardRef = useRef138(null);
|
|
76375
|
+
const projectIdRef = useRef138(projectId);
|
|
76049
76376
|
projectIdRef.current = projectId;
|
|
76050
76377
|
const handleCopy2 = useCallback129(() => {
|
|
76051
76378
|
const { selectedElementId, elements } = usePlayerStore.getState();
|
|
@@ -76171,7 +76498,7 @@ function useClipboard({
|
|
|
76171
76498
|
}
|
|
76172
76499
|
|
|
76173
76500
|
// src/hooks/useCaptionDetection.ts
|
|
76174
|
-
import { useEffect as useEffect108, useRef as
|
|
76501
|
+
import { useEffect as useEffect108, useRef as useRef139 } from "react";
|
|
76175
76502
|
|
|
76176
76503
|
// src/captions/types.ts
|
|
76177
76504
|
var DEFAULT_STYLE = {
|
|
@@ -76423,7 +76750,7 @@ function useCaptionDetection({
|
|
|
76423
76750
|
captionSync,
|
|
76424
76751
|
setRightCollapsed
|
|
76425
76752
|
}) {
|
|
76426
|
-
const prevCompPathRef =
|
|
76753
|
+
const prevCompPathRef = useRef139(activeCompPath);
|
|
76427
76754
|
useEffect108(() => {
|
|
76428
76755
|
if (prevCompPathRef.current !== activeCompPath) {
|
|
76429
76756
|
prevCompPathRef.current = activeCompPath;
|
|
@@ -76528,7 +76855,7 @@ import { useCallback as useCallback132 } from "react";
|
|
|
76528
76855
|
import { createElement as createElement3 } from "react";
|
|
76529
76856
|
|
|
76530
76857
|
// src/player/components/AudioWaveform.tsx
|
|
76531
|
-
import { memo as memo36, useCallback as useCallback130, useMemo as useMemo62, useRef as
|
|
76858
|
+
import { memo as memo36, useCallback as useCallback130, useMemo as useMemo62, useRef as useRef140 } from "react";
|
|
76532
76859
|
import { jsx as jsx169, jsxs as jsxs141 } from "react/jsx-runtime";
|
|
76533
76860
|
var BAR_WIDTH = 2;
|
|
76534
76861
|
var BAR_STEP = 3;
|
|
@@ -76585,8 +76912,8 @@ var AudioWaveform = memo36(function AudioWaveform2({
|
|
|
76585
76912
|
sessionEpoch,
|
|
76586
76913
|
priority
|
|
76587
76914
|
}) {
|
|
76588
|
-
const canvasRef =
|
|
76589
|
-
const observerRef =
|
|
76915
|
+
const canvasRef = useRef140(null);
|
|
76916
|
+
const observerRef = useRef140(null);
|
|
76590
76917
|
const cacheKey = waveformUrl ?? audioUrl;
|
|
76591
76918
|
const request = useMemo62(
|
|
76592
76919
|
() => ({
|
|
@@ -76697,7 +77024,7 @@ var AudioWaveform = memo36(function AudioWaveform2({
|
|
|
76697
77024
|
});
|
|
76698
77025
|
|
|
76699
77026
|
// src/player/components/ImageThumbnail.tsx
|
|
76700
|
-
import { memo as memo37, useCallback as useCallback131, useMemo as useMemo63, useRef as
|
|
77027
|
+
import { memo as memo37, useCallback as useCallback131, useMemo as useMemo63, useRef as useRef141, useState as useState111 } from "react";
|
|
76701
77028
|
import { jsx as jsx170, jsxs as jsxs142 } from "react/jsx-runtime";
|
|
76702
77029
|
var ImageThumbnail = memo37(function ImageThumbnail2({
|
|
76703
77030
|
imageSrc,
|
|
@@ -76709,7 +77036,7 @@ var ImageThumbnail = memo37(function ImageThumbnail2({
|
|
|
76709
77036
|
rich = false
|
|
76710
77037
|
}) {
|
|
76711
77038
|
const [containerWidth, setContainerWidth] = useState111(0);
|
|
76712
|
-
const observerRef =
|
|
77039
|
+
const observerRef = useRef141(null);
|
|
76713
77040
|
const request = useMemo63(
|
|
76714
77041
|
() => ({
|
|
76715
77042
|
key: createThumbnailKey({ kind: "image", source: imageSrc, rich: Number(rich) }),
|
|
@@ -76958,10 +77285,10 @@ function useRenderClipContent({
|
|
|
76958
77285
|
}
|
|
76959
77286
|
|
|
76960
77287
|
// src/hooks/useConsoleErrorCapture.ts
|
|
76961
|
-
import { useCallback as useCallback133, useEffect as useEffect109, useRef as
|
|
77288
|
+
import { useCallback as useCallback133, useEffect as useEffect109, useRef as useRef142, useState as useState112 } from "react";
|
|
76962
77289
|
function useConsoleErrorCapture(previewIframe) {
|
|
76963
77290
|
const [consoleErrors, setConsoleErrors] = useState112(null);
|
|
76964
|
-
const consoleErrorsRef =
|
|
77291
|
+
const consoleErrorsRef = useRef142([]);
|
|
76965
77292
|
const resetErrors = useCallback133(() => {
|
|
76966
77293
|
consoleErrorsRef.current = [];
|
|
76967
77294
|
setConsoleErrors(null);
|
|
@@ -77031,7 +77358,7 @@ function useConsoleErrorCapture(previewIframe) {
|
|
|
77031
77358
|
}
|
|
77032
77359
|
|
|
77033
77360
|
// src/hooks/useFrameCapture.ts
|
|
77034
|
-
import { useState as useState113, useCallback as useCallback134, useRef as
|
|
77361
|
+
import { useState as useState113, useCallback as useCallback134, useRef as useRef143 } from "react";
|
|
77035
77362
|
function useFrameCapture({
|
|
77036
77363
|
projectId,
|
|
77037
77364
|
activeCompPath,
|
|
@@ -77040,7 +77367,7 @@ function useFrameCapture({
|
|
|
77040
77367
|
}) {
|
|
77041
77368
|
const [captureFrameTime, setCaptureFrameTime] = useState113(0);
|
|
77042
77369
|
const [capturing, setCapturing] = useState113(false);
|
|
77043
|
-
const capturingRef =
|
|
77370
|
+
const capturingRef = useRef143(false);
|
|
77044
77371
|
useMountEffect(() => {
|
|
77045
77372
|
setCaptureFrameTime(usePlayerStore.getState().currentTime);
|
|
77046
77373
|
return liveTime.subscribe(setCaptureFrameTime);
|
|
@@ -77125,7 +77452,7 @@ function useFrameCapture({
|
|
|
77125
77452
|
}
|
|
77126
77453
|
|
|
77127
77454
|
// src/hooks/useLintModal.ts
|
|
77128
|
-
import { useState as useState114, useCallback as useCallback135, useEffect as useEffect110, useRef as
|
|
77455
|
+
import { useState as useState114, useCallback as useCallback135, useEffect as useEffect110, useRef as useRef144, useMemo as useMemo64 } from "react";
|
|
77129
77456
|
function parseFinding(f) {
|
|
77130
77457
|
return {
|
|
77131
77458
|
severity: f.severity === "error" ? "error" : "warning",
|
|
@@ -77139,7 +77466,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
77139
77466
|
const [lintModal, setLintModal] = useState114(null);
|
|
77140
77467
|
const [linting, setLinting] = useState114(false);
|
|
77141
77468
|
const [backgroundFindings, setBackgroundFindings] = useState114([]);
|
|
77142
|
-
const autoLintRanRef =
|
|
77469
|
+
const autoLintRanRef = useRef144(false);
|
|
77143
77470
|
const runLint = useCallback135(
|
|
77144
77471
|
async (opts) => {
|
|
77145
77472
|
if (!projectId) return;
|
|
@@ -77166,7 +77493,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
77166
77493
|
[projectId]
|
|
77167
77494
|
);
|
|
77168
77495
|
const handleLint = useCallback135(() => runLint(), [runLint]);
|
|
77169
|
-
const prevProjectIdRef =
|
|
77496
|
+
const prevProjectIdRef = useRef144(projectId);
|
|
77170
77497
|
useEffect110(() => {
|
|
77171
77498
|
if (projectId !== prevProjectIdRef.current) {
|
|
77172
77499
|
autoLintRanRef.current = false;
|
|
@@ -77214,14 +77541,14 @@ function useLintModal(projectId, refreshKey) {
|
|
|
77214
77541
|
}
|
|
77215
77542
|
|
|
77216
77543
|
// src/hooks/useToast.ts
|
|
77217
|
-
import { useState as useState115, useCallback as useCallback136, useRef as
|
|
77544
|
+
import { useState as useState115, useCallback as useCallback136, useRef as useRef145 } from "react";
|
|
77218
77545
|
var AUTO_DISMISS_MS2 = 4e3;
|
|
77219
77546
|
var EXIT_MS2 = 160;
|
|
77220
77547
|
var MAX_TOASTS = 3;
|
|
77221
77548
|
var nextToastId = 1;
|
|
77222
77549
|
function useToast() {
|
|
77223
77550
|
const [toasts, setToasts] = useState115([]);
|
|
77224
|
-
const timersRef =
|
|
77551
|
+
const timersRef = useRef145(/* @__PURE__ */ new Map());
|
|
77225
77552
|
const clearTimer = useCallback136((id) => {
|
|
77226
77553
|
const timer = timersRef.current.get(id);
|
|
77227
77554
|
if (timer) {
|
|
@@ -77270,41 +77597,17 @@ function useToast() {
|
|
|
77270
77597
|
return { toasts, showToast, dismissToast };
|
|
77271
77598
|
}
|
|
77272
77599
|
|
|
77273
|
-
// src/hooks/useCompositionContentLoader.ts
|
|
77274
|
-
import { useCallback as useCallback137 } from "react";
|
|
77275
|
-
function useCompositionContentLoader({
|
|
77276
|
-
projectId,
|
|
77277
|
-
setEditingFile,
|
|
77278
|
-
setActiveCompPath,
|
|
77279
|
-
showToast
|
|
77280
|
-
}) {
|
|
77281
|
-
return useCallback137(
|
|
77282
|
-
(comp) => {
|
|
77283
|
-
if (!projectId) return;
|
|
77284
|
-
setActiveCompPath(comp.endsWith(".html") ? comp : null);
|
|
77285
|
-
setEditingFile({ path: comp, content: null });
|
|
77286
|
-
fetch(buildProjectApiPath(projectId, `/files/${encodeURIComponent(comp)}`)).then(async (r) => {
|
|
77287
|
-
if (!r.ok) throw new Error(`Failed to load ${comp} (${r.status})`);
|
|
77288
|
-
return r.json();
|
|
77289
|
-
}).then((data) => {
|
|
77290
|
-
if (typeof data.content !== "string") throw new Error(`No content returned for ${comp}`);
|
|
77291
|
-
setEditingFile({ path: comp, content: data.content });
|
|
77292
|
-
}).catch((err) => {
|
|
77293
|
-
showToast(err instanceof Error ? err.message : `Failed to load ${comp}`, "error");
|
|
77294
|
-
});
|
|
77295
|
-
},
|
|
77296
|
-
[projectId, setEditingFile, setActiveCompPath, showToast]
|
|
77297
|
-
);
|
|
77298
|
-
}
|
|
77299
|
-
|
|
77300
77600
|
// src/hooks/useStudioUrlState.ts
|
|
77301
|
-
import { useCallback as
|
|
77601
|
+
import { useCallback as useCallback137, useEffect as useEffect111, useRef as useRef146, useState as useState116 } from "react";
|
|
77302
77602
|
|
|
77303
77603
|
// src/utils/studioUrlState.ts
|
|
77304
77604
|
var VALID_TABS = ["layers", "design", "renders", "slideshow", "variables"];
|
|
77305
|
-
function resolveMasterCompositionPath(
|
|
77306
|
-
if (
|
|
77307
|
-
return
|
|
77605
|
+
function resolveMasterCompositionPath(compositions) {
|
|
77606
|
+
if (compositions.includes("index.html")) return "index.html";
|
|
77607
|
+
return compositions.find((p) => p.endsWith(".html")) ?? null;
|
|
77608
|
+
}
|
|
77609
|
+
function isHydratedFromUrlState(urlState) {
|
|
77610
|
+
return urlState.activeCompPath == null;
|
|
77308
77611
|
}
|
|
77309
77612
|
function normalizeStudioUrlPanelTab(tab) {
|
|
77310
77613
|
if (!tab) return null;
|
|
@@ -77527,14 +77830,14 @@ function useStudioUrlState({
|
|
|
77527
77830
|
initialState: initialState2
|
|
77528
77831
|
}) {
|
|
77529
77832
|
const currentTime = usePlayerStore((s) => s.currentTime);
|
|
77530
|
-
const hydratedSeekRef =
|
|
77531
|
-
const hydratedInitialTimeRef =
|
|
77532
|
-
const hydratedSelectionRef =
|
|
77833
|
+
const hydratedSeekRef = useRef146(initialState2.currentTime == null);
|
|
77834
|
+
const hydratedInitialTimeRef = useRef146(initialState2.currentTime == null);
|
|
77835
|
+
const hydratedSelectionRef = useRef146(initialState2.selection == null);
|
|
77533
77836
|
const [selectionHydrated, setSelectionHydrated] = useState116(initialState2.selection == null);
|
|
77534
|
-
const pendingSelectionRef =
|
|
77535
|
-
const stableTimeRef =
|
|
77536
|
-
const selectionApplySeqRef =
|
|
77537
|
-
const buildUrlState =
|
|
77837
|
+
const pendingSelectionRef = useRef146(initialState2.selection);
|
|
77838
|
+
const stableTimeRef = useRef146(initialState2.currentTime);
|
|
77839
|
+
const selectionApplySeqRef = useRef146(0);
|
|
77840
|
+
const buildUrlState = useCallback137(
|
|
77538
77841
|
() => ({
|
|
77539
77842
|
activeCompPath,
|
|
77540
77843
|
currentTime: stableTimeRef.current,
|
|
@@ -77545,7 +77848,7 @@ function useStudioUrlState({
|
|
|
77545
77848
|
}),
|
|
77546
77849
|
[activeCompPath, domEditGroupSelections, domEditSelection, rightCollapsed, rightPanelTab]
|
|
77547
77850
|
);
|
|
77548
|
-
const applyUrlSelection =
|
|
77851
|
+
const applyUrlSelection = useCallback137(
|
|
77549
77852
|
(selection) => {
|
|
77550
77853
|
const applySeq = ++selectionApplySeqRef.current;
|
|
77551
77854
|
if (!selection) {
|
|
@@ -77690,7 +77993,7 @@ function useEffectiveTimelineDuration(timelineDuration2, timelineElements) {
|
|
|
77690
77993
|
}
|
|
77691
77994
|
|
|
77692
77995
|
// src/hooks/useStudioContextValue.ts
|
|
77693
|
-
import { useCallback as
|
|
77996
|
+
import { useCallback as useCallback138, useMemo as useMemo66, useRef as useRef147, useState as useState117 } from "react";
|
|
77694
77997
|
function buildStudioContextValue(input) {
|
|
77695
77998
|
return {
|
|
77696
77999
|
projectId: input.projectId,
|
|
@@ -77749,22 +78052,22 @@ function useInspectorState(rightPanelTab, rightInspectorPanes, rightCollapsed, i
|
|
|
77749
78052
|
}
|
|
77750
78053
|
function useDragOverlay(onImportFiles) {
|
|
77751
78054
|
const [active, setActive] = useState117(false);
|
|
77752
|
-
const counterRef =
|
|
77753
|
-
const onDragOver =
|
|
78055
|
+
const counterRef = useRef147(0);
|
|
78056
|
+
const onDragOver = useCallback138((e) => {
|
|
77754
78057
|
if (!e.dataTransfer.types.includes("Files")) return;
|
|
77755
78058
|
e.preventDefault();
|
|
77756
78059
|
}, []);
|
|
77757
|
-
const onDragEnter =
|
|
78060
|
+
const onDragEnter = useCallback138((e) => {
|
|
77758
78061
|
if (!e.dataTransfer.types.includes("Files")) return;
|
|
77759
78062
|
e.preventDefault();
|
|
77760
78063
|
counterRef.current++;
|
|
77761
78064
|
setActive(true);
|
|
77762
78065
|
}, []);
|
|
77763
|
-
const onDragLeave =
|
|
78066
|
+
const onDragLeave = useCallback138(() => {
|
|
77764
78067
|
counterRef.current--;
|
|
77765
78068
|
if (counterRef.current === 0) setActive(false);
|
|
77766
78069
|
}, []);
|
|
77767
|
-
const onDrop =
|
|
78070
|
+
const onDrop = useCallback138(
|
|
77768
78071
|
(e) => {
|
|
77769
78072
|
counterRef.current = 0;
|
|
77770
78073
|
setActive(false);
|
|
@@ -77777,7 +78080,7 @@ function useDragOverlay(onImportFiles) {
|
|
|
77777
78080
|
return { active, onDragOver, onDragEnter, onDragLeave, onDrop };
|
|
77778
78081
|
}
|
|
77779
78082
|
function useGlobalFileDrop(handleTimelineFileDrop) {
|
|
77780
|
-
const onDrop =
|
|
78083
|
+
const onDrop = useCallback138(
|
|
77781
78084
|
(files) => {
|
|
77782
78085
|
const start = usePlayerStore.getState().currentTime;
|
|
77783
78086
|
void handleTimelineFileDrop(Array.from(files), { start, track: 0 });
|
|
@@ -77788,7 +78091,7 @@ function useGlobalFileDrop(handleTimelineFileDrop) {
|
|
|
77788
78091
|
}
|
|
77789
78092
|
|
|
77790
78093
|
// src/components/StudioHeader.tsx
|
|
77791
|
-
import { useRef as
|
|
78094
|
+
import { useRef as useRef149 } from "react";
|
|
77792
78095
|
|
|
77793
78096
|
// src/contexts/PanelLayoutContext.tsx
|
|
77794
78097
|
import { useContext as useContext8, useMemo as useMemo67 } from "react";
|
|
@@ -77866,11 +78169,11 @@ function PanelLayoutProvider({
|
|
|
77866
78169
|
|
|
77867
78170
|
// src/contexts/ViewModeContext.tsx
|
|
77868
78171
|
import {
|
|
77869
|
-
useCallback as
|
|
78172
|
+
useCallback as useCallback139,
|
|
77870
78173
|
useContext as useContext9,
|
|
77871
78174
|
useEffect as useEffect112,
|
|
77872
78175
|
useMemo as useMemo68,
|
|
77873
|
-
useRef as
|
|
78176
|
+
useRef as useRef148,
|
|
77874
78177
|
useState as useState118
|
|
77875
78178
|
} from "react";
|
|
77876
78179
|
import { jsx as jsx172 } from "react/jsx-runtime";
|
|
@@ -77898,9 +78201,9 @@ function readHistoryLocation() {
|
|
|
77898
78201
|
}
|
|
77899
78202
|
function useViewModeState() {
|
|
77900
78203
|
const [viewMode, setMode] = useState118(() => readViewModeFromUrl());
|
|
77901
|
-
const guardsRef =
|
|
77902
|
-
const acceptedLocationRef =
|
|
77903
|
-
const canSetViewMode =
|
|
78204
|
+
const guardsRef = useRef148(/* @__PURE__ */ new Set());
|
|
78205
|
+
const acceptedLocationRef = useRef148(readHistoryLocation());
|
|
78206
|
+
const canSetViewMode = useCallback139((mode) => {
|
|
77904
78207
|
for (const guard of guardsRef.current) {
|
|
77905
78208
|
if (!guard(mode)) return false;
|
|
77906
78209
|
}
|
|
@@ -77922,7 +78225,7 @@ function useViewModeState() {
|
|
|
77922
78225
|
window.addEventListener("popstate", onPopState);
|
|
77923
78226
|
return () => window.removeEventListener("popstate", onPopState);
|
|
77924
78227
|
}, [canSetViewMode, viewMode]);
|
|
77925
|
-
const setViewMode =
|
|
78228
|
+
const setViewMode = useCallback139(
|
|
77926
78229
|
(mode) => {
|
|
77927
78230
|
if (!canSetViewMode(mode)) return false;
|
|
77928
78231
|
setMode(mode);
|
|
@@ -77932,7 +78235,7 @@ function useViewModeState() {
|
|
|
77932
78235
|
},
|
|
77933
78236
|
[canSetViewMode]
|
|
77934
78237
|
);
|
|
77935
|
-
const registerViewModeGuard =
|
|
78238
|
+
const registerViewModeGuard = useCallback139((guard) => {
|
|
77936
78239
|
guardsRef.current.add(guard);
|
|
77937
78240
|
return () => {
|
|
77938
78241
|
guardsRef.current.delete(guard);
|
|
@@ -78146,7 +78449,7 @@ var VIEW_MODE_OPTIONS = [
|
|
|
78146
78449
|
];
|
|
78147
78450
|
function ViewModeToggle() {
|
|
78148
78451
|
const { viewMode, setViewMode } = useViewMode();
|
|
78149
|
-
const tabRefs =
|
|
78452
|
+
const tabRefs = useRef149([]);
|
|
78150
78453
|
const selectMode = (mode) => {
|
|
78151
78454
|
if (mode === viewMode) return;
|
|
78152
78455
|
if (setViewMode(mode)) trackStudioEvent("view_mode_toggle", { mode });
|
|
@@ -78373,10 +78676,10 @@ function StudioHeader({
|
|
|
78373
78676
|
}
|
|
78374
78677
|
|
|
78375
78678
|
// src/hooks/useGestureCommit.ts
|
|
78376
|
-
import { useState as useState120, useCallback as
|
|
78679
|
+
import { useState as useState120, useCallback as useCallback141, useRef as useRef151, useEffect as useEffect114 } from "react";
|
|
78377
78680
|
|
|
78378
78681
|
// src/hooks/useGestureRecording.ts
|
|
78379
|
-
import { useCallback as
|
|
78682
|
+
import { useCallback as useCallback140, useEffect as useEffect113, useRef as useRef150, useState as useState119 } from "react";
|
|
78380
78683
|
function readBasePosition(element, iframeEl) {
|
|
78381
78684
|
let baseOpacity = 1;
|
|
78382
78685
|
let baseScale = 1;
|
|
@@ -78521,10 +78824,10 @@ function releaseRuntimePreview(r) {
|
|
|
78521
78824
|
function useGestureRecording() {
|
|
78522
78825
|
const [isRecording, setIsRecording] = useState119(false);
|
|
78523
78826
|
const [recordingDuration, setRecordingDuration] = useState119(0);
|
|
78524
|
-
const isRecordingRef =
|
|
78525
|
-
const refs =
|
|
78526
|
-
const samplesRef =
|
|
78527
|
-
const trailRef =
|
|
78827
|
+
const isRecordingRef = useRef150(false);
|
|
78828
|
+
const refs = useRef150(createRecordingRefs());
|
|
78829
|
+
const samplesRef = useRef150(refs.current.samples);
|
|
78830
|
+
const trailRef = useRef150(refs.current.trail);
|
|
78528
78831
|
useEffect113(() => {
|
|
78529
78832
|
const r = refs.current;
|
|
78530
78833
|
return () => {
|
|
@@ -78534,7 +78837,7 @@ function useGestureRecording() {
|
|
|
78534
78837
|
r.cleanup = null;
|
|
78535
78838
|
};
|
|
78536
78839
|
}, []);
|
|
78537
|
-
const startRecording =
|
|
78840
|
+
const startRecording = useCallback140(
|
|
78538
78841
|
(element, iframeEl, elementEndTime) => {
|
|
78539
78842
|
if (isRecordingRef.current) return;
|
|
78540
78843
|
isRecordingRef.current = true;
|
|
@@ -78634,7 +78937,7 @@ function useGestureRecording() {
|
|
|
78634
78937
|
[]
|
|
78635
78938
|
// No deps — uses refs only for all mutable state
|
|
78636
78939
|
);
|
|
78637
|
-
const stopRecording =
|
|
78940
|
+
const stopRecording = useCallback140(() => {
|
|
78638
78941
|
if (!isRecordingRef.current) return [];
|
|
78639
78942
|
isRecordingRef.current = false;
|
|
78640
78943
|
const r = refs.current;
|
|
@@ -78646,7 +78949,7 @@ function useGestureRecording() {
|
|
|
78646
78949
|
setIsRecording(false);
|
|
78647
78950
|
return frozen;
|
|
78648
78951
|
}, []);
|
|
78649
|
-
const clearSamples =
|
|
78952
|
+
const clearSamples = useCallback140(() => {
|
|
78650
78953
|
const r = refs.current;
|
|
78651
78954
|
r.samples = [];
|
|
78652
78955
|
r.trail = [];
|
|
@@ -78903,13 +79206,13 @@ function useGestureCommit({
|
|
|
78903
79206
|
}) {
|
|
78904
79207
|
const gestureRecording = useGestureRecording();
|
|
78905
79208
|
const [gestureState, setGestureState] = useState120("idle");
|
|
78906
|
-
const gestureStateRef =
|
|
78907
|
-
const recordingAutoStopRef =
|
|
78908
|
-
const recordingStartTimeRef =
|
|
78909
|
-
const commitInFlightRef =
|
|
78910
|
-
const capturedSelectionRef =
|
|
79209
|
+
const gestureStateRef = useRef151("idle");
|
|
79210
|
+
const recordingAutoStopRef = useRef151(void 0);
|
|
79211
|
+
const recordingStartTimeRef = useRef151(0);
|
|
79212
|
+
const commitInFlightRef = useRef151(false);
|
|
79213
|
+
const capturedSelectionRef = useRef151(null);
|
|
78911
79214
|
useEffect114(() => () => clearInterval(recordingAutoStopRef.current), []);
|
|
78912
|
-
const stopAndCommitRecording =
|
|
79215
|
+
const stopAndCommitRecording = useCallback141(async () => {
|
|
78913
79216
|
clearInterval(recordingAutoStopRef.current);
|
|
78914
79217
|
if (commitInFlightRef.current) {
|
|
78915
79218
|
return;
|
|
@@ -79082,7 +79385,7 @@ function useGestureCommit({
|
|
|
79082
79385
|
commitInFlightRef.current = false;
|
|
79083
79386
|
}
|
|
79084
79387
|
}, [gestureRecording, showToast, isGestureRecordingRef, domEditSessionRef]);
|
|
79085
|
-
const handleToggleRecording =
|
|
79388
|
+
const handleToggleRecording = useCallback141(() => {
|
|
79086
79389
|
if (gestureStateRef.current === "recording") {
|
|
79087
79390
|
void stopAndCommitRecording();
|
|
79088
79391
|
return;
|
|
@@ -79240,20 +79543,21 @@ var GestureTrailOverlay = memo38(function GestureTrailOverlay2({
|
|
|
79240
79543
|
});
|
|
79241
79544
|
|
|
79242
79545
|
// src/components/StudioLeftSidebar.tsx
|
|
79243
|
-
import { useCallback as
|
|
79546
|
+
import { useCallback as useCallback150 } from "react";
|
|
79244
79547
|
|
|
79245
79548
|
// src/components/sidebar/LeftSidebar.tsx
|
|
79246
79549
|
import {
|
|
79247
79550
|
memo as memo42,
|
|
79248
79551
|
useState as useState130,
|
|
79249
|
-
useCallback as
|
|
79552
|
+
useCallback as useCallback149,
|
|
79250
79553
|
useImperativeHandle,
|
|
79251
|
-
|
|
79554
|
+
useMemo as useMemo72,
|
|
79555
|
+
useRef as useRef159,
|
|
79252
79556
|
forwardRef as forwardRef3
|
|
79253
79557
|
} from "react";
|
|
79254
79558
|
|
|
79255
79559
|
// src/components/sidebar/CompositionsTab.tsx
|
|
79256
|
-
import { memo as memo39, useCallback as
|
|
79560
|
+
import { memo as memo39, useCallback as useCallback142, useEffect as useEffect115, useRef as useRef152, useState as useState121 } from "react";
|
|
79257
79561
|
import { jsx as jsx175, jsxs as jsxs145 } from "react/jsx-runtime";
|
|
79258
79562
|
var DEFAULT_PREVIEW_STAGE = { width: 1920, height: 1080 };
|
|
79259
79563
|
var CARD_W = 80;
|
|
@@ -79315,6 +79619,7 @@ function CompCard({
|
|
|
79315
79619
|
projectId,
|
|
79316
79620
|
comp,
|
|
79317
79621
|
isActive,
|
|
79622
|
+
isRoot,
|
|
79318
79623
|
onSelect,
|
|
79319
79624
|
onRender,
|
|
79320
79625
|
isRendering,
|
|
@@ -79326,11 +79631,11 @@ function CompCard({
|
|
|
79326
79631
|
const [stageSize, setStageSize] = useState121(DEFAULT_PREVIEW_STAGE);
|
|
79327
79632
|
const [livePreviewLoaded, setLivePreviewLoaded] = useState121(false);
|
|
79328
79633
|
const [failedThumbnailUrl, setFailedThumbnailUrl] = useState121(null);
|
|
79329
|
-
const iframeRef =
|
|
79330
|
-
const hoverTimer =
|
|
79331
|
-
const syncTimer =
|
|
79332
|
-
const draggedRef =
|
|
79333
|
-
const requestIframePlaybackSync =
|
|
79634
|
+
const iframeRef = useRef152(null);
|
|
79635
|
+
const hoverTimer = useRef152(null);
|
|
79636
|
+
const syncTimer = useRef152(null);
|
|
79637
|
+
const draggedRef = useRef152(false);
|
|
79638
|
+
const requestIframePlaybackSync = useCallback142((shouldPlay) => {
|
|
79334
79639
|
if (syncTimer.current) {
|
|
79335
79640
|
clearTimeout(syncTimer.current);
|
|
79336
79641
|
syncTimer.current = null;
|
|
@@ -79469,6 +79774,15 @@ function CompCard({
|
|
|
79469
79774
|
children: [
|
|
79470
79775
|
/* @__PURE__ */ jsxs145("div", { className: "flex items-center gap-1", children: [
|
|
79471
79776
|
/* @__PURE__ */ jsx175("span", { className: "text-[11px] font-medium text-neutral-300 truncate", children: name }),
|
|
79777
|
+
isRoot && /* @__PURE__ */ jsx175(
|
|
79778
|
+
"span",
|
|
79779
|
+
{
|
|
79780
|
+
"aria-label": "Root composition \u2014 opens automatically on load",
|
|
79781
|
+
title: "Root composition \u2014 opens automatically on load",
|
|
79782
|
+
className: "flex-shrink-0 rounded-full bg-neutral-700/60 px-1.5 py-px text-[8px] font-bold uppercase tracking-wide text-neutral-300",
|
|
79783
|
+
children: "Root"
|
|
79784
|
+
}
|
|
79785
|
+
),
|
|
79472
79786
|
lintInfo && lintInfo.count > 0 && /* @__PURE__ */ jsx175(
|
|
79473
79787
|
"span",
|
|
79474
79788
|
{
|
|
@@ -79536,6 +79850,7 @@ var CompositionsTab = memo39(function CompositionsTab2({
|
|
|
79536
79850
|
projectId,
|
|
79537
79851
|
compositions,
|
|
79538
79852
|
activeComposition,
|
|
79853
|
+
masterCompositionPath = null,
|
|
79539
79854
|
onSelect,
|
|
79540
79855
|
onRenderComposition,
|
|
79541
79856
|
onAddToTimeline,
|
|
@@ -79552,6 +79867,7 @@ var CompositionsTab = memo39(function CompositionsTab2({
|
|
|
79552
79867
|
projectId,
|
|
79553
79868
|
comp,
|
|
79554
79869
|
isActive: activeComposition === comp,
|
|
79870
|
+
isRoot: comp === masterCompositionPath,
|
|
79555
79871
|
onSelect: () => onSelect(comp),
|
|
79556
79872
|
onRender: onRenderComposition ? () => onRenderComposition(comp) : void 0,
|
|
79557
79873
|
onAddToTimeline: onAddToTimeline ? () => onAddToTimeline(comp) : void 0,
|
|
@@ -79564,7 +79880,7 @@ var CompositionsTab = memo39(function CompositionsTab2({
|
|
|
79564
79880
|
});
|
|
79565
79881
|
|
|
79566
79882
|
// src/components/sidebar/AssetsTab.tsx
|
|
79567
|
-
import { memo as memo40, useState as useState127, useCallback as
|
|
79883
|
+
import { memo as memo40, useState as useState127, useCallback as useCallback146, useRef as useRef156, useMemo as useMemo71, useEffect as useEffect121 } from "react";
|
|
79568
79884
|
|
|
79569
79885
|
// src/components/ui/SearchInput.tsx
|
|
79570
79886
|
import { jsx as jsx176, jsxs as jsxs146 } from "react/jsx-runtime";
|
|
@@ -79675,11 +79991,11 @@ var CATEGORY_LABELS = {
|
|
|
79675
79991
|
var FILTER_ORDER = ["audio", "images", "video", "fonts"];
|
|
79676
79992
|
|
|
79677
79993
|
// src/components/sidebar/AudioRow.tsx
|
|
79678
|
-
import { useState as useState123, useRef as
|
|
79994
|
+
import { useState as useState123, useRef as useRef154, useEffect as useEffect117, useCallback as useCallback144 } from "react";
|
|
79679
79995
|
import { classifyWebAudioMediaRoute } from "@hyperframes/core/runtime/web-audio-route";
|
|
79680
79996
|
|
|
79681
79997
|
// src/components/sidebar/AssetContextMenu.tsx
|
|
79682
|
-
import { useCallback as
|
|
79998
|
+
import { useCallback as useCallback143, useEffect as useEffect116, useLayoutEffect as useLayoutEffect9, useRef as useRef153, useState as useState122 } from "react";
|
|
79683
79999
|
import { Fragment as Fragment51, jsx as jsx177, jsxs as jsxs147 } from "react/jsx-runtime";
|
|
79684
80000
|
function isValidAssetName(name) {
|
|
79685
80001
|
return name.length > 0 && !/[/\\]/.test(name) && !name.includes("..");
|
|
@@ -79694,7 +80010,7 @@ function ContextMenu2({
|
|
|
79694
80010
|
onRename,
|
|
79695
80011
|
onAddAtPlayhead
|
|
79696
80012
|
}) {
|
|
79697
|
-
const menuRef =
|
|
80013
|
+
const menuRef = useRef153(null);
|
|
79698
80014
|
const [pos, setPos] = useState122({ x, y });
|
|
79699
80015
|
const [mode, setMode] = useState122("menu");
|
|
79700
80016
|
const [renameDraft, setRenameDraft] = useState122(() => filename(asset));
|
|
@@ -79739,7 +80055,7 @@ function ContextMenu2({
|
|
|
79739
80055
|
menuRef.current?.querySelector('[role="menuitem"]')?.focus();
|
|
79740
80056
|
}
|
|
79741
80057
|
}, [mode]);
|
|
79742
|
-
const commitRename =
|
|
80058
|
+
const commitRename = useCallback143(() => {
|
|
79743
80059
|
const trimmed = renameDraft.trim();
|
|
79744
80060
|
if (trimmed === filename(asset)) {
|
|
79745
80061
|
onClose();
|
|
@@ -79945,28 +80261,28 @@ function AudioRow({
|
|
|
79945
80261
|
const [contextMenu, setContextMenu] = useState123(null);
|
|
79946
80262
|
const [playing, setPlaying] = useState123(false);
|
|
79947
80263
|
const [bars, setBars] = useState123([]);
|
|
79948
|
-
const audioRef =
|
|
79949
|
-
const actxRef =
|
|
79950
|
-
const analyserRef =
|
|
79951
|
-
const sourceRef =
|
|
79952
|
-
const animRef =
|
|
80264
|
+
const audioRef = useRef154(null);
|
|
80265
|
+
const actxRef = useRef154(null);
|
|
80266
|
+
const analyserRef = useRef154(null);
|
|
80267
|
+
const sourceRef = useRef154(null);
|
|
80268
|
+
const animRef = useRef154(0);
|
|
79953
80269
|
const name = basename2(asset);
|
|
79954
80270
|
const subtype = getAudioSubtype(asset);
|
|
79955
80271
|
const serveUrl = resolveMediaPreviewUrl(asset, projectId);
|
|
79956
80272
|
const isCopied = copyFeedback?.path === asset && copyFeedback.ok;
|
|
79957
80273
|
const copyFailed = copyFeedback?.path === asset && !copyFeedback.ok;
|
|
79958
|
-
const stopPlayback =
|
|
80274
|
+
const stopPlayback = useCallback144(() => {
|
|
79959
80275
|
audioRef.current?.pause();
|
|
79960
80276
|
setPlaying(false);
|
|
79961
80277
|
cancelAnimationFrame(animRef.current);
|
|
79962
80278
|
}, []);
|
|
79963
|
-
const pointerDownRef =
|
|
80279
|
+
const pointerDownRef = useRef154(null);
|
|
79964
80280
|
const setSelectedElementId = usePlayerStore((s) => s.setSelectedElementId);
|
|
79965
80281
|
const requestTimelineFocus = usePlayerStore((s) => s.requestTimelineFocus);
|
|
79966
80282
|
const elements = usePlayerStore((s) => s.elements);
|
|
79967
80283
|
const setPreviewAsset = useAssetPreviewStore((s) => s.setPreviewAsset);
|
|
79968
80284
|
const clearPreviewAsset = useAssetPreviewStore((s) => s.clearPreviewAsset);
|
|
79969
|
-
const activateRow =
|
|
80285
|
+
const activateRow = useCallback144(() => {
|
|
79970
80286
|
if (used) {
|
|
79971
80287
|
const clip = findClipForAsset(elements, asset);
|
|
79972
80288
|
if (clip) {
|
|
@@ -79988,10 +80304,10 @@ function AudioRow({
|
|
|
79988
80304
|
setPreviewAsset,
|
|
79989
80305
|
clearPreviewAsset
|
|
79990
80306
|
]);
|
|
79991
|
-
const handlePointerDown =
|
|
80307
|
+
const handlePointerDown = useCallback144((e) => {
|
|
79992
80308
|
pointerDownRef.current = { x: e.clientX, y: e.clientY };
|
|
79993
80309
|
}, []);
|
|
79994
|
-
const handlePointerUp =
|
|
80310
|
+
const handlePointerUp = useCallback144(
|
|
79995
80311
|
(e) => {
|
|
79996
80312
|
const origin = pointerDownRef.current;
|
|
79997
80313
|
pointerDownRef.current = null;
|
|
@@ -80037,7 +80353,7 @@ function AudioRow({
|
|
|
80037
80353
|
}
|
|
80038
80354
|
return () => cancelAnimationFrame(animRef.current);
|
|
80039
80355
|
}, [playing]);
|
|
80040
|
-
const togglePlay =
|
|
80356
|
+
const togglePlay = useCallback144(async () => {
|
|
80041
80357
|
if (playing) {
|
|
80042
80358
|
stopPlayback();
|
|
80043
80359
|
if (stopCurrentPreview === stopPlayback) stopCurrentPreview = null;
|
|
@@ -80235,7 +80551,7 @@ function GlobalAssetsView({ searchQuery }) {
|
|
|
80235
80551
|
}
|
|
80236
80552
|
|
|
80237
80553
|
// src/components/sidebar/AssetCard.tsx
|
|
80238
|
-
import { useState as useState126, useEffect as useEffect120, useRef as
|
|
80554
|
+
import { useState as useState126, useEffect as useEffect120, useRef as useRef155, useCallback as useCallback145 } from "react";
|
|
80239
80555
|
|
|
80240
80556
|
// src/components/ui/VideoFrameThumbnail.tsx
|
|
80241
80557
|
import { useState as useState125, useEffect as useEffect119 } from "react";
|
|
@@ -80373,16 +80689,16 @@ function AssetCard({
|
|
|
80373
80689
|
const probedDuration = useProbedDuration(serveUrl, !isVideo || duration != null);
|
|
80374
80690
|
const resolvedDuration = duration ?? probedDuration ?? void 0;
|
|
80375
80691
|
const durationLabel = formatDuration(resolvedDuration ?? 0);
|
|
80376
|
-
const pointerDownRef =
|
|
80692
|
+
const pointerDownRef = useRef155(null);
|
|
80377
80693
|
const setSelectedElementId = usePlayerStore((s) => s.setSelectedElementId);
|
|
80378
80694
|
const requestTimelineFocus = usePlayerStore((s) => s.requestTimelineFocus);
|
|
80379
80695
|
const elements = usePlayerStore((s) => s.elements);
|
|
80380
80696
|
const setPreviewAsset = useAssetPreviewStore((s) => s.setPreviewAsset);
|
|
80381
80697
|
const clearPreviewAsset = useAssetPreviewStore((s) => s.clearPreviewAsset);
|
|
80382
|
-
const handlePointerDown =
|
|
80698
|
+
const handlePointerDown = useCallback145((e) => {
|
|
80383
80699
|
pointerDownRef.current = { x: e.clientX, y: e.clientY };
|
|
80384
80700
|
}, []);
|
|
80385
|
-
const activateCard =
|
|
80701
|
+
const activateCard = useCallback145(() => {
|
|
80386
80702
|
if (used) {
|
|
80387
80703
|
const clip = findClipForAsset(elements, asset);
|
|
80388
80704
|
if (clip) {
|
|
@@ -80404,7 +80720,7 @@ function AssetCard({
|
|
|
80404
80720
|
setPreviewAsset,
|
|
80405
80721
|
clearPreviewAsset
|
|
80406
80722
|
]);
|
|
80407
|
-
const handlePointerUp =
|
|
80723
|
+
const handlePointerUp = useCallback145(
|
|
80408
80724
|
(e) => {
|
|
80409
80725
|
const origin = pointerDownRef.current;
|
|
80410
80726
|
pointerDownRef.current = null;
|
|
@@ -80698,7 +81014,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80698
81014
|
onRename,
|
|
80699
81015
|
onAddAssetToTimeline
|
|
80700
81016
|
}) {
|
|
80701
|
-
const fileInputRef =
|
|
81017
|
+
const fileInputRef = useRef156(null);
|
|
80702
81018
|
const [dragOver, setDragOver] = useState127(false);
|
|
80703
81019
|
const [copyFeedback, setCopyFeedback] = useState127(null);
|
|
80704
81020
|
const [importing, setImporting] = useState127(false);
|
|
@@ -80707,7 +81023,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80707
81023
|
const [searchQuery, setSearchQuery] = useState127("");
|
|
80708
81024
|
const [viewMode, setViewMode] = useState127("local");
|
|
80709
81025
|
const [manifest, setManifest] = useState127(/* @__PURE__ */ new Map());
|
|
80710
|
-
const manifest404Ref =
|
|
81026
|
+
const manifest404Ref = useRef156(/* @__PURE__ */ new Set());
|
|
80711
81027
|
const assetsKey = assets.join("|");
|
|
80712
81028
|
useEffect121(() => {
|
|
80713
81029
|
if (manifest404Ref.current.has(projectId)) return;
|
|
@@ -80736,7 +81052,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80736
81052
|
cancelled = true;
|
|
80737
81053
|
};
|
|
80738
81054
|
}, [projectId, assetsKey]);
|
|
80739
|
-
const handleImport =
|
|
81055
|
+
const handleImport = useCallback146(
|
|
80740
81056
|
async (files) => {
|
|
80741
81057
|
if (!onImport) return;
|
|
80742
81058
|
setImporting(true);
|
|
@@ -80748,7 +81064,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80748
81064
|
},
|
|
80749
81065
|
[onImport]
|
|
80750
81066
|
);
|
|
80751
|
-
const handleDrop =
|
|
81067
|
+
const handleDrop = useCallback146(
|
|
80752
81068
|
(e) => {
|
|
80753
81069
|
e.preventDefault();
|
|
80754
81070
|
setDragOver(false);
|
|
@@ -80756,7 +81072,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80756
81072
|
},
|
|
80757
81073
|
[handleImport]
|
|
80758
81074
|
);
|
|
80759
|
-
const handleCopyPath =
|
|
81075
|
+
const handleCopyPath = useCallback146(async (path) => {
|
|
80760
81076
|
const copied = await copyTextToClipboard(path);
|
|
80761
81077
|
setCopyFeedback({ path, ok: copied });
|
|
80762
81078
|
setTimeout(() => setCopyFeedback(null), copied ? 1500 : 3e3);
|
|
@@ -80966,11 +81282,11 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80966
81282
|
});
|
|
80967
81283
|
|
|
80968
81284
|
// src/components/sidebar/BlocksTab.tsx
|
|
80969
|
-
import { memo as memo41, useState as useState129, useCallback as
|
|
81285
|
+
import { memo as memo41, useState as useState129, useCallback as useCallback148, useRef as useRef158, useEffect as useEffect123 } from "react";
|
|
80970
81286
|
import { createPortal as createPortal9 } from "react-dom";
|
|
80971
81287
|
|
|
80972
81288
|
// src/components/sidebar/PromptPreviewModal.tsx
|
|
80973
|
-
import { useState as useState128, useCallback as
|
|
81289
|
+
import { useState as useState128, useCallback as useCallback147, useEffect as useEffect122, useRef as useRef157 } from "react";
|
|
80974
81290
|
import { jsx as jsx183, jsxs as jsxs152 } from "react/jsx-runtime";
|
|
80975
81291
|
function PromptPreviewModal({
|
|
80976
81292
|
title,
|
|
@@ -80980,9 +81296,9 @@ function PromptPreviewModal({
|
|
|
80980
81296
|
const [value, setValue] = useState128(prompt);
|
|
80981
81297
|
const [copyState, setCopyState] = useState128("idle");
|
|
80982
81298
|
const [entered, setEntered] = useState128(false);
|
|
80983
|
-
const containerRef =
|
|
80984
|
-
const textareaRef =
|
|
80985
|
-
const valueRef =
|
|
81299
|
+
const containerRef = useRef157(null);
|
|
81300
|
+
const textareaRef = useRef157(null);
|
|
81301
|
+
const valueRef = useRef157(value);
|
|
80986
81302
|
valueRef.current = value;
|
|
80987
81303
|
const { requestClose } = useDialogBehavior({
|
|
80988
81304
|
open: true,
|
|
@@ -80996,7 +81312,7 @@ function PromptPreviewModal({
|
|
|
80996
81312
|
textareaRef.current?.focus();
|
|
80997
81313
|
});
|
|
80998
81314
|
}, []);
|
|
80999
|
-
const handleCopy2 =
|
|
81315
|
+
const handleCopy2 = useCallback147(async () => {
|
|
81000
81316
|
try {
|
|
81001
81317
|
await navigator.clipboard.writeText(valueRef.current);
|
|
81002
81318
|
setCopyState("copied");
|
|
@@ -81279,16 +81595,16 @@ function BlockCard({
|
|
|
81279
81595
|
}) {
|
|
81280
81596
|
const [hovered, setHovered] = useState129(false);
|
|
81281
81597
|
const [addState, setAddState] = useState129("idle");
|
|
81282
|
-
const hoverTimer =
|
|
81598
|
+
const hoverTimer = useRef158(null);
|
|
81283
81599
|
const colors = getCategoryColors(category);
|
|
81284
81600
|
const needsWebGL = tags?.includes("html-in-canvas") || tags?.includes("webgl");
|
|
81285
|
-
const handleEnter =
|
|
81601
|
+
const handleEnter = useCallback148(() => {
|
|
81286
81602
|
hoverTimer.current = setTimeout(() => {
|
|
81287
81603
|
setHovered(true);
|
|
81288
81604
|
onPreview?.({ videoUrl, posterUrl, title });
|
|
81289
81605
|
}, 300);
|
|
81290
81606
|
}, [onPreview, videoUrl, posterUrl, title]);
|
|
81291
|
-
const handleLeave =
|
|
81607
|
+
const handleLeave = useCallback148(() => {
|
|
81292
81608
|
if (hoverTimer.current) {
|
|
81293
81609
|
clearTimeout(hoverTimer.current);
|
|
81294
81610
|
hoverTimer.current = null;
|
|
@@ -81301,7 +81617,7 @@ function BlockCard({
|
|
|
81301
81617
|
if (hoverTimer.current) clearTimeout(hoverTimer.current);
|
|
81302
81618
|
};
|
|
81303
81619
|
}, []);
|
|
81304
|
-
const handleAdd =
|
|
81620
|
+
const handleAdd = useCallback148(
|
|
81305
81621
|
async (e) => {
|
|
81306
81622
|
e.stopPropagation();
|
|
81307
81623
|
if (addState !== "idle" || !onAdd) return;
|
|
@@ -81317,7 +81633,7 @@ function BlockCard({
|
|
|
81317
81633
|
[onAdd, addState]
|
|
81318
81634
|
);
|
|
81319
81635
|
const { activeCompPath, compositionDimensions } = useStudioShellContext();
|
|
81320
|
-
const handleShowPrompt =
|
|
81636
|
+
const handleShowPrompt = useCallback148(
|
|
81321
81637
|
(e) => {
|
|
81322
81638
|
e.stopPropagation();
|
|
81323
81639
|
const state = usePlayerStore.getState();
|
|
@@ -81509,10 +81825,14 @@ var LeftSidebar = memo42(
|
|
|
81509
81825
|
onAddCompositionToTimeline
|
|
81510
81826
|
}, ref) {
|
|
81511
81827
|
const [tab, setTab] = useState130(getPersistedTab);
|
|
81512
|
-
const tabRef =
|
|
81828
|
+
const tabRef = useRef159(tab);
|
|
81513
81829
|
tabRef.current = tab;
|
|
81514
|
-
const tablistRef =
|
|
81515
|
-
const
|
|
81830
|
+
const tablistRef = useRef159(null);
|
|
81831
|
+
const masterCompositionPath = useMemo72(
|
|
81832
|
+
() => resolveMasterCompositionPath(compositions),
|
|
81833
|
+
[compositions]
|
|
81834
|
+
);
|
|
81835
|
+
const selectTab = useCallback149((t) => {
|
|
81516
81836
|
setTab(t);
|
|
81517
81837
|
try {
|
|
81518
81838
|
safeLocalStorage()?.setItem(STORAGE_KEY, t);
|
|
@@ -81520,9 +81840,9 @@ var LeftSidebar = memo42(
|
|
|
81520
81840
|
}
|
|
81521
81841
|
trackStudioEvent("tab_switch", { panel: "left_sidebar", tab: t });
|
|
81522
81842
|
}, []);
|
|
81523
|
-
const getTab =
|
|
81843
|
+
const getTab = useCallback149(() => tabRef.current, []);
|
|
81524
81844
|
useImperativeHandle(ref, () => ({ selectTab, getTab }), [selectTab, getTab]);
|
|
81525
|
-
const handleTablistKeyDown =
|
|
81845
|
+
const handleTablistKeyDown = useCallback149(
|
|
81526
81846
|
(e) => {
|
|
81527
81847
|
if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
|
|
81528
81848
|
e.preventDefault();
|
|
@@ -81607,6 +81927,7 @@ var LeftSidebar = memo42(
|
|
|
81607
81927
|
projectId,
|
|
81608
81928
|
compositions,
|
|
81609
81929
|
activeComposition,
|
|
81930
|
+
masterCompositionPath,
|
|
81610
81931
|
onSelect: onSelectComposition,
|
|
81611
81932
|
onAddToTimeline: onAddCompositionToTimeline,
|
|
81612
81933
|
onRenderComposition,
|
|
@@ -81879,7 +82200,7 @@ function StudioLeftSidebar({
|
|
|
81879
82200
|
handleImportFiles,
|
|
81880
82201
|
handleContentChange
|
|
81881
82202
|
} = useFileManagerContext();
|
|
81882
|
-
const handleRenderComposition =
|
|
82203
|
+
const handleRenderComposition = useCallback150(
|
|
81883
82204
|
async (comp) => {
|
|
81884
82205
|
if (renderQueue.ffmpegMissing) {
|
|
81885
82206
|
setRightPanelTab("renders");
|
|
@@ -82004,13 +82325,13 @@ function StudioLeftSidebar({
|
|
|
82004
82325
|
}
|
|
82005
82326
|
|
|
82006
82327
|
// src/components/StudioRightPanel.tsx
|
|
82007
|
-
import { useCallback as
|
|
82328
|
+
import { useCallback as useCallback167 } from "react";
|
|
82008
82329
|
|
|
82009
82330
|
// src/components/editor/LayersPanel.tsx
|
|
82010
|
-
import { memo as memo43, useState as useState133, useCallback as
|
|
82331
|
+
import { memo as memo43, useState as useState133, useCallback as useCallback152, useEffect as useEffect124, useRef as useRef161 } from "react";
|
|
82011
82332
|
|
|
82012
82333
|
// src/components/editor/useLayerDrag.ts
|
|
82013
|
-
import { useRef as
|
|
82334
|
+
import { useRef as useRef160, useState as useState132, useCallback as useCallback151 } from "react";
|
|
82014
82335
|
var DRAG_THRESHOLD_PX3 = 4;
|
|
82015
82336
|
function isLayerDraggable(layer) {
|
|
82016
82337
|
if (!(layer.selector || layer.id)) return false;
|
|
@@ -82077,10 +82398,10 @@ function useLayerDrag({
|
|
|
82077
82398
|
onReorder,
|
|
82078
82399
|
onSingleSibling
|
|
82079
82400
|
}) {
|
|
82080
|
-
const dragRef =
|
|
82401
|
+
const dragRef = useRef160(null);
|
|
82081
82402
|
const [dragKey, setDragKey] = useState132(null);
|
|
82082
82403
|
const [insertionLineY, setInsertionLineY] = useState132(null);
|
|
82083
|
-
const handleRowPointerDown =
|
|
82404
|
+
const handleRowPointerDown = useCallback151(
|
|
82084
82405
|
(layerIndex, e) => {
|
|
82085
82406
|
if (e.button !== 0) return;
|
|
82086
82407
|
const layer = visibleLayers[layerIndex];
|
|
@@ -82107,7 +82428,7 @@ function useLayerDrag({
|
|
|
82107
82428
|
},
|
|
82108
82429
|
[visibleLayers, scrollContainerRef, onSingleSibling]
|
|
82109
82430
|
);
|
|
82110
|
-
const handleContainerPointerMove =
|
|
82431
|
+
const handleContainerPointerMove = useCallback151(
|
|
82111
82432
|
(e) => {
|
|
82112
82433
|
const drag = dragRef.current;
|
|
82113
82434
|
if (!drag) return;
|
|
@@ -82133,7 +82454,7 @@ function useLayerDrag({
|
|
|
82133
82454
|
},
|
|
82134
82455
|
[visibleLayers, scrollContainerRef]
|
|
82135
82456
|
);
|
|
82136
|
-
const handleContainerPointerUp =
|
|
82457
|
+
const handleContainerPointerUp = useCallback151(() => {
|
|
82137
82458
|
const drag = dragRef.current;
|
|
82138
82459
|
dragRef.current = null;
|
|
82139
82460
|
setDragKey(null);
|
|
@@ -82283,15 +82604,15 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82283
82604
|
} = useDomEditContext();
|
|
82284
82605
|
const [layers, setLayers] = useState133([]);
|
|
82285
82606
|
const [collapsed, setCollapsed] = useState133({});
|
|
82286
|
-
const prevDocVersionRef =
|
|
82287
|
-
const scrollContainerRef =
|
|
82607
|
+
const prevDocVersionRef = useRef161(0);
|
|
82608
|
+
const scrollContainerRef = useRef161(null);
|
|
82288
82609
|
const mirrorLayerReorderToTimeline = useLayerReorderTimelineMirror();
|
|
82289
82610
|
const { scheduleReveal } = useLayerRevealOverride({
|
|
82290
82611
|
isPlaying,
|
|
82291
82612
|
selectedElement: domEditSelection?.element ?? null
|
|
82292
82613
|
});
|
|
82293
82614
|
const isMasterView = !activeCompPath || activeCompPath === "index.html";
|
|
82294
|
-
const collectLayers =
|
|
82615
|
+
const collectLayers = useCallback152(() => {
|
|
82295
82616
|
const iframe = previewIframeRef.current;
|
|
82296
82617
|
if (!iframe) return;
|
|
82297
82618
|
let doc = null;
|
|
@@ -82340,7 +82661,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82340
82661
|
throttle.cancel();
|
|
82341
82662
|
};
|
|
82342
82663
|
}, [collectLayers]);
|
|
82343
|
-
const resolveSelection =
|
|
82664
|
+
const resolveSelection = useCallback152(
|
|
82344
82665
|
(layer) => {
|
|
82345
82666
|
let el = layer.element;
|
|
82346
82667
|
if (!el.isConnected) {
|
|
@@ -82360,7 +82681,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82360
82681
|
},
|
|
82361
82682
|
[activeCompPath, isMasterView, previewIframeRef, activeGroupElement]
|
|
82362
82683
|
);
|
|
82363
|
-
const seekToLayer =
|
|
82684
|
+
const seekToLayer = useCallback152(
|
|
82364
82685
|
async (layer) => {
|
|
82365
82686
|
const selection = await resolveSelection(layer);
|
|
82366
82687
|
if (!selection) return;
|
|
@@ -82389,7 +82710,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82389
82710
|
},
|
|
82390
82711
|
[currentTime, resolveSelection, timelineElements]
|
|
82391
82712
|
);
|
|
82392
|
-
const handleSelectLayer =
|
|
82713
|
+
const handleSelectLayer = useCallback152(
|
|
82393
82714
|
async (layer) => {
|
|
82394
82715
|
const selection = await resolveSelection(layer);
|
|
82395
82716
|
if (!selection) return;
|
|
@@ -82399,7 +82720,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82399
82720
|
},
|
|
82400
82721
|
[resolveSelection, applyDomSelection, seekToLayer, scheduleReveal]
|
|
82401
82722
|
);
|
|
82402
|
-
const handleLayerDoubleClick =
|
|
82723
|
+
const handleLayerDoubleClick = useCallback152(
|
|
82403
82724
|
async (layer) => {
|
|
82404
82725
|
const selection = await resolveSelection(layer);
|
|
82405
82726
|
if (selection?.element.hasAttribute("data-hf-group")) {
|
|
@@ -82410,7 +82731,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82410
82731
|
},
|
|
82411
82732
|
[resolveSelection, setActiveGroupElement, handleSelectLayer]
|
|
82412
82733
|
);
|
|
82413
|
-
const handleLayerHover =
|
|
82734
|
+
const handleLayerHover = useCallback152(
|
|
82414
82735
|
async (layer) => {
|
|
82415
82736
|
if (!layer) {
|
|
82416
82737
|
updateDomEditHoverSelection(null);
|
|
@@ -82421,11 +82742,11 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82421
82742
|
},
|
|
82422
82743
|
[resolveSelection, updateDomEditHoverSelection]
|
|
82423
82744
|
);
|
|
82424
|
-
const toggleCollapse =
|
|
82745
|
+
const toggleCollapse = useCallback152((key2, e) => {
|
|
82425
82746
|
e.stopPropagation();
|
|
82426
82747
|
setCollapsed((prev) => ({ ...prev, [key2]: !prev[key2] }));
|
|
82427
82748
|
}, []);
|
|
82428
|
-
const handleReorder =
|
|
82749
|
+
const handleReorder = useCallback152(
|
|
82429
82750
|
(event) => {
|
|
82430
82751
|
const { siblingLayers, fromIndex, toIndex } = event;
|
|
82431
82752
|
const reordered = [...siblingLayers];
|
|
@@ -82488,7 +82809,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82488
82809
|
);
|
|
82489
82810
|
const selectedKey = domEditSelection ? getDomEditLayerKey(domEditSelection) : null;
|
|
82490
82811
|
const visibleLayers = getVisibleLayers(layers, collapsed);
|
|
82491
|
-
const handleSingleSibling =
|
|
82812
|
+
const handleSingleSibling = useCallback152(() => {
|
|
82492
82813
|
showToast("Only one layer at this level", "info");
|
|
82493
82814
|
}, [showToast]);
|
|
82494
82815
|
const {
|
|
@@ -82620,13 +82941,13 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82620
82941
|
});
|
|
82621
82942
|
|
|
82622
82943
|
// src/captions/components/CaptionPropertyPanel.tsx
|
|
82623
|
-
import { memo as memo45, useCallback as
|
|
82944
|
+
import { memo as memo45, useCallback as useCallback154, useState as useState135 } from "react";
|
|
82624
82945
|
|
|
82625
82946
|
// src/captions/components/CaptionAnimationPanel.tsx
|
|
82626
|
-
import { memo as memo44, useCallback as
|
|
82947
|
+
import { memo as memo44, useCallback as useCallback153 } from "react";
|
|
82627
82948
|
|
|
82628
82949
|
// src/captions/components/shared.tsx
|
|
82629
|
-
import { useEffect as useEffect125, useRef as
|
|
82950
|
+
import { useEffect as useEffect125, useRef as useRef162, useState as useState134 } from "react";
|
|
82630
82951
|
import { jsx as jsx189, jsxs as jsxs158 } from "react/jsx-runtime";
|
|
82631
82952
|
var inputCls = "w-full bg-neutral-900 border border-neutral-800 rounded px-1.5 py-0.5 text-2xs text-neutral-200 font-mono outline-none focus:border-studio-accent disabled:opacity-40 disabled:cursor-not-allowed";
|
|
82632
82953
|
function Section2({ label, children }) {
|
|
@@ -82652,7 +82973,7 @@ function NumberField({
|
|
|
82652
82973
|
onCommit
|
|
82653
82974
|
}) {
|
|
82654
82975
|
const [draft, setDraft] = useState134(null);
|
|
82655
|
-
const focusedRef =
|
|
82976
|
+
const focusedRef = useRef162(false);
|
|
82656
82977
|
useEffect125(() => {
|
|
82657
82978
|
if (!focusedRef.current) setDraft(null);
|
|
82658
82979
|
}, [value]);
|
|
@@ -82848,25 +83169,25 @@ var CaptionAnimationPanel = memo44(function CaptionAnimationPanel2() {
|
|
|
82848
83169
|
}
|
|
82849
83170
|
const group = resolvedGroupId ? model?.groups.get(resolvedGroupId) : void 0;
|
|
82850
83171
|
const animation = group?.animation;
|
|
82851
|
-
const handleEntranceChange =
|
|
83172
|
+
const handleEntranceChange = useCallback153(
|
|
82852
83173
|
(update) => {
|
|
82853
83174
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "entrance", update);
|
|
82854
83175
|
},
|
|
82855
83176
|
[resolvedGroupId, updateGroupAnimation]
|
|
82856
83177
|
);
|
|
82857
|
-
const handleHighlightChange =
|
|
83178
|
+
const handleHighlightChange = useCallback153(
|
|
82858
83179
|
(update) => {
|
|
82859
83180
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "highlight", update);
|
|
82860
83181
|
},
|
|
82861
83182
|
[resolvedGroupId, updateGroupAnimation]
|
|
82862
83183
|
);
|
|
82863
|
-
const handleExitChange =
|
|
83184
|
+
const handleExitChange = useCallback153(
|
|
82864
83185
|
(update) => {
|
|
82865
83186
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "exit", update);
|
|
82866
83187
|
},
|
|
82867
83188
|
[resolvedGroupId, updateGroupAnimation]
|
|
82868
83189
|
);
|
|
82869
|
-
const handleApplyToAll =
|
|
83190
|
+
const handleApplyToAll = useCallback153(() => {
|
|
82870
83191
|
if (animation) applyAnimationToAll(animation);
|
|
82871
83192
|
}, [animation, applyAnimationToAll]);
|
|
82872
83193
|
if (!group || !resolvedGroupId || !animation) {
|
|
@@ -82966,7 +83287,7 @@ var CaptionPropertyPanel = memo45(function CaptionPropertyPanel2({
|
|
|
82966
83287
|
...groupStyle,
|
|
82967
83288
|
...segmentOverrides
|
|
82968
83289
|
};
|
|
82969
|
-
const applyToIframeDom =
|
|
83290
|
+
const applyToIframeDom = useCallback154(
|
|
82970
83291
|
(updates) => {
|
|
82971
83292
|
const iframe = iframeRef.current;
|
|
82972
83293
|
if (!iframe || !model) return;
|
|
@@ -83040,7 +83361,7 @@ var CaptionPropertyPanel = memo45(function CaptionPropertyPanel2({
|
|
|
83040
83361
|
},
|
|
83041
83362
|
[iframeRef, model, selectedSegmentIds]
|
|
83042
83363
|
);
|
|
83043
|
-
const handleStyleChange =
|
|
83364
|
+
const handleStyleChange = useCallback154(
|
|
83044
83365
|
(updates) => {
|
|
83045
83366
|
if (selectedGroupId) {
|
|
83046
83367
|
updateGroupStyle(selectedGroupId, updates);
|
|
@@ -83145,7 +83466,7 @@ var CaptionPropertyPanel = memo45(function CaptionPropertyPanel2({
|
|
|
83145
83466
|
});
|
|
83146
83467
|
|
|
83147
83468
|
// src/components/editor/BlockParamsPanel.tsx
|
|
83148
|
-
import { memo as memo46, useCallback as
|
|
83469
|
+
import { memo as memo46, useCallback as useCallback155, useEffect as useEffect126, useRef as useRef163, useState as useState136 } from "react";
|
|
83149
83470
|
import { jsx as jsx192, jsxs as jsxs161 } from "react/jsx-runtime";
|
|
83150
83471
|
var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
83151
83472
|
blockName,
|
|
@@ -83163,12 +83484,12 @@ var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
|
83163
83484
|
}
|
|
83164
83485
|
return initial;
|
|
83165
83486
|
});
|
|
83166
|
-
const appliedRef =
|
|
83487
|
+
const appliedRef = useRef163(
|
|
83167
83488
|
Object.fromEntries(params.map((p) => [p.key, p.default]))
|
|
83168
83489
|
);
|
|
83169
83490
|
const [commitState, setCommitState] = useState136({ tone: "idle" });
|
|
83170
|
-
const commitTimersRef =
|
|
83171
|
-
const commitParamNow =
|
|
83491
|
+
const commitTimersRef = useRef163(/* @__PURE__ */ new Map());
|
|
83492
|
+
const commitParamNow = useCallback155(
|
|
83172
83493
|
async (key2, nextValue) => {
|
|
83173
83494
|
if (!fileManager) return;
|
|
83174
83495
|
const previous = appliedRef.current[key2];
|
|
@@ -83209,8 +83530,8 @@ var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
|
83209
83530
|
},
|
|
83210
83531
|
[fileManager, compositionPath, setRefreshKey, blockName]
|
|
83211
83532
|
);
|
|
83212
|
-
const commitChainRef =
|
|
83213
|
-
const commitParam =
|
|
83533
|
+
const commitChainRef = useRef163(Promise.resolve());
|
|
83534
|
+
const commitParam = useCallback155(
|
|
83214
83535
|
(key2, nextValue) => {
|
|
83215
83536
|
const run = commitChainRef.current.then(() => commitParamNow(key2, nextValue));
|
|
83216
83537
|
commitChainRef.current = run.catch(() => void 0);
|
|
@@ -83218,7 +83539,7 @@ var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
|
83218
83539
|
},
|
|
83219
83540
|
[commitParamNow]
|
|
83220
83541
|
);
|
|
83221
|
-
const handleChange =
|
|
83542
|
+
const handleChange = useCallback155(
|
|
83222
83543
|
(key2, value) => {
|
|
83223
83544
|
setValues((prev) => ({ ...prev, [key2]: value }));
|
|
83224
83545
|
const timers = commitTimersRef.current;
|
|
@@ -83234,7 +83555,7 @@ var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
|
83234
83555
|
},
|
|
83235
83556
|
[commitParam]
|
|
83236
83557
|
);
|
|
83237
|
-
const flushRef =
|
|
83558
|
+
const flushRef = useRef163(() => {
|
|
83238
83559
|
});
|
|
83239
83560
|
flushRef.current = () => {
|
|
83240
83561
|
for (const [key2, timer] of commitTimersRef.current) {
|
|
@@ -83376,12 +83697,12 @@ function ParamControl({
|
|
|
83376
83697
|
import { memo as memo50 } from "react";
|
|
83377
83698
|
|
|
83378
83699
|
// src/components/renders/RenderQueue.tsx
|
|
83379
|
-
import { memo as memo49, useState as useState139, useRef as
|
|
83700
|
+
import { memo as memo49, useState as useState139, useRef as useRef165, useEffect as useEffect128, useLayoutEffect as useLayoutEffect10, useId as useId7 } from "react";
|
|
83380
83701
|
import { createPortal as createPortal10 } from "react-dom";
|
|
83381
83702
|
import { CANVAS_DIMENSIONS } from "@hyperframes/parsers";
|
|
83382
83703
|
|
|
83383
83704
|
// src/components/renders/RenderQueueItem.tsx
|
|
83384
|
-
import { memo as memo47, useCallback as
|
|
83705
|
+
import { memo as memo47, useCallback as useCallback156, useState as useState137 } from "react";
|
|
83385
83706
|
import { Fragment as Fragment57, jsx as jsx193, jsxs as jsxs162 } from "react/jsx-runtime";
|
|
83386
83707
|
function formatDuration2(ms) {
|
|
83387
83708
|
if (ms < 1e3) return `${ms}ms`;
|
|
@@ -83404,10 +83725,10 @@ var RenderQueueItem = memo47(function RenderQueueItem2({
|
|
|
83404
83725
|
const [videoReady, setVideoReady] = useState137(false);
|
|
83405
83726
|
const [confirmingDelete, setConfirmingDelete] = useState137(false);
|
|
83406
83727
|
const fileSrc = buildProjectApiPath(projectId, `/renders/file/${job.filename}`);
|
|
83407
|
-
const handleOpen =
|
|
83728
|
+
const handleOpen = useCallback156(() => {
|
|
83408
83729
|
window.open(fileSrc, "_blank");
|
|
83409
83730
|
}, [fileSrc]);
|
|
83410
|
-
const handleDownload =
|
|
83731
|
+
const handleDownload = useCallback156(
|
|
83411
83732
|
(e) => {
|
|
83412
83733
|
e.stopPropagation();
|
|
83413
83734
|
const a = document.createElement("a");
|
|
@@ -83607,7 +83928,7 @@ var RenderQueueItem = memo47(function RenderQueueItem2({
|
|
|
83607
83928
|
});
|
|
83608
83929
|
|
|
83609
83930
|
// src/components/renders/FfmpegRequiredNotice.tsx
|
|
83610
|
-
import { memo as memo48, useEffect as useEffect127, useRef as
|
|
83931
|
+
import { memo as memo48, useEffect as useEffect127, useRef as useRef164, useState as useState138 } from "react";
|
|
83611
83932
|
import { jsx as jsx194, jsxs as jsxs163 } from "react/jsx-runtime";
|
|
83612
83933
|
var DOWNLOAD_URL = "https://ffmpeg.org/download.html";
|
|
83613
83934
|
var CUE_MS = 1600;
|
|
@@ -83619,8 +83940,8 @@ var FfmpegRequiredNotice = memo48(function FfmpegRequiredNotice2({
|
|
|
83619
83940
|
}) {
|
|
83620
83941
|
const [copied, setCopied] = useState138(false);
|
|
83621
83942
|
const [recheckFailed, setRecheckFailed] = useState138(false);
|
|
83622
|
-
const wasChecking =
|
|
83623
|
-
const cueTimer =
|
|
83943
|
+
const wasChecking = useRef164(false);
|
|
83944
|
+
const cueTimer = useRef164(void 0);
|
|
83624
83945
|
useEffect127(() => {
|
|
83625
83946
|
if (wasChecking.current && !checking) setRecheckFailed(true);
|
|
83626
83947
|
wasChecking.current = checking;
|
|
@@ -83750,8 +84071,8 @@ var FORMAT_PANEL_SIZE = { width: 208, height: 150 };
|
|
|
83750
84071
|
function FormatInfoTooltip({ format }) {
|
|
83751
84072
|
const [open, setOpen] = useState139(false);
|
|
83752
84073
|
const [position, setPosition] = useState139(null);
|
|
83753
|
-
const triggerRef =
|
|
83754
|
-
const timeoutRef =
|
|
84074
|
+
const triggerRef = useRef165(null);
|
|
84075
|
+
const timeoutRef = useRef165(void 0);
|
|
83755
84076
|
const panelId = useId7();
|
|
83756
84077
|
const show = () => {
|
|
83757
84078
|
clearTimeout(timeoutRef.current);
|
|
@@ -84002,7 +84323,7 @@ var RenderQueue = memo49(function RenderQueue2({
|
|
|
84002
84323
|
ffmpegChecking,
|
|
84003
84324
|
onRecheckFfmpeg
|
|
84004
84325
|
}) {
|
|
84005
|
-
const listRef =
|
|
84326
|
+
const listRef = useRef165(null);
|
|
84006
84327
|
useEffect128(() => {
|
|
84007
84328
|
if (listRef.current) {
|
|
84008
84329
|
listRef.current.scrollTo({ top: listRef.current.scrollHeight, behavior: "smooth" });
|
|
@@ -84151,11 +84472,11 @@ var RenderQueuePanel = memo50(function RenderQueuePanel2() {
|
|
|
84151
84472
|
});
|
|
84152
84473
|
|
|
84153
84474
|
// src/components/panels/SlideshowPanel.tsx
|
|
84154
|
-
import { useState as useState141, useEffect as useEffect129, useCallback as
|
|
84475
|
+
import { useState as useState141, useEffect as useEffect129, useCallback as useCallback158, useRef as useRef166 } from "react";
|
|
84155
84476
|
import { parseSlideshowManifest } from "@hyperframes/core/slideshow";
|
|
84156
84477
|
|
|
84157
84478
|
// src/components/panels/SlideshowSubPanels.tsx
|
|
84158
|
-
import { useState as useState140, useCallback as
|
|
84479
|
+
import { useState as useState140, useCallback as useCallback157, useId as useId8 } from "react";
|
|
84159
84480
|
import { jsx as jsx197, jsxs as jsxs165 } from "react/jsx-runtime";
|
|
84160
84481
|
function SectionHeader({
|
|
84161
84482
|
children,
|
|
@@ -84343,7 +84664,7 @@ function BranchTree({
|
|
|
84343
84664
|
}) {
|
|
84344
84665
|
const [newLabel, setNewLabel] = useState140("");
|
|
84345
84666
|
const inputId = useId8();
|
|
84346
|
-
const handleCreate =
|
|
84667
|
+
const handleCreate = useCallback157(() => {
|
|
84347
84668
|
const label = newLabel.trim();
|
|
84348
84669
|
if (!label) return;
|
|
84349
84670
|
onCreateSequence(label);
|
|
@@ -84405,7 +84726,7 @@ function BranchItem({
|
|
|
84405
84726
|
const [editing, setEditing] = useState140(false);
|
|
84406
84727
|
const [draft, setDraft] = useState140(seq.label);
|
|
84407
84728
|
const [confirmingDelete, setConfirmingDelete] = useState140(false);
|
|
84408
|
-
const commitRename =
|
|
84729
|
+
const commitRename = useCallback157(() => {
|
|
84409
84730
|
const label = draft.trim();
|
|
84410
84731
|
if (label && label !== seq.label) onRename(seq.id, label);
|
|
84411
84732
|
setEditing(false);
|
|
@@ -84538,7 +84859,7 @@ function HotspotTool({
|
|
|
84538
84859
|
const selectedElementId = domEditSelection?.element?.id ?? null;
|
|
84539
84860
|
const selectedHfId = domEditSelection?.hfId ?? null;
|
|
84540
84861
|
const elementKey2 = selectedElementId || selectedHfId;
|
|
84541
|
-
const handleMakeHotspot =
|
|
84862
|
+
const handleMakeHotspot = useCallback157(() => {
|
|
84542
84863
|
if (!selectedSceneId || !targetSequenceId || !elementKey2) return;
|
|
84543
84864
|
const id = `hotspot-${elementKey2}-${generateId()}`;
|
|
84544
84865
|
const label = hotspotLabel.trim() || elementKey2;
|
|
@@ -84830,12 +85151,12 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84830
85151
|
);
|
|
84831
85152
|
const [persistError, setPersistError] = useState141(false);
|
|
84832
85153
|
const [retrying, setRetrying] = useState141(false);
|
|
84833
|
-
const undoStackRef =
|
|
85154
|
+
const undoStackRef = useRef166([]);
|
|
84834
85155
|
const [undoDepth, setUndoDepth] = useState141(0);
|
|
84835
85156
|
const currentTime = usePlayerStore((s) => s.currentTime);
|
|
84836
85157
|
const { domEditSelection } = useDomEditSelectionContext();
|
|
84837
|
-
const manifestRef =
|
|
84838
|
-
const notesCtrlRef =
|
|
85158
|
+
const manifestRef = useRef166(manifest);
|
|
85159
|
+
const notesCtrlRef = useRef166(makeSlideshowNotesController());
|
|
84839
85160
|
useEffect129(() => {
|
|
84840
85161
|
if (!compHtml) {
|
|
84841
85162
|
notesCtrlRef.current.flush();
|
|
@@ -84852,7 +85173,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84852
85173
|
setUndoDepth(0);
|
|
84853
85174
|
setPersistError(false);
|
|
84854
85175
|
}, [compHtml]);
|
|
84855
|
-
const applyManifest =
|
|
85176
|
+
const applyManifest = useCallback158(
|
|
84856
85177
|
async (next, opts) => {
|
|
84857
85178
|
const merged = notesCtrlRef.current.mergeIntoDiscrete(next);
|
|
84858
85179
|
if (!opts?.skipUndo) {
|
|
@@ -84872,14 +85193,14 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84872
85193
|
},
|
|
84873
85194
|
[onPersist]
|
|
84874
85195
|
);
|
|
84875
|
-
const handleUndo =
|
|
85196
|
+
const handleUndo = useCallback158(() => {
|
|
84876
85197
|
const prev = undoStackRef.current.pop();
|
|
84877
85198
|
if (!prev) return;
|
|
84878
85199
|
setUndoDepth(undoStackRef.current.length);
|
|
84879
85200
|
applyManifest(prev, { skipUndo: true }).catch(() => {
|
|
84880
85201
|
});
|
|
84881
85202
|
}, [applyManifest]);
|
|
84882
|
-
const handleRetryPersist =
|
|
85203
|
+
const handleRetryPersist = useCallback158(async () => {
|
|
84883
85204
|
setRetrying(true);
|
|
84884
85205
|
try {
|
|
84885
85206
|
await onPersist(manifestRef.current);
|
|
@@ -84890,7 +85211,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84890
85211
|
setRetrying(false);
|
|
84891
85212
|
}
|
|
84892
85213
|
}, [onPersist]);
|
|
84893
|
-
const applyNotesManifest =
|
|
85214
|
+
const applyNotesManifest = useCallback158(
|
|
84894
85215
|
(next) => {
|
|
84895
85216
|
setManifest(next);
|
|
84896
85217
|
manifestRef.current = next;
|
|
@@ -84904,7 +85225,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84904
85225
|
ctrl.flush();
|
|
84905
85226
|
};
|
|
84906
85227
|
}, []);
|
|
84907
|
-
const toggleSection =
|
|
85228
|
+
const toggleSection = useCallback158((key2) => {
|
|
84908
85229
|
setExpandedSections((prev) => {
|
|
84909
85230
|
const next = new Set(prev);
|
|
84910
85231
|
if (next.has(key2)) {
|
|
@@ -84918,25 +85239,25 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84918
85239
|
const activeSlides = selectedSequenceId ? (manifest.slideSequences ?? []).find((s) => s.id === selectedSequenceId)?.slides ?? [] : manifest.slides;
|
|
84919
85240
|
const selectedSlide = activeSlides.find((s) => s.sceneId === selectedSceneId);
|
|
84920
85241
|
const sequences = manifest.slideSequences ?? [];
|
|
84921
|
-
const handleSelectBranchSlide =
|
|
85242
|
+
const handleSelectBranchSlide = useCallback158((sequenceId, sceneId) => {
|
|
84922
85243
|
setSelectedSceneId(sceneId);
|
|
84923
85244
|
setSelectedSequenceId(sequenceId);
|
|
84924
85245
|
}, []);
|
|
84925
|
-
const handleToggleSlide =
|
|
85246
|
+
const handleToggleSlide = useCallback158(
|
|
84926
85247
|
(sceneId) => {
|
|
84927
85248
|
applyManifest(toggleMainLineSlide(manifestRef.current, sceneId)).catch(() => {
|
|
84928
85249
|
});
|
|
84929
85250
|
},
|
|
84930
85251
|
[applyManifest]
|
|
84931
85252
|
);
|
|
84932
|
-
const handleReorder =
|
|
85253
|
+
const handleReorder = useCallback158(
|
|
84933
85254
|
(sceneId, dir) => {
|
|
84934
85255
|
applyManifest(reorderMainLineSlide(manifestRef.current, sceneId, dir)).catch(() => {
|
|
84935
85256
|
});
|
|
84936
85257
|
},
|
|
84937
85258
|
[applyManifest]
|
|
84938
85259
|
);
|
|
84939
|
-
const handleSetNotes =
|
|
85260
|
+
const handleSetNotes = useCallback158(
|
|
84940
85261
|
(notes) => {
|
|
84941
85262
|
if (!selectedSceneId) return;
|
|
84942
85263
|
applyNotesManifest(
|
|
@@ -84945,7 +85266,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84945
85266
|
},
|
|
84946
85267
|
[selectedSceneId, selectedSequenceId, applyNotesManifest]
|
|
84947
85268
|
);
|
|
84948
|
-
const handleMarkFragment =
|
|
85269
|
+
const handleMarkFragment = useCallback158(() => {
|
|
84949
85270
|
if (!selectedSceneId) return;
|
|
84950
85271
|
applyManifest(
|
|
84951
85272
|
addFragment(
|
|
@@ -84957,7 +85278,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84957
85278
|
).catch(() => {
|
|
84958
85279
|
});
|
|
84959
85280
|
}, [selectedSceneId, selectedSequenceId, currentTime, applyManifest]);
|
|
84960
|
-
const handleRemoveFragment =
|
|
85281
|
+
const handleRemoveFragment = useCallback158(
|
|
84961
85282
|
(time) => {
|
|
84962
85283
|
if (!selectedSceneId) return;
|
|
84963
85284
|
applyManifest(
|
|
@@ -84967,7 +85288,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84967
85288
|
},
|
|
84968
85289
|
[selectedSceneId, selectedSequenceId, applyManifest]
|
|
84969
85290
|
);
|
|
84970
|
-
const handleCreateSequence =
|
|
85291
|
+
const handleCreateSequence = useCallback158(
|
|
84971
85292
|
(label) => {
|
|
84972
85293
|
const id = `seq-${generateId()}`;
|
|
84973
85294
|
applyManifest(createSequence(manifestRef.current, id, label)).catch(() => {
|
|
@@ -84975,21 +85296,21 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84975
85296
|
},
|
|
84976
85297
|
[applyManifest]
|
|
84977
85298
|
);
|
|
84978
|
-
const handleRenameSequence =
|
|
85299
|
+
const handleRenameSequence = useCallback158(
|
|
84979
85300
|
(id, label) => {
|
|
84980
85301
|
applyManifest(renameSequence(manifestRef.current, id, label)).catch(() => {
|
|
84981
85302
|
});
|
|
84982
85303
|
},
|
|
84983
85304
|
[applyManifest]
|
|
84984
85305
|
);
|
|
84985
|
-
const handleDeleteSequence =
|
|
85306
|
+
const handleDeleteSequence = useCallback158(
|
|
84986
85307
|
(id) => {
|
|
84987
85308
|
applyManifest(deleteSequence(manifestRef.current, id)).catch(() => {
|
|
84988
85309
|
});
|
|
84989
85310
|
},
|
|
84990
85311
|
[applyManifest]
|
|
84991
85312
|
);
|
|
84992
|
-
const handleAssign =
|
|
85313
|
+
const handleAssign = useCallback158(
|
|
84993
85314
|
(sequenceId, sceneId, assign) => {
|
|
84994
85315
|
applyManifest(assignToBranch(manifestRef.current, sequenceId, sceneId, assign)).catch(
|
|
84995
85316
|
() => {
|
|
@@ -84998,7 +85319,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84998
85319
|
},
|
|
84999
85320
|
[applyManifest]
|
|
85000
85321
|
);
|
|
85001
|
-
const handleAddHotspot =
|
|
85322
|
+
const handleAddHotspot = useCallback158(
|
|
85002
85323
|
(sceneId, hotspot) => {
|
|
85003
85324
|
applyManifest(
|
|
85004
85325
|
addHotspot(manifestRef.current, sceneId, hotspot, selectedSequenceId ?? void 0)
|
|
@@ -85007,7 +85328,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85007
85328
|
},
|
|
85008
85329
|
[selectedSequenceId, applyManifest]
|
|
85009
85330
|
);
|
|
85010
|
-
const handleRemoveHotspot =
|
|
85331
|
+
const handleRemoveHotspot = useCallback158(
|
|
85011
85332
|
(sceneId, hotspotId) => {
|
|
85012
85333
|
applyManifest(
|
|
85013
85334
|
removeHotspot(manifestRef.current, sceneId, hotspotId, selectedSequenceId ?? void 0)
|
|
@@ -85160,10 +85481,10 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85160
85481
|
}
|
|
85161
85482
|
|
|
85162
85483
|
// src/components/panels/VariablesPanel.tsx
|
|
85163
|
-
import { memo as memo51, useCallback as
|
|
85484
|
+
import { memo as memo51, useCallback as useCallback162, useEffect as useEffect131, useMemo as useMemo73, useState as useState145 } from "react";
|
|
85164
85485
|
|
|
85165
85486
|
// src/hooks/useVariablesPersist.ts
|
|
85166
|
-
import { useCallback as
|
|
85487
|
+
import { useCallback as useCallback159 } from "react";
|
|
85167
85488
|
function useVariablesPersist({
|
|
85168
85489
|
sdkSession,
|
|
85169
85490
|
activeCompPath,
|
|
@@ -85173,7 +85494,7 @@ function useVariablesPersist({
|
|
|
85173
85494
|
reloadPreview,
|
|
85174
85495
|
publishSdkSession
|
|
85175
85496
|
}) {
|
|
85176
|
-
return
|
|
85497
|
+
return useCallback159(
|
|
85177
85498
|
async (label, mutate) => {
|
|
85178
85499
|
if (!sdkSession) return false;
|
|
85179
85500
|
const path = activeCompPath ?? "index.html";
|
|
@@ -85208,10 +85529,10 @@ function useVariablesPersist({
|
|
|
85208
85529
|
}
|
|
85209
85530
|
|
|
85210
85531
|
// src/components/panels/VariablesOtherCompositions.tsx
|
|
85211
|
-
import { useCallback as
|
|
85532
|
+
import { useCallback as useCallback161, useState as useState144 } from "react";
|
|
85212
85533
|
|
|
85213
85534
|
// src/hooks/useProjectCompositionVariables.ts
|
|
85214
|
-
import { useCallback as
|
|
85535
|
+
import { useCallback as useCallback160, useEffect as useEffect130, useState as useState142 } from "react";
|
|
85215
85536
|
import { openComposition as openComposition4 } from "@hyperframes/sdk";
|
|
85216
85537
|
async function readGroup(path, readProjectFile) {
|
|
85217
85538
|
let content;
|
|
@@ -85254,7 +85575,7 @@ function useProjectCompositionVariables(fileTree, excludePath, readProjectFile,
|
|
|
85254
85575
|
}
|
|
85255
85576
|
function useEditVariablesInFile(deps) {
|
|
85256
85577
|
const { readProjectFile, writeProjectFile, recordEdit, reloadPreview } = deps;
|
|
85257
|
-
return
|
|
85578
|
+
return useCallback160(
|
|
85258
85579
|
async (path, label, mutate) => {
|
|
85259
85580
|
const originalContent = await readProjectFile(path);
|
|
85260
85581
|
await persistSdkSerialize(
|
|
@@ -85631,7 +85952,7 @@ function VariablesOtherCompositions({
|
|
|
85631
85952
|
reloadPreview
|
|
85632
85953
|
});
|
|
85633
85954
|
const [editingKey, setEditingKey] = useState144(null);
|
|
85634
|
-
const onSave =
|
|
85955
|
+
const onSave = useCallback161(
|
|
85635
85956
|
(path, decl) => {
|
|
85636
85957
|
setEditingKey(null);
|
|
85637
85958
|
void editInFile(
|
|
@@ -85642,7 +85963,7 @@ function VariablesOtherCompositions({
|
|
|
85642
85963
|
},
|
|
85643
85964
|
[editInFile]
|
|
85644
85965
|
);
|
|
85645
|
-
const onRemove =
|
|
85966
|
+
const onRemove = useCallback161(
|
|
85646
85967
|
(path, id) => {
|
|
85647
85968
|
void editInFile(
|
|
85648
85969
|
path,
|
|
@@ -85835,9 +86156,9 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85835
86156
|
}) {
|
|
85836
86157
|
const { activeCompPath, showToast } = useStudioShellContext();
|
|
85837
86158
|
const { refreshKey } = useStudioPlaybackContext();
|
|
85838
|
-
const { readProjectFile, writeProjectFile, fileTree } = useFileManagerContext();
|
|
86159
|
+
const { readProjectFile, writeProjectFile, fileTree, compositions } = useFileManagerContext();
|
|
85839
86160
|
const { domEditSelection } = useDomEditContext();
|
|
85840
|
-
const effectiveCompPath = activeCompPath ?? resolveMasterCompositionPath(
|
|
86161
|
+
const effectiveCompPath = activeCompPath ?? resolveMasterCompositionPath(compositions);
|
|
85841
86162
|
const previewValues = usePreviewVariablesStore((s) => s.values);
|
|
85842
86163
|
const setPreviewValues = usePreviewVariablesStore((s) => s.setValues);
|
|
85843
86164
|
const [revision, setRevision] = useState145(0);
|
|
@@ -85856,27 +86177,27 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85856
86177
|
reloadPreview,
|
|
85857
86178
|
publishSdkSession
|
|
85858
86179
|
});
|
|
85859
|
-
const declarations =
|
|
86180
|
+
const declarations = useMemo73(
|
|
85860
86181
|
() => sdkSession?.getVariableDeclarations() ?? [],
|
|
85861
86182
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85862
86183
|
[sdkSession, refreshKey, revision]
|
|
85863
86184
|
);
|
|
85864
|
-
const usage =
|
|
86185
|
+
const usage = useMemo73(
|
|
85865
86186
|
() => sdkSession?.getVariableUsage() ?? null,
|
|
85866
86187
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85867
86188
|
[sdkSession, refreshKey, revision]
|
|
85868
86189
|
);
|
|
85869
|
-
const issues =
|
|
86190
|
+
const issues = useMemo73(
|
|
85870
86191
|
() => previewValues && sdkSession ? sdkSession.validateVariableValues(previewValues) : [],
|
|
85871
86192
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85872
86193
|
[sdkSession, previewValues, refreshKey, revision]
|
|
85873
86194
|
);
|
|
85874
|
-
const effectiveValues =
|
|
86195
|
+
const effectiveValues = useMemo73(
|
|
85875
86196
|
() => sdkSession?.getVariableValues(previewValues ?? void 0) ?? {},
|
|
85876
86197
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85877
86198
|
[sdkSession, previewValues, refreshKey, revision]
|
|
85878
86199
|
);
|
|
85879
|
-
const copyToClipboard =
|
|
86200
|
+
const copyToClipboard = useCallback162(
|
|
85880
86201
|
(text, what) => {
|
|
85881
86202
|
void copyTextToClipboard(text).then(
|
|
85882
86203
|
(ok) => showToast(
|
|
@@ -85887,7 +86208,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85887
86208
|
},
|
|
85888
86209
|
[showToast]
|
|
85889
86210
|
);
|
|
85890
|
-
const dropPreviewOverride =
|
|
86211
|
+
const dropPreviewOverride = useCallback162(
|
|
85891
86212
|
(id) => {
|
|
85892
86213
|
if (previewValues && id in previewValues) {
|
|
85893
86214
|
const next = { ...previewValues };
|
|
@@ -85897,7 +86218,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85897
86218
|
},
|
|
85898
86219
|
[previewValues, setPreviewValues]
|
|
85899
86220
|
);
|
|
85900
|
-
const commitPreviewValue =
|
|
86221
|
+
const commitPreviewValue = useCallback162(
|
|
85901
86222
|
(id, value, declDefault) => {
|
|
85902
86223
|
const next = { ...previewValues ?? {} };
|
|
85903
86224
|
if (JSON.stringify(value) === JSON.stringify(declDefault)) {
|
|
@@ -85910,7 +86231,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85910
86231
|
},
|
|
85911
86232
|
[previewValues, setPreviewValues, reloadPreview]
|
|
85912
86233
|
);
|
|
85913
|
-
const runSchemaEdit =
|
|
86234
|
+
const runSchemaEdit = useCallback162(
|
|
85914
86235
|
async (label, mutate) => {
|
|
85915
86236
|
try {
|
|
85916
86237
|
const changed = await persistVariables(label, mutate);
|
|
@@ -85924,7 +86245,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85924
86245
|
},
|
|
85925
86246
|
[persistVariables, showToast]
|
|
85926
86247
|
);
|
|
85927
|
-
const handleAdd =
|
|
86248
|
+
const handleAdd = useCallback162(
|
|
85928
86249
|
(decl) => {
|
|
85929
86250
|
if (!sdkSession) return;
|
|
85930
86251
|
const check = sdkSession.can({ type: "declareVariable", declaration: decl });
|
|
@@ -85937,7 +86258,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85937
86258
|
},
|
|
85938
86259
|
[sdkSession, runSchemaEdit, showToast]
|
|
85939
86260
|
);
|
|
85940
|
-
const handleUpdate =
|
|
86261
|
+
const handleUpdate = useCallback162(
|
|
85941
86262
|
(decl) => {
|
|
85942
86263
|
if (!sdkSession) return;
|
|
85943
86264
|
const check = sdkSession.can({
|
|
@@ -85957,7 +86278,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85957
86278
|
},
|
|
85958
86279
|
[sdkSession, runSchemaEdit, showToast]
|
|
85959
86280
|
);
|
|
85960
|
-
const handleRemove =
|
|
86281
|
+
const handleRemove = useCallback162(
|
|
85961
86282
|
(id) => {
|
|
85962
86283
|
if (!sdkSession) return;
|
|
85963
86284
|
const check = sdkSession.can({ type: "removeVariableDeclaration", id });
|
|
@@ -85973,18 +86294,18 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85973
86294
|
},
|
|
85974
86295
|
[sdkSession, runSchemaEdit, dropPreviewOverride, showToast]
|
|
85975
86296
|
);
|
|
85976
|
-
const handleSetDefault =
|
|
86297
|
+
const handleSetDefault = useCallback162(
|
|
85977
86298
|
(id, value) => {
|
|
85978
86299
|
void runSchemaEdit(`Set default for "${id}"`, (s) => s.setVariableValue(id, value));
|
|
85979
86300
|
dropPreviewOverride(id);
|
|
85980
86301
|
},
|
|
85981
86302
|
[runSchemaEdit, dropPreviewOverride]
|
|
85982
86303
|
);
|
|
85983
|
-
const resetPreview =
|
|
86304
|
+
const resetPreview = useCallback162(() => {
|
|
85984
86305
|
setPreviewValues(null);
|
|
85985
86306
|
reloadPreview();
|
|
85986
86307
|
}, [setPreviewValues, reloadPreview]);
|
|
85987
|
-
const handleBind =
|
|
86308
|
+
const handleBind = useCallback162(
|
|
85988
86309
|
// Guard chain (session, selection, type-compat) — one branch per guard.
|
|
85989
86310
|
// fallow-ignore-next-line complexity
|
|
85990
86311
|
(action, id) => {
|
|
@@ -86116,7 +86437,7 @@ function PanelTabButton({
|
|
|
86116
86437
|
}
|
|
86117
86438
|
|
|
86118
86439
|
// src/hooks/useSlideshowPersist.ts
|
|
86119
|
-
import { useCallback as
|
|
86440
|
+
import { useCallback as useCallback163 } from "react";
|
|
86120
86441
|
|
|
86121
86442
|
// src/utils/setSlideshowManifest.ts
|
|
86122
86443
|
import {
|
|
@@ -86173,7 +86494,7 @@ function useSlideshowPersist({
|
|
|
86173
86494
|
publishSdkSession,
|
|
86174
86495
|
coalesceKey
|
|
86175
86496
|
}) {
|
|
86176
|
-
return
|
|
86497
|
+
return useCallback163(
|
|
86177
86498
|
async (manifest) => {
|
|
86178
86499
|
if (!sdkSession) return;
|
|
86179
86500
|
const path = activeCompPath ?? "index.html";
|
|
@@ -86206,15 +86527,15 @@ function useSlideshowPersist({
|
|
|
86206
86527
|
}
|
|
86207
86528
|
|
|
86208
86529
|
// src/hooks/useSlideshowTabState.ts
|
|
86209
|
-
import { useEffect as useEffect132, useMemo as
|
|
86530
|
+
import { useEffect as useEffect132, useMemo as useMemo74 } from "react";
|
|
86210
86531
|
import { SLIDESHOW_ISLAND_TYPE as SLIDESHOW_ISLAND_TYPE2, slideshowIslandRegex as slideshowIslandRegex2 } from "@hyperframes/core/slideshow";
|
|
86211
86532
|
function useSlideshowTabState(params) {
|
|
86212
86533
|
const { editingFileContent, previewIframeRef, refreshKey, rightPanelTab, setRightPanelTab } = params;
|
|
86213
|
-
const isSlideshowComposition =
|
|
86534
|
+
const isSlideshowComposition = useMemo74(() => {
|
|
86214
86535
|
if (!editingFileContent || !editingFileContent.includes(SLIDESHOW_ISLAND_TYPE2)) return false;
|
|
86215
86536
|
return slideshowIslandRegex2("i").test(editingFileContent);
|
|
86216
86537
|
}, [editingFileContent]);
|
|
86217
|
-
const slideshowScenes =
|
|
86538
|
+
const slideshowScenes = useMemo74(() => {
|
|
86218
86539
|
try {
|
|
86219
86540
|
const win = previewIframeRef.current?.contentWindow;
|
|
86220
86541
|
return (win?.__clipManifest?.scenes ?? []).map((s) => ({
|
|
@@ -86236,7 +86557,7 @@ function useSlideshowTabState(params) {
|
|
|
86236
86557
|
}
|
|
86237
86558
|
|
|
86238
86559
|
// src/components/DesignPanelPromoteProvider.tsx
|
|
86239
|
-
import { useCallback as
|
|
86560
|
+
import { useCallback as useCallback164 } from "react";
|
|
86240
86561
|
import { jsx as jsx204 } from "react/jsx-runtime";
|
|
86241
86562
|
function DesignPanelPromoteProvider({
|
|
86242
86563
|
selection,
|
|
@@ -86255,7 +86576,7 @@ function DesignPanelPromoteProvider({
|
|
|
86255
86576
|
publishSdkSession: handle.publish,
|
|
86256
86577
|
activeCompPath: targetPath
|
|
86257
86578
|
});
|
|
86258
|
-
const persist2 =
|
|
86579
|
+
const persist2 = useCallback164(
|
|
86259
86580
|
async (label, mutate) => {
|
|
86260
86581
|
const committed = await rawPersist(label, mutate);
|
|
86261
86582
|
if (committed) forceReloadSharedSdkSession?.();
|
|
@@ -86263,7 +86584,7 @@ function DesignPanelPromoteProvider({
|
|
|
86263
86584
|
},
|
|
86264
86585
|
[rawPersist, forceReloadSharedSdkSession]
|
|
86265
86586
|
);
|
|
86266
|
-
const handlePersistError =
|
|
86587
|
+
const handlePersistError = useCallback164(
|
|
86267
86588
|
(error) => showToast(getStudioSaveErrorMessage(error), "error"),
|
|
86268
86589
|
[showToast]
|
|
86269
86590
|
);
|
|
@@ -86496,14 +86817,14 @@ async function applyColorGradingScopeUpdate({
|
|
|
86496
86817
|
}
|
|
86497
86818
|
|
|
86498
86819
|
// src/hooks/useInspectorSplitResize.ts
|
|
86499
|
-
import { useCallback as
|
|
86820
|
+
import { useCallback as useCallback165, useRef as useRef167, useState as useState146 } from "react";
|
|
86500
86821
|
var MIN_INSPECTOR_SPLIT_PERCENT = 20;
|
|
86501
86822
|
var MAX_INSPECTOR_SPLIT_PERCENT = 75;
|
|
86502
86823
|
function useInspectorSplitResize() {
|
|
86503
86824
|
const [layersPanePercent, setLayersPanePercent] = useState146(40);
|
|
86504
|
-
const splitContainerRef =
|
|
86505
|
-
const splitDragRef =
|
|
86506
|
-
const handleInspectorSplitResizeStart =
|
|
86825
|
+
const splitContainerRef = useRef167(null);
|
|
86826
|
+
const splitDragRef = useRef167(null);
|
|
86827
|
+
const handleInspectorSplitResizeStart = useCallback165(
|
|
86507
86828
|
(event) => {
|
|
86508
86829
|
event.preventDefault();
|
|
86509
86830
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
@@ -86516,7 +86837,7 @@ function useInspectorSplitResize() {
|
|
|
86516
86837
|
},
|
|
86517
86838
|
[layersPanePercent]
|
|
86518
86839
|
);
|
|
86519
|
-
const handleInspectorSplitResizeMove =
|
|
86840
|
+
const handleInspectorSplitResizeMove = useCallback165((event) => {
|
|
86520
86841
|
const drag = splitDragRef.current;
|
|
86521
86842
|
if (!drag || drag.height <= 0) return;
|
|
86522
86843
|
const deltaPercent = (event.clientY - drag.startY) / drag.height * 100;
|
|
@@ -86526,7 +86847,7 @@ function useInspectorSplitResize() {
|
|
|
86526
86847
|
);
|
|
86527
86848
|
setLayersPanePercent(next);
|
|
86528
86849
|
}, []);
|
|
86529
|
-
const handleInspectorSplitResizeEnd =
|
|
86850
|
+
const handleInspectorSplitResizeEnd = useCallback165(() => {
|
|
86530
86851
|
splitDragRef.current = null;
|
|
86531
86852
|
}, []);
|
|
86532
86853
|
return {
|
|
@@ -86539,16 +86860,16 @@ function useInspectorSplitResize() {
|
|
|
86539
86860
|
}
|
|
86540
86861
|
|
|
86541
86862
|
// src/hooks/useRemoveBackground.ts
|
|
86542
|
-
import { useCallback as
|
|
86863
|
+
import { useCallback as useCallback166, useEffect as useEffect133, useRef as useRef168 } from "react";
|
|
86543
86864
|
function useRemoveBackground(projectId, refreshFileTree, showToast) {
|
|
86544
|
-
const abortRef =
|
|
86865
|
+
const abortRef = useRef168(null);
|
|
86545
86866
|
useEffect133(
|
|
86546
86867
|
() => () => {
|
|
86547
86868
|
abortRef.current?.abort();
|
|
86548
86869
|
},
|
|
86549
86870
|
[]
|
|
86550
86871
|
);
|
|
86551
|
-
return
|
|
86872
|
+
return useCallback166(
|
|
86552
86873
|
// fallow-ignore-next-line complexity
|
|
86553
86874
|
async (inputPath, options) => {
|
|
86554
86875
|
const response = await fetch(
|
|
@@ -86730,7 +87051,7 @@ function StudioRightPanel({
|
|
|
86730
87051
|
}
|
|
86731
87052
|
toggleRightInspectorPane(pane);
|
|
86732
87053
|
};
|
|
86733
|
-
const handleApplyColorGradingScope =
|
|
87054
|
+
const handleApplyColorGradingScope = useCallback167(
|
|
86734
87055
|
async (scope, value) => applyColorGradingScopeUpdate({
|
|
86735
87056
|
scope,
|
|
86736
87057
|
value,
|
|
@@ -86764,7 +87085,7 @@ function StudioRightPanel({
|
|
|
86764
87085
|
]
|
|
86765
87086
|
);
|
|
86766
87087
|
const handleRemoveBackground = useRemoveBackground(projectId, refreshFileTree, showToast);
|
|
86767
|
-
const setAttributeWhileDragging =
|
|
87088
|
+
const setAttributeWhileDragging = useCallback167(
|
|
86768
87089
|
(attr, value) => handleDomAttributeLiveCommit(attr, value, void 0, { previewOnly: true }),
|
|
86769
87090
|
[handleDomAttributeLiveCommit]
|
|
86770
87091
|
);
|
|
@@ -87012,11 +87333,17 @@ function StudioRightPanel({
|
|
|
87012
87333
|
}
|
|
87013
87334
|
|
|
87014
87335
|
// src/components/TimelineToolbar.tsx
|
|
87015
|
-
import { useEffect as useEffect135, useRef as
|
|
87016
|
-
import {
|
|
87336
|
+
import { useEffect as useEffect135, useRef as useRef169 } from "react";
|
|
87337
|
+
import {
|
|
87338
|
+
Image as Image2,
|
|
87339
|
+
Magnet,
|
|
87340
|
+
MagnifyingGlassMinus,
|
|
87341
|
+
MagnifyingGlassPlus,
|
|
87342
|
+
Waves
|
|
87343
|
+
} from "@phosphor-icons/react";
|
|
87017
87344
|
|
|
87018
87345
|
// src/hooks/useEnableKeyframes.ts
|
|
87019
|
-
import { useCallback as
|
|
87346
|
+
import { useCallback as useCallback168 } from "react";
|
|
87020
87347
|
var enableKeyframesTransactionCounter = 0;
|
|
87021
87348
|
function animatedProps(anim) {
|
|
87022
87349
|
if (!anim) return ["x", "y"];
|
|
@@ -87269,7 +87596,7 @@ async function applyArcKeyframeAtPlayhead(session, sel, arcAnim, t, iframe) {
|
|
|
87269
87596
|
);
|
|
87270
87597
|
}
|
|
87271
87598
|
function useEnableKeyframes(sessionRef) {
|
|
87272
|
-
return
|
|
87599
|
+
return useCallback168(async () => {
|
|
87273
87600
|
const session = sessionRef.current;
|
|
87274
87601
|
if (!session) return;
|
|
87275
87602
|
const sel = session.domEditSelection;
|
|
@@ -87351,7 +87678,7 @@ function useEnableKeyframes(sessionRef) {
|
|
|
87351
87678
|
}
|
|
87352
87679
|
|
|
87353
87680
|
// src/hooks/useKeyframeKeyboard.ts
|
|
87354
|
-
import { useEffect as useEffect134, useCallback as
|
|
87681
|
+
import { useEffect as useEffect134, useCallback as useCallback169 } from "react";
|
|
87355
87682
|
function isTextInput2(el) {
|
|
87356
87683
|
if (!el) return false;
|
|
87357
87684
|
const tag = el.tagName;
|
|
@@ -87368,7 +87695,7 @@ function useKeyframeKeyboard({
|
|
|
87368
87695
|
onToggleExpand,
|
|
87369
87696
|
onNudgeKeyframe
|
|
87370
87697
|
}) {
|
|
87371
|
-
const handler =
|
|
87698
|
+
const handler = useCallback169(
|
|
87372
87699
|
(e) => {
|
|
87373
87700
|
if (!enabled) return;
|
|
87374
87701
|
if (isTextInput2(document.activeElement)) return;
|
|
@@ -87469,7 +87796,7 @@ function useKeyframeToggle(session) {
|
|
|
87469
87796
|
const currentTime = usePlayerStore((s) => s.currentTime);
|
|
87470
87797
|
const selectedElementId = usePlayerStore((s) => s.selectedElementId);
|
|
87471
87798
|
const elements = usePlayerStore((s) => s.elements);
|
|
87472
|
-
const sessionRef =
|
|
87799
|
+
const sessionRef = useRef169(session);
|
|
87473
87800
|
sessionRef.current = session;
|
|
87474
87801
|
const onToggle = useEnableKeyframes(
|
|
87475
87802
|
sessionRef
|
|
@@ -87487,6 +87814,8 @@ function TimelineToolbar({ domEditSession, onSplitElement }) {
|
|
|
87487
87814
|
const setActiveTool = usePlayerStore((s) => s.setActiveTool);
|
|
87488
87815
|
const timelineSnapEnabled = usePlayerStore((s) => s.timelineSnapEnabled);
|
|
87489
87816
|
const setTimelineSnapEnabled = usePlayerStore((s) => s.setTimelineSnapEnabled);
|
|
87817
|
+
const rippleEditEnabled = usePlayerStore((s) => s.rippleEditEnabled);
|
|
87818
|
+
const setRippleEditEnabled = usePlayerStore((s) => s.setRippleEditEnabled);
|
|
87490
87819
|
const autoKeyframeEnabled = usePlayerStore((s) => s.autoKeyframeEnabled);
|
|
87491
87820
|
const setAutoKeyframeEnabled = usePlayerStore((s) => s.setAutoKeyframeEnabled);
|
|
87492
87821
|
const thumbnailMode = usePlayerStore((s) => s.thumbnailMode);
|
|
@@ -87571,6 +87900,23 @@ function TimelineToolbar({ domEditSession, onSplitElement }) {
|
|
|
87571
87900
|
children: /* @__PURE__ */ jsx206(Magnet, { size: 16, weight: "bold", "aria-hidden": "true" })
|
|
87572
87901
|
}
|
|
87573
87902
|
) }),
|
|
87903
|
+
/* @__PURE__ */ jsx206(
|
|
87904
|
+
Tooltip,
|
|
87905
|
+
{
|
|
87906
|
+
label: rippleEditEnabled ? "Ripple on \u2014 keeps the main track gapless" : "Ripple off \u2014 deleting a main-track clip leaves a gap",
|
|
87907
|
+
children: /* @__PURE__ */ jsx206(
|
|
87908
|
+
"button",
|
|
87909
|
+
{
|
|
87910
|
+
type: "button",
|
|
87911
|
+
onClick: () => setRippleEditEnabled(!rippleEditEnabled),
|
|
87912
|
+
"aria-label": "Toggle ripple edit",
|
|
87913
|
+
"aria-pressed": rippleEditEnabled,
|
|
87914
|
+
className: rippleEditEnabled ? flatActive : flatIdle,
|
|
87915
|
+
children: /* @__PURE__ */ jsx206(Waves, { size: 16, weight: "bold", "aria-hidden": "true" })
|
|
87916
|
+
}
|
|
87917
|
+
)
|
|
87918
|
+
}
|
|
87919
|
+
),
|
|
87574
87920
|
/* @__PURE__ */ jsx206(
|
|
87575
87921
|
Tooltip,
|
|
87576
87922
|
{
|
|
@@ -87792,15 +88138,15 @@ import { useState as useState154 } from "react";
|
|
|
87792
88138
|
import { Copy as Copy2, Check as Check2 } from "@phosphor-icons/react";
|
|
87793
88139
|
|
|
87794
88140
|
// src/hooks/useStoryboard.ts
|
|
87795
|
-
import { useCallback as
|
|
88141
|
+
import { useCallback as useCallback170, useEffect as useEffect136, useRef as useRef170, useState as useState147 } from "react";
|
|
87796
88142
|
function useStoryboard(projectId) {
|
|
87797
88143
|
const [data, setData] = useState147(null);
|
|
87798
88144
|
const [loading, setLoading] = useState147(true);
|
|
87799
88145
|
const [error, setError] = useState147(null);
|
|
87800
88146
|
const [reloadKey, setReloadKey] = useState147(0);
|
|
87801
|
-
const hasDataRef =
|
|
87802
|
-
const lastProjectRef =
|
|
87803
|
-
const reload =
|
|
88147
|
+
const hasDataRef = useRef170(false);
|
|
88148
|
+
const lastProjectRef = useRef170(null);
|
|
88149
|
+
const reload = useCallback170(() => setReloadKey((k) => k + 1), []);
|
|
87804
88150
|
useEffect136(() => {
|
|
87805
88151
|
if (!projectId) return;
|
|
87806
88152
|
let cancelled = false;
|
|
@@ -87833,7 +88179,7 @@ function useStoryboard(projectId) {
|
|
|
87833
88179
|
}
|
|
87834
88180
|
|
|
87835
88181
|
// src/hooks/useProjectSignaturePoll.ts
|
|
87836
|
-
import { useEffect as useEffect137, useRef as
|
|
88182
|
+
import { useEffect as useEffect137, useRef as useRef171 } from "react";
|
|
87837
88183
|
var POLL_INTERVAL_MS = 2e3;
|
|
87838
88184
|
async function fetchProjectSignature(projectId) {
|
|
87839
88185
|
try {
|
|
@@ -87846,8 +88192,8 @@ async function fetchProjectSignature(projectId) {
|
|
|
87846
88192
|
}
|
|
87847
88193
|
}
|
|
87848
88194
|
function useProjectSignaturePoll(projectId, currentSignature, onChange) {
|
|
87849
|
-
const signatureRef =
|
|
87850
|
-
const onChangeRef =
|
|
88195
|
+
const signatureRef = useRef171(currentSignature);
|
|
88196
|
+
const onChangeRef = useRef171(onChange);
|
|
87851
88197
|
signatureRef.current = currentSignature;
|
|
87852
88198
|
onChangeRef.current = onChange;
|
|
87853
88199
|
useEffect137(() => {
|
|
@@ -87877,7 +88223,7 @@ function useProjectSignaturePoll(projectId, currentSignature, onChange) {
|
|
|
87877
88223
|
}
|
|
87878
88224
|
|
|
87879
88225
|
// src/components/storyboard/StoryboardLoaded.tsx
|
|
87880
|
-
import { useEffect as useEffect143, useMemo as
|
|
88226
|
+
import { useEffect as useEffect143, useMemo as useMemo77, useState as useState153 } from "react";
|
|
87881
88227
|
|
|
87882
88228
|
// src/components/storyboard/StoryboardDirection.tsx
|
|
87883
88229
|
import { jsx as jsx207, jsxs as jsxs172 } from "react/jsx-runtime";
|
|
@@ -88114,7 +88460,7 @@ function StoryboardScriptPanel({ script }) {
|
|
|
88114
88460
|
}
|
|
88115
88461
|
|
|
88116
88462
|
// src/components/storyboard/StoryboardSourceEditor.tsx
|
|
88117
|
-
import { useCallback as
|
|
88463
|
+
import { useCallback as useCallback171, useEffect as useEffect139, useMemo as useMemo75, useRef as useRef172, useState as useState149 } from "react";
|
|
88118
88464
|
import { marked } from "marked";
|
|
88119
88465
|
import DOMPurify from "dompurify";
|
|
88120
88466
|
import { jsx as jsx212, jsxs as jsxs175 } from "react/jsx-runtime";
|
|
@@ -88144,7 +88490,7 @@ function useEditableFile(path, onSaved) {
|
|
|
88144
88490
|
cancelled = true;
|
|
88145
88491
|
};
|
|
88146
88492
|
}, [path, readProjectFile]);
|
|
88147
|
-
const save =
|
|
88493
|
+
const save = useCallback171(() => {
|
|
88148
88494
|
if (saving) return;
|
|
88149
88495
|
setSaving(true);
|
|
88150
88496
|
setError(null);
|
|
@@ -88163,7 +88509,7 @@ function hardenLinks(node) {
|
|
|
88163
88509
|
}
|
|
88164
88510
|
function useMarkdownPreview(source) {
|
|
88165
88511
|
const [debounced, setDebounced] = useState149(source);
|
|
88166
|
-
const primed =
|
|
88512
|
+
const primed = useRef172(false);
|
|
88167
88513
|
useEffect139(() => {
|
|
88168
88514
|
if (!primed.current && source !== "") {
|
|
88169
88515
|
primed.current = true;
|
|
@@ -88173,7 +88519,7 @@ function useMarkdownPreview(source) {
|
|
|
88173
88519
|
const id = window.setTimeout(() => setDebounced(source), 200);
|
|
88174
88520
|
return () => window.clearTimeout(id);
|
|
88175
88521
|
}, [source]);
|
|
88176
|
-
return
|
|
88522
|
+
return useMemo75(() => {
|
|
88177
88523
|
const html2 = marked.parse(debounced, { async: false });
|
|
88178
88524
|
DOMPurify.addHook("afterSanitizeAttributes", hardenLinks);
|
|
88179
88525
|
try {
|
|
@@ -88269,7 +88615,7 @@ function StoryboardSourceEditor({
|
|
|
88269
88615
|
}
|
|
88270
88616
|
|
|
88271
88617
|
// src/components/storyboard/StoryboardFrameFocus.tsx
|
|
88272
|
-
import { useCallback as
|
|
88618
|
+
import { useCallback as useCallback172, useEffect as useEffect141, useState as useState151 } from "react";
|
|
88273
88619
|
import { setFrameVoiceover } from "@hyperframes/core/storyboard";
|
|
88274
88620
|
|
|
88275
88621
|
// src/components/storyboard/AgentChatMessageButton.tsx
|
|
@@ -88329,7 +88675,7 @@ function StoryboardFrameFocus({
|
|
|
88329
88675
|
const [savedVoiceover, setSavedVoiceover] = useState151(frame.voiceover ?? "");
|
|
88330
88676
|
const [busy, setBusy] = useState151(false);
|
|
88331
88677
|
const [error, setError] = useState151(null);
|
|
88332
|
-
const applyEdit =
|
|
88678
|
+
const applyEdit = useCallback172(
|
|
88333
88679
|
async (edit) => {
|
|
88334
88680
|
if (busy) return false;
|
|
88335
88681
|
setBusy(true);
|
|
@@ -88351,7 +88697,7 @@ function StoryboardFrameFocus({
|
|
|
88351
88697
|
const title = frame.title ?? `Frame ${frame.index}`;
|
|
88352
88698
|
const dirty = draft !== savedVoiceover;
|
|
88353
88699
|
const canOpenPreview = frame.status !== "outline" && frame.srcExists && Boolean(frame.src);
|
|
88354
|
-
const saveVoiceover =
|
|
88700
|
+
const saveVoiceover = useCallback172(async () => {
|
|
88355
88701
|
const saved2 = await applyEdit((src) => setFrameVoiceover(src, frame.index, draft));
|
|
88356
88702
|
if (saved2) setSavedVoiceover(draft);
|
|
88357
88703
|
}, [applyEdit, frame.index, draft]);
|
|
@@ -88363,7 +88709,7 @@ function StoryboardFrameFocus({
|
|
|
88363
88709
|
window.addEventListener("beforeunload", onBeforeUnload);
|
|
88364
88710
|
return () => window.removeEventListener("beforeunload", onBeforeUnload);
|
|
88365
88711
|
}, [dirty]);
|
|
88366
|
-
const confirmLeave =
|
|
88712
|
+
const confirmLeave = useCallback172(
|
|
88367
88713
|
() => !dirty || window.confirm("Discard unsaved voiceover changes?"),
|
|
88368
88714
|
[dirty]
|
|
88369
88715
|
);
|
|
@@ -88845,7 +89191,7 @@ function progressLabel(summary) {
|
|
|
88845
89191
|
}
|
|
88846
89192
|
|
|
88847
89193
|
// src/components/storyboard/useFrameComments.ts
|
|
88848
|
-
import { useCallback as
|
|
89194
|
+
import { useCallback as useCallback173, useEffect as useEffect142, useMemo as useMemo76, useState as useState152 } from "react";
|
|
88849
89195
|
|
|
88850
89196
|
// src/components/storyboard/frameComments.ts
|
|
88851
89197
|
var FRAME_COMMENTS_PATH = ".hyperframes/frame-comments.json";
|
|
@@ -88911,7 +89257,7 @@ function useFrameComments(frames) {
|
|
|
88911
89257
|
const [submitState, setSubmitState] = useState152("idle");
|
|
88912
89258
|
const [submitError, setSubmitError] = useState152(null);
|
|
88913
89259
|
const [pending2, setPending] = useState152(null);
|
|
88914
|
-
const refreshPending =
|
|
89260
|
+
const refreshPending = useCallback173(async () => {
|
|
88915
89261
|
try {
|
|
88916
89262
|
const parsed = parseCommentsFile(await readOptionalProjectFile(FRAME_COMMENTS_PATH));
|
|
88917
89263
|
setPending(parsed && parsed.comments.length > 0 ? parsed.comments : null);
|
|
@@ -88924,14 +89270,14 @@ function useFrameComments(frames) {
|
|
|
88924
89270
|
window.addEventListener("focus", onFocus);
|
|
88925
89271
|
return () => window.removeEventListener("focus", onFocus);
|
|
88926
89272
|
}, [refreshPending]);
|
|
88927
|
-
const setDraft =
|
|
89273
|
+
const setDraft = useCallback173((index, text) => {
|
|
88928
89274
|
setDrafts((prev) => ({ ...prev, [index]: text }));
|
|
88929
89275
|
}, []);
|
|
88930
|
-
const draftCount =
|
|
89276
|
+
const draftCount = useMemo76(
|
|
88931
89277
|
() => Object.values(drafts).filter((text) => text.trim().length > 0).length,
|
|
88932
89278
|
[drafts]
|
|
88933
89279
|
);
|
|
88934
|
-
const submit =
|
|
89280
|
+
const submit = useCallback173(async () => {
|
|
88935
89281
|
if (draftCount === 0 || submitState === "saving") return false;
|
|
88936
89282
|
setSubmitState("saving");
|
|
88937
89283
|
setSubmitError(null);
|
|
@@ -88995,7 +89341,7 @@ function StoryboardLoaded({
|
|
|
88995
89341
|
setFeedbackMessageCopied(false);
|
|
88996
89342
|
}
|
|
88997
89343
|
};
|
|
88998
|
-
const sourceFiles =
|
|
89344
|
+
const sourceFiles = useMemo77(() => {
|
|
88999
89345
|
const files = [{ path: data.path, label: data.path }];
|
|
89000
89346
|
if (data.script?.exists) files.push({ path: data.script.path, label: data.script.path });
|
|
89001
89347
|
return files;
|
|
@@ -89394,18 +89740,21 @@ function useStudioSessionStart(projectId, resolving, waitingForServer) {
|
|
|
89394
89740
|
}
|
|
89395
89741
|
|
|
89396
89742
|
// src/hooks/useTimelineAddAtPlayhead.ts
|
|
89397
|
-
import { useCallback as
|
|
89743
|
+
import { useCallback as useCallback174 } from "react";
|
|
89398
89744
|
function useTimelineAddAtPlayhead(addAsset, addComposition) {
|
|
89399
89745
|
const placement = () => ({ start: usePlayerStore.getState().currentTime, track: 0 });
|
|
89400
89746
|
return {
|
|
89401
|
-
addAssetAtPlayhead:
|
|
89402
|
-
addCompositionAtPlayhead:
|
|
89747
|
+
addAssetAtPlayhead: useCallback174((path) => addAsset(path, placement()), [addAsset]),
|
|
89748
|
+
addCompositionAtPlayhead: useCallback174(
|
|
89403
89749
|
(path) => addComposition(path, placement()),
|
|
89404
89750
|
[addComposition]
|
|
89405
89751
|
)
|
|
89406
89752
|
};
|
|
89407
89753
|
}
|
|
89408
89754
|
|
|
89755
|
+
// src/hooks/useActiveComposition.ts
|
|
89756
|
+
import { useState as useState156 } from "react";
|
|
89757
|
+
|
|
89409
89758
|
// src/hooks/useHydrateActiveCompPathFromUrl.ts
|
|
89410
89759
|
import { useEffect as useEffect146 } from "react";
|
|
89411
89760
|
function useHydrateActiveCompPathFromUrl({
|
|
@@ -89428,29 +89777,136 @@ function useHydrateActiveCompPathFromUrl({
|
|
|
89428
89777
|
}, [hydrated, fileTree, fileTreeLoaded, initialUrlStateRef, setActiveCompPath, setHydrated]);
|
|
89429
89778
|
}
|
|
89430
89779
|
|
|
89780
|
+
// src/hooks/useAutoOpenRootComposition.ts
|
|
89781
|
+
import { useEffect as useEffect147, useRef as useRef173 } from "react";
|
|
89782
|
+
function useAutoOpenRootComposition({
|
|
89783
|
+
projectId,
|
|
89784
|
+
activeCompPath,
|
|
89785
|
+
activeCompPathHydrated,
|
|
89786
|
+
masterCompPath,
|
|
89787
|
+
onSelectComposition
|
|
89788
|
+
}) {
|
|
89789
|
+
const settledForProjectRef = useRef173(void 0);
|
|
89790
|
+
useEffect147(() => {
|
|
89791
|
+
if (settledForProjectRef.current === projectId) return;
|
|
89792
|
+
if (!activeCompPathHydrated) return;
|
|
89793
|
+
if (activeCompPath !== null) {
|
|
89794
|
+
settledForProjectRef.current = projectId;
|
|
89795
|
+
return;
|
|
89796
|
+
}
|
|
89797
|
+
if (!masterCompPath) return;
|
|
89798
|
+
settledForProjectRef.current = projectId;
|
|
89799
|
+
onSelectComposition(masterCompPath);
|
|
89800
|
+
}, [projectId, activeCompPath, activeCompPathHydrated, masterCompPath, onSelectComposition]);
|
|
89801
|
+
}
|
|
89802
|
+
|
|
89803
|
+
// src/hooks/useCompositionContentLoader.ts
|
|
89804
|
+
import { useCallback as useCallback175 } from "react";
|
|
89805
|
+
function useCompositionContentLoader({
|
|
89806
|
+
projectId,
|
|
89807
|
+
setEditingFile,
|
|
89808
|
+
setActiveCompPath,
|
|
89809
|
+
showToast
|
|
89810
|
+
}) {
|
|
89811
|
+
return useCallback175(
|
|
89812
|
+
(comp) => {
|
|
89813
|
+
if (!projectId) return;
|
|
89814
|
+
setActiveCompPath(comp.endsWith(".html") ? comp : null);
|
|
89815
|
+
setEditingFile({ path: comp, content: null });
|
|
89816
|
+
fetch(buildProjectApiPath(projectId, `/files/${encodeURIComponent(comp)}`)).then(async (r) => {
|
|
89817
|
+
if (!r.ok) throw new Error(`Failed to load ${comp} (${r.status})`);
|
|
89818
|
+
return r.json();
|
|
89819
|
+
}).then((data) => {
|
|
89820
|
+
if (typeof data.content !== "string") throw new Error(`No content returned for ${comp}`);
|
|
89821
|
+
setEditingFile({ path: comp, content: data.content });
|
|
89822
|
+
}).catch((err) => {
|
|
89823
|
+
showToast(err instanceof Error ? err.message : `Failed to load ${comp}`, "error");
|
|
89824
|
+
});
|
|
89825
|
+
},
|
|
89826
|
+
[projectId, setEditingFile, setActiveCompPath, showToast]
|
|
89827
|
+
);
|
|
89828
|
+
}
|
|
89829
|
+
|
|
89830
|
+
// src/hooks/useResetSelectionOnProjectSwitch.ts
|
|
89831
|
+
import { useRef as useRef174 } from "react";
|
|
89832
|
+
function useResetSelectionOnProjectSwitch({
|
|
89833
|
+
projectId,
|
|
89834
|
+
initialUrlStateRef,
|
|
89835
|
+
setActiveCompPath,
|
|
89836
|
+
setActiveCompPathHydrated
|
|
89837
|
+
}) {
|
|
89838
|
+
const previousProjectIdRef = useRef174(projectId);
|
|
89839
|
+
if (previousProjectIdRef.current !== projectId) {
|
|
89840
|
+
const isSwitch = previousProjectIdRef.current !== null;
|
|
89841
|
+
previousProjectIdRef.current = projectId;
|
|
89842
|
+
if (isSwitch) {
|
|
89843
|
+
initialUrlStateRef.current = readStudioUrlStateFromWindow();
|
|
89844
|
+
setActiveCompPath(null);
|
|
89845
|
+
setActiveCompPathHydrated(isHydratedFromUrlState(initialUrlStateRef.current));
|
|
89846
|
+
}
|
|
89847
|
+
}
|
|
89848
|
+
}
|
|
89849
|
+
|
|
89850
|
+
// src/hooks/useActiveComposition.ts
|
|
89851
|
+
function useActiveComposition({
|
|
89852
|
+
projectId,
|
|
89853
|
+
initialUrlStateRef,
|
|
89854
|
+
fileTree,
|
|
89855
|
+
fileTreeLoaded,
|
|
89856
|
+
masterCompPath,
|
|
89857
|
+
setEditingFile,
|
|
89858
|
+
showToast
|
|
89859
|
+
}) {
|
|
89860
|
+
const [activeCompPath, setActiveCompPath] = useState156(null);
|
|
89861
|
+
const [activeCompPathHydrated, setActiveCompPathHydrated] = useState156(
|
|
89862
|
+
() => isHydratedFromUrlState(initialUrlStateRef.current)
|
|
89863
|
+
);
|
|
89864
|
+
useResetSelectionOnProjectSwitch({
|
|
89865
|
+
projectId,
|
|
89866
|
+
initialUrlStateRef,
|
|
89867
|
+
setActiveCompPath,
|
|
89868
|
+
setActiveCompPathHydrated
|
|
89869
|
+
});
|
|
89870
|
+
useHydrateActiveCompPathFromUrl({
|
|
89871
|
+
hydrated: activeCompPathHydrated,
|
|
89872
|
+
fileTreeLoaded,
|
|
89873
|
+
fileTree,
|
|
89874
|
+
initialUrlStateRef,
|
|
89875
|
+
setActiveCompPath,
|
|
89876
|
+
setHydrated: setActiveCompPathHydrated
|
|
89877
|
+
});
|
|
89878
|
+
const handleSelectComposition = useCompositionContentLoader({
|
|
89879
|
+
projectId,
|
|
89880
|
+
setEditingFile,
|
|
89881
|
+
setActiveCompPath,
|
|
89882
|
+
showToast
|
|
89883
|
+
});
|
|
89884
|
+
useAutoOpenRootComposition({
|
|
89885
|
+
projectId,
|
|
89886
|
+
activeCompPath,
|
|
89887
|
+
activeCompPathHydrated,
|
|
89888
|
+
masterCompPath,
|
|
89889
|
+
onSelectComposition: handleSelectComposition
|
|
89890
|
+
});
|
|
89891
|
+
return { activeCompPath, activeCompPathHydrated, setActiveCompPath, handleSelectComposition };
|
|
89892
|
+
}
|
|
89893
|
+
|
|
89431
89894
|
// src/App.tsx
|
|
89432
89895
|
import { jsx as jsx219, jsxs as jsxs181 } from "react/jsx-runtime";
|
|
89433
89896
|
var getTimelineSelectionSet = () => usePlayerStore.getState().selectedElementIds;
|
|
89434
89897
|
function StudioApp() {
|
|
89435
89898
|
const { projectId, resolving, waitingForServer } = useServerConnection();
|
|
89436
|
-
const initialUrlStateRef =
|
|
89899
|
+
const initialUrlStateRef = useRef175(readStudioUrlStateFromWindow());
|
|
89437
89900
|
const viewModeValue = useViewModeState();
|
|
89438
89901
|
useStudioSessionStart(projectId, resolving, waitingForServer);
|
|
89439
|
-
const [
|
|
89440
|
-
const [
|
|
89441
|
-
|
|
89442
|
-
);
|
|
89443
|
-
const [compIdToSrc, setCompIdToSrc] = useState156(/* @__PURE__ */ new Map());
|
|
89444
|
-
const [previewIframe, setPreviewIframe] = useState156(null);
|
|
89445
|
-
const [compositionLoading, setCompositionLoading] = useState156(true);
|
|
89446
|
-
const [refreshKey, setRefreshKey] = useState156(0);
|
|
89902
|
+
const [compIdToSrc, setCompIdToSrc] = useState157(/* @__PURE__ */ new Map());
|
|
89903
|
+
const [previewIframe, setPreviewIframe] = useState157(null);
|
|
89904
|
+
const [compositionLoading, setCompositionLoading] = useState157(true);
|
|
89905
|
+
const [refreshKey, setRefreshKey] = useState157(0);
|
|
89447
89906
|
const [previewDocumentVersion, refreshPreviewDocumentVersion] = usePreviewDocumentVersion();
|
|
89448
|
-
const [blockPreview, setBlockPreview] =
|
|
89449
|
-
const previewIframeRef =
|
|
89450
|
-
const
|
|
89451
|
-
activeCompPathRef.current = activeCompPath;
|
|
89452
|
-
const leftSidebarRef = useRef171(null);
|
|
89453
|
-
const renderQueue = useRenderQueue(projectId, activeCompPathRef);
|
|
89907
|
+
const [blockPreview, setBlockPreview] = useState157(null);
|
|
89908
|
+
const previewIframeRef = useRef175(null);
|
|
89909
|
+
const leftSidebarRef = useRef175(null);
|
|
89454
89910
|
const captionEditMode = useCaptionStore((s) => s.isEditMode);
|
|
89455
89911
|
const captionHasSelection = useCaptionStore((s) => s.selectedSegmentIds.size > 0);
|
|
89456
89912
|
const captionSync = useCaptionSync(projectId);
|
|
@@ -89469,9 +89925,9 @@ function StudioApp() {
|
|
|
89469
89925
|
rightPanelTab: initialUrlStateRef.current.rightPanelTab
|
|
89470
89926
|
});
|
|
89471
89927
|
const editHistory = usePersistentEditHistory({ projectId });
|
|
89472
|
-
const handleDomZIndexReorderCommitRef =
|
|
89473
|
-
const pendingTimelineEditPathRef =
|
|
89474
|
-
const isGestureRecordingRef =
|
|
89928
|
+
const handleDomZIndexReorderCommitRef = useRef175(null);
|
|
89929
|
+
const pendingTimelineEditPathRef = useRef175(/* @__PURE__ */ new Set());
|
|
89930
|
+
const isGestureRecordingRef = useRef175(false);
|
|
89475
89931
|
const reloadPreview = useCallback176(() => setRefreshKey((k) => k + 1), []);
|
|
89476
89932
|
const fileManager = useFileManager({
|
|
89477
89933
|
projectId,
|
|
@@ -89479,23 +89935,27 @@ function StudioApp() {
|
|
|
89479
89935
|
recordEdit: editHistory.recordEdit,
|
|
89480
89936
|
setRefreshKey
|
|
89481
89937
|
});
|
|
89482
|
-
const masterCompPath =
|
|
89483
|
-
() => resolveMasterCompositionPath(fileManager.
|
|
89484
|
-
[fileManager.
|
|
89938
|
+
const masterCompPath = useMemo78(
|
|
89939
|
+
() => resolveMasterCompositionPath(fileManager.compositions),
|
|
89940
|
+
[fileManager.compositions]
|
|
89485
89941
|
);
|
|
89942
|
+
const { activeCompPath, activeCompPathHydrated, setActiveCompPath, handleSelectComposition } = useActiveComposition({
|
|
89943
|
+
projectId,
|
|
89944
|
+
initialUrlStateRef,
|
|
89945
|
+
fileTree: fileManager.fileTree,
|
|
89946
|
+
fileTreeLoaded: fileManager.fileTreeLoaded,
|
|
89947
|
+
masterCompPath,
|
|
89948
|
+
setEditingFile: fileManager.setEditingFile,
|
|
89949
|
+
showToast
|
|
89950
|
+
});
|
|
89486
89951
|
const { sdkHandle, editFlowSdkSession } = useStudioSdkSessions(
|
|
89487
89952
|
projectId,
|
|
89488
89953
|
activeCompPath,
|
|
89489
89954
|
masterCompPath
|
|
89490
89955
|
);
|
|
89491
|
-
|
|
89492
|
-
|
|
89493
|
-
|
|
89494
|
-
fileTree: fileManager.fileTree,
|
|
89495
|
-
initialUrlStateRef,
|
|
89496
|
-
setActiveCompPath,
|
|
89497
|
-
setHydrated: setActiveCompPathHydrated
|
|
89498
|
-
});
|
|
89956
|
+
const activeCompPathRef = useRef175(activeCompPath);
|
|
89957
|
+
activeCompPathRef.current = activeCompPath;
|
|
89958
|
+
const renderQueue = useRenderQueue(projectId, activeCompPathRef);
|
|
89499
89959
|
const previewPersistence = usePreviewPersistence({
|
|
89500
89960
|
showToast,
|
|
89501
89961
|
readOptionalProjectFile: fileManager.readOptionalProjectFile,
|
|
@@ -89514,7 +89974,7 @@ function StudioApp() {
|
|
|
89514
89974
|
pendingTimelineEditPathRef,
|
|
89515
89975
|
reloadPreview
|
|
89516
89976
|
});
|
|
89517
|
-
const invalidateGsapCacheRef =
|
|
89977
|
+
const invalidateGsapCacheRef = useRef175(() => {
|
|
89518
89978
|
});
|
|
89519
89979
|
const invalidateGsapCache = useCallback176(() => invalidateGsapCacheRef.current(), []);
|
|
89520
89980
|
const timelineEditing = useTimelineEditing({
|
|
@@ -89573,14 +90033,14 @@ function StudioApp() {
|
|
|
89573
90033
|
setRightCollapsed: panelLayout.setRightCollapsed,
|
|
89574
90034
|
setRightPanelTab: panelLayout.setRightPanelTab
|
|
89575
90035
|
});
|
|
89576
|
-
const clearDomSelectionRef =
|
|
90036
|
+
const clearDomSelectionRef = useRef175(() => {
|
|
89577
90037
|
});
|
|
89578
|
-
const domEditSelectionBridgeRef =
|
|
89579
|
-
const handleDomEditElementDeleteRef =
|
|
90038
|
+
const domEditSelectionBridgeRef = useRef175(null);
|
|
90039
|
+
const handleDomEditElementDeleteRef = useRef175(async () => {
|
|
89580
90040
|
});
|
|
89581
90041
|
const domEditDeleteBridge = (s, o) => handleDomEditElementDeleteRef.current(s, o);
|
|
89582
|
-
const resetKeyframesRef =
|
|
89583
|
-
const deleteSelectedKeyframesRef =
|
|
90042
|
+
const resetKeyframesRef = useRef175(() => false);
|
|
90043
|
+
const deleteSelectedKeyframesRef = useRef175(() => {
|
|
89584
90044
|
});
|
|
89585
90045
|
const { handleCopy: handleCopy2, handlePaste: handlePaste2, handleCut } = useClipboard({
|
|
89586
90046
|
projectId,
|
|
@@ -89620,7 +90080,7 @@ function StudioApp() {
|
|
|
89620
90080
|
forceReloadSdkSession: sdkHandle.forceReload,
|
|
89621
90081
|
onToggleRecording: () => handleToggleRecordingRef.current()
|
|
89622
90082
|
});
|
|
89623
|
-
const sidebarTabRef =
|
|
90083
|
+
const sidebarTabRef = useRef175({
|
|
89624
90084
|
select: (t) => leftSidebarRef.current?.selectTab(t),
|
|
89625
90085
|
get: () => leftSidebarRef.current?.getTab() ?? "compositions"
|
|
89626
90086
|
});
|
|
@@ -89662,7 +90122,8 @@ function StudioApp() {
|
|
|
89662
90122
|
getSidebarTab: sidebarTabRef.current.get,
|
|
89663
90123
|
sdkSession: editFlowSdkSession,
|
|
89664
90124
|
publishSdkSession: sdkHandle.publish,
|
|
89665
|
-
forceReloadSdkSession: sdkHandle.forceReload
|
|
90125
|
+
forceReloadSdkSession: sdkHandle.forceReload,
|
|
90126
|
+
handleTimelineElementsDelete: timelineEditing.handleTimelineElementsDelete
|
|
89666
90127
|
});
|
|
89667
90128
|
domEditSelectionBridgeRef.current = domEditSession.domEditSelection;
|
|
89668
90129
|
handleDomZIndexReorderCommitRef.current = domEditSession.handleDomZIndexReorderCommit;
|
|
@@ -89709,9 +90170,9 @@ function StudioApp() {
|
|
|
89709
90170
|
resetErrors: resetConsoleErrors
|
|
89710
90171
|
} = useConsoleErrorCapture(previewIframe);
|
|
89711
90172
|
const dragOverlay = useGlobalFileDrop(timelineEditing.handleTimelineFileDrop);
|
|
89712
|
-
const handleToggleRecordingRef =
|
|
90173
|
+
const handleToggleRecordingRef = useRef175(() => {
|
|
89713
90174
|
});
|
|
89714
|
-
const domEditSessionRef =
|
|
90175
|
+
const domEditSessionRef = useRef175(domEditSession);
|
|
89715
90176
|
domEditSessionRef.current = domEditSession;
|
|
89716
90177
|
const { gestureState, gestureRecording, handleToggleRecording } = useGestureCommit({
|
|
89717
90178
|
domEditSessionRef,
|
|
@@ -89720,7 +90181,7 @@ function StudioApp() {
|
|
|
89720
90181
|
isGestureRecordingRef
|
|
89721
90182
|
});
|
|
89722
90183
|
handleToggleRecordingRef.current = handleToggleRecording;
|
|
89723
|
-
const canvasRectRef =
|
|
90184
|
+
const canvasRectRef = useRef175(null);
|
|
89724
90185
|
useLayoutEffect11(() => {
|
|
89725
90186
|
if (gestureState !== "recording" || !previewIframe) {
|
|
89726
90187
|
canvasRectRef.current = null;
|
|
@@ -89738,13 +90199,6 @@ function StudioApp() {
|
|
|
89738
90199
|
},
|
|
89739
90200
|
[appHotkeys, resetConsoleErrors, refreshPreviewDocumentVersion]
|
|
89740
90201
|
);
|
|
89741
|
-
const { setEditingFile } = fileManager;
|
|
89742
|
-
const handleSelectComposition = useCompositionContentLoader({
|
|
89743
|
-
projectId,
|
|
89744
|
-
setEditingFile,
|
|
89745
|
-
setActiveCompPath,
|
|
89746
|
-
showToast
|
|
89747
|
-
});
|
|
89748
90202
|
const {
|
|
89749
90203
|
designPanelActive,
|
|
89750
90204
|
inspectorPanelActive,
|
|
@@ -89801,7 +90255,7 @@ function StudioApp() {
|
|
|
89801
90255
|
handlePreviewIframeRef,
|
|
89802
90256
|
refreshPreviewDocumentVersion
|
|
89803
90257
|
});
|
|
89804
|
-
const timelineToolbar =
|
|
90258
|
+
const timelineToolbar = useMemo78(
|
|
89805
90259
|
() => /* @__PURE__ */ jsx219(
|
|
89806
90260
|
TimelineToolbar,
|
|
89807
90261
|
{
|
|
@@ -89959,11 +90413,11 @@ function StudioApp() {
|
|
|
89959
90413
|
}
|
|
89960
90414
|
|
|
89961
90415
|
// src/hooks/useElementPicker.ts
|
|
89962
|
-
import { useState as
|
|
90416
|
+
import { useState as useState158, useCallback as useCallback177, useRef as useRef176 } from "react";
|
|
89963
90417
|
function useElementPicker(iframeRef, options) {
|
|
89964
|
-
const [isPickMode, setIsPickMode] =
|
|
89965
|
-
const [pickedElement, setPickedElement] =
|
|
89966
|
-
const activeOverrideRef =
|
|
90418
|
+
const [isPickMode, setIsPickMode] = useState158(false);
|
|
90419
|
+
const [pickedElement, setPickedElement] = useState158(null);
|
|
90420
|
+
const activeOverrideRef = useRef176(null);
|
|
89967
90421
|
const getActiveIframe = useCallback177(() => {
|
|
89968
90422
|
return activeOverrideRef.current ?? iframeRef.current;
|
|
89969
90423
|
}, [iframeRef]);
|
|
@@ -90037,7 +90491,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
90037
90491
|
window.addEventListener("message", handleMessage);
|
|
90038
90492
|
return () => window.removeEventListener("message", handleMessage);
|
|
90039
90493
|
});
|
|
90040
|
-
const optionsRef =
|
|
90494
|
+
const optionsRef = useRef176(options);
|
|
90041
90495
|
optionsRef.current = options;
|
|
90042
90496
|
const syncToSource = useCallback177(
|
|
90043
90497
|
(elementId2, selector, op) => {
|
|
@@ -90148,7 +90602,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
90148
90602
|
},
|
|
90149
90603
|
[pickedElement, getActiveIframe, syncToSource]
|
|
90150
90604
|
);
|
|
90151
|
-
const activeIframeRef =
|
|
90605
|
+
const activeIframeRef = useRef176(null);
|
|
90152
90606
|
activeIframeRef.current = getActiveIframe();
|
|
90153
90607
|
return {
|
|
90154
90608
|
isPickMode,
|
|
@@ -90314,6 +90768,7 @@ function findElementBlock(html2, elementId2) {
|
|
|
90314
90768
|
return null;
|
|
90315
90769
|
}
|
|
90316
90770
|
export {
|
|
90771
|
+
AskAgentModal,
|
|
90317
90772
|
CompositionBreadcrumb,
|
|
90318
90773
|
CompositionThumbnail,
|
|
90319
90774
|
EditorShell,
|
|
@@ -90327,6 +90782,8 @@ export {
|
|
|
90327
90782
|
Timeline,
|
|
90328
90783
|
VideoThumbnail,
|
|
90329
90784
|
applyPatch,
|
|
90785
|
+
buildPickerAgentContextPreview,
|
|
90786
|
+
buildPickerAgentPrompt,
|
|
90330
90787
|
findElementBlock,
|
|
90331
90788
|
formatTime,
|
|
90332
90789
|
liveTime,
|