hyperframes 0.8.47 → 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/cli.js +1728 -1486
- package/dist/fontLocalizeCli.js +2 -2
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/studio/assets/{hyperframes-player-B7fsB8C2.js → hyperframes-player-CtVX6jL_.js} +1 -1
- package/dist/studio/assets/{index-ryL7q1QG.js → index-B3-orIjW.js} +1 -1
- package/dist/studio/assets/index-B9LfWNyM.css +1 -0
- package/dist/studio/assets/index-C9gJKpqQ.js +441 -0
- package/dist/studio/assets/{index-B50xQfSG.js → index-D_j-0PD3.js} +1 -1
- package/dist/studio/index.d.ts +66 -23
- package/dist/studio/index.html +2 -2
- package/dist/studio/index.js +1015 -621
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/studio/assets/index-DnRfAiK2.css +0 -1
- package/dist/studio/assets/index-j-4hCrZU.js +0 -441
package/dist/studio/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
|
}
|
|
@@ -1837,6 +1840,12 @@ var usePlayerStore = create2((set, get) => ({
|
|
|
1837
1840
|
writeStudioUiPreferences({ timelineSnapEnabled: enabled });
|
|
1838
1841
|
set({ timelineSnapEnabled: enabled });
|
|
1839
1842
|
},
|
|
1843
|
+
rippleEditEnabled: readStudioUiPreferences().rippleEditEnabled ?? true,
|
|
1844
|
+
// default on
|
|
1845
|
+
setRippleEditEnabled: (enabled) => {
|
|
1846
|
+
writeStudioUiPreferences({ rippleEditEnabled: enabled });
|
|
1847
|
+
set({ rippleEditEnabled: enabled });
|
|
1848
|
+
},
|
|
1840
1849
|
timeDisplayMode: readStudioUiPreferences().timeDisplayMode ?? "time",
|
|
1841
1850
|
setTimeDisplayMode: (mode) => {
|
|
1842
1851
|
writeStudioUiPreferences({ timeDisplayMode: mode });
|
|
@@ -3052,6 +3061,10 @@ function isAudioTimelineElement(element) {
|
|
|
3052
3061
|
if (AUDIO_TIMELINE_TAGS.has(tag)) return true;
|
|
3053
3062
|
return Boolean(element.src && AUDIO_SOURCE_EXT_RE.test(element.src));
|
|
3054
3063
|
}
|
|
3064
|
+
function isAudioOrVideoTimelineElement(element) {
|
|
3065
|
+
if (!element) return false;
|
|
3066
|
+
return isAudioTimelineElement(element) || element.tag.trim().toLowerCase() === "video";
|
|
3067
|
+
}
|
|
3055
3068
|
function isMusicTrack(element) {
|
|
3056
3069
|
if (!element) return false;
|
|
3057
3070
|
if (!isAudioTimelineElement(element)) return false;
|
|
@@ -3127,7 +3140,6 @@ function FileManagerProvider({
|
|
|
3127
3140
|
projectDir,
|
|
3128
3141
|
fileTree,
|
|
3129
3142
|
fileTreeLoaded,
|
|
3130
|
-
setFileTree,
|
|
3131
3143
|
editingPathRef,
|
|
3132
3144
|
projectIdRef,
|
|
3133
3145
|
saveRafRef,
|
|
@@ -3168,7 +3180,6 @@ function FileManagerProvider({
|
|
|
3168
3180
|
projectDir,
|
|
3169
3181
|
fileTree,
|
|
3170
3182
|
fileTreeLoaded,
|
|
3171
|
-
setFileTree,
|
|
3172
3183
|
editingPathRef,
|
|
3173
3184
|
projectIdRef,
|
|
3174
3185
|
saveRafRef,
|
|
@@ -3206,7 +3217,6 @@ function FileManagerProvider({
|
|
|
3206
3217
|
projectDir,
|
|
3207
3218
|
fileTree,
|
|
3208
3219
|
fileTreeLoaded,
|
|
3209
|
-
setFileTree,
|
|
3210
3220
|
editingPathRef,
|
|
3211
3221
|
projectIdRef,
|
|
3212
3222
|
saveRafRef,
|
|
@@ -3962,6 +3972,7 @@ function buildMissingCompositionEntry(params) {
|
|
|
3962
3972
|
start: window2.start,
|
|
3963
3973
|
duration: window2.duration,
|
|
3964
3974
|
track: timing.trackIndex,
|
|
3975
|
+
authoredTrack: timing.trackIndex,
|
|
3965
3976
|
domId: optionalNonEmpty(element.id),
|
|
3966
3977
|
hfId: optionalNonEmpty(element.getAttribute("data-hf-id")),
|
|
3967
3978
|
selector,
|
|
@@ -5237,10 +5248,7 @@ function resolveTimelineAssetDrop(input, clientX, clientY) {
|
|
|
5237
5248
|
});
|
|
5238
5249
|
const contentY = clientY - input.rectTop + input.scrollTop;
|
|
5239
5250
|
const pointerStart = Math.round(x / Math.max(input.pixelsPerSecond, 1) * 100) / 100;
|
|
5240
|
-
const start = Math.max(
|
|
5241
|
-
0,
|
|
5242
|
-
input.clampStartToDuration === false ? pointerStart : Math.min(input.duration, pointerStart)
|
|
5243
|
-
);
|
|
5251
|
+
const start = Math.max(0, pointerStart);
|
|
5244
5252
|
const rowIndex = Math.floor(getTimelineRowFromY(contentY, input.rowHeights));
|
|
5245
5253
|
return {
|
|
5246
5254
|
start,
|
|
@@ -6602,10 +6610,6 @@ function invokeDropCallback(callback) {
|
|
|
6602
6610
|
} catch {
|
|
6603
6611
|
}
|
|
6604
6612
|
}
|
|
6605
|
-
function resolveDropStart(usePointerStart, pointerStart) {
|
|
6606
|
-
if (usePointerStart) return pointerStart;
|
|
6607
|
-
return Math.max(0, usePlayerStore.getState().currentTime);
|
|
6608
|
-
}
|
|
6609
6613
|
function applyFileDrop(transfer, onFileDrop, placement) {
|
|
6610
6614
|
if (!onFileDrop || transfer.files.length === 0) return false;
|
|
6611
6615
|
invokeDropCallback(() => onFileDrop(Array.from(transfer.files), placement));
|
|
@@ -6625,7 +6629,6 @@ function applyTypedJsonDrop(transfer, mime, field, apply, placement) {
|
|
|
6625
6629
|
function useTimelineAssetDrop({
|
|
6626
6630
|
scrollRef,
|
|
6627
6631
|
ppsRef,
|
|
6628
|
-
durationRef,
|
|
6629
6632
|
trackOrderRef,
|
|
6630
6633
|
rowGeometryRef,
|
|
6631
6634
|
contentOrigin,
|
|
@@ -6706,10 +6709,10 @@ function useTimelineAssetDrop({
|
|
|
6706
6709
|
[clearDropPreview]
|
|
6707
6710
|
);
|
|
6708
6711
|
const resolveDropPlacement2 = useCallback7(
|
|
6709
|
-
(clientX, clientY
|
|
6712
|
+
(clientX, clientY) => {
|
|
6710
6713
|
const scroll = scrollRef.current;
|
|
6711
6714
|
const rect = scroll?.getBoundingClientRect();
|
|
6712
|
-
|
|
6715
|
+
return resolveTimelineAssetDrop(
|
|
6713
6716
|
{
|
|
6714
6717
|
rectLeft: rect?.left ?? 0,
|
|
6715
6718
|
rectTop: rect?.top ?? 0,
|
|
@@ -6717,20 +6720,14 @@ function useTimelineAssetDrop({
|
|
|
6717
6720
|
scrollTop: scroll?.scrollTop ?? 0,
|
|
6718
6721
|
contentOrigin,
|
|
6719
6722
|
pixelsPerSecond: ppsRef.current,
|
|
6720
|
-
duration: durationRef.current,
|
|
6721
|
-
clampStartToDuration: !usePointerStart,
|
|
6722
6723
|
rowHeights: rowGeometryRef.current.rowHeights,
|
|
6723
6724
|
trackOrder: trackOrderRef.current
|
|
6724
6725
|
},
|
|
6725
6726
|
clientX,
|
|
6726
6727
|
clientY
|
|
6727
6728
|
);
|
|
6728
|
-
return {
|
|
6729
|
-
start: resolveDropStart(usePointerStart, pointer.start),
|
|
6730
|
-
track: pointer.track
|
|
6731
|
-
};
|
|
6732
6729
|
},
|
|
6733
|
-
[scrollRef, ppsRef,
|
|
6730
|
+
[scrollRef, ppsRef, trackOrderRef, rowGeometryRef, contentOrigin]
|
|
6734
6731
|
);
|
|
6735
6732
|
const handleAssetDrop = useCallback7(
|
|
6736
6733
|
(e) => {
|
|
@@ -6738,15 +6735,14 @@ function useTimelineAssetDrop({
|
|
|
6738
6735
|
const canCommit = activeDropEpochRef.current === sessionEpoch;
|
|
6739
6736
|
clearDropPreview();
|
|
6740
6737
|
if (!canCommit) return;
|
|
6738
|
+
const placement = resolveDropPlacement2(e.clientX, e.clientY);
|
|
6741
6739
|
const compositionPayload = parseTimelineCompositionPayload(
|
|
6742
6740
|
e.dataTransfer.getData(TIMELINE_COMPOSITION_MIME)
|
|
6743
6741
|
);
|
|
6744
6742
|
if (compositionPayload && onCompositionDrop) {
|
|
6745
|
-
|
|
6746
|
-
invokeDropCallback(() => onCompositionDrop(compositionPayload.sourcePath, placement2));
|
|
6743
|
+
invokeDropCallback(() => onCompositionDrop(compositionPayload.sourcePath, placement));
|
|
6747
6744
|
return;
|
|
6748
6745
|
}
|
|
6749
|
-
const placement = resolveDropPlacement2(e.clientX, e.clientY);
|
|
6750
6746
|
if (applyFileDrop(e.dataTransfer, onFileDrop, placement)) return;
|
|
6751
6747
|
if (applyTypedJsonDrop(e.dataTransfer, TIMELINE_ASSET_MIME, "path", onAssetDrop, placement)) {
|
|
6752
6748
|
return;
|
|
@@ -9065,6 +9061,11 @@ function keyframeTarget(keyframe) {
|
|
|
9065
9061
|
|
|
9066
9062
|
// src/player/components/TimelineDiamondConnectors.tsx
|
|
9067
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
|
+
}
|
|
9068
9069
|
function TimelineDiamondConnectors({
|
|
9069
9070
|
markers,
|
|
9070
9071
|
centerY,
|
|
@@ -9123,6 +9124,7 @@ function TimelineDiamondConnectors({
|
|
|
9123
9124
|
previous.keyframe.percentage
|
|
9124
9125
|
),
|
|
9125
9126
|
roomForFullTarget: connectorWidth >= 24,
|
|
9127
|
+
restingVisible: hasRoomForRestingEase(connectorWidth),
|
|
9126
9128
|
onSelectSegment
|
|
9127
9129
|
}
|
|
9128
9130
|
)
|
|
@@ -9142,6 +9144,7 @@ function SegmentEaseControl({
|
|
|
9142
9144
|
rovingTargetId,
|
|
9143
9145
|
afterLabel,
|
|
9144
9146
|
roomForFullTarget,
|
|
9147
|
+
restingVisible,
|
|
9145
9148
|
onSelectSegment
|
|
9146
9149
|
}) {
|
|
9147
9150
|
const pressXRef = useRef12(null);
|
|
@@ -9174,7 +9177,7 @@ function SegmentEaseControl({
|
|
|
9174
9177
|
tabIndex: focusId === rovingTargetId ? 0 : -1,
|
|
9175
9178
|
"aria-label": `Edit ${ease} easing after ${afterLabel}`,
|
|
9176
9179
|
title: `Edit ${ease} easing`,
|
|
9177
|
-
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-['']" : ""}`,
|
|
9178
9181
|
style: {
|
|
9179
9182
|
left: "50%",
|
|
9180
9183
|
top: "50%",
|
|
@@ -10919,6 +10922,11 @@ import {
|
|
|
10919
10922
|
} from "@hyperframes/core/audio-automation";
|
|
10920
10923
|
import { getAudioFxDef } from "@hyperframes/core/audio-fx";
|
|
10921
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
|
+
}
|
|
10922
10930
|
var MIN_POINT_GAP_SEC = 1e-3;
|
|
10923
10931
|
var GRAB_PX = 7;
|
|
10924
10932
|
var SEGMENT_GRAB_PX = 5;
|
|
@@ -11817,12 +11825,7 @@ function useAutomationLaneGestures({
|
|
|
11817
11825
|
return;
|
|
11818
11826
|
}
|
|
11819
11827
|
const { t, v } = pointAt(e.clientX, e.clientY);
|
|
11820
|
-
|
|
11821
|
-
const seeded = lane.points.length === 0 && t > POINT_MERGE_SEC ? [{ t: 0, v }] : [];
|
|
11822
|
-
commitPoints(
|
|
11823
|
-
[...seeded, ...kept, { t, v }].sort((a, b) => a.t - b.t),
|
|
11824
|
-
true
|
|
11825
|
-
);
|
|
11828
|
+
commitPoints(mergeInsertPoint(lane.points, t, v), true);
|
|
11826
11829
|
},
|
|
11827
11830
|
[lane, pointAt, commitPoints, readOnly, hitIndex, segmentIndex]
|
|
11828
11831
|
);
|
|
@@ -12545,7 +12548,7 @@ function laneGroupKey(target, chain) {
|
|
|
12545
12548
|
function groupAutomationLanes(elements) {
|
|
12546
12549
|
const groups = /* @__PURE__ */ new Map();
|
|
12547
12550
|
for (const element of elements) {
|
|
12548
|
-
if (!
|
|
12551
|
+
if (!isAudioOrVideoTimelineElement(element)) continue;
|
|
12549
12552
|
const chain = elementFxChain(element);
|
|
12550
12553
|
for (const lane of elementAutomationLanes(element)) {
|
|
12551
12554
|
const key2 = laneGroupKey(lane.target, chain);
|
|
@@ -12642,7 +12645,7 @@ function TimelineAutomationLaneSlot({
|
|
|
12642
12645
|
currentTime,
|
|
12643
12646
|
beatTimes
|
|
12644
12647
|
}) {
|
|
12645
|
-
const clips = elements.filter(
|
|
12648
|
+
const clips = elements.filter(isAudioOrVideoTimelineElement);
|
|
12646
12649
|
const rowsByClip = /* @__PURE__ */ new Map();
|
|
12647
12650
|
groupAutomationLanes(clips).forEach((group, rowIndex) => {
|
|
12648
12651
|
for (const entry2 of group.entries) {
|
|
@@ -13074,6 +13077,10 @@ function matchesByDomId(selection, element, selectionSourceFile) {
|
|
|
13074
13077
|
if (!selection.id) return false;
|
|
13075
13078
|
return element.domId === selection.id && (element.sourceFile || "index.html") === selectionSourceFile;
|
|
13076
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
|
+
}
|
|
13077
13084
|
function matchesByCompositionHost(selection, element) {
|
|
13078
13085
|
if (!selection.isCompositionHost || !selection.compositionSrc) return false;
|
|
13079
13086
|
return element.compositionSrc === selection.compositionSrc;
|
|
@@ -13086,6 +13093,8 @@ function findMatchingTimelineElementId(selection, elements) {
|
|
|
13086
13093
|
const selectionSourceFile = selection.sourceFile || "index.html";
|
|
13087
13094
|
const byId = selection.id ? elements.find((el) => matchesByDomId(selection, el, selectionSourceFile)) : void 0;
|
|
13088
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;
|
|
13089
13098
|
const bySelector = selection.selector ? elements.find((el) => matchesBySelector(selection, el)) : void 0;
|
|
13090
13099
|
if (bySelector) return bySelector.key ?? bySelector.id;
|
|
13091
13100
|
const byHost = elements.find((el) => matchesByCompositionHost(selection, el));
|
|
@@ -13095,6 +13104,11 @@ function findMatchingTimelineElementId(selection, elements) {
|
|
|
13095
13104
|
}
|
|
13096
13105
|
return null;
|
|
13097
13106
|
}
|
|
13107
|
+
function resolveElementTrack(element) {
|
|
13108
|
+
return Math.round(
|
|
13109
|
+
Number.isFinite(element.authoredTrack) ? element.authoredTrack : element.track
|
|
13110
|
+
);
|
|
13111
|
+
}
|
|
13098
13112
|
function findTimelineIdByAncestor(element, elements, sourceFile) {
|
|
13099
13113
|
let ancestor = element?.parentElement ?? null;
|
|
13100
13114
|
while (ancestor) {
|
|
@@ -15670,7 +15684,7 @@ function trackShowsBeatStrip(els, beatTimes, ctx3) {
|
|
|
15670
15684
|
return ctx3.selectedElementId ? els.some((e) => (e.key ?? e.id) === ctx3.selectedElementId) : els.some((e) => ctx3.isMusicTrack(e));
|
|
15671
15685
|
}
|
|
15672
15686
|
function automationLaneCountOf(element) {
|
|
15673
|
-
return
|
|
15687
|
+
return isAudioOrVideoTimelineElement(element) ? elementAutomationLanes(element).length : 0;
|
|
15674
15688
|
}
|
|
15675
15689
|
function trackAutomationLaneCount(elements) {
|
|
15676
15690
|
return groupAutomationLanes(elements).length;
|
|
@@ -19169,6 +19183,9 @@ import { useRef as useRef29, useState as useState17, useCallback as useCallback1
|
|
|
19169
19183
|
function classifyZone(el) {
|
|
19170
19184
|
return isAudioTimelineElement(el) ? "audio" : "visual";
|
|
19171
19185
|
}
|
|
19186
|
+
function isMainTrackElement(el) {
|
|
19187
|
+
return el.track === 0 && classifyZone(el) === "visual" && el.expandedParentStart == null;
|
|
19188
|
+
}
|
|
19172
19189
|
var keyOf = (el) => el.key ?? el.id;
|
|
19173
19190
|
var EPS = 1e-6;
|
|
19174
19191
|
function overlaps2(a, b) {
|
|
@@ -21962,20 +21979,23 @@ function resolveCloseGapShifts(elements, gap) {
|
|
|
21962
21979
|
// src/player/components/timelineGapCommit.ts
|
|
21963
21980
|
var keyOf5 = (e) => e.key ?? e.id;
|
|
21964
21981
|
var gapCloseGestureSeq = 0;
|
|
21965
|
-
function
|
|
21966
|
-
const byKey = new Map(
|
|
21967
|
-
return shifts.
|
|
21982
|
+
function resolveShiftedElements(elements, shifts) {
|
|
21983
|
+
const byKey = new Map(elements.map((e) => [keyOf5(e), e]));
|
|
21984
|
+
return shifts.flatMap((s) => {
|
|
21968
21985
|
const element = byKey.get(s.key);
|
|
21969
|
-
return element
|
|
21986
|
+
return element ? [{ element, start: s.newStart }] : [];
|
|
21970
21987
|
});
|
|
21971
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
|
+
}
|
|
21972
21993
|
function buildShiftEdits(laneElements, shifts) {
|
|
21973
21994
|
if (shifts.length === 0 || !canShiftTrackGapClips(laneElements, shifts)) return null;
|
|
21974
|
-
|
|
21975
|
-
|
|
21976
|
-
|
|
21977
|
-
|
|
21978
|
-
});
|
|
21995
|
+
return resolveShiftedElements(laneElements, shifts).map(({ element, start }) => ({
|
|
21996
|
+
element,
|
|
21997
|
+
updates: { start, track: element.track }
|
|
21998
|
+
}));
|
|
21979
21999
|
}
|
|
21980
22000
|
function commitShifts(laneElements, shifts, deps) {
|
|
21981
22001
|
const edits = buildShiftEdits(laneElements, shifts);
|
|
@@ -21995,6 +22015,22 @@ function commitCloseAllTrackGaps(laneElements, deps) {
|
|
|
21995
22015
|
deps
|
|
21996
22016
|
);
|
|
21997
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
|
+
}
|
|
21998
22034
|
|
|
21999
22035
|
// src/player/components/useTrackGapMenu.ts
|
|
22000
22036
|
function useTrackGapMenu({
|
|
@@ -23202,7 +23238,6 @@ var Timeline = memo16(function Timeline2({
|
|
|
23202
23238
|
const assetDrop = useTimelineAssetDrop({
|
|
23203
23239
|
scrollRef,
|
|
23204
23240
|
ppsRef,
|
|
23205
|
-
durationRef,
|
|
23206
23241
|
trackOrderRef,
|
|
23207
23242
|
rowGeometryRef,
|
|
23208
23243
|
contentOrigin,
|
|
@@ -24684,6 +24719,9 @@ function canvasNudgeKeysClaimed() {
|
|
|
24684
24719
|
}
|
|
24685
24720
|
|
|
24686
24721
|
// src/player/hooks/usePlaybackKeyboard.ts
|
|
24722
|
+
function shouldRazorClaimPlainA(e) {
|
|
24723
|
+
return !e.shiftKey && !e.altKey && usePlayerStore.getState().activeTool === "razor";
|
|
24724
|
+
}
|
|
24687
24725
|
function usePlaybackKeyboard({
|
|
24688
24726
|
iframeRef,
|
|
24689
24727
|
shuttleDirectionRef,
|
|
@@ -24813,6 +24851,7 @@ function usePlaybackKeyboard({
|
|
|
24813
24851
|
return;
|
|
24814
24852
|
}
|
|
24815
24853
|
if (key2 === "a") {
|
|
24854
|
+
if (shouldRazorClaimPlainA(e)) return;
|
|
24816
24855
|
e.preventDefault();
|
|
24817
24856
|
seek(usePlayerStore.getState().inPoint ?? 0, { keepPlaying: true });
|
|
24818
24857
|
return;
|
|
@@ -28547,6 +28586,13 @@ function pauseStudioPreviewPlayback(iframe) {
|
|
|
28547
28586
|
}
|
|
28548
28587
|
|
|
28549
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
|
+
];
|
|
28550
28596
|
function formatBoundingBox(bounds) {
|
|
28551
28597
|
return `x=${Math.round(bounds.x)}, y=${Math.round(bounds.y)}, width=${Math.round(bounds.width)}, height=${Math.round(bounds.height)}`;
|
|
28552
28598
|
}
|
|
@@ -28558,6 +28604,35 @@ function formatTextFields(fields) {
|
|
|
28558
28604
|
(field) => `- key=${field.key}; tag=<${field.tagName}>; source=${field.source}; text=${JSON.stringify(field.value)}`
|
|
28559
28605
|
).join("\n");
|
|
28560
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
|
+
}
|
|
28561
28636
|
function buildElementAgentPrompt({
|
|
28562
28637
|
selection,
|
|
28563
28638
|
currentTime,
|
|
@@ -28567,6 +28642,17 @@ function buildElementAgentPrompt({
|
|
|
28567
28642
|
sourceFilePath
|
|
28568
28643
|
}) {
|
|
28569
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
|
+
};
|
|
28570
28656
|
const lines = [
|
|
28571
28657
|
"## HyperFrames element edit request v1",
|
|
28572
28658
|
"Schema version: 1",
|
|
@@ -28576,52 +28662,62 @@ function buildElementAgentPrompt({
|
|
|
28576
28662
|
`Composition: ${selection.compositionPath}`,
|
|
28577
28663
|
`Playback time: ${formatTime(currentTime)}`,
|
|
28578
28664
|
`Source file: ${displayedSourceFile}`,
|
|
28579
|
-
|
|
28580
|
-
`Selector: ${selection.selector ?? "(none)"}`,
|
|
28581
|
-
`Selector index: ${selection.selectorIndex ?? 0}`,
|
|
28582
|
-
`Tag: <${selection.tagName}>`,
|
|
28583
|
-
`Bounds: ${formatBoundingBox(selection.boundingBox)}`
|
|
28665
|
+
...buildElementInfoLines(info)
|
|
28584
28666
|
];
|
|
28585
|
-
if (selection.textContent) {
|
|
28586
|
-
lines.push(`Text: ${selection.textContent}`);
|
|
28587
|
-
}
|
|
28588
28667
|
const trimmedSelectionContext = selectionContext?.trim();
|
|
28589
28668
|
if (trimmedSelectionContext) {
|
|
28590
28669
|
lines.push("", "Selection context:", trimmedSelectionContext);
|
|
28591
28670
|
}
|
|
28592
|
-
|
|
28593
|
-
if (textFieldsBlock) {
|
|
28594
|
-
lines.push("", "Text fields:", textFieldsBlock);
|
|
28595
|
-
}
|
|
28596
|
-
const inlineStyleBlock = formatStyleBlock(selection.inlineStyles);
|
|
28597
|
-
if (inlineStyleBlock) {
|
|
28598
|
-
lines.push("", "Inline styles:", inlineStyleBlock);
|
|
28599
|
-
}
|
|
28600
|
-
const computedStyleBlock = formatStyleBlock(selection.computedStyles);
|
|
28601
|
-
if (computedStyleBlock) {
|
|
28602
|
-
lines.push("", "Computed styles (browser-resolved):", computedStyleBlock);
|
|
28603
|
-
}
|
|
28671
|
+
lines.push(...buildElementDetailLines(info));
|
|
28604
28672
|
if (tagSnippet) {
|
|
28605
28673
|
lines.push("", "Target HTML:", tagSnippet);
|
|
28606
28674
|
}
|
|
28607
|
-
lines.push(
|
|
28608
|
-
"",
|
|
28609
|
-
"Guardrails:",
|
|
28610
|
-
"- Make a targeted change to this element only.",
|
|
28611
|
-
"- Preserve the rest of the composition and its timing.",
|
|
28612
|
-
"- Do not modify other elements' data-* attributes or positioning.",
|
|
28613
|
-
"- Prefer existing inline styles or existing CSS rules for this element over adding unrelated selectors."
|
|
28614
|
-
);
|
|
28675
|
+
lines.push("", ...GUARDRAIL_LINES);
|
|
28615
28676
|
return lines.join("\n");
|
|
28616
28677
|
}
|
|
28678
|
+
function buildSelectorAndTextLines(info) {
|
|
28679
|
+
return [formatSelectorTagLine(info), formatTextLine(info.textContent)];
|
|
28680
|
+
}
|
|
28617
28681
|
function buildAgentContextPreview(selection, activeCompPath) {
|
|
28618
28682
|
return [
|
|
28619
28683
|
`Composition: ${selection.compositionPath}`,
|
|
28620
28684
|
`Source: ${selection.sourceFile || activeCompPath || "index.html"}`,
|
|
28621
|
-
|
|
28622
|
-
selection.textContent ? `Text: ${selection.textContent}` : ""
|
|
28685
|
+
...buildSelectorAndTextLines(selection)
|
|
28623
28686
|
].filter(Boolean).join("\n");
|
|
28624
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
|
+
}
|
|
28625
28721
|
|
|
28626
28722
|
// src/components/editor/domEditOverlayBasis.ts
|
|
28627
28723
|
function readPositiveDimension(value) {
|
|
@@ -39570,14 +39666,7 @@ function useElementLifecycleOps({
|
|
|
39570
39666
|
},
|
|
39571
39667
|
[commitDomEditPatchBatches, onReorderShadow]
|
|
39572
39668
|
);
|
|
39573
|
-
const handleDomEditElementDelete = useCallback54(
|
|
39574
|
-
async (selection) => {
|
|
39575
|
-
await handleDomEditElementsDelete([selection]);
|
|
39576
|
-
},
|
|
39577
|
-
[handleDomEditElementsDelete]
|
|
39578
|
-
);
|
|
39579
39669
|
return {
|
|
39580
|
-
handleDomEditElementDelete,
|
|
39581
39670
|
handleDomEditElementsDelete,
|
|
39582
39671
|
handleDomZIndexReorderCommit
|
|
39583
39672
|
};
|
|
@@ -54128,6 +54217,10 @@ function withLane2(automation, lane) {
|
|
|
54128
54217
|
lanes: [...automation.lanes.filter((l) => l.target !== lane.target), lane]
|
|
54129
54218
|
};
|
|
54130
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
|
+
}
|
|
54131
54224
|
function automationAttrValue(automation) {
|
|
54132
54225
|
return automation.lanes.length > 0 ? serializeAutomation2(automation) : "";
|
|
54133
54226
|
}
|
|
@@ -56991,24 +57084,33 @@ function AudioFxGroup({
|
|
|
56991
57084
|
}
|
|
56992
57085
|
|
|
56993
57086
|
// src/components/editor/useVolumeAutomation.ts
|
|
56994
|
-
import {
|
|
56995
|
-
|
|
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) {
|
|
56996
57093
|
const automation = readPanelAutomation(
|
|
56997
57094
|
element.dataAttributes?.[HF_AUDIO_AUTOMATION_DATA_KEY2],
|
|
56998
57095
|
void 0
|
|
56999
57096
|
);
|
|
57097
|
+
const { start: elStart, duration: elDuration } = deriveElementTiming(element);
|
|
57098
|
+
const clipTimeSec = clampNumber(currentTime - elStart, 0, elDuration > 0 ? elDuration : Infinity);
|
|
57000
57099
|
const write = (next) => {
|
|
57001
57100
|
void onSetAttributeQuiet(HF_AUDIO_AUTOMATION_ATTR3, automationAttrValue(next) || null);
|
|
57002
57101
|
};
|
|
57003
57102
|
const raw = element.dataAttributes?.["volume"];
|
|
57004
57103
|
const parsed = raw ? Number(raw) : 1;
|
|
57005
57104
|
const current = Number.isFinite(parsed) ? parsed : 1;
|
|
57105
|
+
const volumeLane = automation.lanes.find((lane) => lane.target === VOLUME_TARGET2);
|
|
57006
57106
|
return {
|
|
57007
|
-
volumeAutomated:
|
|
57107
|
+
volumeAutomated: volumeLane !== void 0,
|
|
57108
|
+
automatedVolumeValue: volumeLane ? sampleAutomationLane9(volumeLane, clipTimeSec) : void 0,
|
|
57008
57109
|
// Seeded at the level the slider already shows, so automating the track does
|
|
57009
57110
|
// not change how loud it is.
|
|
57010
57111
|
onAutomateVolume: () => write(withSeededLane(automation, VOLUME_TARGET2, Number.isFinite(current) ? current : 1)),
|
|
57011
|
-
onRemoveVolumeAutomation: () => write(withoutLane(automation, VOLUME_TARGET2))
|
|
57112
|
+
onRemoveVolumeAutomation: () => write(withoutLane(automation, VOLUME_TARGET2)),
|
|
57113
|
+
onCommitVolumeAt: (v) => write(withPointAt(automation, VOLUME_TARGET2, clipTimeSec, v))
|
|
57012
57114
|
};
|
|
57013
57115
|
}
|
|
57014
57116
|
|
|
@@ -57101,7 +57203,9 @@ function FlatMediaSection({
|
|
|
57101
57203
|
onRemoveBackground,
|
|
57102
57204
|
volumeAutomated,
|
|
57103
57205
|
onAutomateVolume,
|
|
57104
|
-
onRemoveVolumeAutomation
|
|
57206
|
+
onRemoveVolumeAutomation,
|
|
57207
|
+
onCommitVolumeAt,
|
|
57208
|
+
automatedVolumeValue
|
|
57105
57209
|
}) {
|
|
57106
57210
|
const track2 = useTrackDesignInput();
|
|
57107
57211
|
const isVideo = element.tagName === "video";
|
|
@@ -57109,7 +57213,7 @@ function FlatMediaSection({
|
|
|
57109
57213
|
const isImage = element.tagName === "img";
|
|
57110
57214
|
const isVisualMedia = isVideo || isImage;
|
|
57111
57215
|
const el = element.element;
|
|
57112
|
-
const volume = parseNumericValue(element.dataAttributes.volume ?? "") ?? 1;
|
|
57216
|
+
const volume = volumeAutomated && automatedVolumeValue !== void 0 ? automatedVolumeValue : parseNumericValue(element.dataAttributes.volume ?? "") ?? 1;
|
|
57113
57217
|
const volumeFaderPosition = audioGainToFaderPosition2(volume);
|
|
57114
57218
|
const mediaStart = Number.parseFloat(
|
|
57115
57219
|
element.dataAttributes["media-start"] ?? element.dataAttributes["playback-start"] ?? "0"
|
|
@@ -57258,9 +57362,15 @@ function FlatMediaSection({
|
|
|
57258
57362
|
max: AUDIO_GAIN_FADER_MAX2,
|
|
57259
57363
|
tier: volume === 1 ? "default" : "explicitCustom",
|
|
57260
57364
|
displayValue: audioGainToText2(volume),
|
|
57261
|
-
disabled: volumeAutomated,
|
|
57262
57365
|
centerTick: true,
|
|
57263
|
-
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
|
+
}
|
|
57264
57374
|
}
|
|
57265
57375
|
) }),
|
|
57266
57376
|
/* @__PURE__ */ jsx142(
|
|
@@ -60939,7 +61049,11 @@ function PropertyPanelFlat({
|
|
|
60939
61049
|
const audioSelection = isAudioDomElement(element.element);
|
|
60940
61050
|
const showMotionEffects = gsapEffectHandlers !== null && !audioSelection;
|
|
60941
61051
|
const showMotionGroup = showMotionTiming || showMotionEffects;
|
|
60942
|
-
const volumeAutomation = useVolumeAutomation(
|
|
61052
|
+
const volumeAutomation = useVolumeAutomation(
|
|
61053
|
+
element,
|
|
61054
|
+
currentTime,
|
|
61055
|
+
onSetAttributeQuiet ?? onSetAttributeLive
|
|
61056
|
+
);
|
|
60943
61057
|
const audioGroupLabel = useMemo52(() => {
|
|
60944
61058
|
const doc = element.element?.ownerDocument;
|
|
60945
61059
|
const id = element.id;
|
|
@@ -62782,7 +62896,7 @@ var FileTree = memo34(function FileTree2({
|
|
|
62782
62896
|
});
|
|
62783
62897
|
|
|
62784
62898
|
// src/App.tsx
|
|
62785
|
-
import { useState as
|
|
62899
|
+
import { useState as useState157, useCallback as useCallback176, useRef as useRef175, useMemo as useMemo78, useLayoutEffect as useLayoutEffect11 } from "react";
|
|
62786
62900
|
|
|
62787
62901
|
// src/components/renders/useRenderQueue.ts
|
|
62788
62902
|
import { useState as useState95, useEffect as useEffect89, useCallback as useCallback80, useRef as useRef104, useMemo as useMemo56 } from "react";
|
|
@@ -65199,45 +65313,70 @@ function usePanelLayout(initialState2) {
|
|
|
65199
65313
|
}
|
|
65200
65314
|
|
|
65201
65315
|
// src/hooks/useFileManager.ts
|
|
65202
|
-
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";
|
|
65203
65317
|
|
|
65204
65318
|
// src/hooks/useFileTree.ts
|
|
65205
|
-
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 = [];
|
|
65206
65321
|
function useFileTree({ projectId, projectIdRef }) {
|
|
65207
|
-
const [
|
|
65208
|
-
const
|
|
65209
|
-
const
|
|
65210
|
-
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;
|
|
65211
65328
|
useEffect94(() => {
|
|
65212
|
-
if (!projectId)
|
|
65213
|
-
setFileTreeLoaded(false);
|
|
65214
|
-
return;
|
|
65215
|
-
}
|
|
65329
|
+
if (!projectId) return;
|
|
65216
65330
|
let cancelled = false;
|
|
65217
|
-
|
|
65331
|
+
setFetched({ projectId, loaded: false, fileTree: [], compositionPaths: [], projectDir: null });
|
|
65218
65332
|
fetch(buildProjectApiPath(projectId)).then((r) => r.json()).then((data) => {
|
|
65219
65333
|
if (cancelled) return;
|
|
65220
|
-
|
|
65221
|
-
|
|
65222
|
-
|
|
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
|
+
});
|
|
65223
65341
|
void captureProjectProvenance(projectId, data.files ?? [], data.compositions ?? []);
|
|
65224
65342
|
}).catch(() => {
|
|
65225
|
-
if (!cancelled)
|
|
65226
|
-
|
|
65227
|
-
|
|
65343
|
+
if (!cancelled) {
|
|
65344
|
+
setFetched((prev) => prev?.projectId === projectId ? { ...prev, loaded: true } : prev);
|
|
65345
|
+
}
|
|
65228
65346
|
});
|
|
65229
65347
|
return () => {
|
|
65230
65348
|
cancelled = true;
|
|
65231
65349
|
};
|
|
65232
65350
|
}, [projectId]);
|
|
65351
|
+
const refreshRequestRef = useRef113(0);
|
|
65352
|
+
const refreshAbortRef = useRef113(null);
|
|
65233
65353
|
const refreshFileTree = useCallback86(async () => {
|
|
65234
65354
|
const pid = projectIdRef.current;
|
|
65235
65355
|
if (!pid) return;
|
|
65236
|
-
|
|
65237
|
-
const
|
|
65238
|
-
|
|
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
|
+
}
|
|
65239
65379
|
}, [projectIdRef]);
|
|
65240
|
-
const compositions = compositionPaths;
|
|
65241
65380
|
const assets = useMemo58(
|
|
65242
65381
|
() => fileTree.filter((f) => !f.endsWith(".html") && !f.endsWith(".md") && !f.endsWith(".json")),
|
|
65243
65382
|
[fileTree]
|
|
@@ -65253,17 +65392,16 @@ function useFileTree({ projectId, projectIdRef }) {
|
|
|
65253
65392
|
return {
|
|
65254
65393
|
projectDir,
|
|
65255
65394
|
fileTree,
|
|
65256
|
-
setFileTree,
|
|
65257
65395
|
fileTreeLoaded,
|
|
65258
65396
|
refreshFileTree,
|
|
65259
|
-
compositions,
|
|
65397
|
+
compositions: compositionPaths,
|
|
65260
65398
|
assets,
|
|
65261
65399
|
fontAssets
|
|
65262
65400
|
};
|
|
65263
65401
|
}
|
|
65264
65402
|
|
|
65265
65403
|
// src/hooks/useEditorSave.ts
|
|
65266
|
-
import { useCallback as useCallback87, useRef as
|
|
65404
|
+
import { useCallback as useCallback87, useRef as useRef114 } from "react";
|
|
65267
65405
|
var FAILURE_BURST_MS = 5e3;
|
|
65268
65406
|
function useEditorSave({
|
|
65269
65407
|
editingPathRef,
|
|
@@ -65274,13 +65412,13 @@ function useEditorSave({
|
|
|
65274
65412
|
setRefreshKey,
|
|
65275
65413
|
showToast
|
|
65276
65414
|
}) {
|
|
65277
|
-
const saveRafRef =
|
|
65278
|
-
const refreshRafRef =
|
|
65279
|
-
const lastFailureToastAtRef =
|
|
65280
|
-
const lastFailureReportRef =
|
|
65281
|
-
const pendingCandidateRef =
|
|
65282
|
-
const inFlightRef =
|
|
65283
|
-
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);
|
|
65284
65422
|
const reportFailure = useCallback87(
|
|
65285
65423
|
(path, error) => {
|
|
65286
65424
|
const now2 = Date.now();
|
|
@@ -65396,11 +65534,11 @@ function useFileManager({
|
|
|
65396
65534
|
}) {
|
|
65397
65535
|
const [editingFile, setEditingFile] = useState103(null);
|
|
65398
65536
|
const [revealSourceOffset, setRevealSourceOffset] = useState103(null);
|
|
65399
|
-
const editingPathRef =
|
|
65537
|
+
const editingPathRef = useRef115(editingFile?.path);
|
|
65400
65538
|
editingPathRef.current = editingFile?.path;
|
|
65401
|
-
const projectIdRef =
|
|
65539
|
+
const projectIdRef = useRef115(projectId);
|
|
65402
65540
|
projectIdRef.current = projectId;
|
|
65403
|
-
const importedFontAssetsRef =
|
|
65541
|
+
const importedFontAssetsRef = useRef115([]);
|
|
65404
65542
|
const fileVersionScope = useMemo59(
|
|
65405
65543
|
() => ({ projectId, versions: /* @__PURE__ */ new Map() }),
|
|
65406
65544
|
[projectId]
|
|
@@ -65415,7 +65553,6 @@ function useFileManager({
|
|
|
65415
65553
|
const {
|
|
65416
65554
|
projectDir,
|
|
65417
65555
|
fileTree,
|
|
65418
|
-
setFileTree,
|
|
65419
65556
|
fileTreeLoaded,
|
|
65420
65557
|
refreshFileTree,
|
|
65421
65558
|
compositions,
|
|
@@ -65550,8 +65687,8 @@ function useFileManager({
|
|
|
65550
65687
|
},
|
|
65551
65688
|
[fileVersions, updateEditingFileContent, writeProjectFile]
|
|
65552
65689
|
);
|
|
65553
|
-
const revealRequestIdRef =
|
|
65554
|
-
const revealAbortRef =
|
|
65690
|
+
const revealRequestIdRef = useRef115(0);
|
|
65691
|
+
const revealAbortRef = useRef115(null);
|
|
65555
65692
|
const handleFileSelect = useCallback88(
|
|
65556
65693
|
(path) => {
|
|
65557
65694
|
const pid = projectIdRef.current;
|
|
@@ -65799,7 +65936,6 @@ function useFileManager({
|
|
|
65799
65936
|
projectDir,
|
|
65800
65937
|
fileTree,
|
|
65801
65938
|
fileTreeLoaded,
|
|
65802
|
-
setFileTree,
|
|
65803
65939
|
// Refs
|
|
65804
65940
|
editingPathRef,
|
|
65805
65941
|
projectIdRef,
|
|
@@ -65839,7 +65975,7 @@ function useFileManager({
|
|
|
65839
65975
|
}
|
|
65840
65976
|
|
|
65841
65977
|
// src/hooks/usePreviewPersistence.ts
|
|
65842
|
-
import { useCallback as useCallback89, useRef as
|
|
65978
|
+
import { useCallback as useCallback89, useRef as useRef116, useState as useState104 } from "react";
|
|
65843
65979
|
|
|
65844
65980
|
// src/utils/gsapUndoRestore.ts
|
|
65845
65981
|
function elementIdentityKey(el) {
|
|
@@ -66075,11 +66211,11 @@ function usePreviewPersistence({
|
|
|
66075
66211
|
}) {
|
|
66076
66212
|
void _recordEdit;
|
|
66077
66213
|
const [domEditSaveQueuePaused, setDomEditSaveQueuePaused] = useState104(null);
|
|
66078
|
-
const domTextCommitVersionRef =
|
|
66079
|
-
const showToastRef =
|
|
66214
|
+
const domTextCommitVersionRef = useRef116(0);
|
|
66215
|
+
const showToastRef = useRef116(showToast);
|
|
66080
66216
|
showToastRef.current = showToast;
|
|
66081
|
-
const domEditSaveQueueRef =
|
|
66082
|
-
const applyStudioManualEditsToPreviewRef =
|
|
66217
|
+
const domEditSaveQueueRef = useRef116(null);
|
|
66218
|
+
const applyStudioManualEditsToPreviewRef = useRef116(async () => {
|
|
66083
66219
|
});
|
|
66084
66220
|
if (!domEditSaveQueueRef.current) {
|
|
66085
66221
|
domEditSaveQueueRef.current = createDomEditSaveQueue({
|
|
@@ -66172,10 +66308,10 @@ function usePreviewPersistence({
|
|
|
66172
66308
|
}
|
|
66173
66309
|
|
|
66174
66310
|
// src/hooks/usePreviewDocumentVersion.ts
|
|
66175
|
-
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";
|
|
66176
66312
|
function usePreviewDocumentVersion() {
|
|
66177
66313
|
const [previewDocumentVersion, setPreviewDocumentVersion] = useState105(0);
|
|
66178
|
-
const refreshTimersRef =
|
|
66314
|
+
const refreshTimersRef = useRef117([]);
|
|
66179
66315
|
const refresh = useCallback90(() => {
|
|
66180
66316
|
for (const id of refreshTimersRef.current) clearTimeout(id);
|
|
66181
66317
|
refreshTimersRef.current = [];
|
|
@@ -66195,10 +66331,10 @@ function usePreviewDocumentVersion() {
|
|
|
66195
66331
|
}
|
|
66196
66332
|
|
|
66197
66333
|
// src/hooks/useTimelineEditing.ts
|
|
66198
|
-
import { useCallback as useCallback100, useRef as
|
|
66334
|
+
import { useCallback as useCallback100, useRef as useRef121 } from "react";
|
|
66199
66335
|
|
|
66200
66336
|
// src/hooks/useRazorSplit.ts
|
|
66201
|
-
import { useCallback as useCallback91, useRef as
|
|
66337
|
+
import { useCallback as useCallback91, useRef as useRef118 } from "react";
|
|
66202
66338
|
|
|
66203
66339
|
// src/utils/razorSplitTransaction.ts
|
|
66204
66340
|
function targetIdentity(path, target) {
|
|
@@ -66216,7 +66352,10 @@ function buildCutTarget(element, target, splitTime) {
|
|
|
66216
66352
|
elementDuration: element.duration,
|
|
66217
66353
|
...element.playbackStart != null ? { playbackStart: element.playbackStart } : {},
|
|
66218
66354
|
...element.playbackRate != null ? { playbackRate: element.playbackRate } : {},
|
|
66219
|
-
...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)
|
|
66220
66359
|
};
|
|
66221
66360
|
}
|
|
66222
66361
|
function buildAtomicCutIntents(elements, splitTime, activeCompPath) {
|
|
@@ -66330,7 +66469,7 @@ function useRazorSplit({
|
|
|
66330
66469
|
forceReloadSdkSession,
|
|
66331
66470
|
isRecordingRef
|
|
66332
66471
|
}) {
|
|
66333
|
-
const projectIdRef =
|
|
66472
|
+
const projectIdRef = useRef118(projectId);
|
|
66334
66473
|
projectIdRef.current = projectId;
|
|
66335
66474
|
const synchronize = useCallback91(() => {
|
|
66336
66475
|
let failure;
|
|
@@ -66531,22 +66670,25 @@ function useTimelineAssetDropOps({
|
|
|
66531
66670
|
(te) => (te.sourceFile || activeCompPath || "index.html") === resolvedTargetPath
|
|
66532
66671
|
);
|
|
66533
66672
|
const newElementZIndex = Math.max(1, relevantElements.length + 1);
|
|
66534
|
-
const patchedContent =
|
|
66535
|
-
|
|
66536
|
-
|
|
66537
|
-
|
|
66538
|
-
|
|
66539
|
-
|
|
66540
|
-
|
|
66541
|
-
|
|
66542
|
-
|
|
66543
|
-
|
|
66544
|
-
|
|
66545
|
-
|
|
66546
|
-
|
|
66547
|
-
|
|
66548
|
-
|
|
66549
|
-
|
|
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
|
|
66550
66692
|
);
|
|
66551
66693
|
await saveProjectFilesWithHistory({
|
|
66552
66694
|
projectId: pid,
|
|
@@ -66887,7 +67029,16 @@ function useSetElementAttribute({
|
|
|
66887
67029
|
}
|
|
66888
67030
|
|
|
66889
67031
|
// src/hooks/useTimelineDeleteOps.ts
|
|
66890
|
-
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;
|
|
66891
67042
|
function useTimelineDeleteOps({
|
|
66892
67043
|
projectIdRef,
|
|
66893
67044
|
activeCompPath,
|
|
@@ -66898,8 +67049,10 @@ function useTimelineDeleteOps({
|
|
|
66898
67049
|
reloadPreview,
|
|
66899
67050
|
isRecordingRef,
|
|
66900
67051
|
forceReloadSdkSession,
|
|
66901
|
-
previewIframeRef
|
|
67052
|
+
previewIframeRef,
|
|
67053
|
+
handleTimelineGroupMove
|
|
66902
67054
|
}) {
|
|
67055
|
+
const rippleNoticeShownRef = useRef119(false);
|
|
66903
67056
|
const handleTimelineElementsDelete = useCallback95(
|
|
66904
67057
|
// fallow-ignore-next-line complexity
|
|
66905
67058
|
async (selection) => {
|
|
@@ -66947,11 +67100,14 @@ function useTimelineDeleteOps({
|
|
|
66947
67100
|
if (deleteContentEnd > 0 && targetPath === (activeCompPath || "index.html")) {
|
|
66948
67101
|
usePlayerStore.getState().setDuration(deleteContentEnd);
|
|
66949
67102
|
}
|
|
67103
|
+
const coalesceKey = `main-track-ripple-delete:${deleteGestureSeq++}`;
|
|
67104
|
+
const deleteHistoryLabel = "Delete timeline clip";
|
|
66950
67105
|
try {
|
|
66951
67106
|
await saveProjectFilesWithHistory({
|
|
66952
67107
|
projectId: pid,
|
|
66953
|
-
label:
|
|
67108
|
+
label: deleteHistoryLabel,
|
|
66954
67109
|
kind: "timeline",
|
|
67110
|
+
coalesceKey,
|
|
66955
67111
|
files: { [targetPath]: patchedContent },
|
|
66956
67112
|
readFile: async () => originalContent,
|
|
66957
67113
|
// remove-element already wrote the removal, so disk holds THAT — not the
|
|
@@ -66965,15 +67121,53 @@ function useTimelineDeleteOps({
|
|
|
66965
67121
|
throw error;
|
|
66966
67122
|
}
|
|
66967
67123
|
const deletedKeys = new Set(sameFile.map((te) => te.key ?? te.id));
|
|
66968
|
-
|
|
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));
|
|
66969
67154
|
usePlayerStore.getState().setSelectedElementId(null);
|
|
66970
67155
|
usePlayerStore.getState().setSelectedElementIds(/* @__PURE__ */ new Set());
|
|
66971
67156
|
forceReloadSdkSession?.();
|
|
66972
67157
|
reloadPreview();
|
|
66973
|
-
|
|
66974
|
-
|
|
66975
|
-
|
|
66976
|
-
|
|
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
|
+
}
|
|
66977
67171
|
} catch (error) {
|
|
66978
67172
|
const message = error instanceof Error ? error.message : "Failed to delete timeline clip";
|
|
66979
67173
|
showToast(message);
|
|
@@ -66989,7 +67183,8 @@ function useTimelineDeleteOps({
|
|
|
66989
67183
|
reloadPreview,
|
|
66990
67184
|
isRecordingRef,
|
|
66991
67185
|
forceReloadSdkSession,
|
|
66992
|
-
previewIframeRef
|
|
67186
|
+
previewIframeRef,
|
|
67187
|
+
handleTimelineGroupMove
|
|
66993
67188
|
]
|
|
66994
67189
|
);
|
|
66995
67190
|
const handleTimelineElementDelete = useCallback95(
|
|
@@ -67593,21 +67788,22 @@ function useTimelineGroupEditing({
|
|
|
67593
67788
|
syncPreviewContentDuration(previewIframeRef.current);
|
|
67594
67789
|
const coalesceKey = options?.coalesceKey ?? moveCoalesceKey(changes);
|
|
67595
67790
|
const coalesceMs = options?.coalesceMs;
|
|
67596
|
-
|
|
67791
|
+
const label = options?.label ?? "Move timeline clips";
|
|
67792
|
+
return enqueueGroupOperation(label, async (projectId) => {
|
|
67597
67793
|
await options?.beforeTiming;
|
|
67598
67794
|
const handledBySdk = await trySdkBatchPersist({
|
|
67599
67795
|
changes,
|
|
67600
67796
|
sdkChanges: toSdkTimingChanges(changes, (change) => ({ start: change.start })),
|
|
67601
67797
|
eligible: changes.every((change) => change.track == null),
|
|
67602
67798
|
needsExtension,
|
|
67603
|
-
label
|
|
67799
|
+
label,
|
|
67604
67800
|
coalesceKey,
|
|
67605
67801
|
coalesceMs
|
|
67606
67802
|
});
|
|
67607
67803
|
if (!handledBySdk) {
|
|
67608
67804
|
await persistServerBatch(
|
|
67609
67805
|
projectId,
|
|
67610
|
-
|
|
67806
|
+
label,
|
|
67611
67807
|
changes.map((change) => ({
|
|
67612
67808
|
element: change.element,
|
|
67613
67809
|
buildPatches: (original, target) => buildTimelineMoveTimingPatch(
|
|
@@ -67628,7 +67824,7 @@ function useTimelineGroupEditing({
|
|
|
67628
67824
|
projectId,
|
|
67629
67825
|
iframe: previewIframeRef.current,
|
|
67630
67826
|
reloadPreview,
|
|
67631
|
-
label
|
|
67827
|
+
label,
|
|
67632
67828
|
errorLabel: "Failed to shift GSAP positions",
|
|
67633
67829
|
coalesceKey,
|
|
67634
67830
|
recordEdit,
|
|
@@ -67647,7 +67843,11 @@ function useTimelineGroupEditing({
|
|
|
67647
67843
|
}
|
|
67648
67844
|
}).catch((error) => {
|
|
67649
67845
|
rollbackDuration();
|
|
67650
|
-
|
|
67846
|
+
if (options?.suppressFailureToast) {
|
|
67847
|
+
console.error("[Timeline] group move failed to persist", error);
|
|
67848
|
+
} else {
|
|
67849
|
+
showToast(getStudioSaveErrorMessage(error), "error");
|
|
67850
|
+
}
|
|
67651
67851
|
throw error;
|
|
67652
67852
|
});
|
|
67653
67853
|
},
|
|
@@ -67765,10 +67965,10 @@ function useTimelineGroupEditing({
|
|
|
67765
67965
|
}
|
|
67766
67966
|
|
|
67767
67967
|
// src/hooks/useBlockedTimelineEditToast.ts
|
|
67768
|
-
import { useCallback as useCallback99, useRef as
|
|
67968
|
+
import { useCallback as useCallback99, useRef as useRef120 } from "react";
|
|
67769
67969
|
var BLOCKED_TOAST_INTERVAL_MS = 1500;
|
|
67770
67970
|
function useBlockedTimelineEditToast(showToast) {
|
|
67771
|
-
const lastAtRef =
|
|
67971
|
+
const lastAtRef = useRef120(0);
|
|
67772
67972
|
return useCallback99(
|
|
67773
67973
|
(_element) => {
|
|
67774
67974
|
const now2 = Date.now();
|
|
@@ -67800,9 +68000,9 @@ function useTimelineEditing({
|
|
|
67800
68000
|
invalidateGsapCache,
|
|
67801
68001
|
handleDomZIndexReorderCommitRef
|
|
67802
68002
|
}) {
|
|
67803
|
-
const projectIdRef =
|
|
68003
|
+
const projectIdRef = useRef121(projectId);
|
|
67804
68004
|
projectIdRef.current = projectId;
|
|
67805
|
-
const editQueueRef =
|
|
68005
|
+
const editQueueRef = useRef121(Promise.resolve());
|
|
67806
68006
|
const enqueueEdit = useCallback100(
|
|
67807
68007
|
(element, label, buildPatches, coalesceKey) => {
|
|
67808
68008
|
if (isRecordingRef?.current) {
|
|
@@ -68104,7 +68304,8 @@ function useTimelineEditing({
|
|
|
68104
68304
|
reloadPreview,
|
|
68105
68305
|
isRecordingRef,
|
|
68106
68306
|
forceReloadSdkSession,
|
|
68107
|
-
previewIframeRef
|
|
68307
|
+
previewIframeRef,
|
|
68308
|
+
handleTimelineGroupMove: groupEditing.handleTimelineGroupMove
|
|
68108
68309
|
});
|
|
68109
68310
|
const { handleTimelineAssetDrop, handleTimelineFileDrop, handleTimelineCompositionDrop } = useTimelineAssetDropOps({
|
|
68110
68311
|
projectIdRef,
|
|
@@ -68172,7 +68373,7 @@ function persistTimelineMoveEditsAtomically(edits, coalesceKey, operation, deps,
|
|
|
68172
68373
|
import { useCallback as useCallback123 } from "react";
|
|
68173
68374
|
|
|
68174
68375
|
// src/hooks/useAskAgentModal.ts
|
|
68175
|
-
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";
|
|
68176
68377
|
function useAskAgentModal({
|
|
68177
68378
|
activeCompPath,
|
|
68178
68379
|
projectDir,
|
|
@@ -68188,7 +68389,7 @@ function useAskAgentModal({
|
|
|
68188
68389
|
);
|
|
68189
68390
|
const [copiedAgentPrompt, setCopiedAgentPrompt] = useState106(false);
|
|
68190
68391
|
const [agentModalOpen, setAgentModalOpen] = useState106(false);
|
|
68191
|
-
const copiedAgentTimerRef =
|
|
68392
|
+
const copiedAgentTimerRef = useRef122(null);
|
|
68192
68393
|
const preloadAgentPromptSnippet = useCallback101(
|
|
68193
68394
|
async (selection) => {
|
|
68194
68395
|
const pid = projectIdRef.current;
|
|
@@ -68283,7 +68484,7 @@ function useAskAgentModal({
|
|
|
68283
68484
|
}
|
|
68284
68485
|
|
|
68285
68486
|
// src/hooks/useDomSelection.ts
|
|
68286
|
-
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";
|
|
68287
68488
|
|
|
68288
68489
|
// src/utils/domEditHelpers.ts
|
|
68289
68490
|
function domEditSelectionsTargetSame(a, b) {
|
|
@@ -68510,14 +68711,14 @@ function useDomSelection({
|
|
|
68510
68711
|
const [domEditGroupSelections, setDomEditGroupSelections] = useState107([]);
|
|
68511
68712
|
const [domEditHoverSelection, setDomEditHoverSelection] = useState107(null);
|
|
68512
68713
|
const [activeGroupElement, setActiveGroupElementState] = useState107(null);
|
|
68513
|
-
const rightPanelTabRef =
|
|
68714
|
+
const rightPanelTabRef = useRef123(rightPanelTab);
|
|
68514
68715
|
rightPanelTabRef.current = rightPanelTab;
|
|
68515
|
-
const domEditSelectionRef =
|
|
68516
|
-
const domEditGroupSelectionsRef =
|
|
68517
|
-
const domEditHoverSelectionRef =
|
|
68518
|
-
const activeGroupElementRef =
|
|
68519
|
-
const compositionIdentityRef =
|
|
68520
|
-
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);
|
|
68521
68722
|
domEditSelectionRef.current = domEditSelection;
|
|
68522
68723
|
domEditGroupSelectionsRef.current = domEditGroupSelections;
|
|
68523
68724
|
domEditHoverSelectionRef.current = domEditHoverSelection;
|
|
@@ -68712,7 +68913,7 @@ function useDomSelection({
|
|
|
68712
68913
|
},
|
|
68713
68914
|
[applyDomSelection, buildDomSelectionForTimelineElement]
|
|
68714
68915
|
);
|
|
68715
|
-
const refreshDomEditGroupSelectionsFromPreviewRef =
|
|
68916
|
+
const refreshDomEditGroupSelectionsFromPreviewRef = useRef123(async () => {
|
|
68716
68917
|
});
|
|
68717
68918
|
const refreshDomEditSelectionFromPreview = useCallback102(
|
|
68718
68919
|
// fallow-ignore-next-line complexity
|
|
@@ -68870,7 +69071,7 @@ function useDomSelection({
|
|
|
68870
69071
|
}
|
|
68871
69072
|
|
|
68872
69073
|
// src/hooks/usePreviewInteraction.ts
|
|
68873
|
-
import { useCallback as useCallback103, useRef as
|
|
69074
|
+
import { useCallback as useCallback103, useRef as useRef124 } from "react";
|
|
68874
69075
|
var CYCLE_RADIUS_PX = 6;
|
|
68875
69076
|
var CYCLE_WINDOW_MS = 600;
|
|
68876
69077
|
var DOUBLE_CLICK_MS = 400;
|
|
@@ -68887,8 +69088,8 @@ function usePreviewInteraction({
|
|
|
68887
69088
|
setActiveGroupElement,
|
|
68888
69089
|
onClickToSource
|
|
68889
69090
|
}) {
|
|
68890
|
-
const cycleRef =
|
|
68891
|
-
const lastDownRef =
|
|
69091
|
+
const cycleRef = useRef124(null);
|
|
69092
|
+
const lastDownRef = useRef124(null);
|
|
68892
69093
|
const pausePreviewPlayback = useCallback103(() => {
|
|
68893
69094
|
const pausedTime = pauseStudioPreviewPlayback(previewIframeRef.current);
|
|
68894
69095
|
const playerStore = usePlayerStore.getState();
|
|
@@ -69046,7 +69247,7 @@ function usePreviewInteraction({
|
|
|
69046
69247
|
}
|
|
69047
69248
|
|
|
69048
69249
|
// src/hooks/useDomEditCommits.ts
|
|
69049
|
-
import { useCallback as useCallback108, useRef as
|
|
69250
|
+
import { useCallback as useCallback108, useRef as useRef127 } from "react";
|
|
69050
69251
|
import { findUnsafeDomPatchValues as findUnsafeDomPatchValues2 } from "@hyperframes/core/studio-api/finite-mutation";
|
|
69051
69252
|
|
|
69052
69253
|
// src/utils/studioFontHelpers.ts
|
|
@@ -69207,7 +69408,7 @@ function useDomEditPositionPatchCommit({
|
|
|
69207
69408
|
}
|
|
69208
69409
|
|
|
69209
69410
|
// src/hooks/useDomEditTextCommits.ts
|
|
69210
|
-
import { useCallback as useCallback106, useRef as
|
|
69411
|
+
import { useCallback as useCallback106, useRef as useRef126 } from "react";
|
|
69211
69412
|
|
|
69212
69413
|
// src/hooks/domEditTextFieldCommitOps.ts
|
|
69213
69414
|
function hasSameKeysInSamePositions(originalFields, nextFields) {
|
|
@@ -69262,7 +69463,7 @@ function planDomTextCommit(originalTextFields, nextTextFields, plainTextContent)
|
|
|
69262
69463
|
}
|
|
69263
69464
|
|
|
69264
69465
|
// src/hooks/useDomEditAttributeCommits.ts
|
|
69265
|
-
import { useCallback as useCallback105, useRef as
|
|
69466
|
+
import { useCallback as useCallback105, useRef as useRef125 } from "react";
|
|
69266
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";
|
|
69267
69468
|
function resolveFullAttrName(attr, prefixData) {
|
|
69268
69469
|
return prefixData && !attr.startsWith("data-") ? `data-${attr}` : attr;
|
|
@@ -69302,7 +69503,7 @@ function useDomEditAttributeCommits({
|
|
|
69302
69503
|
refreshDomEditSelectionFromPreview,
|
|
69303
69504
|
persistDomEditOperations
|
|
69304
69505
|
}) {
|
|
69305
|
-
const domAttributeCommitVersionRef =
|
|
69506
|
+
const domAttributeCommitVersionRef = useRef125(/* @__PURE__ */ new Map());
|
|
69306
69507
|
const commitDataAttribute = useCallback105(
|
|
69307
69508
|
async (attr, value, options) => {
|
|
69308
69509
|
if (!domEditSelection) return;
|
|
@@ -69584,8 +69785,8 @@ function useDomEditTextCommits({
|
|
|
69584
69785
|
persistDomEditOperations,
|
|
69585
69786
|
resolveImportedFontAsset
|
|
69586
69787
|
}) {
|
|
69587
|
-
const domTextCommitVersionRef =
|
|
69588
|
-
const domStyleCommitVersionRef =
|
|
69788
|
+
const domTextCommitVersionRef = useRef126(/* @__PURE__ */ new Map());
|
|
69789
|
+
const domStyleCommitVersionRef = useRef126(/* @__PURE__ */ new Map());
|
|
69589
69790
|
const {
|
|
69590
69791
|
handleDomAttributeCommit,
|
|
69591
69792
|
handleDomAttributeLiveCommit,
|
|
@@ -70496,7 +70697,7 @@ function useDomEditCommits({
|
|
|
70496
70697
|
},
|
|
70497
70698
|
[fileTree, projectId, importedFontAssetsRef]
|
|
70498
70699
|
);
|
|
70499
|
-
const reportedUnresolvableRef =
|
|
70700
|
+
const reportedUnresolvableRef = useRef127(/* @__PURE__ */ new Set());
|
|
70500
70701
|
const performPersistDomEditOperations = useCallback108(
|
|
70501
70702
|
// fallow-ignore-next-line complexity
|
|
70502
70703
|
async (selection, operations, options, expectedProjectId) => {
|
|
@@ -70741,7 +70942,7 @@ function useDomEditCommits({
|
|
|
70741
70942
|
showToast,
|
|
70742
70943
|
commitPositionPatchToHtml
|
|
70743
70944
|
});
|
|
70744
|
-
const {
|
|
70945
|
+
const { handleDomEditElementsDelete, handleDomZIndexReorderCommit } = useElementLifecycleOps({
|
|
70745
70946
|
activeCompPath,
|
|
70746
70947
|
showToast,
|
|
70747
70948
|
writeProjectFile,
|
|
@@ -70774,7 +70975,6 @@ function useDomEditCommits({
|
|
|
70774
70975
|
handleDomBoxSizeCommit,
|
|
70775
70976
|
handleDomRotationCommit,
|
|
70776
70977
|
handleDomManualEditsReset,
|
|
70777
|
-
handleDomEditElementDelete,
|
|
70778
70978
|
handleDomEditElementsDelete,
|
|
70779
70979
|
handleDomZIndexReorderCommit
|
|
70780
70980
|
};
|
|
@@ -70782,13 +70982,21 @@ function useDomEditCommits({
|
|
|
70782
70982
|
|
|
70783
70983
|
// src/hooks/useGroupCommits.ts
|
|
70784
70984
|
import { useCallback as useCallback109 } from "react";
|
|
70785
|
-
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) {
|
|
70786
70993
|
const boxes = members.map((m) => ({
|
|
70787
70994
|
target: buildDomEditPatchTarget(m),
|
|
70788
70995
|
left: m.element.offsetLeft,
|
|
70789
70996
|
top: m.element.offsetTop,
|
|
70790
70997
|
right: m.element.offsetLeft + m.element.offsetWidth,
|
|
70791
|
-
bottom: m.element.offsetTop + m.element.offsetHeight
|
|
70998
|
+
bottom: m.element.offsetTop + m.element.offsetHeight,
|
|
70999
|
+
track: resolveAuthoredTrack(m, timelineElements)
|
|
70792
71000
|
}));
|
|
70793
71001
|
const left = Math.min(...boxes.map((b) => b.left));
|
|
70794
71002
|
const top = Math.min(...boxes.map((b) => b.top));
|
|
@@ -70797,9 +71005,29 @@ function computeGroupGeometry(members) {
|
|
|
70797
71005
|
return {
|
|
70798
71006
|
bbox: { left, top, width, height },
|
|
70799
71007
|
targets: boxes.map((b) => b.target),
|
|
70800
|
-
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
|
+
}))
|
|
70801
71014
|
};
|
|
70802
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
|
+
}
|
|
70803
71031
|
async function commitStructuralMutation(pid, targetPath, route, body, label, deps) {
|
|
70804
71032
|
const originalContent = await readProjectFileContent(pid, targetPath);
|
|
70805
71033
|
const mutateResponse = await fetch(
|
|
@@ -70831,7 +71059,7 @@ async function commitStructuralMutation(pid, targetPath, route, body, label, dep
|
|
|
70831
71059
|
return mutateData;
|
|
70832
71060
|
}
|
|
70833
71061
|
function useGroupCommits(params) {
|
|
70834
|
-
const { activeCompPath, showToast, projectIdRef } = params;
|
|
71062
|
+
const { activeCompPath, showToast, projectIdRef, timelineElements } = params;
|
|
70835
71063
|
const groupSelection = useCallback109(
|
|
70836
71064
|
async (members) => {
|
|
70837
71065
|
const pid = projectIdRef.current;
|
|
@@ -70843,7 +71071,7 @@ function useGroupCommits(params) {
|
|
|
70843
71071
|
}
|
|
70844
71072
|
const doc = members[0].element.ownerDocument;
|
|
70845
71073
|
const groupId = `Group ${doc.querySelectorAll("[data-hf-group]").length + 1}`;
|
|
70846
|
-
const { bbox, targets, rebases } = computeGroupGeometry(members);
|
|
71074
|
+
const { bbox, targets, rebases } = computeGroupGeometry(members, timelineElements);
|
|
70847
71075
|
try {
|
|
70848
71076
|
const data = await commitStructuralMutation(
|
|
70849
71077
|
pid,
|
|
@@ -70859,19 +71087,20 @@ function useGroupCommits(params) {
|
|
|
70859
71087
|
return null;
|
|
70860
71088
|
}
|
|
70861
71089
|
},
|
|
70862
|
-
[activeCompPath, projectIdRef, showToast, params]
|
|
71090
|
+
[activeCompPath, projectIdRef, showToast, params, timelineElements]
|
|
70863
71091
|
);
|
|
70864
71092
|
const ungroupSelection = useCallback109(
|
|
70865
71093
|
async (group) => {
|
|
70866
71094
|
const pid = projectIdRef.current;
|
|
70867
71095
|
if (!pid) return;
|
|
70868
71096
|
const targetPath = group.sourceFile || activeCompPath || "index.html";
|
|
71097
|
+
const childTracks = resolveGroupChildTracks(group, timelineElements);
|
|
70869
71098
|
try {
|
|
70870
71099
|
await commitStructuralMutation(
|
|
70871
71100
|
pid,
|
|
70872
71101
|
targetPath,
|
|
70873
71102
|
"unwrap-elements",
|
|
70874
|
-
{ target: buildDomEditPatchTarget(group) },
|
|
71103
|
+
{ target: buildDomEditPatchTarget(group), childTracks },
|
|
70875
71104
|
"Ungroup elements",
|
|
70876
71105
|
params
|
|
70877
71106
|
);
|
|
@@ -70879,13 +71108,13 @@ function useGroupCommits(params) {
|
|
|
70879
71108
|
showToast(error instanceof Error ? error.message : "Failed to ungroup elements", "error");
|
|
70880
71109
|
}
|
|
70881
71110
|
},
|
|
70882
|
-
[activeCompPath, projectIdRef, showToast, params]
|
|
71111
|
+
[activeCompPath, projectIdRef, showToast, params, timelineElements]
|
|
70883
71112
|
);
|
|
70884
71113
|
return { groupSelection, ungroupSelection };
|
|
70885
71114
|
}
|
|
70886
71115
|
|
|
70887
71116
|
// src/hooks/useGsapScriptCommits.ts
|
|
70888
|
-
import { useCallback as useCallback115, useMemo as useMemo60, useRef as
|
|
71117
|
+
import { useCallback as useCallback115, useMemo as useMemo60, useRef as useRef129 } from "react";
|
|
70889
71118
|
import { findUnsafeMutationValues } from "@hyperframes/core/studio-api/finite-mutation";
|
|
70890
71119
|
|
|
70891
71120
|
// src/hooks/gsapRuntimePatch.ts
|
|
@@ -71680,7 +71909,7 @@ function useGsapKeyframeOps({
|
|
|
71680
71909
|
}
|
|
71681
71910
|
|
|
71682
71911
|
// src/hooks/useGsapPropertyDebounce.ts
|
|
71683
|
-
import { useCallback as useCallback113, useEffect as useEffect99, useRef as
|
|
71912
|
+
import { useCallback as useCallback113, useEffect as useEffect99, useRef as useRef128 } from "react";
|
|
71684
71913
|
import { parseGsapScriptAcorn } from "@hyperframes/core/gsap-parser-acorn";
|
|
71685
71914
|
var DEBOUNCE_MS = 150;
|
|
71686
71915
|
function mergeTweenProperties(sdkSession, animationId, edited, kind) {
|
|
@@ -71696,9 +71925,9 @@ function mergeTweenProperties(sdkSession, animationId, edited, kind) {
|
|
|
71696
71925
|
}
|
|
71697
71926
|
}
|
|
71698
71927
|
function useGsapPropertyDebounce(commitMutationSafely, sdk) {
|
|
71699
|
-
const pendingPropertyEditRef =
|
|
71700
|
-
const debounceTimerRef =
|
|
71701
|
-
const sdkRef =
|
|
71928
|
+
const pendingPropertyEditRef = useRef128(null);
|
|
71929
|
+
const debounceTimerRef = useRef128(null);
|
|
71930
|
+
const sdkRef = useRef128(sdk);
|
|
71702
71931
|
sdkRef.current = sdk;
|
|
71703
71932
|
const flushPendingPropertyEdit = useCallback113(async () => {
|
|
71704
71933
|
const pending2 = pendingPropertyEditRef.current;
|
|
@@ -72129,9 +72358,9 @@ function instantPatchesFor(options) {
|
|
|
72129
72358
|
}
|
|
72130
72359
|
function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef, editHistory, reloadPreview, onCacheInvalidate, onFileContentChanged, showToast, sdkSession, publishSdkSession, writeProjectFile, forceReloadSdkSession }) {
|
|
72131
72360
|
const activeProjectId = projectIdRef.current;
|
|
72132
|
-
const activeCompPathRef =
|
|
72361
|
+
const activeCompPathRef = useRef129(activeCompPath);
|
|
72133
72362
|
activeCompPathRef.current = activeCompPath;
|
|
72134
|
-
const serializerRef =
|
|
72363
|
+
const serializerRef = useRef129(createKeyedSerializer());
|
|
72135
72364
|
const recordMutationEdit = useCallback115(async (targetPath, result, options) => {
|
|
72136
72365
|
if (result.before == null || result.after == null) return;
|
|
72137
72366
|
await editHistory.recordEdit({
|
|
@@ -72312,10 +72541,10 @@ function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef,
|
|
|
72312
72541
|
}
|
|
72313
72542
|
|
|
72314
72543
|
// src/hooks/useDomEditWiring.ts
|
|
72315
|
-
import { useCallback as useCallback119, useEffect as useEffect101, useRef as
|
|
72544
|
+
import { useCallback as useCallback119, useEffect as useEffect101, useRef as useRef132 } from "react";
|
|
72316
72545
|
|
|
72317
72546
|
// src/hooks/useDomEditPreviewSync.ts
|
|
72318
|
-
import { useEffect as useEffect100, useRef as
|
|
72547
|
+
import { useEffect as useEffect100, useRef as useRef130 } from "react";
|
|
72319
72548
|
function useDomEditPreviewSync({
|
|
72320
72549
|
previewIframe,
|
|
72321
72550
|
activeCompPath,
|
|
@@ -72394,7 +72623,7 @@ function useDomEditPreviewSync({
|
|
|
72394
72623
|
applyStudioManualEditsToPreviewRef,
|
|
72395
72624
|
gsapCacheVersion
|
|
72396
72625
|
]);
|
|
72397
|
-
const openSourceRef =
|
|
72626
|
+
const openSourceRef = useRef130(openSourceForSelection);
|
|
72398
72627
|
openSourceRef.current = openSourceForSelection;
|
|
72399
72628
|
useEffect100(
|
|
72400
72629
|
// fallow-ignore-next-line complexity
|
|
@@ -72492,7 +72721,7 @@ function useGsapInteractionFailureTelemetry(activeCompPath, showToast) {
|
|
|
72492
72721
|
}
|
|
72493
72722
|
|
|
72494
72723
|
// src/hooks/useGsapSelectionHandlers.ts
|
|
72495
|
-
import { useCallback as useCallback118, useRef as
|
|
72724
|
+
import { useCallback as useCallback118, useRef as useRef131 } from "react";
|
|
72496
72725
|
function useGsapSelectionHandlers({
|
|
72497
72726
|
domEditSelection,
|
|
72498
72727
|
updateGsapProperty,
|
|
@@ -72516,7 +72745,7 @@ function useGsapSelectionHandlers({
|
|
|
72516
72745
|
selectedGsapAnimations,
|
|
72517
72746
|
showToast
|
|
72518
72747
|
}) {
|
|
72519
|
-
const lastSelectionRef =
|
|
72748
|
+
const lastSelectionRef = useRef131(null);
|
|
72520
72749
|
if (domEditSelection) lastSelectionRef.current = domEditSelection;
|
|
72521
72750
|
const resolveWriteSelection2 = useCallback118(
|
|
72522
72751
|
(selectionOverride) => selectionOverride === void 0 ? domEditSelection ?? lastSelectionRef.current : selectionOverride,
|
|
@@ -72860,7 +73089,7 @@ function useDomEditWiring({
|
|
|
72860
73089
|
const key2 = matchKey ? matchKey.key ?? matchKey.id : null;
|
|
72861
73090
|
if (key2 && key2 !== selectedElementId) setSelectedElementId(key2);
|
|
72862
73091
|
}, [domEditSelection?.id]);
|
|
72863
|
-
const prevRefreshKeyRef =
|
|
73092
|
+
const prevRefreshKeyRef = useRef132(refreshKey);
|
|
72864
73093
|
useEffect101(() => {
|
|
72865
73094
|
if (refreshKey !== prevRefreshKeyRef.current) {
|
|
72866
73095
|
prevRefreshKeyRef.current = refreshKey;
|
|
@@ -73961,7 +74190,7 @@ function useGsapAwareEditing({
|
|
|
73961
74190
|
}
|
|
73962
74191
|
|
|
73963
74192
|
// src/hooks/useStudioSelectionPublisher.ts
|
|
73964
|
-
import { useEffect as useEffect102, useRef as
|
|
74193
|
+
import { useEffect as useEffect102, useRef as useRef133 } from "react";
|
|
73965
74194
|
|
|
73966
74195
|
// src/utils/studioSelectionSnapshot.ts
|
|
73967
74196
|
function round34(value) {
|
|
@@ -74052,8 +74281,8 @@ function useStudioSelectionPublisher({
|
|
|
74052
74281
|
previewDocumentVersion,
|
|
74053
74282
|
refreshDomEditSelectionFromPreview
|
|
74054
74283
|
}) {
|
|
74055
|
-
const lastSelectionRefreshKeyRef =
|
|
74056
|
-
const pendingSelectionRefreshKeyRef =
|
|
74284
|
+
const lastSelectionRefreshKeyRef = useRef133(refreshKey);
|
|
74285
|
+
const pendingSelectionRefreshKeyRef = useRef133(null);
|
|
74057
74286
|
useEffect102(() => {
|
|
74058
74287
|
if (!projectId) return;
|
|
74059
74288
|
const selection = domEditSelection?.element.isConnected ? buildStudioSelectionSnapshot({
|
|
@@ -74156,6 +74385,16 @@ function useKeyframeEaseCommits({
|
|
|
74156
74385
|
function membersForDelete(selection, group, options) {
|
|
74157
74386
|
return options?.expandGroup && group.length > 0 ? group : [selection];
|
|
74158
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
|
+
}
|
|
74159
74398
|
|
|
74160
74399
|
// src/hooks/useDomEditSession.ts
|
|
74161
74400
|
function useDomEditSession({
|
|
@@ -74196,7 +74435,8 @@ function useDomEditSession({
|
|
|
74196
74435
|
getSidebarTab,
|
|
74197
74436
|
sdkSession,
|
|
74198
74437
|
publishSdkSession,
|
|
74199
|
-
forceReloadSdkSession
|
|
74438
|
+
forceReloadSdkSession,
|
|
74439
|
+
handleTimelineElementsDelete
|
|
74200
74440
|
}) {
|
|
74201
74441
|
const isMasterView = !activeCompPath || activeCompPath === "index.html";
|
|
74202
74442
|
void _setRefreshKey;
|
|
@@ -74366,9 +74606,8 @@ function useDomEditSession({
|
|
|
74366
74606
|
readProjectFile,
|
|
74367
74607
|
publishSession: publishSdkSession
|
|
74368
74608
|
}) : void 0,
|
|
74369
|
-
//
|
|
74370
|
-
//
|
|
74371
|
-
// 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.
|
|
74372
74611
|
onReorderShadow: sdkSession ? (targets) => {
|
|
74373
74612
|
let reorderSrcPromise;
|
|
74374
74613
|
const reorderSrc = activeCompPath ? () => reorderSrcPromise ??= readProjectFile(activeCompPath) : void 0;
|
|
@@ -74384,7 +74623,8 @@ function useDomEditSession({
|
|
|
74384
74623
|
projectIdRef,
|
|
74385
74624
|
reloadPreview,
|
|
74386
74625
|
clearDomSelection,
|
|
74387
|
-
forceReloadSdkSession
|
|
74626
|
+
forceReloadSdkSession,
|
|
74627
|
+
timelineElements
|
|
74388
74628
|
});
|
|
74389
74629
|
const handleDomEditElementDelete = useCallback123(
|
|
74390
74630
|
async (selection, options) => {
|
|
@@ -74393,9 +74633,21 @@ function useDomEditSession({
|
|
|
74393
74633
|
return;
|
|
74394
74634
|
}
|
|
74395
74635
|
const members = membersForDelete(selection, domEditGroupSelectionsRef.current, options);
|
|
74636
|
+
const timelineTargets = timelineElementsForDelete(members, timelineElements);
|
|
74637
|
+
if (timelineTargets) {
|
|
74638
|
+
await handleTimelineElementsDelete(timelineTargets);
|
|
74639
|
+
return;
|
|
74640
|
+
}
|
|
74396
74641
|
await handleDomEditElementsDelete(members);
|
|
74397
74642
|
},
|
|
74398
|
-
[
|
|
74643
|
+
[
|
|
74644
|
+
domEditGroupSelectionsRef,
|
|
74645
|
+
handleDomEditElementsDelete,
|
|
74646
|
+
handleTimelineElementsDelete,
|
|
74647
|
+
isRecordingRef,
|
|
74648
|
+
showToast,
|
|
74649
|
+
timelineElements
|
|
74650
|
+
]
|
|
74399
74651
|
);
|
|
74400
74652
|
const handleGroupSelection = useCallback123(() => {
|
|
74401
74653
|
const group = domEditGroupSelectionsRef.current;
|
|
@@ -74646,7 +74898,7 @@ function useSdkSelectionSync(session, domEditSelection, domEditGroupSelections)
|
|
|
74646
74898
|
import { useEffect as useEffect105 } from "react";
|
|
74647
74899
|
|
|
74648
74900
|
// src/hooks/useSdkSession.ts
|
|
74649
|
-
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";
|
|
74650
74902
|
import { openComposition as openComposition3 } from "@hyperframes/sdk";
|
|
74651
74903
|
|
|
74652
74904
|
// src/hooks/externalFileReloadBus.ts
|
|
@@ -74696,15 +74948,15 @@ function disposeSdkSession(session) {
|
|
|
74696
74948
|
}
|
|
74697
74949
|
function useSdkSession(projectId, activeCompPath) {
|
|
74698
74950
|
const [ownedSession, setOwnedSession] = useState108(null);
|
|
74699
|
-
const ownedSessionRef =
|
|
74700
|
-
const sessionOwnersRef =
|
|
74701
|
-
const generationRef =
|
|
74702
|
-
const projectIdRef =
|
|
74951
|
+
const ownedSessionRef = useRef134(null);
|
|
74952
|
+
const sessionOwnersRef = useRef134(/* @__PURE__ */ new WeakMap());
|
|
74953
|
+
const generationRef = useRef134(0);
|
|
74954
|
+
const projectIdRef = useRef134(projectId);
|
|
74703
74955
|
projectIdRef.current = projectId;
|
|
74704
|
-
const activeCompPathRef =
|
|
74956
|
+
const activeCompPathRef = useRef134(activeCompPath);
|
|
74705
74957
|
activeCompPathRef.current = activeCompPath;
|
|
74706
74958
|
const [reloadToken, setReloadToken] = useState108(0);
|
|
74707
|
-
const reloadTokenRef =
|
|
74959
|
+
const reloadTokenRef = useRef134(reloadToken);
|
|
74708
74960
|
reloadTokenRef.current = reloadToken;
|
|
74709
74961
|
useEffect104(
|
|
74710
74962
|
() => addExternalFileReloadListener((changedPath) => {
|
|
@@ -74915,7 +75167,7 @@ async function deleteExternalConflictSnapshot(projectId, filePath) {
|
|
|
74915
75167
|
}
|
|
74916
75168
|
|
|
74917
75169
|
// src/hooks/useExternalFileChangeCoordinator.ts
|
|
74918
|
-
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";
|
|
74919
75171
|
function testHotAdapter() {
|
|
74920
75172
|
const value = globalThis.__HF_STUDIO_HOT_TEST_ADAPTER__;
|
|
74921
75173
|
if (!value || typeof value !== "object") return null;
|
|
@@ -74967,13 +75219,13 @@ function useExternalFileChangeCoordinator({
|
|
|
74967
75219
|
onAcceptedPersistedFileChange
|
|
74968
75220
|
}) {
|
|
74969
75221
|
const [blocked, setBlocked] = useState109(null);
|
|
74970
|
-
const generationRef =
|
|
74971
|
-
const mountedRef =
|
|
74972
|
-
const lastEventIdentityRef =
|
|
74973
|
-
const blockedRef =
|
|
74974
|
-
const snapshotWriteTailRef =
|
|
74975
|
-
const drainingRef =
|
|
74976
|
-
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);
|
|
74977
75229
|
blockedRef.current = blocked;
|
|
74978
75230
|
useEffect106(() => {
|
|
74979
75231
|
mountedRef.current = true;
|
|
@@ -75330,7 +75582,7 @@ function useStudioExternalFileChanges({
|
|
|
75330
75582
|
}
|
|
75331
75583
|
|
|
75332
75584
|
// src/hooks/useBlockHandlers.ts
|
|
75333
|
-
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";
|
|
75334
75586
|
|
|
75335
75587
|
// src/utils/blockInstaller.ts
|
|
75336
75588
|
function getMaxZIndexFromIframe(iframe) {
|
|
@@ -75539,7 +75791,7 @@ function useBlockHandlers({
|
|
|
75539
75791
|
blockCtxDeps.showToast
|
|
75540
75792
|
]
|
|
75541
75793
|
);
|
|
75542
|
-
const installingBlockRef =
|
|
75794
|
+
const installingBlockRef = useRef136(false);
|
|
75543
75795
|
const runBlockInstall = useCallback127(
|
|
75544
75796
|
async (blockName, install) => {
|
|
75545
75797
|
if (installingBlockRef.current) {
|
|
@@ -75650,26 +75902,9 @@ function useBlockHandlers({
|
|
|
75650
75902
|
}
|
|
75651
75903
|
|
|
75652
75904
|
// src/hooks/useAppHotkeys.ts
|
|
75653
|
-
import { useCallback as useCallback128, useEffect as useEffect107, useRef as
|
|
75654
|
-
|
|
75655
|
-
|
|
75656
|
-
return iframe?.contentWindow ?? null;
|
|
75657
|
-
} catch {
|
|
75658
|
-
return null;
|
|
75659
|
-
}
|
|
75660
|
-
}
|
|
75661
|
-
function safeAddListener(t, type, h, capture = false) {
|
|
75662
|
-
try {
|
|
75663
|
-
t?.addEventListener(type, h, capture);
|
|
75664
|
-
} catch {
|
|
75665
|
-
}
|
|
75666
|
-
}
|
|
75667
|
-
function safeRemoveListener(t, type, h) {
|
|
75668
|
-
try {
|
|
75669
|
-
t?.removeEventListener(type, h);
|
|
75670
|
-
} catch {
|
|
75671
|
-
}
|
|
75672
|
-
}
|
|
75905
|
+
import { useCallback as useCallback128, useEffect as useEffect107, useRef as useRef137 } from "react";
|
|
75906
|
+
|
|
75907
|
+
// src/hooks/appHotkeysDispatch.ts
|
|
75673
75908
|
function handleUndoRedoKey(event, onUndo, onRedo) {
|
|
75674
75909
|
const key2 = event.key.toLowerCase();
|
|
75675
75910
|
if (key2 === "z" && !event.shiftKey) {
|
|
@@ -75684,18 +75919,6 @@ function handleUndoRedoKey(event, onUndo, onRedo) {
|
|
|
75684
75919
|
}
|
|
75685
75920
|
return false;
|
|
75686
75921
|
}
|
|
75687
|
-
function tryApplyBeatHistory(direction, fileState, showToast) {
|
|
75688
|
-
const ps = usePlayerStore.getState();
|
|
75689
|
-
const beatStack = direction === "undo" ? ps.beatUndo : ps.beatRedo;
|
|
75690
|
-
const beatAt = beatStack[beatStack.length - 1]?.at ?? null;
|
|
75691
|
-
if (beatAt === null) return false;
|
|
75692
|
-
const fileStack = fileState[direction];
|
|
75693
|
-
const fileAt = fileStack[fileStack.length - 1]?.createdAt ?? null;
|
|
75694
|
-
if (fileAt !== null && (direction === "undo" ? beatAt < fileAt : beatAt > fileAt)) return false;
|
|
75695
|
-
const label = direction === "undo" ? ps.undoBeatEdits() : ps.redoBeatEdits();
|
|
75696
|
-
if (label) showToast(`${direction === "undo" ? "Undid" : "Redid"} ${label}`, "info");
|
|
75697
|
-
return true;
|
|
75698
|
-
}
|
|
75699
75922
|
function dispatchModifierKey(event, key2, cb) {
|
|
75700
75923
|
if (!shouldIgnoreHistoryShortcut(event.target) && handleUndoRedoKey(
|
|
75701
75924
|
event,
|
|
@@ -75787,6 +76010,14 @@ function dispatchPlainKey(event, key2, cb) {
|
|
|
75787
76010
|
usePlayerStore.getState().setActiveTool("select");
|
|
75788
76011
|
return;
|
|
75789
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
|
+
}
|
|
75790
76021
|
if (event.key === "Escape") {
|
|
75791
76022
|
const { activeTool, selectedElementId, setActiveTool, setSelectedElementId } = usePlayerStore.getState();
|
|
75792
76023
|
if (activeTool === "razor") {
|
|
@@ -75832,6 +76063,39 @@ function dispatchPlainKey(event, key2, cb) {
|
|
|
75832
76063
|
cb.onToggleRecording();
|
|
75833
76064
|
}
|
|
75834
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
|
+
}
|
|
75835
76099
|
function useAppHotkeys({
|
|
75836
76100
|
handleTimelineElementsDelete,
|
|
75837
76101
|
handleTimelineElementSplit,
|
|
@@ -75857,7 +76121,7 @@ function useAppHotkeys({
|
|
|
75857
76121
|
activeCompPath,
|
|
75858
76122
|
forceReloadSdkSession
|
|
75859
76123
|
}) {
|
|
75860
|
-
const previewHistoryCleanupRef =
|
|
76124
|
+
const previewHistoryCleanupRef = useRef137(null);
|
|
75861
76125
|
const readHistoryFile = useCallback128(
|
|
75862
76126
|
(path) => path === STUDIO_MOTION_PATH ? readOptionalProjectFile(path) : readProjectFile(path),
|
|
75863
76127
|
[readOptionalProjectFile, readProjectFile]
|
|
@@ -75921,7 +76185,7 @@ function useAppHotkeys({
|
|
|
75921
76185
|
);
|
|
75922
76186
|
const handleUndo = useCallback128(() => applyHistory("undo"), [applyHistory]);
|
|
75923
76187
|
const handleRedo = useCallback128(() => applyHistory("redo"), [applyHistory]);
|
|
75924
|
-
const cbRef =
|
|
76188
|
+
const cbRef = useRef137(null);
|
|
75925
76189
|
cbRef.current = {
|
|
75926
76190
|
handleTimelineElementsDelete,
|
|
75927
76191
|
handleTimelineElementSplit,
|
|
@@ -76001,7 +76265,7 @@ function useAppHotkeys({
|
|
|
76001
76265
|
}
|
|
76002
76266
|
|
|
76003
76267
|
// src/hooks/useClipboard.ts
|
|
76004
|
-
import { useCallback as useCallback129, useRef as
|
|
76268
|
+
import { useCallback as useCallback129, useRef as useRef138 } from "react";
|
|
76005
76269
|
|
|
76006
76270
|
// src/utils/clipboardPayload.ts
|
|
76007
76271
|
function insertAsSibling(source, newHtml, selector, selectorIndex) {
|
|
@@ -76107,8 +76371,8 @@ function useClipboard({
|
|
|
76107
76371
|
handleDomEditElementDelete,
|
|
76108
76372
|
previewIframeRef
|
|
76109
76373
|
}) {
|
|
76110
|
-
const clipboardRef =
|
|
76111
|
-
const projectIdRef =
|
|
76374
|
+
const clipboardRef = useRef138(null);
|
|
76375
|
+
const projectIdRef = useRef138(projectId);
|
|
76112
76376
|
projectIdRef.current = projectId;
|
|
76113
76377
|
const handleCopy2 = useCallback129(() => {
|
|
76114
76378
|
const { selectedElementId, elements } = usePlayerStore.getState();
|
|
@@ -76234,7 +76498,7 @@ function useClipboard({
|
|
|
76234
76498
|
}
|
|
76235
76499
|
|
|
76236
76500
|
// src/hooks/useCaptionDetection.ts
|
|
76237
|
-
import { useEffect as useEffect108, useRef as
|
|
76501
|
+
import { useEffect as useEffect108, useRef as useRef139 } from "react";
|
|
76238
76502
|
|
|
76239
76503
|
// src/captions/types.ts
|
|
76240
76504
|
var DEFAULT_STYLE = {
|
|
@@ -76486,7 +76750,7 @@ function useCaptionDetection({
|
|
|
76486
76750
|
captionSync,
|
|
76487
76751
|
setRightCollapsed
|
|
76488
76752
|
}) {
|
|
76489
|
-
const prevCompPathRef =
|
|
76753
|
+
const prevCompPathRef = useRef139(activeCompPath);
|
|
76490
76754
|
useEffect108(() => {
|
|
76491
76755
|
if (prevCompPathRef.current !== activeCompPath) {
|
|
76492
76756
|
prevCompPathRef.current = activeCompPath;
|
|
@@ -76591,7 +76855,7 @@ import { useCallback as useCallback132 } from "react";
|
|
|
76591
76855
|
import { createElement as createElement3 } from "react";
|
|
76592
76856
|
|
|
76593
76857
|
// src/player/components/AudioWaveform.tsx
|
|
76594
|
-
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";
|
|
76595
76859
|
import { jsx as jsx169, jsxs as jsxs141 } from "react/jsx-runtime";
|
|
76596
76860
|
var BAR_WIDTH = 2;
|
|
76597
76861
|
var BAR_STEP = 3;
|
|
@@ -76648,8 +76912,8 @@ var AudioWaveform = memo36(function AudioWaveform2({
|
|
|
76648
76912
|
sessionEpoch,
|
|
76649
76913
|
priority
|
|
76650
76914
|
}) {
|
|
76651
|
-
const canvasRef =
|
|
76652
|
-
const observerRef =
|
|
76915
|
+
const canvasRef = useRef140(null);
|
|
76916
|
+
const observerRef = useRef140(null);
|
|
76653
76917
|
const cacheKey = waveformUrl ?? audioUrl;
|
|
76654
76918
|
const request = useMemo62(
|
|
76655
76919
|
() => ({
|
|
@@ -76760,7 +77024,7 @@ var AudioWaveform = memo36(function AudioWaveform2({
|
|
|
76760
77024
|
});
|
|
76761
77025
|
|
|
76762
77026
|
// src/player/components/ImageThumbnail.tsx
|
|
76763
|
-
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";
|
|
76764
77028
|
import { jsx as jsx170, jsxs as jsxs142 } from "react/jsx-runtime";
|
|
76765
77029
|
var ImageThumbnail = memo37(function ImageThumbnail2({
|
|
76766
77030
|
imageSrc,
|
|
@@ -76772,7 +77036,7 @@ var ImageThumbnail = memo37(function ImageThumbnail2({
|
|
|
76772
77036
|
rich = false
|
|
76773
77037
|
}) {
|
|
76774
77038
|
const [containerWidth, setContainerWidth] = useState111(0);
|
|
76775
|
-
const observerRef =
|
|
77039
|
+
const observerRef = useRef141(null);
|
|
76776
77040
|
const request = useMemo63(
|
|
76777
77041
|
() => ({
|
|
76778
77042
|
key: createThumbnailKey({ kind: "image", source: imageSrc, rich: Number(rich) }),
|
|
@@ -77021,10 +77285,10 @@ function useRenderClipContent({
|
|
|
77021
77285
|
}
|
|
77022
77286
|
|
|
77023
77287
|
// src/hooks/useConsoleErrorCapture.ts
|
|
77024
|
-
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";
|
|
77025
77289
|
function useConsoleErrorCapture(previewIframe) {
|
|
77026
77290
|
const [consoleErrors, setConsoleErrors] = useState112(null);
|
|
77027
|
-
const consoleErrorsRef =
|
|
77291
|
+
const consoleErrorsRef = useRef142([]);
|
|
77028
77292
|
const resetErrors = useCallback133(() => {
|
|
77029
77293
|
consoleErrorsRef.current = [];
|
|
77030
77294
|
setConsoleErrors(null);
|
|
@@ -77094,7 +77358,7 @@ function useConsoleErrorCapture(previewIframe) {
|
|
|
77094
77358
|
}
|
|
77095
77359
|
|
|
77096
77360
|
// src/hooks/useFrameCapture.ts
|
|
77097
|
-
import { useState as useState113, useCallback as useCallback134, useRef as
|
|
77361
|
+
import { useState as useState113, useCallback as useCallback134, useRef as useRef143 } from "react";
|
|
77098
77362
|
function useFrameCapture({
|
|
77099
77363
|
projectId,
|
|
77100
77364
|
activeCompPath,
|
|
@@ -77103,7 +77367,7 @@ function useFrameCapture({
|
|
|
77103
77367
|
}) {
|
|
77104
77368
|
const [captureFrameTime, setCaptureFrameTime] = useState113(0);
|
|
77105
77369
|
const [capturing, setCapturing] = useState113(false);
|
|
77106
|
-
const capturingRef =
|
|
77370
|
+
const capturingRef = useRef143(false);
|
|
77107
77371
|
useMountEffect(() => {
|
|
77108
77372
|
setCaptureFrameTime(usePlayerStore.getState().currentTime);
|
|
77109
77373
|
return liveTime.subscribe(setCaptureFrameTime);
|
|
@@ -77188,7 +77452,7 @@ function useFrameCapture({
|
|
|
77188
77452
|
}
|
|
77189
77453
|
|
|
77190
77454
|
// src/hooks/useLintModal.ts
|
|
77191
|
-
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";
|
|
77192
77456
|
function parseFinding(f) {
|
|
77193
77457
|
return {
|
|
77194
77458
|
severity: f.severity === "error" ? "error" : "warning",
|
|
@@ -77202,7 +77466,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
77202
77466
|
const [lintModal, setLintModal] = useState114(null);
|
|
77203
77467
|
const [linting, setLinting] = useState114(false);
|
|
77204
77468
|
const [backgroundFindings, setBackgroundFindings] = useState114([]);
|
|
77205
|
-
const autoLintRanRef =
|
|
77469
|
+
const autoLintRanRef = useRef144(false);
|
|
77206
77470
|
const runLint = useCallback135(
|
|
77207
77471
|
async (opts) => {
|
|
77208
77472
|
if (!projectId) return;
|
|
@@ -77229,7 +77493,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
77229
77493
|
[projectId]
|
|
77230
77494
|
);
|
|
77231
77495
|
const handleLint = useCallback135(() => runLint(), [runLint]);
|
|
77232
|
-
const prevProjectIdRef =
|
|
77496
|
+
const prevProjectIdRef = useRef144(projectId);
|
|
77233
77497
|
useEffect110(() => {
|
|
77234
77498
|
if (projectId !== prevProjectIdRef.current) {
|
|
77235
77499
|
autoLintRanRef.current = false;
|
|
@@ -77277,14 +77541,14 @@ function useLintModal(projectId, refreshKey) {
|
|
|
77277
77541
|
}
|
|
77278
77542
|
|
|
77279
77543
|
// src/hooks/useToast.ts
|
|
77280
|
-
import { useState as useState115, useCallback as useCallback136, useRef as
|
|
77544
|
+
import { useState as useState115, useCallback as useCallback136, useRef as useRef145 } from "react";
|
|
77281
77545
|
var AUTO_DISMISS_MS2 = 4e3;
|
|
77282
77546
|
var EXIT_MS2 = 160;
|
|
77283
77547
|
var MAX_TOASTS = 3;
|
|
77284
77548
|
var nextToastId = 1;
|
|
77285
77549
|
function useToast() {
|
|
77286
77550
|
const [toasts, setToasts] = useState115([]);
|
|
77287
|
-
const timersRef =
|
|
77551
|
+
const timersRef = useRef145(/* @__PURE__ */ new Map());
|
|
77288
77552
|
const clearTimer = useCallback136((id) => {
|
|
77289
77553
|
const timer = timersRef.current.get(id);
|
|
77290
77554
|
if (timer) {
|
|
@@ -77333,41 +77597,17 @@ function useToast() {
|
|
|
77333
77597
|
return { toasts, showToast, dismissToast };
|
|
77334
77598
|
}
|
|
77335
77599
|
|
|
77336
|
-
// src/hooks/useCompositionContentLoader.ts
|
|
77337
|
-
import { useCallback as useCallback137 } from "react";
|
|
77338
|
-
function useCompositionContentLoader({
|
|
77339
|
-
projectId,
|
|
77340
|
-
setEditingFile,
|
|
77341
|
-
setActiveCompPath,
|
|
77342
|
-
showToast
|
|
77343
|
-
}) {
|
|
77344
|
-
return useCallback137(
|
|
77345
|
-
(comp) => {
|
|
77346
|
-
if (!projectId) return;
|
|
77347
|
-
setActiveCompPath(comp.endsWith(".html") ? comp : null);
|
|
77348
|
-
setEditingFile({ path: comp, content: null });
|
|
77349
|
-
fetch(buildProjectApiPath(projectId, `/files/${encodeURIComponent(comp)}`)).then(async (r) => {
|
|
77350
|
-
if (!r.ok) throw new Error(`Failed to load ${comp} (${r.status})`);
|
|
77351
|
-
return r.json();
|
|
77352
|
-
}).then((data) => {
|
|
77353
|
-
if (typeof data.content !== "string") throw new Error(`No content returned for ${comp}`);
|
|
77354
|
-
setEditingFile({ path: comp, content: data.content });
|
|
77355
|
-
}).catch((err) => {
|
|
77356
|
-
showToast(err instanceof Error ? err.message : `Failed to load ${comp}`, "error");
|
|
77357
|
-
});
|
|
77358
|
-
},
|
|
77359
|
-
[projectId, setEditingFile, setActiveCompPath, showToast]
|
|
77360
|
-
);
|
|
77361
|
-
}
|
|
77362
|
-
|
|
77363
77600
|
// src/hooks/useStudioUrlState.ts
|
|
77364
|
-
import { useCallback as
|
|
77601
|
+
import { useCallback as useCallback137, useEffect as useEffect111, useRef as useRef146, useState as useState116 } from "react";
|
|
77365
77602
|
|
|
77366
77603
|
// src/utils/studioUrlState.ts
|
|
77367
77604
|
var VALID_TABS = ["layers", "design", "renders", "slideshow", "variables"];
|
|
77368
|
-
function resolveMasterCompositionPath(
|
|
77369
|
-
if (
|
|
77370
|
-
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;
|
|
77371
77611
|
}
|
|
77372
77612
|
function normalizeStudioUrlPanelTab(tab) {
|
|
77373
77613
|
if (!tab) return null;
|
|
@@ -77590,14 +77830,14 @@ function useStudioUrlState({
|
|
|
77590
77830
|
initialState: initialState2
|
|
77591
77831
|
}) {
|
|
77592
77832
|
const currentTime = usePlayerStore((s) => s.currentTime);
|
|
77593
|
-
const hydratedSeekRef =
|
|
77594
|
-
const hydratedInitialTimeRef =
|
|
77595
|
-
const hydratedSelectionRef =
|
|
77833
|
+
const hydratedSeekRef = useRef146(initialState2.currentTime == null);
|
|
77834
|
+
const hydratedInitialTimeRef = useRef146(initialState2.currentTime == null);
|
|
77835
|
+
const hydratedSelectionRef = useRef146(initialState2.selection == null);
|
|
77596
77836
|
const [selectionHydrated, setSelectionHydrated] = useState116(initialState2.selection == null);
|
|
77597
|
-
const pendingSelectionRef =
|
|
77598
|
-
const stableTimeRef =
|
|
77599
|
-
const selectionApplySeqRef =
|
|
77600
|
-
const buildUrlState =
|
|
77837
|
+
const pendingSelectionRef = useRef146(initialState2.selection);
|
|
77838
|
+
const stableTimeRef = useRef146(initialState2.currentTime);
|
|
77839
|
+
const selectionApplySeqRef = useRef146(0);
|
|
77840
|
+
const buildUrlState = useCallback137(
|
|
77601
77841
|
() => ({
|
|
77602
77842
|
activeCompPath,
|
|
77603
77843
|
currentTime: stableTimeRef.current,
|
|
@@ -77608,7 +77848,7 @@ function useStudioUrlState({
|
|
|
77608
77848
|
}),
|
|
77609
77849
|
[activeCompPath, domEditGroupSelections, domEditSelection, rightCollapsed, rightPanelTab]
|
|
77610
77850
|
);
|
|
77611
|
-
const applyUrlSelection =
|
|
77851
|
+
const applyUrlSelection = useCallback137(
|
|
77612
77852
|
(selection) => {
|
|
77613
77853
|
const applySeq = ++selectionApplySeqRef.current;
|
|
77614
77854
|
if (!selection) {
|
|
@@ -77753,7 +77993,7 @@ function useEffectiveTimelineDuration(timelineDuration2, timelineElements) {
|
|
|
77753
77993
|
}
|
|
77754
77994
|
|
|
77755
77995
|
// src/hooks/useStudioContextValue.ts
|
|
77756
|
-
import { useCallback as
|
|
77996
|
+
import { useCallback as useCallback138, useMemo as useMemo66, useRef as useRef147, useState as useState117 } from "react";
|
|
77757
77997
|
function buildStudioContextValue(input) {
|
|
77758
77998
|
return {
|
|
77759
77999
|
projectId: input.projectId,
|
|
@@ -77812,22 +78052,22 @@ function useInspectorState(rightPanelTab, rightInspectorPanes, rightCollapsed, i
|
|
|
77812
78052
|
}
|
|
77813
78053
|
function useDragOverlay(onImportFiles) {
|
|
77814
78054
|
const [active, setActive] = useState117(false);
|
|
77815
|
-
const counterRef =
|
|
77816
|
-
const onDragOver =
|
|
78055
|
+
const counterRef = useRef147(0);
|
|
78056
|
+
const onDragOver = useCallback138((e) => {
|
|
77817
78057
|
if (!e.dataTransfer.types.includes("Files")) return;
|
|
77818
78058
|
e.preventDefault();
|
|
77819
78059
|
}, []);
|
|
77820
|
-
const onDragEnter =
|
|
78060
|
+
const onDragEnter = useCallback138((e) => {
|
|
77821
78061
|
if (!e.dataTransfer.types.includes("Files")) return;
|
|
77822
78062
|
e.preventDefault();
|
|
77823
78063
|
counterRef.current++;
|
|
77824
78064
|
setActive(true);
|
|
77825
78065
|
}, []);
|
|
77826
|
-
const onDragLeave =
|
|
78066
|
+
const onDragLeave = useCallback138(() => {
|
|
77827
78067
|
counterRef.current--;
|
|
77828
78068
|
if (counterRef.current === 0) setActive(false);
|
|
77829
78069
|
}, []);
|
|
77830
|
-
const onDrop =
|
|
78070
|
+
const onDrop = useCallback138(
|
|
77831
78071
|
(e) => {
|
|
77832
78072
|
counterRef.current = 0;
|
|
77833
78073
|
setActive(false);
|
|
@@ -77840,7 +78080,7 @@ function useDragOverlay(onImportFiles) {
|
|
|
77840
78080
|
return { active, onDragOver, onDragEnter, onDragLeave, onDrop };
|
|
77841
78081
|
}
|
|
77842
78082
|
function useGlobalFileDrop(handleTimelineFileDrop) {
|
|
77843
|
-
const onDrop =
|
|
78083
|
+
const onDrop = useCallback138(
|
|
77844
78084
|
(files) => {
|
|
77845
78085
|
const start = usePlayerStore.getState().currentTime;
|
|
77846
78086
|
void handleTimelineFileDrop(Array.from(files), { start, track: 0 });
|
|
@@ -77851,7 +78091,7 @@ function useGlobalFileDrop(handleTimelineFileDrop) {
|
|
|
77851
78091
|
}
|
|
77852
78092
|
|
|
77853
78093
|
// src/components/StudioHeader.tsx
|
|
77854
|
-
import { useRef as
|
|
78094
|
+
import { useRef as useRef149 } from "react";
|
|
77855
78095
|
|
|
77856
78096
|
// src/contexts/PanelLayoutContext.tsx
|
|
77857
78097
|
import { useContext as useContext8, useMemo as useMemo67 } from "react";
|
|
@@ -77929,11 +78169,11 @@ function PanelLayoutProvider({
|
|
|
77929
78169
|
|
|
77930
78170
|
// src/contexts/ViewModeContext.tsx
|
|
77931
78171
|
import {
|
|
77932
|
-
useCallback as
|
|
78172
|
+
useCallback as useCallback139,
|
|
77933
78173
|
useContext as useContext9,
|
|
77934
78174
|
useEffect as useEffect112,
|
|
77935
78175
|
useMemo as useMemo68,
|
|
77936
|
-
useRef as
|
|
78176
|
+
useRef as useRef148,
|
|
77937
78177
|
useState as useState118
|
|
77938
78178
|
} from "react";
|
|
77939
78179
|
import { jsx as jsx172 } from "react/jsx-runtime";
|
|
@@ -77961,9 +78201,9 @@ function readHistoryLocation() {
|
|
|
77961
78201
|
}
|
|
77962
78202
|
function useViewModeState() {
|
|
77963
78203
|
const [viewMode, setMode] = useState118(() => readViewModeFromUrl());
|
|
77964
|
-
const guardsRef =
|
|
77965
|
-
const acceptedLocationRef =
|
|
77966
|
-
const canSetViewMode =
|
|
78204
|
+
const guardsRef = useRef148(/* @__PURE__ */ new Set());
|
|
78205
|
+
const acceptedLocationRef = useRef148(readHistoryLocation());
|
|
78206
|
+
const canSetViewMode = useCallback139((mode) => {
|
|
77967
78207
|
for (const guard of guardsRef.current) {
|
|
77968
78208
|
if (!guard(mode)) return false;
|
|
77969
78209
|
}
|
|
@@ -77985,7 +78225,7 @@ function useViewModeState() {
|
|
|
77985
78225
|
window.addEventListener("popstate", onPopState);
|
|
77986
78226
|
return () => window.removeEventListener("popstate", onPopState);
|
|
77987
78227
|
}, [canSetViewMode, viewMode]);
|
|
77988
|
-
const setViewMode =
|
|
78228
|
+
const setViewMode = useCallback139(
|
|
77989
78229
|
(mode) => {
|
|
77990
78230
|
if (!canSetViewMode(mode)) return false;
|
|
77991
78231
|
setMode(mode);
|
|
@@ -77995,7 +78235,7 @@ function useViewModeState() {
|
|
|
77995
78235
|
},
|
|
77996
78236
|
[canSetViewMode]
|
|
77997
78237
|
);
|
|
77998
|
-
const registerViewModeGuard =
|
|
78238
|
+
const registerViewModeGuard = useCallback139((guard) => {
|
|
77999
78239
|
guardsRef.current.add(guard);
|
|
78000
78240
|
return () => {
|
|
78001
78241
|
guardsRef.current.delete(guard);
|
|
@@ -78209,7 +78449,7 @@ var VIEW_MODE_OPTIONS = [
|
|
|
78209
78449
|
];
|
|
78210
78450
|
function ViewModeToggle() {
|
|
78211
78451
|
const { viewMode, setViewMode } = useViewMode();
|
|
78212
|
-
const tabRefs =
|
|
78452
|
+
const tabRefs = useRef149([]);
|
|
78213
78453
|
const selectMode = (mode) => {
|
|
78214
78454
|
if (mode === viewMode) return;
|
|
78215
78455
|
if (setViewMode(mode)) trackStudioEvent("view_mode_toggle", { mode });
|
|
@@ -78436,10 +78676,10 @@ function StudioHeader({
|
|
|
78436
78676
|
}
|
|
78437
78677
|
|
|
78438
78678
|
// src/hooks/useGestureCommit.ts
|
|
78439
|
-
import { useState as useState120, useCallback as
|
|
78679
|
+
import { useState as useState120, useCallback as useCallback141, useRef as useRef151, useEffect as useEffect114 } from "react";
|
|
78440
78680
|
|
|
78441
78681
|
// src/hooks/useGestureRecording.ts
|
|
78442
|
-
import { useCallback as
|
|
78682
|
+
import { useCallback as useCallback140, useEffect as useEffect113, useRef as useRef150, useState as useState119 } from "react";
|
|
78443
78683
|
function readBasePosition(element, iframeEl) {
|
|
78444
78684
|
let baseOpacity = 1;
|
|
78445
78685
|
let baseScale = 1;
|
|
@@ -78584,10 +78824,10 @@ function releaseRuntimePreview(r) {
|
|
|
78584
78824
|
function useGestureRecording() {
|
|
78585
78825
|
const [isRecording, setIsRecording] = useState119(false);
|
|
78586
78826
|
const [recordingDuration, setRecordingDuration] = useState119(0);
|
|
78587
|
-
const isRecordingRef =
|
|
78588
|
-
const refs =
|
|
78589
|
-
const samplesRef =
|
|
78590
|
-
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);
|
|
78591
78831
|
useEffect113(() => {
|
|
78592
78832
|
const r = refs.current;
|
|
78593
78833
|
return () => {
|
|
@@ -78597,7 +78837,7 @@ function useGestureRecording() {
|
|
|
78597
78837
|
r.cleanup = null;
|
|
78598
78838
|
};
|
|
78599
78839
|
}, []);
|
|
78600
|
-
const startRecording =
|
|
78840
|
+
const startRecording = useCallback140(
|
|
78601
78841
|
(element, iframeEl, elementEndTime) => {
|
|
78602
78842
|
if (isRecordingRef.current) return;
|
|
78603
78843
|
isRecordingRef.current = true;
|
|
@@ -78697,7 +78937,7 @@ function useGestureRecording() {
|
|
|
78697
78937
|
[]
|
|
78698
78938
|
// No deps — uses refs only for all mutable state
|
|
78699
78939
|
);
|
|
78700
|
-
const stopRecording =
|
|
78940
|
+
const stopRecording = useCallback140(() => {
|
|
78701
78941
|
if (!isRecordingRef.current) return [];
|
|
78702
78942
|
isRecordingRef.current = false;
|
|
78703
78943
|
const r = refs.current;
|
|
@@ -78709,7 +78949,7 @@ function useGestureRecording() {
|
|
|
78709
78949
|
setIsRecording(false);
|
|
78710
78950
|
return frozen;
|
|
78711
78951
|
}, []);
|
|
78712
|
-
const clearSamples =
|
|
78952
|
+
const clearSamples = useCallback140(() => {
|
|
78713
78953
|
const r = refs.current;
|
|
78714
78954
|
r.samples = [];
|
|
78715
78955
|
r.trail = [];
|
|
@@ -78966,13 +79206,13 @@ function useGestureCommit({
|
|
|
78966
79206
|
}) {
|
|
78967
79207
|
const gestureRecording = useGestureRecording();
|
|
78968
79208
|
const [gestureState, setGestureState] = useState120("idle");
|
|
78969
|
-
const gestureStateRef =
|
|
78970
|
-
const recordingAutoStopRef =
|
|
78971
|
-
const recordingStartTimeRef =
|
|
78972
|
-
const commitInFlightRef =
|
|
78973
|
-
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);
|
|
78974
79214
|
useEffect114(() => () => clearInterval(recordingAutoStopRef.current), []);
|
|
78975
|
-
const stopAndCommitRecording =
|
|
79215
|
+
const stopAndCommitRecording = useCallback141(async () => {
|
|
78976
79216
|
clearInterval(recordingAutoStopRef.current);
|
|
78977
79217
|
if (commitInFlightRef.current) {
|
|
78978
79218
|
return;
|
|
@@ -79145,7 +79385,7 @@ function useGestureCommit({
|
|
|
79145
79385
|
commitInFlightRef.current = false;
|
|
79146
79386
|
}
|
|
79147
79387
|
}, [gestureRecording, showToast, isGestureRecordingRef, domEditSessionRef]);
|
|
79148
|
-
const handleToggleRecording =
|
|
79388
|
+
const handleToggleRecording = useCallback141(() => {
|
|
79149
79389
|
if (gestureStateRef.current === "recording") {
|
|
79150
79390
|
void stopAndCommitRecording();
|
|
79151
79391
|
return;
|
|
@@ -79303,20 +79543,21 @@ var GestureTrailOverlay = memo38(function GestureTrailOverlay2({
|
|
|
79303
79543
|
});
|
|
79304
79544
|
|
|
79305
79545
|
// src/components/StudioLeftSidebar.tsx
|
|
79306
|
-
import { useCallback as
|
|
79546
|
+
import { useCallback as useCallback150 } from "react";
|
|
79307
79547
|
|
|
79308
79548
|
// src/components/sidebar/LeftSidebar.tsx
|
|
79309
79549
|
import {
|
|
79310
79550
|
memo as memo42,
|
|
79311
79551
|
useState as useState130,
|
|
79312
|
-
useCallback as
|
|
79552
|
+
useCallback as useCallback149,
|
|
79313
79553
|
useImperativeHandle,
|
|
79314
|
-
|
|
79554
|
+
useMemo as useMemo72,
|
|
79555
|
+
useRef as useRef159,
|
|
79315
79556
|
forwardRef as forwardRef3
|
|
79316
79557
|
} from "react";
|
|
79317
79558
|
|
|
79318
79559
|
// src/components/sidebar/CompositionsTab.tsx
|
|
79319
|
-
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";
|
|
79320
79561
|
import { jsx as jsx175, jsxs as jsxs145 } from "react/jsx-runtime";
|
|
79321
79562
|
var DEFAULT_PREVIEW_STAGE = { width: 1920, height: 1080 };
|
|
79322
79563
|
var CARD_W = 80;
|
|
@@ -79378,6 +79619,7 @@ function CompCard({
|
|
|
79378
79619
|
projectId,
|
|
79379
79620
|
comp,
|
|
79380
79621
|
isActive,
|
|
79622
|
+
isRoot,
|
|
79381
79623
|
onSelect,
|
|
79382
79624
|
onRender,
|
|
79383
79625
|
isRendering,
|
|
@@ -79389,11 +79631,11 @@ function CompCard({
|
|
|
79389
79631
|
const [stageSize, setStageSize] = useState121(DEFAULT_PREVIEW_STAGE);
|
|
79390
79632
|
const [livePreviewLoaded, setLivePreviewLoaded] = useState121(false);
|
|
79391
79633
|
const [failedThumbnailUrl, setFailedThumbnailUrl] = useState121(null);
|
|
79392
|
-
const iframeRef =
|
|
79393
|
-
const hoverTimer =
|
|
79394
|
-
const syncTimer =
|
|
79395
|
-
const draggedRef =
|
|
79396
|
-
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) => {
|
|
79397
79639
|
if (syncTimer.current) {
|
|
79398
79640
|
clearTimeout(syncTimer.current);
|
|
79399
79641
|
syncTimer.current = null;
|
|
@@ -79532,6 +79774,15 @@ function CompCard({
|
|
|
79532
79774
|
children: [
|
|
79533
79775
|
/* @__PURE__ */ jsxs145("div", { className: "flex items-center gap-1", children: [
|
|
79534
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
|
+
),
|
|
79535
79786
|
lintInfo && lintInfo.count > 0 && /* @__PURE__ */ jsx175(
|
|
79536
79787
|
"span",
|
|
79537
79788
|
{
|
|
@@ -79599,6 +79850,7 @@ var CompositionsTab = memo39(function CompositionsTab2({
|
|
|
79599
79850
|
projectId,
|
|
79600
79851
|
compositions,
|
|
79601
79852
|
activeComposition,
|
|
79853
|
+
masterCompositionPath = null,
|
|
79602
79854
|
onSelect,
|
|
79603
79855
|
onRenderComposition,
|
|
79604
79856
|
onAddToTimeline,
|
|
@@ -79615,6 +79867,7 @@ var CompositionsTab = memo39(function CompositionsTab2({
|
|
|
79615
79867
|
projectId,
|
|
79616
79868
|
comp,
|
|
79617
79869
|
isActive: activeComposition === comp,
|
|
79870
|
+
isRoot: comp === masterCompositionPath,
|
|
79618
79871
|
onSelect: () => onSelect(comp),
|
|
79619
79872
|
onRender: onRenderComposition ? () => onRenderComposition(comp) : void 0,
|
|
79620
79873
|
onAddToTimeline: onAddToTimeline ? () => onAddToTimeline(comp) : void 0,
|
|
@@ -79627,7 +79880,7 @@ var CompositionsTab = memo39(function CompositionsTab2({
|
|
|
79627
79880
|
});
|
|
79628
79881
|
|
|
79629
79882
|
// src/components/sidebar/AssetsTab.tsx
|
|
79630
|
-
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";
|
|
79631
79884
|
|
|
79632
79885
|
// src/components/ui/SearchInput.tsx
|
|
79633
79886
|
import { jsx as jsx176, jsxs as jsxs146 } from "react/jsx-runtime";
|
|
@@ -79738,11 +79991,11 @@ var CATEGORY_LABELS = {
|
|
|
79738
79991
|
var FILTER_ORDER = ["audio", "images", "video", "fonts"];
|
|
79739
79992
|
|
|
79740
79993
|
// src/components/sidebar/AudioRow.tsx
|
|
79741
|
-
import { useState as useState123, useRef as
|
|
79994
|
+
import { useState as useState123, useRef as useRef154, useEffect as useEffect117, useCallback as useCallback144 } from "react";
|
|
79742
79995
|
import { classifyWebAudioMediaRoute } from "@hyperframes/core/runtime/web-audio-route";
|
|
79743
79996
|
|
|
79744
79997
|
// src/components/sidebar/AssetContextMenu.tsx
|
|
79745
|
-
import { useCallback as
|
|
79998
|
+
import { useCallback as useCallback143, useEffect as useEffect116, useLayoutEffect as useLayoutEffect9, useRef as useRef153, useState as useState122 } from "react";
|
|
79746
79999
|
import { Fragment as Fragment51, jsx as jsx177, jsxs as jsxs147 } from "react/jsx-runtime";
|
|
79747
80000
|
function isValidAssetName(name) {
|
|
79748
80001
|
return name.length > 0 && !/[/\\]/.test(name) && !name.includes("..");
|
|
@@ -79757,7 +80010,7 @@ function ContextMenu2({
|
|
|
79757
80010
|
onRename,
|
|
79758
80011
|
onAddAtPlayhead
|
|
79759
80012
|
}) {
|
|
79760
|
-
const menuRef =
|
|
80013
|
+
const menuRef = useRef153(null);
|
|
79761
80014
|
const [pos, setPos] = useState122({ x, y });
|
|
79762
80015
|
const [mode, setMode] = useState122("menu");
|
|
79763
80016
|
const [renameDraft, setRenameDraft] = useState122(() => filename(asset));
|
|
@@ -79802,7 +80055,7 @@ function ContextMenu2({
|
|
|
79802
80055
|
menuRef.current?.querySelector('[role="menuitem"]')?.focus();
|
|
79803
80056
|
}
|
|
79804
80057
|
}, [mode]);
|
|
79805
|
-
const commitRename =
|
|
80058
|
+
const commitRename = useCallback143(() => {
|
|
79806
80059
|
const trimmed = renameDraft.trim();
|
|
79807
80060
|
if (trimmed === filename(asset)) {
|
|
79808
80061
|
onClose();
|
|
@@ -80008,28 +80261,28 @@ function AudioRow({
|
|
|
80008
80261
|
const [contextMenu, setContextMenu] = useState123(null);
|
|
80009
80262
|
const [playing, setPlaying] = useState123(false);
|
|
80010
80263
|
const [bars, setBars] = useState123([]);
|
|
80011
|
-
const audioRef =
|
|
80012
|
-
const actxRef =
|
|
80013
|
-
const analyserRef =
|
|
80014
|
-
const sourceRef =
|
|
80015
|
-
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);
|
|
80016
80269
|
const name = basename2(asset);
|
|
80017
80270
|
const subtype = getAudioSubtype(asset);
|
|
80018
80271
|
const serveUrl = resolveMediaPreviewUrl(asset, projectId);
|
|
80019
80272
|
const isCopied = copyFeedback?.path === asset && copyFeedback.ok;
|
|
80020
80273
|
const copyFailed = copyFeedback?.path === asset && !copyFeedback.ok;
|
|
80021
|
-
const stopPlayback =
|
|
80274
|
+
const stopPlayback = useCallback144(() => {
|
|
80022
80275
|
audioRef.current?.pause();
|
|
80023
80276
|
setPlaying(false);
|
|
80024
80277
|
cancelAnimationFrame(animRef.current);
|
|
80025
80278
|
}, []);
|
|
80026
|
-
const pointerDownRef =
|
|
80279
|
+
const pointerDownRef = useRef154(null);
|
|
80027
80280
|
const setSelectedElementId = usePlayerStore((s) => s.setSelectedElementId);
|
|
80028
80281
|
const requestTimelineFocus = usePlayerStore((s) => s.requestTimelineFocus);
|
|
80029
80282
|
const elements = usePlayerStore((s) => s.elements);
|
|
80030
80283
|
const setPreviewAsset = useAssetPreviewStore((s) => s.setPreviewAsset);
|
|
80031
80284
|
const clearPreviewAsset = useAssetPreviewStore((s) => s.clearPreviewAsset);
|
|
80032
|
-
const activateRow =
|
|
80285
|
+
const activateRow = useCallback144(() => {
|
|
80033
80286
|
if (used) {
|
|
80034
80287
|
const clip = findClipForAsset(elements, asset);
|
|
80035
80288
|
if (clip) {
|
|
@@ -80051,10 +80304,10 @@ function AudioRow({
|
|
|
80051
80304
|
setPreviewAsset,
|
|
80052
80305
|
clearPreviewAsset
|
|
80053
80306
|
]);
|
|
80054
|
-
const handlePointerDown =
|
|
80307
|
+
const handlePointerDown = useCallback144((e) => {
|
|
80055
80308
|
pointerDownRef.current = { x: e.clientX, y: e.clientY };
|
|
80056
80309
|
}, []);
|
|
80057
|
-
const handlePointerUp =
|
|
80310
|
+
const handlePointerUp = useCallback144(
|
|
80058
80311
|
(e) => {
|
|
80059
80312
|
const origin = pointerDownRef.current;
|
|
80060
80313
|
pointerDownRef.current = null;
|
|
@@ -80100,7 +80353,7 @@ function AudioRow({
|
|
|
80100
80353
|
}
|
|
80101
80354
|
return () => cancelAnimationFrame(animRef.current);
|
|
80102
80355
|
}, [playing]);
|
|
80103
|
-
const togglePlay =
|
|
80356
|
+
const togglePlay = useCallback144(async () => {
|
|
80104
80357
|
if (playing) {
|
|
80105
80358
|
stopPlayback();
|
|
80106
80359
|
if (stopCurrentPreview === stopPlayback) stopCurrentPreview = null;
|
|
@@ -80298,7 +80551,7 @@ function GlobalAssetsView({ searchQuery }) {
|
|
|
80298
80551
|
}
|
|
80299
80552
|
|
|
80300
80553
|
// src/components/sidebar/AssetCard.tsx
|
|
80301
|
-
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";
|
|
80302
80555
|
|
|
80303
80556
|
// src/components/ui/VideoFrameThumbnail.tsx
|
|
80304
80557
|
import { useState as useState125, useEffect as useEffect119 } from "react";
|
|
@@ -80436,16 +80689,16 @@ function AssetCard({
|
|
|
80436
80689
|
const probedDuration = useProbedDuration(serveUrl, !isVideo || duration != null);
|
|
80437
80690
|
const resolvedDuration = duration ?? probedDuration ?? void 0;
|
|
80438
80691
|
const durationLabel = formatDuration(resolvedDuration ?? 0);
|
|
80439
|
-
const pointerDownRef =
|
|
80692
|
+
const pointerDownRef = useRef155(null);
|
|
80440
80693
|
const setSelectedElementId = usePlayerStore((s) => s.setSelectedElementId);
|
|
80441
80694
|
const requestTimelineFocus = usePlayerStore((s) => s.requestTimelineFocus);
|
|
80442
80695
|
const elements = usePlayerStore((s) => s.elements);
|
|
80443
80696
|
const setPreviewAsset = useAssetPreviewStore((s) => s.setPreviewAsset);
|
|
80444
80697
|
const clearPreviewAsset = useAssetPreviewStore((s) => s.clearPreviewAsset);
|
|
80445
|
-
const handlePointerDown =
|
|
80698
|
+
const handlePointerDown = useCallback145((e) => {
|
|
80446
80699
|
pointerDownRef.current = { x: e.clientX, y: e.clientY };
|
|
80447
80700
|
}, []);
|
|
80448
|
-
const activateCard =
|
|
80701
|
+
const activateCard = useCallback145(() => {
|
|
80449
80702
|
if (used) {
|
|
80450
80703
|
const clip = findClipForAsset(elements, asset);
|
|
80451
80704
|
if (clip) {
|
|
@@ -80467,7 +80720,7 @@ function AssetCard({
|
|
|
80467
80720
|
setPreviewAsset,
|
|
80468
80721
|
clearPreviewAsset
|
|
80469
80722
|
]);
|
|
80470
|
-
const handlePointerUp =
|
|
80723
|
+
const handlePointerUp = useCallback145(
|
|
80471
80724
|
(e) => {
|
|
80472
80725
|
const origin = pointerDownRef.current;
|
|
80473
80726
|
pointerDownRef.current = null;
|
|
@@ -80761,7 +81014,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80761
81014
|
onRename,
|
|
80762
81015
|
onAddAssetToTimeline
|
|
80763
81016
|
}) {
|
|
80764
|
-
const fileInputRef =
|
|
81017
|
+
const fileInputRef = useRef156(null);
|
|
80765
81018
|
const [dragOver, setDragOver] = useState127(false);
|
|
80766
81019
|
const [copyFeedback, setCopyFeedback] = useState127(null);
|
|
80767
81020
|
const [importing, setImporting] = useState127(false);
|
|
@@ -80770,7 +81023,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80770
81023
|
const [searchQuery, setSearchQuery] = useState127("");
|
|
80771
81024
|
const [viewMode, setViewMode] = useState127("local");
|
|
80772
81025
|
const [manifest, setManifest] = useState127(/* @__PURE__ */ new Map());
|
|
80773
|
-
const manifest404Ref =
|
|
81026
|
+
const manifest404Ref = useRef156(/* @__PURE__ */ new Set());
|
|
80774
81027
|
const assetsKey = assets.join("|");
|
|
80775
81028
|
useEffect121(() => {
|
|
80776
81029
|
if (manifest404Ref.current.has(projectId)) return;
|
|
@@ -80799,7 +81052,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80799
81052
|
cancelled = true;
|
|
80800
81053
|
};
|
|
80801
81054
|
}, [projectId, assetsKey]);
|
|
80802
|
-
const handleImport =
|
|
81055
|
+
const handleImport = useCallback146(
|
|
80803
81056
|
async (files) => {
|
|
80804
81057
|
if (!onImport) return;
|
|
80805
81058
|
setImporting(true);
|
|
@@ -80811,7 +81064,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80811
81064
|
},
|
|
80812
81065
|
[onImport]
|
|
80813
81066
|
);
|
|
80814
|
-
const handleDrop =
|
|
81067
|
+
const handleDrop = useCallback146(
|
|
80815
81068
|
(e) => {
|
|
80816
81069
|
e.preventDefault();
|
|
80817
81070
|
setDragOver(false);
|
|
@@ -80819,7 +81072,7 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
80819
81072
|
},
|
|
80820
81073
|
[handleImport]
|
|
80821
81074
|
);
|
|
80822
|
-
const handleCopyPath =
|
|
81075
|
+
const handleCopyPath = useCallback146(async (path) => {
|
|
80823
81076
|
const copied = await copyTextToClipboard(path);
|
|
80824
81077
|
setCopyFeedback({ path, ok: copied });
|
|
80825
81078
|
setTimeout(() => setCopyFeedback(null), copied ? 1500 : 3e3);
|
|
@@ -81029,11 +81282,11 @@ var AssetsTab = memo40(function AssetsTab2({
|
|
|
81029
81282
|
});
|
|
81030
81283
|
|
|
81031
81284
|
// src/components/sidebar/BlocksTab.tsx
|
|
81032
|
-
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";
|
|
81033
81286
|
import { createPortal as createPortal9 } from "react-dom";
|
|
81034
81287
|
|
|
81035
81288
|
// src/components/sidebar/PromptPreviewModal.tsx
|
|
81036
|
-
import { useState as useState128, useCallback as
|
|
81289
|
+
import { useState as useState128, useCallback as useCallback147, useEffect as useEffect122, useRef as useRef157 } from "react";
|
|
81037
81290
|
import { jsx as jsx183, jsxs as jsxs152 } from "react/jsx-runtime";
|
|
81038
81291
|
function PromptPreviewModal({
|
|
81039
81292
|
title,
|
|
@@ -81043,9 +81296,9 @@ function PromptPreviewModal({
|
|
|
81043
81296
|
const [value, setValue] = useState128(prompt);
|
|
81044
81297
|
const [copyState, setCopyState] = useState128("idle");
|
|
81045
81298
|
const [entered, setEntered] = useState128(false);
|
|
81046
|
-
const containerRef =
|
|
81047
|
-
const textareaRef =
|
|
81048
|
-
const valueRef =
|
|
81299
|
+
const containerRef = useRef157(null);
|
|
81300
|
+
const textareaRef = useRef157(null);
|
|
81301
|
+
const valueRef = useRef157(value);
|
|
81049
81302
|
valueRef.current = value;
|
|
81050
81303
|
const { requestClose } = useDialogBehavior({
|
|
81051
81304
|
open: true,
|
|
@@ -81059,7 +81312,7 @@ function PromptPreviewModal({
|
|
|
81059
81312
|
textareaRef.current?.focus();
|
|
81060
81313
|
});
|
|
81061
81314
|
}, []);
|
|
81062
|
-
const handleCopy2 =
|
|
81315
|
+
const handleCopy2 = useCallback147(async () => {
|
|
81063
81316
|
try {
|
|
81064
81317
|
await navigator.clipboard.writeText(valueRef.current);
|
|
81065
81318
|
setCopyState("copied");
|
|
@@ -81342,16 +81595,16 @@ function BlockCard({
|
|
|
81342
81595
|
}) {
|
|
81343
81596
|
const [hovered, setHovered] = useState129(false);
|
|
81344
81597
|
const [addState, setAddState] = useState129("idle");
|
|
81345
|
-
const hoverTimer =
|
|
81598
|
+
const hoverTimer = useRef158(null);
|
|
81346
81599
|
const colors = getCategoryColors(category);
|
|
81347
81600
|
const needsWebGL = tags?.includes("html-in-canvas") || tags?.includes("webgl");
|
|
81348
|
-
const handleEnter =
|
|
81601
|
+
const handleEnter = useCallback148(() => {
|
|
81349
81602
|
hoverTimer.current = setTimeout(() => {
|
|
81350
81603
|
setHovered(true);
|
|
81351
81604
|
onPreview?.({ videoUrl, posterUrl, title });
|
|
81352
81605
|
}, 300);
|
|
81353
81606
|
}, [onPreview, videoUrl, posterUrl, title]);
|
|
81354
|
-
const handleLeave =
|
|
81607
|
+
const handleLeave = useCallback148(() => {
|
|
81355
81608
|
if (hoverTimer.current) {
|
|
81356
81609
|
clearTimeout(hoverTimer.current);
|
|
81357
81610
|
hoverTimer.current = null;
|
|
@@ -81364,7 +81617,7 @@ function BlockCard({
|
|
|
81364
81617
|
if (hoverTimer.current) clearTimeout(hoverTimer.current);
|
|
81365
81618
|
};
|
|
81366
81619
|
}, []);
|
|
81367
|
-
const handleAdd =
|
|
81620
|
+
const handleAdd = useCallback148(
|
|
81368
81621
|
async (e) => {
|
|
81369
81622
|
e.stopPropagation();
|
|
81370
81623
|
if (addState !== "idle" || !onAdd) return;
|
|
@@ -81380,7 +81633,7 @@ function BlockCard({
|
|
|
81380
81633
|
[onAdd, addState]
|
|
81381
81634
|
);
|
|
81382
81635
|
const { activeCompPath, compositionDimensions } = useStudioShellContext();
|
|
81383
|
-
const handleShowPrompt =
|
|
81636
|
+
const handleShowPrompt = useCallback148(
|
|
81384
81637
|
(e) => {
|
|
81385
81638
|
e.stopPropagation();
|
|
81386
81639
|
const state = usePlayerStore.getState();
|
|
@@ -81572,10 +81825,14 @@ var LeftSidebar = memo42(
|
|
|
81572
81825
|
onAddCompositionToTimeline
|
|
81573
81826
|
}, ref) {
|
|
81574
81827
|
const [tab, setTab] = useState130(getPersistedTab);
|
|
81575
|
-
const tabRef =
|
|
81828
|
+
const tabRef = useRef159(tab);
|
|
81576
81829
|
tabRef.current = tab;
|
|
81577
|
-
const tablistRef =
|
|
81578
|
-
const
|
|
81830
|
+
const tablistRef = useRef159(null);
|
|
81831
|
+
const masterCompositionPath = useMemo72(
|
|
81832
|
+
() => resolveMasterCompositionPath(compositions),
|
|
81833
|
+
[compositions]
|
|
81834
|
+
);
|
|
81835
|
+
const selectTab = useCallback149((t) => {
|
|
81579
81836
|
setTab(t);
|
|
81580
81837
|
try {
|
|
81581
81838
|
safeLocalStorage()?.setItem(STORAGE_KEY, t);
|
|
@@ -81583,9 +81840,9 @@ var LeftSidebar = memo42(
|
|
|
81583
81840
|
}
|
|
81584
81841
|
trackStudioEvent("tab_switch", { panel: "left_sidebar", tab: t });
|
|
81585
81842
|
}, []);
|
|
81586
|
-
const getTab =
|
|
81843
|
+
const getTab = useCallback149(() => tabRef.current, []);
|
|
81587
81844
|
useImperativeHandle(ref, () => ({ selectTab, getTab }), [selectTab, getTab]);
|
|
81588
|
-
const handleTablistKeyDown =
|
|
81845
|
+
const handleTablistKeyDown = useCallback149(
|
|
81589
81846
|
(e) => {
|
|
81590
81847
|
if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
|
|
81591
81848
|
e.preventDefault();
|
|
@@ -81670,6 +81927,7 @@ var LeftSidebar = memo42(
|
|
|
81670
81927
|
projectId,
|
|
81671
81928
|
compositions,
|
|
81672
81929
|
activeComposition,
|
|
81930
|
+
masterCompositionPath,
|
|
81673
81931
|
onSelect: onSelectComposition,
|
|
81674
81932
|
onAddToTimeline: onAddCompositionToTimeline,
|
|
81675
81933
|
onRenderComposition,
|
|
@@ -81942,7 +82200,7 @@ function StudioLeftSidebar({
|
|
|
81942
82200
|
handleImportFiles,
|
|
81943
82201
|
handleContentChange
|
|
81944
82202
|
} = useFileManagerContext();
|
|
81945
|
-
const handleRenderComposition =
|
|
82203
|
+
const handleRenderComposition = useCallback150(
|
|
81946
82204
|
async (comp) => {
|
|
81947
82205
|
if (renderQueue.ffmpegMissing) {
|
|
81948
82206
|
setRightPanelTab("renders");
|
|
@@ -82067,13 +82325,13 @@ function StudioLeftSidebar({
|
|
|
82067
82325
|
}
|
|
82068
82326
|
|
|
82069
82327
|
// src/components/StudioRightPanel.tsx
|
|
82070
|
-
import { useCallback as
|
|
82328
|
+
import { useCallback as useCallback167 } from "react";
|
|
82071
82329
|
|
|
82072
82330
|
// src/components/editor/LayersPanel.tsx
|
|
82073
|
-
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";
|
|
82074
82332
|
|
|
82075
82333
|
// src/components/editor/useLayerDrag.ts
|
|
82076
|
-
import { useRef as
|
|
82334
|
+
import { useRef as useRef160, useState as useState132, useCallback as useCallback151 } from "react";
|
|
82077
82335
|
var DRAG_THRESHOLD_PX3 = 4;
|
|
82078
82336
|
function isLayerDraggable(layer) {
|
|
82079
82337
|
if (!(layer.selector || layer.id)) return false;
|
|
@@ -82140,10 +82398,10 @@ function useLayerDrag({
|
|
|
82140
82398
|
onReorder,
|
|
82141
82399
|
onSingleSibling
|
|
82142
82400
|
}) {
|
|
82143
|
-
const dragRef =
|
|
82401
|
+
const dragRef = useRef160(null);
|
|
82144
82402
|
const [dragKey, setDragKey] = useState132(null);
|
|
82145
82403
|
const [insertionLineY, setInsertionLineY] = useState132(null);
|
|
82146
|
-
const handleRowPointerDown =
|
|
82404
|
+
const handleRowPointerDown = useCallback151(
|
|
82147
82405
|
(layerIndex, e) => {
|
|
82148
82406
|
if (e.button !== 0) return;
|
|
82149
82407
|
const layer = visibleLayers[layerIndex];
|
|
@@ -82170,7 +82428,7 @@ function useLayerDrag({
|
|
|
82170
82428
|
},
|
|
82171
82429
|
[visibleLayers, scrollContainerRef, onSingleSibling]
|
|
82172
82430
|
);
|
|
82173
|
-
const handleContainerPointerMove =
|
|
82431
|
+
const handleContainerPointerMove = useCallback151(
|
|
82174
82432
|
(e) => {
|
|
82175
82433
|
const drag = dragRef.current;
|
|
82176
82434
|
if (!drag) return;
|
|
@@ -82196,7 +82454,7 @@ function useLayerDrag({
|
|
|
82196
82454
|
},
|
|
82197
82455
|
[visibleLayers, scrollContainerRef]
|
|
82198
82456
|
);
|
|
82199
|
-
const handleContainerPointerUp =
|
|
82457
|
+
const handleContainerPointerUp = useCallback151(() => {
|
|
82200
82458
|
const drag = dragRef.current;
|
|
82201
82459
|
dragRef.current = null;
|
|
82202
82460
|
setDragKey(null);
|
|
@@ -82346,15 +82604,15 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82346
82604
|
} = useDomEditContext();
|
|
82347
82605
|
const [layers, setLayers] = useState133([]);
|
|
82348
82606
|
const [collapsed, setCollapsed] = useState133({});
|
|
82349
|
-
const prevDocVersionRef =
|
|
82350
|
-
const scrollContainerRef =
|
|
82607
|
+
const prevDocVersionRef = useRef161(0);
|
|
82608
|
+
const scrollContainerRef = useRef161(null);
|
|
82351
82609
|
const mirrorLayerReorderToTimeline = useLayerReorderTimelineMirror();
|
|
82352
82610
|
const { scheduleReveal } = useLayerRevealOverride({
|
|
82353
82611
|
isPlaying,
|
|
82354
82612
|
selectedElement: domEditSelection?.element ?? null
|
|
82355
82613
|
});
|
|
82356
82614
|
const isMasterView = !activeCompPath || activeCompPath === "index.html";
|
|
82357
|
-
const collectLayers =
|
|
82615
|
+
const collectLayers = useCallback152(() => {
|
|
82358
82616
|
const iframe = previewIframeRef.current;
|
|
82359
82617
|
if (!iframe) return;
|
|
82360
82618
|
let doc = null;
|
|
@@ -82403,7 +82661,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82403
82661
|
throttle.cancel();
|
|
82404
82662
|
};
|
|
82405
82663
|
}, [collectLayers]);
|
|
82406
|
-
const resolveSelection =
|
|
82664
|
+
const resolveSelection = useCallback152(
|
|
82407
82665
|
(layer) => {
|
|
82408
82666
|
let el = layer.element;
|
|
82409
82667
|
if (!el.isConnected) {
|
|
@@ -82423,7 +82681,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82423
82681
|
},
|
|
82424
82682
|
[activeCompPath, isMasterView, previewIframeRef, activeGroupElement]
|
|
82425
82683
|
);
|
|
82426
|
-
const seekToLayer =
|
|
82684
|
+
const seekToLayer = useCallback152(
|
|
82427
82685
|
async (layer) => {
|
|
82428
82686
|
const selection = await resolveSelection(layer);
|
|
82429
82687
|
if (!selection) return;
|
|
@@ -82452,7 +82710,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82452
82710
|
},
|
|
82453
82711
|
[currentTime, resolveSelection, timelineElements]
|
|
82454
82712
|
);
|
|
82455
|
-
const handleSelectLayer =
|
|
82713
|
+
const handleSelectLayer = useCallback152(
|
|
82456
82714
|
async (layer) => {
|
|
82457
82715
|
const selection = await resolveSelection(layer);
|
|
82458
82716
|
if (!selection) return;
|
|
@@ -82462,7 +82720,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82462
82720
|
},
|
|
82463
82721
|
[resolveSelection, applyDomSelection, seekToLayer, scheduleReveal]
|
|
82464
82722
|
);
|
|
82465
|
-
const handleLayerDoubleClick =
|
|
82723
|
+
const handleLayerDoubleClick = useCallback152(
|
|
82466
82724
|
async (layer) => {
|
|
82467
82725
|
const selection = await resolveSelection(layer);
|
|
82468
82726
|
if (selection?.element.hasAttribute("data-hf-group")) {
|
|
@@ -82473,7 +82731,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82473
82731
|
},
|
|
82474
82732
|
[resolveSelection, setActiveGroupElement, handleSelectLayer]
|
|
82475
82733
|
);
|
|
82476
|
-
const handleLayerHover =
|
|
82734
|
+
const handleLayerHover = useCallback152(
|
|
82477
82735
|
async (layer) => {
|
|
82478
82736
|
if (!layer) {
|
|
82479
82737
|
updateDomEditHoverSelection(null);
|
|
@@ -82484,11 +82742,11 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82484
82742
|
},
|
|
82485
82743
|
[resolveSelection, updateDomEditHoverSelection]
|
|
82486
82744
|
);
|
|
82487
|
-
const toggleCollapse =
|
|
82745
|
+
const toggleCollapse = useCallback152((key2, e) => {
|
|
82488
82746
|
e.stopPropagation();
|
|
82489
82747
|
setCollapsed((prev) => ({ ...prev, [key2]: !prev[key2] }));
|
|
82490
82748
|
}, []);
|
|
82491
|
-
const handleReorder =
|
|
82749
|
+
const handleReorder = useCallback152(
|
|
82492
82750
|
(event) => {
|
|
82493
82751
|
const { siblingLayers, fromIndex, toIndex } = event;
|
|
82494
82752
|
const reordered = [...siblingLayers];
|
|
@@ -82551,7 +82809,7 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82551
82809
|
);
|
|
82552
82810
|
const selectedKey = domEditSelection ? getDomEditLayerKey(domEditSelection) : null;
|
|
82553
82811
|
const visibleLayers = getVisibleLayers(layers, collapsed);
|
|
82554
|
-
const handleSingleSibling =
|
|
82812
|
+
const handleSingleSibling = useCallback152(() => {
|
|
82555
82813
|
showToast("Only one layer at this level", "info");
|
|
82556
82814
|
}, [showToast]);
|
|
82557
82815
|
const {
|
|
@@ -82683,13 +82941,13 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
82683
82941
|
});
|
|
82684
82942
|
|
|
82685
82943
|
// src/captions/components/CaptionPropertyPanel.tsx
|
|
82686
|
-
import { memo as memo45, useCallback as
|
|
82944
|
+
import { memo as memo45, useCallback as useCallback154, useState as useState135 } from "react";
|
|
82687
82945
|
|
|
82688
82946
|
// src/captions/components/CaptionAnimationPanel.tsx
|
|
82689
|
-
import { memo as memo44, useCallback as
|
|
82947
|
+
import { memo as memo44, useCallback as useCallback153 } from "react";
|
|
82690
82948
|
|
|
82691
82949
|
// src/captions/components/shared.tsx
|
|
82692
|
-
import { useEffect as useEffect125, useRef as
|
|
82950
|
+
import { useEffect as useEffect125, useRef as useRef162, useState as useState134 } from "react";
|
|
82693
82951
|
import { jsx as jsx189, jsxs as jsxs158 } from "react/jsx-runtime";
|
|
82694
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";
|
|
82695
82953
|
function Section2({ label, children }) {
|
|
@@ -82715,7 +82973,7 @@ function NumberField({
|
|
|
82715
82973
|
onCommit
|
|
82716
82974
|
}) {
|
|
82717
82975
|
const [draft, setDraft] = useState134(null);
|
|
82718
|
-
const focusedRef =
|
|
82976
|
+
const focusedRef = useRef162(false);
|
|
82719
82977
|
useEffect125(() => {
|
|
82720
82978
|
if (!focusedRef.current) setDraft(null);
|
|
82721
82979
|
}, [value]);
|
|
@@ -82911,25 +83169,25 @@ var CaptionAnimationPanel = memo44(function CaptionAnimationPanel2() {
|
|
|
82911
83169
|
}
|
|
82912
83170
|
const group = resolvedGroupId ? model?.groups.get(resolvedGroupId) : void 0;
|
|
82913
83171
|
const animation = group?.animation;
|
|
82914
|
-
const handleEntranceChange =
|
|
83172
|
+
const handleEntranceChange = useCallback153(
|
|
82915
83173
|
(update) => {
|
|
82916
83174
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "entrance", update);
|
|
82917
83175
|
},
|
|
82918
83176
|
[resolvedGroupId, updateGroupAnimation]
|
|
82919
83177
|
);
|
|
82920
|
-
const handleHighlightChange =
|
|
83178
|
+
const handleHighlightChange = useCallback153(
|
|
82921
83179
|
(update) => {
|
|
82922
83180
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "highlight", update);
|
|
82923
83181
|
},
|
|
82924
83182
|
[resolvedGroupId, updateGroupAnimation]
|
|
82925
83183
|
);
|
|
82926
|
-
const handleExitChange =
|
|
83184
|
+
const handleExitChange = useCallback153(
|
|
82927
83185
|
(update) => {
|
|
82928
83186
|
if (resolvedGroupId) updateGroupAnimation(resolvedGroupId, "exit", update);
|
|
82929
83187
|
},
|
|
82930
83188
|
[resolvedGroupId, updateGroupAnimation]
|
|
82931
83189
|
);
|
|
82932
|
-
const handleApplyToAll =
|
|
83190
|
+
const handleApplyToAll = useCallback153(() => {
|
|
82933
83191
|
if (animation) applyAnimationToAll(animation);
|
|
82934
83192
|
}, [animation, applyAnimationToAll]);
|
|
82935
83193
|
if (!group || !resolvedGroupId || !animation) {
|
|
@@ -83029,7 +83287,7 @@ var CaptionPropertyPanel = memo45(function CaptionPropertyPanel2({
|
|
|
83029
83287
|
...groupStyle,
|
|
83030
83288
|
...segmentOverrides
|
|
83031
83289
|
};
|
|
83032
|
-
const applyToIframeDom =
|
|
83290
|
+
const applyToIframeDom = useCallback154(
|
|
83033
83291
|
(updates) => {
|
|
83034
83292
|
const iframe = iframeRef.current;
|
|
83035
83293
|
if (!iframe || !model) return;
|
|
@@ -83103,7 +83361,7 @@ var CaptionPropertyPanel = memo45(function CaptionPropertyPanel2({
|
|
|
83103
83361
|
},
|
|
83104
83362
|
[iframeRef, model, selectedSegmentIds]
|
|
83105
83363
|
);
|
|
83106
|
-
const handleStyleChange =
|
|
83364
|
+
const handleStyleChange = useCallback154(
|
|
83107
83365
|
(updates) => {
|
|
83108
83366
|
if (selectedGroupId) {
|
|
83109
83367
|
updateGroupStyle(selectedGroupId, updates);
|
|
@@ -83208,7 +83466,7 @@ var CaptionPropertyPanel = memo45(function CaptionPropertyPanel2({
|
|
|
83208
83466
|
});
|
|
83209
83467
|
|
|
83210
83468
|
// src/components/editor/BlockParamsPanel.tsx
|
|
83211
|
-
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";
|
|
83212
83470
|
import { jsx as jsx192, jsxs as jsxs161 } from "react/jsx-runtime";
|
|
83213
83471
|
var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
83214
83472
|
blockName,
|
|
@@ -83226,12 +83484,12 @@ var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
|
83226
83484
|
}
|
|
83227
83485
|
return initial;
|
|
83228
83486
|
});
|
|
83229
|
-
const appliedRef =
|
|
83487
|
+
const appliedRef = useRef163(
|
|
83230
83488
|
Object.fromEntries(params.map((p) => [p.key, p.default]))
|
|
83231
83489
|
);
|
|
83232
83490
|
const [commitState, setCommitState] = useState136({ tone: "idle" });
|
|
83233
|
-
const commitTimersRef =
|
|
83234
|
-
const commitParamNow =
|
|
83491
|
+
const commitTimersRef = useRef163(/* @__PURE__ */ new Map());
|
|
83492
|
+
const commitParamNow = useCallback155(
|
|
83235
83493
|
async (key2, nextValue) => {
|
|
83236
83494
|
if (!fileManager) return;
|
|
83237
83495
|
const previous = appliedRef.current[key2];
|
|
@@ -83272,8 +83530,8 @@ var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
|
83272
83530
|
},
|
|
83273
83531
|
[fileManager, compositionPath, setRefreshKey, blockName]
|
|
83274
83532
|
);
|
|
83275
|
-
const commitChainRef =
|
|
83276
|
-
const commitParam =
|
|
83533
|
+
const commitChainRef = useRef163(Promise.resolve());
|
|
83534
|
+
const commitParam = useCallback155(
|
|
83277
83535
|
(key2, nextValue) => {
|
|
83278
83536
|
const run = commitChainRef.current.then(() => commitParamNow(key2, nextValue));
|
|
83279
83537
|
commitChainRef.current = run.catch(() => void 0);
|
|
@@ -83281,7 +83539,7 @@ var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
|
83281
83539
|
},
|
|
83282
83540
|
[commitParamNow]
|
|
83283
83541
|
);
|
|
83284
|
-
const handleChange =
|
|
83542
|
+
const handleChange = useCallback155(
|
|
83285
83543
|
(key2, value) => {
|
|
83286
83544
|
setValues((prev) => ({ ...prev, [key2]: value }));
|
|
83287
83545
|
const timers = commitTimersRef.current;
|
|
@@ -83297,7 +83555,7 @@ var BlockParamsPanel = memo46(function BlockParamsPanel2({
|
|
|
83297
83555
|
},
|
|
83298
83556
|
[commitParam]
|
|
83299
83557
|
);
|
|
83300
|
-
const flushRef =
|
|
83558
|
+
const flushRef = useRef163(() => {
|
|
83301
83559
|
});
|
|
83302
83560
|
flushRef.current = () => {
|
|
83303
83561
|
for (const [key2, timer] of commitTimersRef.current) {
|
|
@@ -83439,12 +83697,12 @@ function ParamControl({
|
|
|
83439
83697
|
import { memo as memo50 } from "react";
|
|
83440
83698
|
|
|
83441
83699
|
// src/components/renders/RenderQueue.tsx
|
|
83442
|
-
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";
|
|
83443
83701
|
import { createPortal as createPortal10 } from "react-dom";
|
|
83444
83702
|
import { CANVAS_DIMENSIONS } from "@hyperframes/parsers";
|
|
83445
83703
|
|
|
83446
83704
|
// src/components/renders/RenderQueueItem.tsx
|
|
83447
|
-
import { memo as memo47, useCallback as
|
|
83705
|
+
import { memo as memo47, useCallback as useCallback156, useState as useState137 } from "react";
|
|
83448
83706
|
import { Fragment as Fragment57, jsx as jsx193, jsxs as jsxs162 } from "react/jsx-runtime";
|
|
83449
83707
|
function formatDuration2(ms) {
|
|
83450
83708
|
if (ms < 1e3) return `${ms}ms`;
|
|
@@ -83467,10 +83725,10 @@ var RenderQueueItem = memo47(function RenderQueueItem2({
|
|
|
83467
83725
|
const [videoReady, setVideoReady] = useState137(false);
|
|
83468
83726
|
const [confirmingDelete, setConfirmingDelete] = useState137(false);
|
|
83469
83727
|
const fileSrc = buildProjectApiPath(projectId, `/renders/file/${job.filename}`);
|
|
83470
|
-
const handleOpen =
|
|
83728
|
+
const handleOpen = useCallback156(() => {
|
|
83471
83729
|
window.open(fileSrc, "_blank");
|
|
83472
83730
|
}, [fileSrc]);
|
|
83473
|
-
const handleDownload =
|
|
83731
|
+
const handleDownload = useCallback156(
|
|
83474
83732
|
(e) => {
|
|
83475
83733
|
e.stopPropagation();
|
|
83476
83734
|
const a = document.createElement("a");
|
|
@@ -83670,7 +83928,7 @@ var RenderQueueItem = memo47(function RenderQueueItem2({
|
|
|
83670
83928
|
});
|
|
83671
83929
|
|
|
83672
83930
|
// src/components/renders/FfmpegRequiredNotice.tsx
|
|
83673
|
-
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";
|
|
83674
83932
|
import { jsx as jsx194, jsxs as jsxs163 } from "react/jsx-runtime";
|
|
83675
83933
|
var DOWNLOAD_URL = "https://ffmpeg.org/download.html";
|
|
83676
83934
|
var CUE_MS = 1600;
|
|
@@ -83682,8 +83940,8 @@ var FfmpegRequiredNotice = memo48(function FfmpegRequiredNotice2({
|
|
|
83682
83940
|
}) {
|
|
83683
83941
|
const [copied, setCopied] = useState138(false);
|
|
83684
83942
|
const [recheckFailed, setRecheckFailed] = useState138(false);
|
|
83685
|
-
const wasChecking =
|
|
83686
|
-
const cueTimer =
|
|
83943
|
+
const wasChecking = useRef164(false);
|
|
83944
|
+
const cueTimer = useRef164(void 0);
|
|
83687
83945
|
useEffect127(() => {
|
|
83688
83946
|
if (wasChecking.current && !checking) setRecheckFailed(true);
|
|
83689
83947
|
wasChecking.current = checking;
|
|
@@ -83813,8 +84071,8 @@ var FORMAT_PANEL_SIZE = { width: 208, height: 150 };
|
|
|
83813
84071
|
function FormatInfoTooltip({ format }) {
|
|
83814
84072
|
const [open, setOpen] = useState139(false);
|
|
83815
84073
|
const [position, setPosition] = useState139(null);
|
|
83816
|
-
const triggerRef =
|
|
83817
|
-
const timeoutRef =
|
|
84074
|
+
const triggerRef = useRef165(null);
|
|
84075
|
+
const timeoutRef = useRef165(void 0);
|
|
83818
84076
|
const panelId = useId7();
|
|
83819
84077
|
const show = () => {
|
|
83820
84078
|
clearTimeout(timeoutRef.current);
|
|
@@ -84065,7 +84323,7 @@ var RenderQueue = memo49(function RenderQueue2({
|
|
|
84065
84323
|
ffmpegChecking,
|
|
84066
84324
|
onRecheckFfmpeg
|
|
84067
84325
|
}) {
|
|
84068
|
-
const listRef =
|
|
84326
|
+
const listRef = useRef165(null);
|
|
84069
84327
|
useEffect128(() => {
|
|
84070
84328
|
if (listRef.current) {
|
|
84071
84329
|
listRef.current.scrollTo({ top: listRef.current.scrollHeight, behavior: "smooth" });
|
|
@@ -84214,11 +84472,11 @@ var RenderQueuePanel = memo50(function RenderQueuePanel2() {
|
|
|
84214
84472
|
});
|
|
84215
84473
|
|
|
84216
84474
|
// src/components/panels/SlideshowPanel.tsx
|
|
84217
|
-
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";
|
|
84218
84476
|
import { parseSlideshowManifest } from "@hyperframes/core/slideshow";
|
|
84219
84477
|
|
|
84220
84478
|
// src/components/panels/SlideshowSubPanels.tsx
|
|
84221
|
-
import { useState as useState140, useCallback as
|
|
84479
|
+
import { useState as useState140, useCallback as useCallback157, useId as useId8 } from "react";
|
|
84222
84480
|
import { jsx as jsx197, jsxs as jsxs165 } from "react/jsx-runtime";
|
|
84223
84481
|
function SectionHeader({
|
|
84224
84482
|
children,
|
|
@@ -84406,7 +84664,7 @@ function BranchTree({
|
|
|
84406
84664
|
}) {
|
|
84407
84665
|
const [newLabel, setNewLabel] = useState140("");
|
|
84408
84666
|
const inputId = useId8();
|
|
84409
|
-
const handleCreate =
|
|
84667
|
+
const handleCreate = useCallback157(() => {
|
|
84410
84668
|
const label = newLabel.trim();
|
|
84411
84669
|
if (!label) return;
|
|
84412
84670
|
onCreateSequence(label);
|
|
@@ -84468,7 +84726,7 @@ function BranchItem({
|
|
|
84468
84726
|
const [editing, setEditing] = useState140(false);
|
|
84469
84727
|
const [draft, setDraft] = useState140(seq.label);
|
|
84470
84728
|
const [confirmingDelete, setConfirmingDelete] = useState140(false);
|
|
84471
|
-
const commitRename =
|
|
84729
|
+
const commitRename = useCallback157(() => {
|
|
84472
84730
|
const label = draft.trim();
|
|
84473
84731
|
if (label && label !== seq.label) onRename(seq.id, label);
|
|
84474
84732
|
setEditing(false);
|
|
@@ -84601,7 +84859,7 @@ function HotspotTool({
|
|
|
84601
84859
|
const selectedElementId = domEditSelection?.element?.id ?? null;
|
|
84602
84860
|
const selectedHfId = domEditSelection?.hfId ?? null;
|
|
84603
84861
|
const elementKey2 = selectedElementId || selectedHfId;
|
|
84604
|
-
const handleMakeHotspot =
|
|
84862
|
+
const handleMakeHotspot = useCallback157(() => {
|
|
84605
84863
|
if (!selectedSceneId || !targetSequenceId || !elementKey2) return;
|
|
84606
84864
|
const id = `hotspot-${elementKey2}-${generateId()}`;
|
|
84607
84865
|
const label = hotspotLabel.trim() || elementKey2;
|
|
@@ -84893,12 +85151,12 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84893
85151
|
);
|
|
84894
85152
|
const [persistError, setPersistError] = useState141(false);
|
|
84895
85153
|
const [retrying, setRetrying] = useState141(false);
|
|
84896
|
-
const undoStackRef =
|
|
85154
|
+
const undoStackRef = useRef166([]);
|
|
84897
85155
|
const [undoDepth, setUndoDepth] = useState141(0);
|
|
84898
85156
|
const currentTime = usePlayerStore((s) => s.currentTime);
|
|
84899
85157
|
const { domEditSelection } = useDomEditSelectionContext();
|
|
84900
|
-
const manifestRef =
|
|
84901
|
-
const notesCtrlRef =
|
|
85158
|
+
const manifestRef = useRef166(manifest);
|
|
85159
|
+
const notesCtrlRef = useRef166(makeSlideshowNotesController());
|
|
84902
85160
|
useEffect129(() => {
|
|
84903
85161
|
if (!compHtml) {
|
|
84904
85162
|
notesCtrlRef.current.flush();
|
|
@@ -84915,7 +85173,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84915
85173
|
setUndoDepth(0);
|
|
84916
85174
|
setPersistError(false);
|
|
84917
85175
|
}, [compHtml]);
|
|
84918
|
-
const applyManifest =
|
|
85176
|
+
const applyManifest = useCallback158(
|
|
84919
85177
|
async (next, opts) => {
|
|
84920
85178
|
const merged = notesCtrlRef.current.mergeIntoDiscrete(next);
|
|
84921
85179
|
if (!opts?.skipUndo) {
|
|
@@ -84935,14 +85193,14 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84935
85193
|
},
|
|
84936
85194
|
[onPersist]
|
|
84937
85195
|
);
|
|
84938
|
-
const handleUndo =
|
|
85196
|
+
const handleUndo = useCallback158(() => {
|
|
84939
85197
|
const prev = undoStackRef.current.pop();
|
|
84940
85198
|
if (!prev) return;
|
|
84941
85199
|
setUndoDepth(undoStackRef.current.length);
|
|
84942
85200
|
applyManifest(prev, { skipUndo: true }).catch(() => {
|
|
84943
85201
|
});
|
|
84944
85202
|
}, [applyManifest]);
|
|
84945
|
-
const handleRetryPersist =
|
|
85203
|
+
const handleRetryPersist = useCallback158(async () => {
|
|
84946
85204
|
setRetrying(true);
|
|
84947
85205
|
try {
|
|
84948
85206
|
await onPersist(manifestRef.current);
|
|
@@ -84953,7 +85211,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84953
85211
|
setRetrying(false);
|
|
84954
85212
|
}
|
|
84955
85213
|
}, [onPersist]);
|
|
84956
|
-
const applyNotesManifest =
|
|
85214
|
+
const applyNotesManifest = useCallback158(
|
|
84957
85215
|
(next) => {
|
|
84958
85216
|
setManifest(next);
|
|
84959
85217
|
manifestRef.current = next;
|
|
@@ -84967,7 +85225,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84967
85225
|
ctrl.flush();
|
|
84968
85226
|
};
|
|
84969
85227
|
}, []);
|
|
84970
|
-
const toggleSection =
|
|
85228
|
+
const toggleSection = useCallback158((key2) => {
|
|
84971
85229
|
setExpandedSections((prev) => {
|
|
84972
85230
|
const next = new Set(prev);
|
|
84973
85231
|
if (next.has(key2)) {
|
|
@@ -84981,25 +85239,25 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
84981
85239
|
const activeSlides = selectedSequenceId ? (manifest.slideSequences ?? []).find((s) => s.id === selectedSequenceId)?.slides ?? [] : manifest.slides;
|
|
84982
85240
|
const selectedSlide = activeSlides.find((s) => s.sceneId === selectedSceneId);
|
|
84983
85241
|
const sequences = manifest.slideSequences ?? [];
|
|
84984
|
-
const handleSelectBranchSlide =
|
|
85242
|
+
const handleSelectBranchSlide = useCallback158((sequenceId, sceneId) => {
|
|
84985
85243
|
setSelectedSceneId(sceneId);
|
|
84986
85244
|
setSelectedSequenceId(sequenceId);
|
|
84987
85245
|
}, []);
|
|
84988
|
-
const handleToggleSlide =
|
|
85246
|
+
const handleToggleSlide = useCallback158(
|
|
84989
85247
|
(sceneId) => {
|
|
84990
85248
|
applyManifest(toggleMainLineSlide(manifestRef.current, sceneId)).catch(() => {
|
|
84991
85249
|
});
|
|
84992
85250
|
},
|
|
84993
85251
|
[applyManifest]
|
|
84994
85252
|
);
|
|
84995
|
-
const handleReorder =
|
|
85253
|
+
const handleReorder = useCallback158(
|
|
84996
85254
|
(sceneId, dir) => {
|
|
84997
85255
|
applyManifest(reorderMainLineSlide(manifestRef.current, sceneId, dir)).catch(() => {
|
|
84998
85256
|
});
|
|
84999
85257
|
},
|
|
85000
85258
|
[applyManifest]
|
|
85001
85259
|
);
|
|
85002
|
-
const handleSetNotes =
|
|
85260
|
+
const handleSetNotes = useCallback158(
|
|
85003
85261
|
(notes) => {
|
|
85004
85262
|
if (!selectedSceneId) return;
|
|
85005
85263
|
applyNotesManifest(
|
|
@@ -85008,7 +85266,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85008
85266
|
},
|
|
85009
85267
|
[selectedSceneId, selectedSequenceId, applyNotesManifest]
|
|
85010
85268
|
);
|
|
85011
|
-
const handleMarkFragment =
|
|
85269
|
+
const handleMarkFragment = useCallback158(() => {
|
|
85012
85270
|
if (!selectedSceneId) return;
|
|
85013
85271
|
applyManifest(
|
|
85014
85272
|
addFragment(
|
|
@@ -85020,7 +85278,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85020
85278
|
).catch(() => {
|
|
85021
85279
|
});
|
|
85022
85280
|
}, [selectedSceneId, selectedSequenceId, currentTime, applyManifest]);
|
|
85023
|
-
const handleRemoveFragment =
|
|
85281
|
+
const handleRemoveFragment = useCallback158(
|
|
85024
85282
|
(time) => {
|
|
85025
85283
|
if (!selectedSceneId) return;
|
|
85026
85284
|
applyManifest(
|
|
@@ -85030,7 +85288,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85030
85288
|
},
|
|
85031
85289
|
[selectedSceneId, selectedSequenceId, applyManifest]
|
|
85032
85290
|
);
|
|
85033
|
-
const handleCreateSequence =
|
|
85291
|
+
const handleCreateSequence = useCallback158(
|
|
85034
85292
|
(label) => {
|
|
85035
85293
|
const id = `seq-${generateId()}`;
|
|
85036
85294
|
applyManifest(createSequence(manifestRef.current, id, label)).catch(() => {
|
|
@@ -85038,21 +85296,21 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85038
85296
|
},
|
|
85039
85297
|
[applyManifest]
|
|
85040
85298
|
);
|
|
85041
|
-
const handleRenameSequence =
|
|
85299
|
+
const handleRenameSequence = useCallback158(
|
|
85042
85300
|
(id, label) => {
|
|
85043
85301
|
applyManifest(renameSequence(manifestRef.current, id, label)).catch(() => {
|
|
85044
85302
|
});
|
|
85045
85303
|
},
|
|
85046
85304
|
[applyManifest]
|
|
85047
85305
|
);
|
|
85048
|
-
const handleDeleteSequence =
|
|
85306
|
+
const handleDeleteSequence = useCallback158(
|
|
85049
85307
|
(id) => {
|
|
85050
85308
|
applyManifest(deleteSequence(manifestRef.current, id)).catch(() => {
|
|
85051
85309
|
});
|
|
85052
85310
|
},
|
|
85053
85311
|
[applyManifest]
|
|
85054
85312
|
);
|
|
85055
|
-
const handleAssign =
|
|
85313
|
+
const handleAssign = useCallback158(
|
|
85056
85314
|
(sequenceId, sceneId, assign) => {
|
|
85057
85315
|
applyManifest(assignToBranch(manifestRef.current, sequenceId, sceneId, assign)).catch(
|
|
85058
85316
|
() => {
|
|
@@ -85061,7 +85319,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85061
85319
|
},
|
|
85062
85320
|
[applyManifest]
|
|
85063
85321
|
);
|
|
85064
|
-
const handleAddHotspot =
|
|
85322
|
+
const handleAddHotspot = useCallback158(
|
|
85065
85323
|
(sceneId, hotspot) => {
|
|
85066
85324
|
applyManifest(
|
|
85067
85325
|
addHotspot(manifestRef.current, sceneId, hotspot, selectedSequenceId ?? void 0)
|
|
@@ -85070,7 +85328,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85070
85328
|
},
|
|
85071
85329
|
[selectedSequenceId, applyManifest]
|
|
85072
85330
|
);
|
|
85073
|
-
const handleRemoveHotspot =
|
|
85331
|
+
const handleRemoveHotspot = useCallback158(
|
|
85074
85332
|
(sceneId, hotspotId) => {
|
|
85075
85333
|
applyManifest(
|
|
85076
85334
|
removeHotspot(manifestRef.current, sceneId, hotspotId, selectedSequenceId ?? void 0)
|
|
@@ -85223,10 +85481,10 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
85223
85481
|
}
|
|
85224
85482
|
|
|
85225
85483
|
// src/components/panels/VariablesPanel.tsx
|
|
85226
|
-
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";
|
|
85227
85485
|
|
|
85228
85486
|
// src/hooks/useVariablesPersist.ts
|
|
85229
|
-
import { useCallback as
|
|
85487
|
+
import { useCallback as useCallback159 } from "react";
|
|
85230
85488
|
function useVariablesPersist({
|
|
85231
85489
|
sdkSession,
|
|
85232
85490
|
activeCompPath,
|
|
@@ -85236,7 +85494,7 @@ function useVariablesPersist({
|
|
|
85236
85494
|
reloadPreview,
|
|
85237
85495
|
publishSdkSession
|
|
85238
85496
|
}) {
|
|
85239
|
-
return
|
|
85497
|
+
return useCallback159(
|
|
85240
85498
|
async (label, mutate) => {
|
|
85241
85499
|
if (!sdkSession) return false;
|
|
85242
85500
|
const path = activeCompPath ?? "index.html";
|
|
@@ -85271,10 +85529,10 @@ function useVariablesPersist({
|
|
|
85271
85529
|
}
|
|
85272
85530
|
|
|
85273
85531
|
// src/components/panels/VariablesOtherCompositions.tsx
|
|
85274
|
-
import { useCallback as
|
|
85532
|
+
import { useCallback as useCallback161, useState as useState144 } from "react";
|
|
85275
85533
|
|
|
85276
85534
|
// src/hooks/useProjectCompositionVariables.ts
|
|
85277
|
-
import { useCallback as
|
|
85535
|
+
import { useCallback as useCallback160, useEffect as useEffect130, useState as useState142 } from "react";
|
|
85278
85536
|
import { openComposition as openComposition4 } from "@hyperframes/sdk";
|
|
85279
85537
|
async function readGroup(path, readProjectFile) {
|
|
85280
85538
|
let content;
|
|
@@ -85317,7 +85575,7 @@ function useProjectCompositionVariables(fileTree, excludePath, readProjectFile,
|
|
|
85317
85575
|
}
|
|
85318
85576
|
function useEditVariablesInFile(deps) {
|
|
85319
85577
|
const { readProjectFile, writeProjectFile, recordEdit, reloadPreview } = deps;
|
|
85320
|
-
return
|
|
85578
|
+
return useCallback160(
|
|
85321
85579
|
async (path, label, mutate) => {
|
|
85322
85580
|
const originalContent = await readProjectFile(path);
|
|
85323
85581
|
await persistSdkSerialize(
|
|
@@ -85694,7 +85952,7 @@ function VariablesOtherCompositions({
|
|
|
85694
85952
|
reloadPreview
|
|
85695
85953
|
});
|
|
85696
85954
|
const [editingKey, setEditingKey] = useState144(null);
|
|
85697
|
-
const onSave =
|
|
85955
|
+
const onSave = useCallback161(
|
|
85698
85956
|
(path, decl) => {
|
|
85699
85957
|
setEditingKey(null);
|
|
85700
85958
|
void editInFile(
|
|
@@ -85705,7 +85963,7 @@ function VariablesOtherCompositions({
|
|
|
85705
85963
|
},
|
|
85706
85964
|
[editInFile]
|
|
85707
85965
|
);
|
|
85708
|
-
const onRemove =
|
|
85966
|
+
const onRemove = useCallback161(
|
|
85709
85967
|
(path, id) => {
|
|
85710
85968
|
void editInFile(
|
|
85711
85969
|
path,
|
|
@@ -85898,9 +86156,9 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85898
86156
|
}) {
|
|
85899
86157
|
const { activeCompPath, showToast } = useStudioShellContext();
|
|
85900
86158
|
const { refreshKey } = useStudioPlaybackContext();
|
|
85901
|
-
const { readProjectFile, writeProjectFile, fileTree } = useFileManagerContext();
|
|
86159
|
+
const { readProjectFile, writeProjectFile, fileTree, compositions } = useFileManagerContext();
|
|
85902
86160
|
const { domEditSelection } = useDomEditContext();
|
|
85903
|
-
const effectiveCompPath = activeCompPath ?? resolveMasterCompositionPath(
|
|
86161
|
+
const effectiveCompPath = activeCompPath ?? resolveMasterCompositionPath(compositions);
|
|
85904
86162
|
const previewValues = usePreviewVariablesStore((s) => s.values);
|
|
85905
86163
|
const setPreviewValues = usePreviewVariablesStore((s) => s.setValues);
|
|
85906
86164
|
const [revision, setRevision] = useState145(0);
|
|
@@ -85919,27 +86177,27 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85919
86177
|
reloadPreview,
|
|
85920
86178
|
publishSdkSession
|
|
85921
86179
|
});
|
|
85922
|
-
const declarations =
|
|
86180
|
+
const declarations = useMemo73(
|
|
85923
86181
|
() => sdkSession?.getVariableDeclarations() ?? [],
|
|
85924
86182
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85925
86183
|
[sdkSession, refreshKey, revision]
|
|
85926
86184
|
);
|
|
85927
|
-
const usage =
|
|
86185
|
+
const usage = useMemo73(
|
|
85928
86186
|
() => sdkSession?.getVariableUsage() ?? null,
|
|
85929
86187
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85930
86188
|
[sdkSession, refreshKey, revision]
|
|
85931
86189
|
);
|
|
85932
|
-
const issues =
|
|
86190
|
+
const issues = useMemo73(
|
|
85933
86191
|
() => previewValues && sdkSession ? sdkSession.validateVariableValues(previewValues) : [],
|
|
85934
86192
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85935
86193
|
[sdkSession, previewValues, refreshKey, revision]
|
|
85936
86194
|
);
|
|
85937
|
-
const effectiveValues =
|
|
86195
|
+
const effectiveValues = useMemo73(
|
|
85938
86196
|
() => sdkSession?.getVariableValues(previewValues ?? void 0) ?? {},
|
|
85939
86197
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85940
86198
|
[sdkSession, previewValues, refreshKey, revision]
|
|
85941
86199
|
);
|
|
85942
|
-
const copyToClipboard =
|
|
86200
|
+
const copyToClipboard = useCallback162(
|
|
85943
86201
|
(text, what) => {
|
|
85944
86202
|
void copyTextToClipboard(text).then(
|
|
85945
86203
|
(ok) => showToast(
|
|
@@ -85950,7 +86208,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85950
86208
|
},
|
|
85951
86209
|
[showToast]
|
|
85952
86210
|
);
|
|
85953
|
-
const dropPreviewOverride =
|
|
86211
|
+
const dropPreviewOverride = useCallback162(
|
|
85954
86212
|
(id) => {
|
|
85955
86213
|
if (previewValues && id in previewValues) {
|
|
85956
86214
|
const next = { ...previewValues };
|
|
@@ -85960,7 +86218,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85960
86218
|
},
|
|
85961
86219
|
[previewValues, setPreviewValues]
|
|
85962
86220
|
);
|
|
85963
|
-
const commitPreviewValue =
|
|
86221
|
+
const commitPreviewValue = useCallback162(
|
|
85964
86222
|
(id, value, declDefault) => {
|
|
85965
86223
|
const next = { ...previewValues ?? {} };
|
|
85966
86224
|
if (JSON.stringify(value) === JSON.stringify(declDefault)) {
|
|
@@ -85973,7 +86231,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85973
86231
|
},
|
|
85974
86232
|
[previewValues, setPreviewValues, reloadPreview]
|
|
85975
86233
|
);
|
|
85976
|
-
const runSchemaEdit =
|
|
86234
|
+
const runSchemaEdit = useCallback162(
|
|
85977
86235
|
async (label, mutate) => {
|
|
85978
86236
|
try {
|
|
85979
86237
|
const changed = await persistVariables(label, mutate);
|
|
@@ -85987,7 +86245,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
85987
86245
|
},
|
|
85988
86246
|
[persistVariables, showToast]
|
|
85989
86247
|
);
|
|
85990
|
-
const handleAdd =
|
|
86248
|
+
const handleAdd = useCallback162(
|
|
85991
86249
|
(decl) => {
|
|
85992
86250
|
if (!sdkSession) return;
|
|
85993
86251
|
const check = sdkSession.can({ type: "declareVariable", declaration: decl });
|
|
@@ -86000,7 +86258,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
86000
86258
|
},
|
|
86001
86259
|
[sdkSession, runSchemaEdit, showToast]
|
|
86002
86260
|
);
|
|
86003
|
-
const handleUpdate =
|
|
86261
|
+
const handleUpdate = useCallback162(
|
|
86004
86262
|
(decl) => {
|
|
86005
86263
|
if (!sdkSession) return;
|
|
86006
86264
|
const check = sdkSession.can({
|
|
@@ -86020,7 +86278,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
86020
86278
|
},
|
|
86021
86279
|
[sdkSession, runSchemaEdit, showToast]
|
|
86022
86280
|
);
|
|
86023
|
-
const handleRemove =
|
|
86281
|
+
const handleRemove = useCallback162(
|
|
86024
86282
|
(id) => {
|
|
86025
86283
|
if (!sdkSession) return;
|
|
86026
86284
|
const check = sdkSession.can({ type: "removeVariableDeclaration", id });
|
|
@@ -86036,18 +86294,18 @@ var VariablesPanel = memo51(function VariablesPanel2({
|
|
|
86036
86294
|
},
|
|
86037
86295
|
[sdkSession, runSchemaEdit, dropPreviewOverride, showToast]
|
|
86038
86296
|
);
|
|
86039
|
-
const handleSetDefault =
|
|
86297
|
+
const handleSetDefault = useCallback162(
|
|
86040
86298
|
(id, value) => {
|
|
86041
86299
|
void runSchemaEdit(`Set default for "${id}"`, (s) => s.setVariableValue(id, value));
|
|
86042
86300
|
dropPreviewOverride(id);
|
|
86043
86301
|
},
|
|
86044
86302
|
[runSchemaEdit, dropPreviewOverride]
|
|
86045
86303
|
);
|
|
86046
|
-
const resetPreview =
|
|
86304
|
+
const resetPreview = useCallback162(() => {
|
|
86047
86305
|
setPreviewValues(null);
|
|
86048
86306
|
reloadPreview();
|
|
86049
86307
|
}, [setPreviewValues, reloadPreview]);
|
|
86050
|
-
const handleBind =
|
|
86308
|
+
const handleBind = useCallback162(
|
|
86051
86309
|
// Guard chain (session, selection, type-compat) — one branch per guard.
|
|
86052
86310
|
// fallow-ignore-next-line complexity
|
|
86053
86311
|
(action, id) => {
|
|
@@ -86179,7 +86437,7 @@ function PanelTabButton({
|
|
|
86179
86437
|
}
|
|
86180
86438
|
|
|
86181
86439
|
// src/hooks/useSlideshowPersist.ts
|
|
86182
|
-
import { useCallback as
|
|
86440
|
+
import { useCallback as useCallback163 } from "react";
|
|
86183
86441
|
|
|
86184
86442
|
// src/utils/setSlideshowManifest.ts
|
|
86185
86443
|
import {
|
|
@@ -86236,7 +86494,7 @@ function useSlideshowPersist({
|
|
|
86236
86494
|
publishSdkSession,
|
|
86237
86495
|
coalesceKey
|
|
86238
86496
|
}) {
|
|
86239
|
-
return
|
|
86497
|
+
return useCallback163(
|
|
86240
86498
|
async (manifest) => {
|
|
86241
86499
|
if (!sdkSession) return;
|
|
86242
86500
|
const path = activeCompPath ?? "index.html";
|
|
@@ -86269,15 +86527,15 @@ function useSlideshowPersist({
|
|
|
86269
86527
|
}
|
|
86270
86528
|
|
|
86271
86529
|
// src/hooks/useSlideshowTabState.ts
|
|
86272
|
-
import { useEffect as useEffect132, useMemo as
|
|
86530
|
+
import { useEffect as useEffect132, useMemo as useMemo74 } from "react";
|
|
86273
86531
|
import { SLIDESHOW_ISLAND_TYPE as SLIDESHOW_ISLAND_TYPE2, slideshowIslandRegex as slideshowIslandRegex2 } from "@hyperframes/core/slideshow";
|
|
86274
86532
|
function useSlideshowTabState(params) {
|
|
86275
86533
|
const { editingFileContent, previewIframeRef, refreshKey, rightPanelTab, setRightPanelTab } = params;
|
|
86276
|
-
const isSlideshowComposition =
|
|
86534
|
+
const isSlideshowComposition = useMemo74(() => {
|
|
86277
86535
|
if (!editingFileContent || !editingFileContent.includes(SLIDESHOW_ISLAND_TYPE2)) return false;
|
|
86278
86536
|
return slideshowIslandRegex2("i").test(editingFileContent);
|
|
86279
86537
|
}, [editingFileContent]);
|
|
86280
|
-
const slideshowScenes =
|
|
86538
|
+
const slideshowScenes = useMemo74(() => {
|
|
86281
86539
|
try {
|
|
86282
86540
|
const win = previewIframeRef.current?.contentWindow;
|
|
86283
86541
|
return (win?.__clipManifest?.scenes ?? []).map((s) => ({
|
|
@@ -86299,7 +86557,7 @@ function useSlideshowTabState(params) {
|
|
|
86299
86557
|
}
|
|
86300
86558
|
|
|
86301
86559
|
// src/components/DesignPanelPromoteProvider.tsx
|
|
86302
|
-
import { useCallback as
|
|
86560
|
+
import { useCallback as useCallback164 } from "react";
|
|
86303
86561
|
import { jsx as jsx204 } from "react/jsx-runtime";
|
|
86304
86562
|
function DesignPanelPromoteProvider({
|
|
86305
86563
|
selection,
|
|
@@ -86318,7 +86576,7 @@ function DesignPanelPromoteProvider({
|
|
|
86318
86576
|
publishSdkSession: handle.publish,
|
|
86319
86577
|
activeCompPath: targetPath
|
|
86320
86578
|
});
|
|
86321
|
-
const persist2 =
|
|
86579
|
+
const persist2 = useCallback164(
|
|
86322
86580
|
async (label, mutate) => {
|
|
86323
86581
|
const committed = await rawPersist(label, mutate);
|
|
86324
86582
|
if (committed) forceReloadSharedSdkSession?.();
|
|
@@ -86326,7 +86584,7 @@ function DesignPanelPromoteProvider({
|
|
|
86326
86584
|
},
|
|
86327
86585
|
[rawPersist, forceReloadSharedSdkSession]
|
|
86328
86586
|
);
|
|
86329
|
-
const handlePersistError =
|
|
86587
|
+
const handlePersistError = useCallback164(
|
|
86330
86588
|
(error) => showToast(getStudioSaveErrorMessage(error), "error"),
|
|
86331
86589
|
[showToast]
|
|
86332
86590
|
);
|
|
@@ -86559,14 +86817,14 @@ async function applyColorGradingScopeUpdate({
|
|
|
86559
86817
|
}
|
|
86560
86818
|
|
|
86561
86819
|
// src/hooks/useInspectorSplitResize.ts
|
|
86562
|
-
import { useCallback as
|
|
86820
|
+
import { useCallback as useCallback165, useRef as useRef167, useState as useState146 } from "react";
|
|
86563
86821
|
var MIN_INSPECTOR_SPLIT_PERCENT = 20;
|
|
86564
86822
|
var MAX_INSPECTOR_SPLIT_PERCENT = 75;
|
|
86565
86823
|
function useInspectorSplitResize() {
|
|
86566
86824
|
const [layersPanePercent, setLayersPanePercent] = useState146(40);
|
|
86567
|
-
const splitContainerRef =
|
|
86568
|
-
const splitDragRef =
|
|
86569
|
-
const handleInspectorSplitResizeStart =
|
|
86825
|
+
const splitContainerRef = useRef167(null);
|
|
86826
|
+
const splitDragRef = useRef167(null);
|
|
86827
|
+
const handleInspectorSplitResizeStart = useCallback165(
|
|
86570
86828
|
(event) => {
|
|
86571
86829
|
event.preventDefault();
|
|
86572
86830
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
@@ -86579,7 +86837,7 @@ function useInspectorSplitResize() {
|
|
|
86579
86837
|
},
|
|
86580
86838
|
[layersPanePercent]
|
|
86581
86839
|
);
|
|
86582
|
-
const handleInspectorSplitResizeMove =
|
|
86840
|
+
const handleInspectorSplitResizeMove = useCallback165((event) => {
|
|
86583
86841
|
const drag = splitDragRef.current;
|
|
86584
86842
|
if (!drag || drag.height <= 0) return;
|
|
86585
86843
|
const deltaPercent = (event.clientY - drag.startY) / drag.height * 100;
|
|
@@ -86589,7 +86847,7 @@ function useInspectorSplitResize() {
|
|
|
86589
86847
|
);
|
|
86590
86848
|
setLayersPanePercent(next);
|
|
86591
86849
|
}, []);
|
|
86592
|
-
const handleInspectorSplitResizeEnd =
|
|
86850
|
+
const handleInspectorSplitResizeEnd = useCallback165(() => {
|
|
86593
86851
|
splitDragRef.current = null;
|
|
86594
86852
|
}, []);
|
|
86595
86853
|
return {
|
|
@@ -86602,16 +86860,16 @@ function useInspectorSplitResize() {
|
|
|
86602
86860
|
}
|
|
86603
86861
|
|
|
86604
86862
|
// src/hooks/useRemoveBackground.ts
|
|
86605
|
-
import { useCallback as
|
|
86863
|
+
import { useCallback as useCallback166, useEffect as useEffect133, useRef as useRef168 } from "react";
|
|
86606
86864
|
function useRemoveBackground(projectId, refreshFileTree, showToast) {
|
|
86607
|
-
const abortRef =
|
|
86865
|
+
const abortRef = useRef168(null);
|
|
86608
86866
|
useEffect133(
|
|
86609
86867
|
() => () => {
|
|
86610
86868
|
abortRef.current?.abort();
|
|
86611
86869
|
},
|
|
86612
86870
|
[]
|
|
86613
86871
|
);
|
|
86614
|
-
return
|
|
86872
|
+
return useCallback166(
|
|
86615
86873
|
// fallow-ignore-next-line complexity
|
|
86616
86874
|
async (inputPath, options) => {
|
|
86617
86875
|
const response = await fetch(
|
|
@@ -86793,7 +87051,7 @@ function StudioRightPanel({
|
|
|
86793
87051
|
}
|
|
86794
87052
|
toggleRightInspectorPane(pane);
|
|
86795
87053
|
};
|
|
86796
|
-
const handleApplyColorGradingScope =
|
|
87054
|
+
const handleApplyColorGradingScope = useCallback167(
|
|
86797
87055
|
async (scope, value) => applyColorGradingScopeUpdate({
|
|
86798
87056
|
scope,
|
|
86799
87057
|
value,
|
|
@@ -86827,7 +87085,7 @@ function StudioRightPanel({
|
|
|
86827
87085
|
]
|
|
86828
87086
|
);
|
|
86829
87087
|
const handleRemoveBackground = useRemoveBackground(projectId, refreshFileTree, showToast);
|
|
86830
|
-
const setAttributeWhileDragging =
|
|
87088
|
+
const setAttributeWhileDragging = useCallback167(
|
|
86831
87089
|
(attr, value) => handleDomAttributeLiveCommit(attr, value, void 0, { previewOnly: true }),
|
|
86832
87090
|
[handleDomAttributeLiveCommit]
|
|
86833
87091
|
);
|
|
@@ -87075,11 +87333,17 @@ function StudioRightPanel({
|
|
|
87075
87333
|
}
|
|
87076
87334
|
|
|
87077
87335
|
// src/components/TimelineToolbar.tsx
|
|
87078
|
-
import { useEffect as useEffect135, useRef as
|
|
87079
|
-
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";
|
|
87080
87344
|
|
|
87081
87345
|
// src/hooks/useEnableKeyframes.ts
|
|
87082
|
-
import { useCallback as
|
|
87346
|
+
import { useCallback as useCallback168 } from "react";
|
|
87083
87347
|
var enableKeyframesTransactionCounter = 0;
|
|
87084
87348
|
function animatedProps(anim) {
|
|
87085
87349
|
if (!anim) return ["x", "y"];
|
|
@@ -87332,7 +87596,7 @@ async function applyArcKeyframeAtPlayhead(session, sel, arcAnim, t, iframe) {
|
|
|
87332
87596
|
);
|
|
87333
87597
|
}
|
|
87334
87598
|
function useEnableKeyframes(sessionRef) {
|
|
87335
|
-
return
|
|
87599
|
+
return useCallback168(async () => {
|
|
87336
87600
|
const session = sessionRef.current;
|
|
87337
87601
|
if (!session) return;
|
|
87338
87602
|
const sel = session.domEditSelection;
|
|
@@ -87414,7 +87678,7 @@ function useEnableKeyframes(sessionRef) {
|
|
|
87414
87678
|
}
|
|
87415
87679
|
|
|
87416
87680
|
// src/hooks/useKeyframeKeyboard.ts
|
|
87417
|
-
import { useEffect as useEffect134, useCallback as
|
|
87681
|
+
import { useEffect as useEffect134, useCallback as useCallback169 } from "react";
|
|
87418
87682
|
function isTextInput2(el) {
|
|
87419
87683
|
if (!el) return false;
|
|
87420
87684
|
const tag = el.tagName;
|
|
@@ -87431,7 +87695,7 @@ function useKeyframeKeyboard({
|
|
|
87431
87695
|
onToggleExpand,
|
|
87432
87696
|
onNudgeKeyframe
|
|
87433
87697
|
}) {
|
|
87434
|
-
const handler =
|
|
87698
|
+
const handler = useCallback169(
|
|
87435
87699
|
(e) => {
|
|
87436
87700
|
if (!enabled) return;
|
|
87437
87701
|
if (isTextInput2(document.activeElement)) return;
|
|
@@ -87532,7 +87796,7 @@ function useKeyframeToggle(session) {
|
|
|
87532
87796
|
const currentTime = usePlayerStore((s) => s.currentTime);
|
|
87533
87797
|
const selectedElementId = usePlayerStore((s) => s.selectedElementId);
|
|
87534
87798
|
const elements = usePlayerStore((s) => s.elements);
|
|
87535
|
-
const sessionRef =
|
|
87799
|
+
const sessionRef = useRef169(session);
|
|
87536
87800
|
sessionRef.current = session;
|
|
87537
87801
|
const onToggle = useEnableKeyframes(
|
|
87538
87802
|
sessionRef
|
|
@@ -87550,6 +87814,8 @@ function TimelineToolbar({ domEditSession, onSplitElement }) {
|
|
|
87550
87814
|
const setActiveTool = usePlayerStore((s) => s.setActiveTool);
|
|
87551
87815
|
const timelineSnapEnabled = usePlayerStore((s) => s.timelineSnapEnabled);
|
|
87552
87816
|
const setTimelineSnapEnabled = usePlayerStore((s) => s.setTimelineSnapEnabled);
|
|
87817
|
+
const rippleEditEnabled = usePlayerStore((s) => s.rippleEditEnabled);
|
|
87818
|
+
const setRippleEditEnabled = usePlayerStore((s) => s.setRippleEditEnabled);
|
|
87553
87819
|
const autoKeyframeEnabled = usePlayerStore((s) => s.autoKeyframeEnabled);
|
|
87554
87820
|
const setAutoKeyframeEnabled = usePlayerStore((s) => s.setAutoKeyframeEnabled);
|
|
87555
87821
|
const thumbnailMode = usePlayerStore((s) => s.thumbnailMode);
|
|
@@ -87634,6 +87900,23 @@ function TimelineToolbar({ domEditSession, onSplitElement }) {
|
|
|
87634
87900
|
children: /* @__PURE__ */ jsx206(Magnet, { size: 16, weight: "bold", "aria-hidden": "true" })
|
|
87635
87901
|
}
|
|
87636
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
|
+
),
|
|
87637
87920
|
/* @__PURE__ */ jsx206(
|
|
87638
87921
|
Tooltip,
|
|
87639
87922
|
{
|
|
@@ -87855,15 +88138,15 @@ import { useState as useState154 } from "react";
|
|
|
87855
88138
|
import { Copy as Copy2, Check as Check2 } from "@phosphor-icons/react";
|
|
87856
88139
|
|
|
87857
88140
|
// src/hooks/useStoryboard.ts
|
|
87858
|
-
import { useCallback as
|
|
88141
|
+
import { useCallback as useCallback170, useEffect as useEffect136, useRef as useRef170, useState as useState147 } from "react";
|
|
87859
88142
|
function useStoryboard(projectId) {
|
|
87860
88143
|
const [data, setData] = useState147(null);
|
|
87861
88144
|
const [loading, setLoading] = useState147(true);
|
|
87862
88145
|
const [error, setError] = useState147(null);
|
|
87863
88146
|
const [reloadKey, setReloadKey] = useState147(0);
|
|
87864
|
-
const hasDataRef =
|
|
87865
|
-
const lastProjectRef =
|
|
87866
|
-
const reload =
|
|
88147
|
+
const hasDataRef = useRef170(false);
|
|
88148
|
+
const lastProjectRef = useRef170(null);
|
|
88149
|
+
const reload = useCallback170(() => setReloadKey((k) => k + 1), []);
|
|
87867
88150
|
useEffect136(() => {
|
|
87868
88151
|
if (!projectId) return;
|
|
87869
88152
|
let cancelled = false;
|
|
@@ -87896,7 +88179,7 @@ function useStoryboard(projectId) {
|
|
|
87896
88179
|
}
|
|
87897
88180
|
|
|
87898
88181
|
// src/hooks/useProjectSignaturePoll.ts
|
|
87899
|
-
import { useEffect as useEffect137, useRef as
|
|
88182
|
+
import { useEffect as useEffect137, useRef as useRef171 } from "react";
|
|
87900
88183
|
var POLL_INTERVAL_MS = 2e3;
|
|
87901
88184
|
async function fetchProjectSignature(projectId) {
|
|
87902
88185
|
try {
|
|
@@ -87909,8 +88192,8 @@ async function fetchProjectSignature(projectId) {
|
|
|
87909
88192
|
}
|
|
87910
88193
|
}
|
|
87911
88194
|
function useProjectSignaturePoll(projectId, currentSignature, onChange) {
|
|
87912
|
-
const signatureRef =
|
|
87913
|
-
const onChangeRef =
|
|
88195
|
+
const signatureRef = useRef171(currentSignature);
|
|
88196
|
+
const onChangeRef = useRef171(onChange);
|
|
87914
88197
|
signatureRef.current = currentSignature;
|
|
87915
88198
|
onChangeRef.current = onChange;
|
|
87916
88199
|
useEffect137(() => {
|
|
@@ -87940,7 +88223,7 @@ function useProjectSignaturePoll(projectId, currentSignature, onChange) {
|
|
|
87940
88223
|
}
|
|
87941
88224
|
|
|
87942
88225
|
// src/components/storyboard/StoryboardLoaded.tsx
|
|
87943
|
-
import { useEffect as useEffect143, useMemo as
|
|
88226
|
+
import { useEffect as useEffect143, useMemo as useMemo77, useState as useState153 } from "react";
|
|
87944
88227
|
|
|
87945
88228
|
// src/components/storyboard/StoryboardDirection.tsx
|
|
87946
88229
|
import { jsx as jsx207, jsxs as jsxs172 } from "react/jsx-runtime";
|
|
@@ -88177,7 +88460,7 @@ function StoryboardScriptPanel({ script }) {
|
|
|
88177
88460
|
}
|
|
88178
88461
|
|
|
88179
88462
|
// src/components/storyboard/StoryboardSourceEditor.tsx
|
|
88180
|
-
import { useCallback as
|
|
88463
|
+
import { useCallback as useCallback171, useEffect as useEffect139, useMemo as useMemo75, useRef as useRef172, useState as useState149 } from "react";
|
|
88181
88464
|
import { marked } from "marked";
|
|
88182
88465
|
import DOMPurify from "dompurify";
|
|
88183
88466
|
import { jsx as jsx212, jsxs as jsxs175 } from "react/jsx-runtime";
|
|
@@ -88207,7 +88490,7 @@ function useEditableFile(path, onSaved) {
|
|
|
88207
88490
|
cancelled = true;
|
|
88208
88491
|
};
|
|
88209
88492
|
}, [path, readProjectFile]);
|
|
88210
|
-
const save =
|
|
88493
|
+
const save = useCallback171(() => {
|
|
88211
88494
|
if (saving) return;
|
|
88212
88495
|
setSaving(true);
|
|
88213
88496
|
setError(null);
|
|
@@ -88226,7 +88509,7 @@ function hardenLinks(node) {
|
|
|
88226
88509
|
}
|
|
88227
88510
|
function useMarkdownPreview(source) {
|
|
88228
88511
|
const [debounced, setDebounced] = useState149(source);
|
|
88229
|
-
const primed =
|
|
88512
|
+
const primed = useRef172(false);
|
|
88230
88513
|
useEffect139(() => {
|
|
88231
88514
|
if (!primed.current && source !== "") {
|
|
88232
88515
|
primed.current = true;
|
|
@@ -88236,7 +88519,7 @@ function useMarkdownPreview(source) {
|
|
|
88236
88519
|
const id = window.setTimeout(() => setDebounced(source), 200);
|
|
88237
88520
|
return () => window.clearTimeout(id);
|
|
88238
88521
|
}, [source]);
|
|
88239
|
-
return
|
|
88522
|
+
return useMemo75(() => {
|
|
88240
88523
|
const html2 = marked.parse(debounced, { async: false });
|
|
88241
88524
|
DOMPurify.addHook("afterSanitizeAttributes", hardenLinks);
|
|
88242
88525
|
try {
|
|
@@ -88332,7 +88615,7 @@ function StoryboardSourceEditor({
|
|
|
88332
88615
|
}
|
|
88333
88616
|
|
|
88334
88617
|
// src/components/storyboard/StoryboardFrameFocus.tsx
|
|
88335
|
-
import { useCallback as
|
|
88618
|
+
import { useCallback as useCallback172, useEffect as useEffect141, useState as useState151 } from "react";
|
|
88336
88619
|
import { setFrameVoiceover } from "@hyperframes/core/storyboard";
|
|
88337
88620
|
|
|
88338
88621
|
// src/components/storyboard/AgentChatMessageButton.tsx
|
|
@@ -88392,7 +88675,7 @@ function StoryboardFrameFocus({
|
|
|
88392
88675
|
const [savedVoiceover, setSavedVoiceover] = useState151(frame.voiceover ?? "");
|
|
88393
88676
|
const [busy, setBusy] = useState151(false);
|
|
88394
88677
|
const [error, setError] = useState151(null);
|
|
88395
|
-
const applyEdit =
|
|
88678
|
+
const applyEdit = useCallback172(
|
|
88396
88679
|
async (edit) => {
|
|
88397
88680
|
if (busy) return false;
|
|
88398
88681
|
setBusy(true);
|
|
@@ -88414,7 +88697,7 @@ function StoryboardFrameFocus({
|
|
|
88414
88697
|
const title = frame.title ?? `Frame ${frame.index}`;
|
|
88415
88698
|
const dirty = draft !== savedVoiceover;
|
|
88416
88699
|
const canOpenPreview = frame.status !== "outline" && frame.srcExists && Boolean(frame.src);
|
|
88417
|
-
const saveVoiceover =
|
|
88700
|
+
const saveVoiceover = useCallback172(async () => {
|
|
88418
88701
|
const saved2 = await applyEdit((src) => setFrameVoiceover(src, frame.index, draft));
|
|
88419
88702
|
if (saved2) setSavedVoiceover(draft);
|
|
88420
88703
|
}, [applyEdit, frame.index, draft]);
|
|
@@ -88426,7 +88709,7 @@ function StoryboardFrameFocus({
|
|
|
88426
88709
|
window.addEventListener("beforeunload", onBeforeUnload);
|
|
88427
88710
|
return () => window.removeEventListener("beforeunload", onBeforeUnload);
|
|
88428
88711
|
}, [dirty]);
|
|
88429
|
-
const confirmLeave =
|
|
88712
|
+
const confirmLeave = useCallback172(
|
|
88430
88713
|
() => !dirty || window.confirm("Discard unsaved voiceover changes?"),
|
|
88431
88714
|
[dirty]
|
|
88432
88715
|
);
|
|
@@ -88908,7 +89191,7 @@ function progressLabel(summary) {
|
|
|
88908
89191
|
}
|
|
88909
89192
|
|
|
88910
89193
|
// src/components/storyboard/useFrameComments.ts
|
|
88911
|
-
import { useCallback as
|
|
89194
|
+
import { useCallback as useCallback173, useEffect as useEffect142, useMemo as useMemo76, useState as useState152 } from "react";
|
|
88912
89195
|
|
|
88913
89196
|
// src/components/storyboard/frameComments.ts
|
|
88914
89197
|
var FRAME_COMMENTS_PATH = ".hyperframes/frame-comments.json";
|
|
@@ -88974,7 +89257,7 @@ function useFrameComments(frames) {
|
|
|
88974
89257
|
const [submitState, setSubmitState] = useState152("idle");
|
|
88975
89258
|
const [submitError, setSubmitError] = useState152(null);
|
|
88976
89259
|
const [pending2, setPending] = useState152(null);
|
|
88977
|
-
const refreshPending =
|
|
89260
|
+
const refreshPending = useCallback173(async () => {
|
|
88978
89261
|
try {
|
|
88979
89262
|
const parsed = parseCommentsFile(await readOptionalProjectFile(FRAME_COMMENTS_PATH));
|
|
88980
89263
|
setPending(parsed && parsed.comments.length > 0 ? parsed.comments : null);
|
|
@@ -88987,14 +89270,14 @@ function useFrameComments(frames) {
|
|
|
88987
89270
|
window.addEventListener("focus", onFocus);
|
|
88988
89271
|
return () => window.removeEventListener("focus", onFocus);
|
|
88989
89272
|
}, [refreshPending]);
|
|
88990
|
-
const setDraft =
|
|
89273
|
+
const setDraft = useCallback173((index, text) => {
|
|
88991
89274
|
setDrafts((prev) => ({ ...prev, [index]: text }));
|
|
88992
89275
|
}, []);
|
|
88993
|
-
const draftCount =
|
|
89276
|
+
const draftCount = useMemo76(
|
|
88994
89277
|
() => Object.values(drafts).filter((text) => text.trim().length > 0).length,
|
|
88995
89278
|
[drafts]
|
|
88996
89279
|
);
|
|
88997
|
-
const submit =
|
|
89280
|
+
const submit = useCallback173(async () => {
|
|
88998
89281
|
if (draftCount === 0 || submitState === "saving") return false;
|
|
88999
89282
|
setSubmitState("saving");
|
|
89000
89283
|
setSubmitError(null);
|
|
@@ -89058,7 +89341,7 @@ function StoryboardLoaded({
|
|
|
89058
89341
|
setFeedbackMessageCopied(false);
|
|
89059
89342
|
}
|
|
89060
89343
|
};
|
|
89061
|
-
const sourceFiles =
|
|
89344
|
+
const sourceFiles = useMemo77(() => {
|
|
89062
89345
|
const files = [{ path: data.path, label: data.path }];
|
|
89063
89346
|
if (data.script?.exists) files.push({ path: data.script.path, label: data.script.path });
|
|
89064
89347
|
return files;
|
|
@@ -89457,18 +89740,21 @@ function useStudioSessionStart(projectId, resolving, waitingForServer) {
|
|
|
89457
89740
|
}
|
|
89458
89741
|
|
|
89459
89742
|
// src/hooks/useTimelineAddAtPlayhead.ts
|
|
89460
|
-
import { useCallback as
|
|
89743
|
+
import { useCallback as useCallback174 } from "react";
|
|
89461
89744
|
function useTimelineAddAtPlayhead(addAsset, addComposition) {
|
|
89462
89745
|
const placement = () => ({ start: usePlayerStore.getState().currentTime, track: 0 });
|
|
89463
89746
|
return {
|
|
89464
|
-
addAssetAtPlayhead:
|
|
89465
|
-
addCompositionAtPlayhead:
|
|
89747
|
+
addAssetAtPlayhead: useCallback174((path) => addAsset(path, placement()), [addAsset]),
|
|
89748
|
+
addCompositionAtPlayhead: useCallback174(
|
|
89466
89749
|
(path) => addComposition(path, placement()),
|
|
89467
89750
|
[addComposition]
|
|
89468
89751
|
)
|
|
89469
89752
|
};
|
|
89470
89753
|
}
|
|
89471
89754
|
|
|
89755
|
+
// src/hooks/useActiveComposition.ts
|
|
89756
|
+
import { useState as useState156 } from "react";
|
|
89757
|
+
|
|
89472
89758
|
// src/hooks/useHydrateActiveCompPathFromUrl.ts
|
|
89473
89759
|
import { useEffect as useEffect146 } from "react";
|
|
89474
89760
|
function useHydrateActiveCompPathFromUrl({
|
|
@@ -89491,29 +89777,136 @@ function useHydrateActiveCompPathFromUrl({
|
|
|
89491
89777
|
}, [hydrated, fileTree, fileTreeLoaded, initialUrlStateRef, setActiveCompPath, setHydrated]);
|
|
89492
89778
|
}
|
|
89493
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
|
+
|
|
89494
89894
|
// src/App.tsx
|
|
89495
89895
|
import { jsx as jsx219, jsxs as jsxs181 } from "react/jsx-runtime";
|
|
89496
89896
|
var getTimelineSelectionSet = () => usePlayerStore.getState().selectedElementIds;
|
|
89497
89897
|
function StudioApp() {
|
|
89498
89898
|
const { projectId, resolving, waitingForServer } = useServerConnection();
|
|
89499
|
-
const initialUrlStateRef =
|
|
89899
|
+
const initialUrlStateRef = useRef175(readStudioUrlStateFromWindow());
|
|
89500
89900
|
const viewModeValue = useViewModeState();
|
|
89501
89901
|
useStudioSessionStart(projectId, resolving, waitingForServer);
|
|
89502
|
-
const [
|
|
89503
|
-
const [
|
|
89504
|
-
|
|
89505
|
-
);
|
|
89506
|
-
const [compIdToSrc, setCompIdToSrc] = useState156(/* @__PURE__ */ new Map());
|
|
89507
|
-
const [previewIframe, setPreviewIframe] = useState156(null);
|
|
89508
|
-
const [compositionLoading, setCompositionLoading] = useState156(true);
|
|
89509
|
-
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);
|
|
89510
89906
|
const [previewDocumentVersion, refreshPreviewDocumentVersion] = usePreviewDocumentVersion();
|
|
89511
|
-
const [blockPreview, setBlockPreview] =
|
|
89512
|
-
const previewIframeRef =
|
|
89513
|
-
const
|
|
89514
|
-
activeCompPathRef.current = activeCompPath;
|
|
89515
|
-
const leftSidebarRef = useRef171(null);
|
|
89516
|
-
const renderQueue = useRenderQueue(projectId, activeCompPathRef);
|
|
89907
|
+
const [blockPreview, setBlockPreview] = useState157(null);
|
|
89908
|
+
const previewIframeRef = useRef175(null);
|
|
89909
|
+
const leftSidebarRef = useRef175(null);
|
|
89517
89910
|
const captionEditMode = useCaptionStore((s) => s.isEditMode);
|
|
89518
89911
|
const captionHasSelection = useCaptionStore((s) => s.selectedSegmentIds.size > 0);
|
|
89519
89912
|
const captionSync = useCaptionSync(projectId);
|
|
@@ -89532,9 +89925,9 @@ function StudioApp() {
|
|
|
89532
89925
|
rightPanelTab: initialUrlStateRef.current.rightPanelTab
|
|
89533
89926
|
});
|
|
89534
89927
|
const editHistory = usePersistentEditHistory({ projectId });
|
|
89535
|
-
const handleDomZIndexReorderCommitRef =
|
|
89536
|
-
const pendingTimelineEditPathRef =
|
|
89537
|
-
const isGestureRecordingRef =
|
|
89928
|
+
const handleDomZIndexReorderCommitRef = useRef175(null);
|
|
89929
|
+
const pendingTimelineEditPathRef = useRef175(/* @__PURE__ */ new Set());
|
|
89930
|
+
const isGestureRecordingRef = useRef175(false);
|
|
89538
89931
|
const reloadPreview = useCallback176(() => setRefreshKey((k) => k + 1), []);
|
|
89539
89932
|
const fileManager = useFileManager({
|
|
89540
89933
|
projectId,
|
|
@@ -89542,23 +89935,27 @@ function StudioApp() {
|
|
|
89542
89935
|
recordEdit: editHistory.recordEdit,
|
|
89543
89936
|
setRefreshKey
|
|
89544
89937
|
});
|
|
89545
|
-
const masterCompPath =
|
|
89546
|
-
() => resolveMasterCompositionPath(fileManager.
|
|
89547
|
-
[fileManager.
|
|
89938
|
+
const masterCompPath = useMemo78(
|
|
89939
|
+
() => resolveMasterCompositionPath(fileManager.compositions),
|
|
89940
|
+
[fileManager.compositions]
|
|
89548
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
|
+
});
|
|
89549
89951
|
const { sdkHandle, editFlowSdkSession } = useStudioSdkSessions(
|
|
89550
89952
|
projectId,
|
|
89551
89953
|
activeCompPath,
|
|
89552
89954
|
masterCompPath
|
|
89553
89955
|
);
|
|
89554
|
-
|
|
89555
|
-
|
|
89556
|
-
|
|
89557
|
-
fileTree: fileManager.fileTree,
|
|
89558
|
-
initialUrlStateRef,
|
|
89559
|
-
setActiveCompPath,
|
|
89560
|
-
setHydrated: setActiveCompPathHydrated
|
|
89561
|
-
});
|
|
89956
|
+
const activeCompPathRef = useRef175(activeCompPath);
|
|
89957
|
+
activeCompPathRef.current = activeCompPath;
|
|
89958
|
+
const renderQueue = useRenderQueue(projectId, activeCompPathRef);
|
|
89562
89959
|
const previewPersistence = usePreviewPersistence({
|
|
89563
89960
|
showToast,
|
|
89564
89961
|
readOptionalProjectFile: fileManager.readOptionalProjectFile,
|
|
@@ -89577,7 +89974,7 @@ function StudioApp() {
|
|
|
89577
89974
|
pendingTimelineEditPathRef,
|
|
89578
89975
|
reloadPreview
|
|
89579
89976
|
});
|
|
89580
|
-
const invalidateGsapCacheRef =
|
|
89977
|
+
const invalidateGsapCacheRef = useRef175(() => {
|
|
89581
89978
|
});
|
|
89582
89979
|
const invalidateGsapCache = useCallback176(() => invalidateGsapCacheRef.current(), []);
|
|
89583
89980
|
const timelineEditing = useTimelineEditing({
|
|
@@ -89636,14 +90033,14 @@ function StudioApp() {
|
|
|
89636
90033
|
setRightCollapsed: panelLayout.setRightCollapsed,
|
|
89637
90034
|
setRightPanelTab: panelLayout.setRightPanelTab
|
|
89638
90035
|
});
|
|
89639
|
-
const clearDomSelectionRef =
|
|
90036
|
+
const clearDomSelectionRef = useRef175(() => {
|
|
89640
90037
|
});
|
|
89641
|
-
const domEditSelectionBridgeRef =
|
|
89642
|
-
const handleDomEditElementDeleteRef =
|
|
90038
|
+
const domEditSelectionBridgeRef = useRef175(null);
|
|
90039
|
+
const handleDomEditElementDeleteRef = useRef175(async () => {
|
|
89643
90040
|
});
|
|
89644
90041
|
const domEditDeleteBridge = (s, o) => handleDomEditElementDeleteRef.current(s, o);
|
|
89645
|
-
const resetKeyframesRef =
|
|
89646
|
-
const deleteSelectedKeyframesRef =
|
|
90042
|
+
const resetKeyframesRef = useRef175(() => false);
|
|
90043
|
+
const deleteSelectedKeyframesRef = useRef175(() => {
|
|
89647
90044
|
});
|
|
89648
90045
|
const { handleCopy: handleCopy2, handlePaste: handlePaste2, handleCut } = useClipboard({
|
|
89649
90046
|
projectId,
|
|
@@ -89683,7 +90080,7 @@ function StudioApp() {
|
|
|
89683
90080
|
forceReloadSdkSession: sdkHandle.forceReload,
|
|
89684
90081
|
onToggleRecording: () => handleToggleRecordingRef.current()
|
|
89685
90082
|
});
|
|
89686
|
-
const sidebarTabRef =
|
|
90083
|
+
const sidebarTabRef = useRef175({
|
|
89687
90084
|
select: (t) => leftSidebarRef.current?.selectTab(t),
|
|
89688
90085
|
get: () => leftSidebarRef.current?.getTab() ?? "compositions"
|
|
89689
90086
|
});
|
|
@@ -89725,7 +90122,8 @@ function StudioApp() {
|
|
|
89725
90122
|
getSidebarTab: sidebarTabRef.current.get,
|
|
89726
90123
|
sdkSession: editFlowSdkSession,
|
|
89727
90124
|
publishSdkSession: sdkHandle.publish,
|
|
89728
|
-
forceReloadSdkSession: sdkHandle.forceReload
|
|
90125
|
+
forceReloadSdkSession: sdkHandle.forceReload,
|
|
90126
|
+
handleTimelineElementsDelete: timelineEditing.handleTimelineElementsDelete
|
|
89729
90127
|
});
|
|
89730
90128
|
domEditSelectionBridgeRef.current = domEditSession.domEditSelection;
|
|
89731
90129
|
handleDomZIndexReorderCommitRef.current = domEditSession.handleDomZIndexReorderCommit;
|
|
@@ -89772,9 +90170,9 @@ function StudioApp() {
|
|
|
89772
90170
|
resetErrors: resetConsoleErrors
|
|
89773
90171
|
} = useConsoleErrorCapture(previewIframe);
|
|
89774
90172
|
const dragOverlay = useGlobalFileDrop(timelineEditing.handleTimelineFileDrop);
|
|
89775
|
-
const handleToggleRecordingRef =
|
|
90173
|
+
const handleToggleRecordingRef = useRef175(() => {
|
|
89776
90174
|
});
|
|
89777
|
-
const domEditSessionRef =
|
|
90175
|
+
const domEditSessionRef = useRef175(domEditSession);
|
|
89778
90176
|
domEditSessionRef.current = domEditSession;
|
|
89779
90177
|
const { gestureState, gestureRecording, handleToggleRecording } = useGestureCommit({
|
|
89780
90178
|
domEditSessionRef,
|
|
@@ -89783,7 +90181,7 @@ function StudioApp() {
|
|
|
89783
90181
|
isGestureRecordingRef
|
|
89784
90182
|
});
|
|
89785
90183
|
handleToggleRecordingRef.current = handleToggleRecording;
|
|
89786
|
-
const canvasRectRef =
|
|
90184
|
+
const canvasRectRef = useRef175(null);
|
|
89787
90185
|
useLayoutEffect11(() => {
|
|
89788
90186
|
if (gestureState !== "recording" || !previewIframe) {
|
|
89789
90187
|
canvasRectRef.current = null;
|
|
@@ -89801,13 +90199,6 @@ function StudioApp() {
|
|
|
89801
90199
|
},
|
|
89802
90200
|
[appHotkeys, resetConsoleErrors, refreshPreviewDocumentVersion]
|
|
89803
90201
|
);
|
|
89804
|
-
const { setEditingFile } = fileManager;
|
|
89805
|
-
const handleSelectComposition = useCompositionContentLoader({
|
|
89806
|
-
projectId,
|
|
89807
|
-
setEditingFile,
|
|
89808
|
-
setActiveCompPath,
|
|
89809
|
-
showToast
|
|
89810
|
-
});
|
|
89811
90202
|
const {
|
|
89812
90203
|
designPanelActive,
|
|
89813
90204
|
inspectorPanelActive,
|
|
@@ -89864,7 +90255,7 @@ function StudioApp() {
|
|
|
89864
90255
|
handlePreviewIframeRef,
|
|
89865
90256
|
refreshPreviewDocumentVersion
|
|
89866
90257
|
});
|
|
89867
|
-
const timelineToolbar =
|
|
90258
|
+
const timelineToolbar = useMemo78(
|
|
89868
90259
|
() => /* @__PURE__ */ jsx219(
|
|
89869
90260
|
TimelineToolbar,
|
|
89870
90261
|
{
|
|
@@ -90022,11 +90413,11 @@ function StudioApp() {
|
|
|
90022
90413
|
}
|
|
90023
90414
|
|
|
90024
90415
|
// src/hooks/useElementPicker.ts
|
|
90025
|
-
import { useState as
|
|
90416
|
+
import { useState as useState158, useCallback as useCallback177, useRef as useRef176 } from "react";
|
|
90026
90417
|
function useElementPicker(iframeRef, options) {
|
|
90027
|
-
const [isPickMode, setIsPickMode] =
|
|
90028
|
-
const [pickedElement, setPickedElement] =
|
|
90029
|
-
const activeOverrideRef =
|
|
90418
|
+
const [isPickMode, setIsPickMode] = useState158(false);
|
|
90419
|
+
const [pickedElement, setPickedElement] = useState158(null);
|
|
90420
|
+
const activeOverrideRef = useRef176(null);
|
|
90030
90421
|
const getActiveIframe = useCallback177(() => {
|
|
90031
90422
|
return activeOverrideRef.current ?? iframeRef.current;
|
|
90032
90423
|
}, [iframeRef]);
|
|
@@ -90100,7 +90491,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
90100
90491
|
window.addEventListener("message", handleMessage);
|
|
90101
90492
|
return () => window.removeEventListener("message", handleMessage);
|
|
90102
90493
|
});
|
|
90103
|
-
const optionsRef =
|
|
90494
|
+
const optionsRef = useRef176(options);
|
|
90104
90495
|
optionsRef.current = options;
|
|
90105
90496
|
const syncToSource = useCallback177(
|
|
90106
90497
|
(elementId2, selector, op) => {
|
|
@@ -90211,7 +90602,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
90211
90602
|
},
|
|
90212
90603
|
[pickedElement, getActiveIframe, syncToSource]
|
|
90213
90604
|
);
|
|
90214
|
-
const activeIframeRef =
|
|
90605
|
+
const activeIframeRef = useRef176(null);
|
|
90215
90606
|
activeIframeRef.current = getActiveIframe();
|
|
90216
90607
|
return {
|
|
90217
90608
|
isPickMode,
|
|
@@ -90377,6 +90768,7 @@ function findElementBlock(html2, elementId2) {
|
|
|
90377
90768
|
return null;
|
|
90378
90769
|
}
|
|
90379
90770
|
export {
|
|
90771
|
+
AskAgentModal,
|
|
90380
90772
|
CompositionBreadcrumb,
|
|
90381
90773
|
CompositionThumbnail,
|
|
90382
90774
|
EditorShell,
|
|
@@ -90390,6 +90782,8 @@ export {
|
|
|
90390
90782
|
Timeline,
|
|
90391
90783
|
VideoThumbnail,
|
|
90392
90784
|
applyPatch,
|
|
90785
|
+
buildPickerAgentContextPreview,
|
|
90786
|
+
buildPickerAgentPrompt,
|
|
90393
90787
|
findElementBlock,
|
|
90394
90788
|
formatTime,
|
|
90395
90789
|
liveTime,
|