hyperframes 0.8.3 → 0.8.4
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/README.md +23 -1
- package/dist/cli.js +2791 -1501
- package/dist/hyperframe-runtime.js +25 -25
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +25 -25
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/skills/hyperframes-cli/SKILL.md +2 -2
- package/dist/skills/hyperframes-cli/references/preview-render.md +8 -6
- package/dist/studio/assets/{hyperframes-player-C-CeZlk1.js → hyperframes-player-70BfjZRz.js} +1 -1
- package/dist/studio/assets/{index-BU-aDh5r.js → index-DEnjB744.js} +1 -1
- package/dist/studio/assets/{index-B4X3myFN.js → index-KH4Y5JCd.js} +202 -202
- package/dist/studio/assets/{index-BSDQyOWB.js → index-RQ7S6nvA.js} +1 -1
- package/dist/studio/{chunk-AZYHQC6V.js → chunk-ZALQ3CW7.js} +2 -2
- package/dist/studio/chunk-ZALQ3CW7.js.map +1 -0
- package/dist/studio/{domEditingLayers-7AMZ7GFI.js → domEditingLayers-XRVXRTNX.js} +2 -2
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +228 -157
- package/dist/studio/index.js.map +1 -1
- package/dist/templates/_shared/AGENTS.md +9 -4
- package/dist/templates/_shared/CLAUDE.md +9 -4
- package/package.json +1 -1
- package/dist/studio/chunk-AZYHQC6V.js.map +0 -1
- /package/dist/studio/{domEditingLayers-7AMZ7GFI.js.map → domEditingLayers-XRVXRTNX.js.map} +0 -0
package/dist/studio/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
resolveDomEditSelection,
|
|
25
25
|
serializeDomEditTextFields,
|
|
26
26
|
setCompositionSourceMap
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-ZALQ3CW7.js";
|
|
28
28
|
import {
|
|
29
29
|
__export
|
|
30
30
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -23822,20 +23822,6 @@ var NLEPreview = memo19(function NLEPreview2({
|
|
|
23822
23822
|
document.addEventListener("wheel", handleWheel, { passive: false, capture: true });
|
|
23823
23823
|
return () => document.removeEventListener("wheel", handleWheel, { capture: true });
|
|
23824
23824
|
}, [applyZoom, applyPan]);
|
|
23825
|
-
useEffect27(() => {
|
|
23826
|
-
const viewport = viewportRef.current;
|
|
23827
|
-
if (!viewport) return;
|
|
23828
|
-
const handleDblClick = (event) => {
|
|
23829
|
-
if (isPreviewAtFit(zoomRef.current)) return;
|
|
23830
|
-
const rect = viewport.getBoundingClientRect();
|
|
23831
|
-
if (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom) {
|
|
23832
|
-
return;
|
|
23833
|
-
}
|
|
23834
|
-
applyZoom(DEFAULT_PREVIEW_ZOOM);
|
|
23835
|
-
};
|
|
23836
|
-
document.addEventListener("dblclick", handleDblClick, { capture: true });
|
|
23837
|
-
return () => document.removeEventListener("dblclick", handleDblClick, { capture: true });
|
|
23838
|
-
}, [applyZoom]);
|
|
23839
23825
|
useEffect27(() => {
|
|
23840
23826
|
const isInsideViewport = (clientX, clientY) => {
|
|
23841
23827
|
const viewport = viewportRef.current;
|
|
@@ -26425,7 +26411,7 @@ function resolveElementForOverlay(doc, sel, activeCompositionPath, cacheRef) {
|
|
|
26425
26411
|
|
|
26426
26412
|
// src/components/editor/marqueeCommit.ts
|
|
26427
26413
|
var MARQUEE_THRESHOLD_PX = 4;
|
|
26428
|
-
function
|
|
26414
|
+
function collectMarqueeCandidates(iframe, overlayEl, activeCompositionPath) {
|
|
26429
26415
|
const doc = iframe.contentDocument;
|
|
26430
26416
|
if (!doc) return [];
|
|
26431
26417
|
const root = doc.querySelector("[data-composition-id]") ?? doc.body;
|
|
@@ -26438,28 +26424,32 @@ function collectMarqueeHits(rect, iframe, overlayEl, activeCompositionPath) {
|
|
|
26438
26424
|
width: declW > 0 ? declW : rootEl.getBoundingClientRect().width || 1,
|
|
26439
26425
|
height: declH > 0 ? declH : rootEl.getBoundingClientRect().height || 1
|
|
26440
26426
|
};
|
|
26441
|
-
const
|
|
26427
|
+
const candidates = [];
|
|
26442
26428
|
for (const item of items) {
|
|
26443
26429
|
const el = item.element;
|
|
26444
26430
|
if (!isElementComputedVisible(el)) continue;
|
|
26445
26431
|
if (coversComposition(el.getBoundingClientRect(), viewport)) continue;
|
|
26446
26432
|
const overlayRect = toVisibleOverlayRect(overlayEl, iframe, el);
|
|
26447
26433
|
if (!overlayRect) continue;
|
|
26448
|
-
|
|
26449
|
-
|
|
26450
|
-
|
|
26451
|
-
|
|
26452
|
-
|
|
26453
|
-
|
|
26454
|
-
|
|
26455
|
-
|
|
26434
|
+
candidates.push({
|
|
26435
|
+
element: el,
|
|
26436
|
+
rect: {
|
|
26437
|
+
left: overlayRect.left,
|
|
26438
|
+
top: overlayRect.top,
|
|
26439
|
+
width: overlayRect.width,
|
|
26440
|
+
height: overlayRect.height
|
|
26441
|
+
}
|
|
26442
|
+
});
|
|
26456
26443
|
}
|
|
26457
|
-
return
|
|
26444
|
+
return candidates;
|
|
26445
|
+
}
|
|
26446
|
+
function hitsWithin(rect, candidates) {
|
|
26447
|
+
return candidates.filter((candidate) => rectsOverlap(rect, candidate.rect));
|
|
26458
26448
|
}
|
|
26459
|
-
async function runMarqueeIntersection(rect,
|
|
26449
|
+
async function runMarqueeIntersection(rect, candidates, activeCompositionPath) {
|
|
26460
26450
|
const isMasterView = !activeCompositionPath || activeCompositionPath === "index.html";
|
|
26461
26451
|
const hits = [];
|
|
26462
|
-
for (const { element } of
|
|
26452
|
+
for (const { element } of hitsWithin(rect, candidates)) {
|
|
26463
26453
|
const sel = await resolveDomEditSelection(element, {
|
|
26464
26454
|
activeCompositionPath,
|
|
26465
26455
|
isMasterView,
|
|
@@ -26473,13 +26463,15 @@ function useMarqueeGestures(deps) {
|
|
|
26473
26463
|
const marqueeRef = useRef45(null);
|
|
26474
26464
|
const [marqueeRect, setMarqueeRect] = useState29(null);
|
|
26475
26465
|
const [candidateRects, setCandidateRects] = useState29([]);
|
|
26466
|
+
const candidatesRef = useRef45(null);
|
|
26476
26467
|
const commitMarquee = useCallback43(
|
|
26477
26468
|
async (rect, additive) => {
|
|
26478
26469
|
const iframe = deps.iframeRef.current;
|
|
26479
26470
|
const overlay = deps.overlayRef.current;
|
|
26480
26471
|
if (!iframe || !overlay || !deps.onMarqueeSelectRef.current) return;
|
|
26481
26472
|
const acp = deps.activeCompositionPathRef.current ?? "index.html";
|
|
26482
|
-
const
|
|
26473
|
+
const candidates = candidatesRef.current ?? collectMarqueeCandidates(iframe, overlay, acp);
|
|
26474
|
+
const hits = await runMarqueeIntersection(rect, candidates, acp);
|
|
26483
26475
|
deps.onMarqueeSelectRef.current(hits, additive);
|
|
26484
26476
|
},
|
|
26485
26477
|
[deps.iframeRef, deps.overlayRef, deps.onMarqueeSelectRef, deps.activeCompositionPathRef]
|
|
@@ -26497,6 +26489,7 @@ function useMarqueeGestures(deps) {
|
|
|
26497
26489
|
const dy = m.currentY - m.startY;
|
|
26498
26490
|
if (Math.hypot(dx, dy) < MARQUEE_THRESHOLD_PX) return;
|
|
26499
26491
|
m.pastThreshold = true;
|
|
26492
|
+
candidatesRef.current = null;
|
|
26500
26493
|
}
|
|
26501
26494
|
const rect = {
|
|
26502
26495
|
left: Math.min(m.startX, m.currentX),
|
|
@@ -26509,7 +26502,8 @@ function useMarqueeGestures(deps) {
|
|
|
26509
26502
|
const overlay = deps.overlayRef.current;
|
|
26510
26503
|
if (iframe && overlay) {
|
|
26511
26504
|
const acp = deps.activeCompositionPathRef.current ?? "index.html";
|
|
26512
|
-
|
|
26505
|
+
candidatesRef.current ??= collectMarqueeCandidates(iframe, overlay, acp);
|
|
26506
|
+
setCandidateRects(hitsWithin(rect, candidatesRef.current).map((h) => h.rect));
|
|
26513
26507
|
}
|
|
26514
26508
|
return;
|
|
26515
26509
|
}
|
|
@@ -26541,6 +26535,7 @@ function useMarqueeGestures(deps) {
|
|
|
26541
26535
|
}
|
|
26542
26536
|
setMarqueeRect(null);
|
|
26543
26537
|
setCandidateRects([]);
|
|
26538
|
+
candidatesRef.current = null;
|
|
26544
26539
|
return;
|
|
26545
26540
|
}
|
|
26546
26541
|
deps.gestures.onPointerUp(event);
|
|
@@ -26552,6 +26547,7 @@ function useMarqueeGestures(deps) {
|
|
|
26552
26547
|
marqueeRef.current = null;
|
|
26553
26548
|
setMarqueeRect(null);
|
|
26554
26549
|
setCandidateRects([]);
|
|
26550
|
+
candidatesRef.current = null;
|
|
26555
26551
|
return;
|
|
26556
26552
|
}
|
|
26557
26553
|
deps.gestures.clearPointerState(deps.selectionRef);
|
|
@@ -26989,7 +26985,7 @@ function OffCanvasIndicators({
|
|
|
26989
26985
|
const selectOffCanvas = async () => {
|
|
26990
26986
|
const el = elements.current.get(r.key);
|
|
26991
26987
|
if (!el) return;
|
|
26992
|
-
const { resolveDomEditSelection: resolveDomEditSelection2 } = await import("./domEditingLayers-
|
|
26988
|
+
const { resolveDomEditSelection: resolveDomEditSelection2 } = await import("./domEditingLayers-XRVXRTNX.js");
|
|
26993
26989
|
const acp = activeCompositionPathRef.current ?? "index.html";
|
|
26994
26990
|
const sel = await resolveDomEditSelection2(el, {
|
|
26995
26991
|
activeCompositionPath: acp,
|
|
@@ -30590,9 +30586,14 @@ function observeDoc(doc, markDirty) {
|
|
|
30590
30586
|
});
|
|
30591
30587
|
return observer;
|
|
30592
30588
|
}
|
|
30589
|
+
var RECOMPUTE_INTERVAL_MS = 100;
|
|
30590
|
+
function rebuildDue(dirty, lastAt, now2) {
|
|
30591
|
+
return dirty && now2 - lastAt >= RECOMPUTE_INTERVAL_MS;
|
|
30592
|
+
}
|
|
30593
30593
|
function startOffCanvasIndicatorRefresh(options) {
|
|
30594
30594
|
let frame = 0;
|
|
30595
30595
|
let lastCompSig = "";
|
|
30596
|
+
let lastRecomputeAt = Number.NEGATIVE_INFINITY;
|
|
30596
30597
|
const markDirty = () => {
|
|
30597
30598
|
options.dirtyRef.current = true;
|
|
30598
30599
|
};
|
|
@@ -30621,7 +30622,9 @@ function startOffCanvasIndicatorRefresh(options) {
|
|
|
30621
30622
|
if (options.dirtyRef.current) clearIndicators(options);
|
|
30622
30623
|
return;
|
|
30623
30624
|
}
|
|
30624
|
-
|
|
30625
|
+
const now2 = performance.now();
|
|
30626
|
+
if (!rebuildDue(options.dirtyRef.current, lastRecomputeAt, now2)) return;
|
|
30627
|
+
lastRecomputeAt = now2;
|
|
30625
30628
|
options.dirtyRef.current = false;
|
|
30626
30629
|
recomputeOffCanvasIndicators(
|
|
30627
30630
|
iframe,
|
|
@@ -35368,35 +35371,52 @@ function useElementLifecycleOps({
|
|
|
35368
35371
|
commitDomEditPatchBatches,
|
|
35369
35372
|
onElementDeleted
|
|
35370
35373
|
}) {
|
|
35371
|
-
const
|
|
35374
|
+
const handleDomEditElementsDelete = useCallback51(
|
|
35372
35375
|
// fallow-ignore-next-line complexity
|
|
35373
|
-
async (
|
|
35376
|
+
async (selections) => {
|
|
35374
35377
|
const pid = projectIdRef.current;
|
|
35375
35378
|
if (!pid) return;
|
|
35376
|
-
const
|
|
35379
|
+
const [selection] = selections;
|
|
35380
|
+
if (!selection) return;
|
|
35381
|
+
const label = selections.length === 1 ? selection.label || selection.id || selection.selector || selection.tagName : `${selections.length} elements`;
|
|
35382
|
+
if (selections.length > 1) showToast(`Deleting ${label}...`, "info");
|
|
35377
35383
|
const targetPath = selection.sourceFile || activeCompPath || "index.html";
|
|
35384
|
+
const sameFile = selections.filter(
|
|
35385
|
+
(candidate) => (candidate.sourceFile || activeCompPath || "index.html") === targetPath
|
|
35386
|
+
);
|
|
35378
35387
|
try {
|
|
35379
35388
|
const originalContent = await readProjectFileContent(pid, targetPath);
|
|
35380
|
-
const
|
|
35381
|
-
if (!
|
|
35389
|
+
const patchTargets = sameFile.map((member) => buildDomEditPatchTarget(member));
|
|
35390
|
+
if (patchTargets.some((t) => !t.id && !t.selector && !t.hfId)) {
|
|
35382
35391
|
throw new Error("Selected element has no patchable target");
|
|
35383
35392
|
}
|
|
35384
|
-
|
|
35385
|
-
|
|
35386
|
-
|
|
35393
|
+
const hfIds = sameFile.map((member) => member.hfId).filter((hfId) => Boolean(hfId));
|
|
35394
|
+
if (onTrySdkDelete && hfIds.length === sameFile.length) {
|
|
35395
|
+
let allHandled = true;
|
|
35396
|
+
for (const hfId of hfIds) {
|
|
35397
|
+
const handled = await onTrySdkDelete(hfId, originalContent, targetPath);
|
|
35398
|
+
if (!cutoverCommittedOrThrow(handled)) {
|
|
35399
|
+
allHandled = false;
|
|
35400
|
+
break;
|
|
35401
|
+
}
|
|
35402
|
+
}
|
|
35403
|
+
if (allHandled) {
|
|
35387
35404
|
clearDomSelection();
|
|
35388
35405
|
usePlayerStore.getState().setSelectedElementId(null);
|
|
35389
|
-
showToast(
|
|
35406
|
+
showToast(
|
|
35407
|
+
`Deleted ${label}. Use Undo to restore ${sameFile.length === 1 ? "it" : "them"}.`,
|
|
35408
|
+
"info"
|
|
35409
|
+
);
|
|
35390
35410
|
return;
|
|
35391
35411
|
}
|
|
35392
35412
|
}
|
|
35393
35413
|
domEditSaveTimestampRef.current = Date.now();
|
|
35394
35414
|
const removeResponse = await fetch(
|
|
35395
|
-
`/api/projects/${pid}/file-mutations/remove-
|
|
35415
|
+
`/api/projects/${pid}/file-mutations/remove-elements/${encodeURIComponent(targetPath)}`,
|
|
35396
35416
|
{
|
|
35397
35417
|
method: "POST",
|
|
35398
35418
|
headers: { "Content-Type": "application/json", ...studioWriteHeaders() },
|
|
35399
|
-
body: JSON.stringify({
|
|
35419
|
+
body: JSON.stringify({ targets: patchTargets })
|
|
35400
35420
|
}
|
|
35401
35421
|
);
|
|
35402
35422
|
if (!removeResponse.ok) {
|
|
@@ -35406,6 +35426,10 @@ function useElementLifecycleOps({
|
|
|
35406
35426
|
);
|
|
35407
35427
|
}
|
|
35408
35428
|
const removeData = await removeResponse.json();
|
|
35429
|
+
if (!removeData.changed) {
|
|
35430
|
+
reloadPreview();
|
|
35431
|
+
throw new Error("Nothing to delete \u2014 the preview was out of date. Try again.");
|
|
35432
|
+
}
|
|
35409
35433
|
const patchedContent = typeof removeData.content === "string" ? removeData.content : originalContent;
|
|
35410
35434
|
await saveProjectFilesWithHistory({
|
|
35411
35435
|
projectId: pid,
|
|
@@ -35423,8 +35447,11 @@ function useElementLifecycleOps({
|
|
|
35423
35447
|
usePlayerStore.getState().setSelectedElementId(null);
|
|
35424
35448
|
forceReloadSdkSession?.();
|
|
35425
35449
|
reloadPreview();
|
|
35426
|
-
onElementDeleted?.(
|
|
35427
|
-
showToast(
|
|
35450
|
+
for (const member of sameFile) onElementDeleted?.(member);
|
|
35451
|
+
showToast(
|
|
35452
|
+
`Deleted ${label}. Use Undo to restore ${sameFile.length === 1 ? "it" : "them"}.`,
|
|
35453
|
+
"info"
|
|
35454
|
+
);
|
|
35428
35455
|
} catch (error) {
|
|
35429
35456
|
const message = error instanceof Error ? error.message : "Failed to delete element";
|
|
35430
35457
|
showToast(message);
|
|
@@ -35551,8 +35578,15 @@ function useElementLifecycleOps({
|
|
|
35551
35578
|
},
|
|
35552
35579
|
[commitDomEditPatchBatches, onReorderShadow]
|
|
35553
35580
|
);
|
|
35581
|
+
const handleDomEditElementDelete = useCallback51(
|
|
35582
|
+
async (selection) => {
|
|
35583
|
+
await handleDomEditElementsDelete([selection]);
|
|
35584
|
+
},
|
|
35585
|
+
[handleDomEditElementsDelete]
|
|
35586
|
+
);
|
|
35554
35587
|
return {
|
|
35555
35588
|
handleDomEditElementDelete,
|
|
35589
|
+
handleDomEditElementsDelete,
|
|
35556
35590
|
handleDomZIndexReorderCommit
|
|
35557
35591
|
};
|
|
35558
35592
|
}
|
|
@@ -37638,6 +37672,9 @@ function selectionIdsMatch(currentIds, selectedIds, currentAnchor, wantedAnchor)
|
|
|
37638
37672
|
}
|
|
37639
37673
|
return currentAnchor === wantedAnchor;
|
|
37640
37674
|
}
|
|
37675
|
+
function anchorIsOutsideSelection(anchor2, selectedIds) {
|
|
37676
|
+
return anchor2 !== null && !selectedIds.includes(anchor2);
|
|
37677
|
+
}
|
|
37641
37678
|
function useTimelineSelectionPreviewSync({
|
|
37642
37679
|
selectedElementId,
|
|
37643
37680
|
selectedElementIds,
|
|
@@ -37688,6 +37725,11 @@ function useTimelineSelectionPreviewSync({
|
|
|
37688
37725
|
return;
|
|
37689
37726
|
}
|
|
37690
37727
|
let cancelled = false;
|
|
37728
|
+
const warnSelectionMissingOnce = () => {
|
|
37729
|
+
if (missingSelectionKeyRef.current === selectedKey) return;
|
|
37730
|
+
missingSelectionKeyRef.current = selectedKey;
|
|
37731
|
+
onSelectionNotFound();
|
|
37732
|
+
};
|
|
37691
37733
|
const syncSelection = async () => {
|
|
37692
37734
|
const selections = [];
|
|
37693
37735
|
let resolvableCount = 0;
|
|
@@ -37700,9 +37742,9 @@ function useTimelineSelectionPreviewSync({
|
|
|
37700
37742
|
}
|
|
37701
37743
|
if (cancelled) return;
|
|
37702
37744
|
if (selections.length < resolvableCount) {
|
|
37703
|
-
|
|
37704
|
-
|
|
37705
|
-
|
|
37745
|
+
warnSelectionMissingOnce();
|
|
37746
|
+
if (anchorIsOutsideSelection(currentAnchor, selectedIds)) {
|
|
37747
|
+
applyDomSelection(null, { revealPanel: false, announce: false });
|
|
37706
37748
|
}
|
|
37707
37749
|
return;
|
|
37708
37750
|
}
|
|
@@ -39358,6 +39400,14 @@ import { resolveEditingSections } from "@hyperframes/core/editing";
|
|
|
39358
39400
|
|
|
39359
39401
|
// src/components/editor/propertyPanelMediaSection.tsx
|
|
39360
39402
|
import { useEffect as useEffect48, useState as useState47 } from "react";
|
|
39403
|
+
import {
|
|
39404
|
+
AUDIO_GAIN_FADER_MAX,
|
|
39405
|
+
AUDIO_GAIN_FADER_MIN,
|
|
39406
|
+
audioFaderPositionToGain,
|
|
39407
|
+
formatAudioGain,
|
|
39408
|
+
audioGainToFaderPosition,
|
|
39409
|
+
audioGainToText
|
|
39410
|
+
} from "@hyperframes/core/audio-gain";
|
|
39361
39411
|
import { Fragment as Fragment25, jsx as jsx83, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
39362
39412
|
function MediaSection({
|
|
39363
39413
|
projectDir,
|
|
@@ -39375,7 +39425,7 @@ function MediaSection({
|
|
|
39375
39425
|
const isVisualMedia = isVideo || isImage;
|
|
39376
39426
|
const el = element.element;
|
|
39377
39427
|
const volume = parseNumericValue(element.dataAttributes.volume ?? "") ?? 1;
|
|
39378
|
-
const
|
|
39428
|
+
const volumeFaderPosition = audioGainToFaderPosition(volume);
|
|
39379
39429
|
const mediaStart = Number.parseFloat(
|
|
39380
39430
|
element.dataAttributes["media-start"] ?? element.dataAttributes["playback-start"] ?? "0"
|
|
39381
39431
|
) || 0;
|
|
@@ -39557,14 +39607,14 @@ function MediaSection({
|
|
|
39557
39607
|
SliderControl,
|
|
39558
39608
|
{
|
|
39559
39609
|
trackName: "Volume",
|
|
39560
|
-
value:
|
|
39561
|
-
min:
|
|
39562
|
-
max:
|
|
39610
|
+
value: volumeFaderPosition,
|
|
39611
|
+
min: AUDIO_GAIN_FADER_MIN,
|
|
39612
|
+
max: AUDIO_GAIN_FADER_MAX,
|
|
39563
39613
|
step: 1,
|
|
39564
|
-
displayValue:
|
|
39565
|
-
formatDisplayValue: (next) =>
|
|
39614
|
+
displayValue: audioGainToText(volume),
|
|
39615
|
+
formatDisplayValue: (next) => audioGainToText(audioFaderPositionToGain(next)),
|
|
39566
39616
|
onCommit: (next) => {
|
|
39567
|
-
void onSetAttribute("volume",
|
|
39617
|
+
void onSetAttribute("volume", formatAudioGain(audioFaderPositionToGain(next)));
|
|
39568
39618
|
}
|
|
39569
39619
|
}
|
|
39570
39620
|
)
|
|
@@ -51435,6 +51485,14 @@ function FlatToggle({
|
|
|
51435
51485
|
}
|
|
51436
51486
|
|
|
51437
51487
|
// src/components/editor/propertyPanelFlatMediaSection.tsx
|
|
51488
|
+
import {
|
|
51489
|
+
AUDIO_GAIN_FADER_MAX as AUDIO_GAIN_FADER_MAX2,
|
|
51490
|
+
AUDIO_GAIN_FADER_MIN as AUDIO_GAIN_FADER_MIN2,
|
|
51491
|
+
audioFaderPositionToGain as audioFaderPositionToGain2,
|
|
51492
|
+
formatAudioGain as formatAudioGain2,
|
|
51493
|
+
audioGainToFaderPosition as audioGainToFaderPosition2,
|
|
51494
|
+
audioGainToText as audioGainToText2
|
|
51495
|
+
} from "@hyperframes/core/audio-gain";
|
|
51438
51496
|
import { Fragment as Fragment37, jsx as jsx131, jsxs as jsxs106 } from "react/jsx-runtime";
|
|
51439
51497
|
function FlatMediaSection({
|
|
51440
51498
|
projectDir,
|
|
@@ -51455,7 +51513,7 @@ function FlatMediaSection({
|
|
|
51455
51513
|
const isVisualMedia = isVideo || isImage;
|
|
51456
51514
|
const el = element.element;
|
|
51457
51515
|
const volume = parseNumericValue(element.dataAttributes.volume ?? "") ?? 1;
|
|
51458
|
-
const
|
|
51516
|
+
const volumeFaderPosition = audioGainToFaderPosition2(volume);
|
|
51459
51517
|
const mediaStart = Number.parseFloat(
|
|
51460
51518
|
element.dataAttributes["media-start"] ?? element.dataAttributes["playback-start"] ?? "0"
|
|
51461
51519
|
) || 0;
|
|
@@ -51598,13 +51656,14 @@ function FlatMediaSection({
|
|
|
51598
51656
|
FlatSlider,
|
|
51599
51657
|
{
|
|
51600
51658
|
label: "Volume",
|
|
51601
|
-
value:
|
|
51602
|
-
min:
|
|
51603
|
-
max:
|
|
51604
|
-
tier:
|
|
51605
|
-
displayValue:
|
|
51659
|
+
value: volumeFaderPosition,
|
|
51660
|
+
min: AUDIO_GAIN_FADER_MIN2,
|
|
51661
|
+
max: AUDIO_GAIN_FADER_MAX2,
|
|
51662
|
+
tier: volume === 1 ? "default" : "explicitCustom",
|
|
51663
|
+
displayValue: audioGainToText2(volume),
|
|
51606
51664
|
disabled: volumeAutomated,
|
|
51607
|
-
|
|
51665
|
+
centerTick: true,
|
|
51666
|
+
onCommit: (next) => void onSetAttribute("volume", formatAudioGain2(audioFaderPositionToGain2(next)))
|
|
51608
51667
|
}
|
|
51609
51668
|
) }),
|
|
51610
51669
|
/* @__PURE__ */ jsx131(
|
|
@@ -61820,36 +61879,44 @@ function useTimelineEditing({
|
|
|
61820
61879
|
isRecordingRef,
|
|
61821
61880
|
forceReloadSdkSession
|
|
61822
61881
|
});
|
|
61823
|
-
const
|
|
61882
|
+
const handleTimelineElementsDelete = useCallback91(
|
|
61824
61883
|
// fallow-ignore-next-line complexity
|
|
61825
|
-
async (
|
|
61884
|
+
async (selection) => {
|
|
61826
61885
|
if (isRecordingRef?.current) {
|
|
61827
61886
|
showToast("Cannot edit timeline while recording", "error");
|
|
61828
61887
|
return;
|
|
61829
61888
|
}
|
|
61830
61889
|
const pid = projectIdRef.current;
|
|
61831
61890
|
if (!pid) throw new Error("No active project");
|
|
61832
|
-
const
|
|
61891
|
+
const [element] = selection;
|
|
61892
|
+
if (!element) return;
|
|
61893
|
+
const label = selection.length === 1 ? getTimelineElementLabel(element) : `${selection.length} clips`;
|
|
61833
61894
|
const targetPath = element.sourceFile || activeCompPath || "index.html";
|
|
61895
|
+
const sameFile = selection.filter(
|
|
61896
|
+
(candidate) => (candidate.sourceFile || activeCompPath || "index.html") === targetPath
|
|
61897
|
+
);
|
|
61834
61898
|
try {
|
|
61835
61899
|
const originalContent = await readFileContent(pid, targetPath);
|
|
61836
|
-
|
|
61837
|
-
|
|
61838
|
-
|
|
61839
|
-
|
|
61840
|
-
|
|
61841
|
-
`/api/projects/${pid}/file-mutations/remove-element/${encodeURIComponent(targetPath)}`,
|
|
61842
|
-
{
|
|
61843
|
-
method: "POST",
|
|
61844
|
-
headers: { "Content-Type": "application/json", ...studioWriteHeaders() },
|
|
61845
|
-
body: JSON.stringify({ target: patchTarget })
|
|
61900
|
+
let removedContent = originalContent;
|
|
61901
|
+
for (const target of sameFile) {
|
|
61902
|
+
const patchTarget = buildPatchTarget(target);
|
|
61903
|
+
if (!patchTarget) {
|
|
61904
|
+
throw new Error(`Timeline element ${target.id} is missing a patchable target`);
|
|
61846
61905
|
}
|
|
61847
|
-
|
|
61848
|
-
|
|
61849
|
-
|
|
61906
|
+
const removeResponse = await fetch(
|
|
61907
|
+
`/api/projects/${pid}/file-mutations/remove-element/${encodeURIComponent(targetPath)}`,
|
|
61908
|
+
{
|
|
61909
|
+
method: "POST",
|
|
61910
|
+
headers: { "Content-Type": "application/json", ...studioWriteHeaders() },
|
|
61911
|
+
body: JSON.stringify({ target: patchTarget })
|
|
61912
|
+
}
|
|
61913
|
+
);
|
|
61914
|
+
if (!removeResponse.ok) {
|
|
61915
|
+
throw new Error(`Failed to delete ${target.id} from ${targetPath}`);
|
|
61916
|
+
}
|
|
61917
|
+
const removeData = await removeResponse.json();
|
|
61918
|
+
if (typeof removeData.content === "string") removedContent = removeData.content;
|
|
61850
61919
|
}
|
|
61851
|
-
const removeData = await removeResponse.json();
|
|
61852
|
-
const removedContent = typeof removeData.content === "string" ? removeData.content : originalContent;
|
|
61853
61920
|
const deleteContentEnd = furthestClipEndFromSource(removedContent);
|
|
61854
61921
|
const patchedContent = setCompositionDurationToContent(removedContent, deleteContentEnd);
|
|
61855
61922
|
const rollbackDuration = captureDurationRollback(previewIframeRef.current);
|
|
@@ -61874,13 +61941,16 @@ function useTimelineEditing({
|
|
|
61874
61941
|
rollbackDuration();
|
|
61875
61942
|
throw error;
|
|
61876
61943
|
}
|
|
61877
|
-
|
|
61878
|
-
|
|
61879
|
-
);
|
|
61944
|
+
const deletedKeys = new Set(sameFile.map((te) => te.key ?? te.id));
|
|
61945
|
+
usePlayerStore.getState().setElements(timelineElements.filter((te) => !deletedKeys.has(te.key ?? te.id)));
|
|
61880
61946
|
usePlayerStore.getState().setSelectedElementId(null);
|
|
61947
|
+
usePlayerStore.getState().setSelectedElementIds(/* @__PURE__ */ new Set());
|
|
61881
61948
|
forceReloadSdkSession?.();
|
|
61882
61949
|
reloadPreview();
|
|
61883
|
-
showToast(
|
|
61950
|
+
showToast(
|
|
61951
|
+
`Deleted ${label}. Use Undo to restore ${sameFile.length === 1 ? "it" : "them"}.`,
|
|
61952
|
+
"info"
|
|
61953
|
+
);
|
|
61884
61954
|
} catch (error) {
|
|
61885
61955
|
const message = error instanceof Error ? error.message : "Failed to delete timeline clip";
|
|
61886
61956
|
showToast(message);
|
|
@@ -61899,6 +61969,12 @@ function useTimelineEditing({
|
|
|
61899
61969
|
previewIframeRef
|
|
61900
61970
|
]
|
|
61901
61971
|
);
|
|
61972
|
+
const handleTimelineElementDelete = useCallback91(
|
|
61973
|
+
async (element) => {
|
|
61974
|
+
await handleTimelineElementsDelete([element]);
|
|
61975
|
+
},
|
|
61976
|
+
[handleTimelineElementsDelete]
|
|
61977
|
+
);
|
|
61902
61978
|
const { handleTimelineAssetDrop, handleTimelineFileDrop, handleTimelineCompositionDrop } = useTimelineAssetDropOps({
|
|
61903
61979
|
projectIdRef,
|
|
61904
61980
|
activeCompPath,
|
|
@@ -61940,6 +62016,7 @@ function useTimelineEditing({
|
|
|
61940
62016
|
handleToggleTrackHidden,
|
|
61941
62017
|
handleToggleElementHidden,
|
|
61942
62018
|
handleTimelineElementDelete,
|
|
62019
|
+
handleTimelineElementsDelete,
|
|
61943
62020
|
handleTimelineElementSplit: handleRazorSplit,
|
|
61944
62021
|
handleRazorSplit,
|
|
61945
62022
|
handleRazorSplitAll,
|
|
@@ -62341,7 +62418,7 @@ function useDomSelection({
|
|
|
62341
62418
|
domEditGroupSelectionsRef.current = [];
|
|
62342
62419
|
setDomEditSelection(null);
|
|
62343
62420
|
setDomEditGroupSelections([]);
|
|
62344
|
-
announceTimelineSelection2([], null);
|
|
62421
|
+
if (options?.announce !== false) announceTimelineSelection2([], null);
|
|
62345
62422
|
return;
|
|
62346
62423
|
}
|
|
62347
62424
|
const isAdditiveSelection = Boolean(options?.additive);
|
|
@@ -62487,7 +62564,11 @@ function useDomSelection({
|
|
|
62487
62564
|
}
|
|
62488
62565
|
const selection = await buildDomSelectionForTimelineElement(element);
|
|
62489
62566
|
if (seq !== timelineSelectSeqRef.current) return;
|
|
62490
|
-
if (selection)
|
|
62567
|
+
if (selection) {
|
|
62568
|
+
applyDomSelection(selection);
|
|
62569
|
+
return;
|
|
62570
|
+
}
|
|
62571
|
+
applyDomSelection(null, { revealPanel: false, announce: false });
|
|
62491
62572
|
},
|
|
62492
62573
|
[applyDomSelection, buildDomSelectionForTimelineElement]
|
|
62493
62574
|
);
|
|
@@ -64463,7 +64544,7 @@ function useDomEditCommits({
|
|
|
64463
64544
|
showToast,
|
|
64464
64545
|
commitPositionPatchToHtml
|
|
64465
64546
|
});
|
|
64466
|
-
const { handleDomEditElementDelete, handleDomZIndexReorderCommit } = useElementLifecycleOps({
|
|
64547
|
+
const { handleDomEditElementDelete, handleDomEditElementsDelete, handleDomZIndexReorderCommit } = useElementLifecycleOps({
|
|
64467
64548
|
activeCompPath,
|
|
64468
64549
|
showToast,
|
|
64469
64550
|
writeProjectFile,
|
|
@@ -64496,6 +64577,7 @@ function useDomEditCommits({
|
|
|
64496
64577
|
handleDomRotationCommit,
|
|
64497
64578
|
handleDomManualEditsReset,
|
|
64498
64579
|
handleDomEditElementDelete,
|
|
64580
|
+
handleDomEditElementsDelete,
|
|
64499
64581
|
handleDomZIndexReorderCommit
|
|
64500
64582
|
};
|
|
64501
64583
|
}
|
|
@@ -66051,7 +66133,7 @@ function useDomEditPreviewSync({
|
|
|
66051
66133
|
refreshDomEditGroupSelectionsFromPreview,
|
|
66052
66134
|
buildDomSelectionFromTarget,
|
|
66053
66135
|
refreshPreviewDocumentVersion,
|
|
66054
|
-
|
|
66136
|
+
syncPreviewHotkeys,
|
|
66055
66137
|
applyStudioManualEditsToPreviewRef,
|
|
66056
66138
|
openSourceForSelection,
|
|
66057
66139
|
getSidebarTab,
|
|
@@ -66090,12 +66172,12 @@ function useDomEditPreviewSync({
|
|
|
66090
66172
|
applyDomSelection(nextSelection, { revealPanel: false, preserveGroup: true });
|
|
66091
66173
|
}
|
|
66092
66174
|
};
|
|
66093
|
-
|
|
66175
|
+
syncPreviewHotkeys(previewIframe);
|
|
66094
66176
|
void applyStudioManualEditsToPreviewRef.current(previewIframe);
|
|
66095
66177
|
void syncSelectionFromDocument();
|
|
66096
66178
|
refreshPreviewDocumentVersion();
|
|
66097
66179
|
const handleLoad = () => {
|
|
66098
|
-
|
|
66180
|
+
syncPreviewHotkeys(previewIframe);
|
|
66099
66181
|
void applyStudioManualEditsToPreviewRef.current(previewIframe);
|
|
66100
66182
|
void syncSelectionFromDocument();
|
|
66101
66183
|
refreshPreviewDocumentVersion();
|
|
@@ -66114,7 +66196,7 @@ function useDomEditPreviewSync({
|
|
|
66114
66196
|
previewIframe,
|
|
66115
66197
|
refreshDomEditGroupSelectionsFromPreview,
|
|
66116
66198
|
refreshPreviewDocumentVersion,
|
|
66117
|
-
|
|
66199
|
+
syncPreviewHotkeys,
|
|
66118
66200
|
applyStudioManualEditsToPreviewRef,
|
|
66119
66201
|
gsapCacheVersion
|
|
66120
66202
|
]);
|
|
@@ -66522,7 +66604,7 @@ function useDomEditWiring({
|
|
|
66522
66604
|
bumpGsapCache,
|
|
66523
66605
|
showToast,
|
|
66524
66606
|
refreshPreviewDocumentVersion,
|
|
66525
|
-
|
|
66607
|
+
syncPreviewHotkeys,
|
|
66526
66608
|
applyStudioManualEditsToPreviewRef,
|
|
66527
66609
|
applyDomSelection,
|
|
66528
66610
|
buildDomSelectionFromTarget,
|
|
@@ -66633,7 +66715,7 @@ function useDomEditWiring({
|
|
|
66633
66715
|
refreshDomEditGroupSelectionsFromPreview,
|
|
66634
66716
|
buildDomSelectionFromTarget,
|
|
66635
66717
|
refreshPreviewDocumentVersion,
|
|
66636
|
-
|
|
66718
|
+
syncPreviewHotkeys,
|
|
66637
66719
|
applyStudioManualEditsToPreviewRef,
|
|
66638
66720
|
openSourceForSelection,
|
|
66639
66721
|
getSidebarTab,
|
|
@@ -67849,6 +67931,9 @@ function useKeyframeEaseCommits({
|
|
|
67849
67931
|
}
|
|
67850
67932
|
|
|
67851
67933
|
// src/hooks/useDomEditSession.ts
|
|
67934
|
+
function membersForDelete(selection, group, options) {
|
|
67935
|
+
return options?.expandGroup && group.length > 0 ? group : [selection];
|
|
67936
|
+
}
|
|
67852
67937
|
function useDomEditSession({
|
|
67853
67938
|
projectId,
|
|
67854
67939
|
activeCompPath,
|
|
@@ -67863,6 +67948,7 @@ function useDomEditSession({
|
|
|
67863
67948
|
setRightCollapsed,
|
|
67864
67949
|
setRightPanelTab,
|
|
67865
67950
|
showToast,
|
|
67951
|
+
isRecordingRef,
|
|
67866
67952
|
refreshPreviewDocumentVersion,
|
|
67867
67953
|
queueDomEditSave,
|
|
67868
67954
|
readProjectFile,
|
|
@@ -67879,7 +67965,7 @@ function useDomEditSession({
|
|
|
67879
67965
|
previewDocumentVersion,
|
|
67880
67966
|
rightPanelTab,
|
|
67881
67967
|
applyStudioManualEditsToPreviewRef,
|
|
67882
|
-
|
|
67968
|
+
syncPreviewHotkeys,
|
|
67883
67969
|
reloadPreview,
|
|
67884
67970
|
setRefreshKey: _setRefreshKey,
|
|
67885
67971
|
openSourceForSelection,
|
|
@@ -68006,7 +68092,7 @@ function useDomEditSession({
|
|
|
68006
68092
|
handleDomRemoveTextField,
|
|
68007
68093
|
handleDomBoxSizeCommit,
|
|
68008
68094
|
handleDomManualEditsReset,
|
|
68009
|
-
|
|
68095
|
+
handleDomEditElementsDelete,
|
|
68010
68096
|
handleDomZIndexReorderCommit
|
|
68011
68097
|
} = useDomEditCommits({
|
|
68012
68098
|
activeCompPath,
|
|
@@ -68080,6 +68166,17 @@ function useDomEditSession({
|
|
|
68080
68166
|
clearDomSelection,
|
|
68081
68167
|
forceReloadSdkSession
|
|
68082
68168
|
});
|
|
68169
|
+
const handleDomEditElementDelete = useCallback114(
|
|
68170
|
+
async (selection, options) => {
|
|
68171
|
+
if (isRecordingRef?.current) {
|
|
68172
|
+
showToast("Cannot edit timeline while recording", "error");
|
|
68173
|
+
return;
|
|
68174
|
+
}
|
|
68175
|
+
const members = membersForDelete(selection, domEditGroupSelectionsRef.current, options);
|
|
68176
|
+
await handleDomEditElementsDelete(members);
|
|
68177
|
+
},
|
|
68178
|
+
[domEditGroupSelectionsRef, handleDomEditElementsDelete, isRecordingRef, showToast]
|
|
68179
|
+
);
|
|
68083
68180
|
const handleGroupSelection = useCallback114(() => {
|
|
68084
68181
|
const group = domEditGroupSelectionsRef.current;
|
|
68085
68182
|
const single = domEditSelectionRef.current;
|
|
@@ -68143,7 +68240,7 @@ function useDomEditSession({
|
|
|
68143
68240
|
bumpGsapCache,
|
|
68144
68241
|
showToast,
|
|
68145
68242
|
refreshPreviewDocumentVersion,
|
|
68146
|
-
|
|
68243
|
+
syncPreviewHotkeys,
|
|
68147
68244
|
applyStudioManualEditsToPreviewRef,
|
|
68148
68245
|
applyDomSelection,
|
|
68149
68246
|
buildDomSelectionFromTarget,
|
|
@@ -69437,21 +69534,19 @@ function dispatchPlainKey(event, key2, cb) {
|
|
|
69437
69534
|
return;
|
|
69438
69535
|
}
|
|
69439
69536
|
}
|
|
69537
|
+
const domSel = cb.domEditSelectionRef.current;
|
|
69538
|
+
if (domSel) {
|
|
69539
|
+
event.preventDefault();
|
|
69540
|
+
void cb.handleDomEditElementDelete(domSel, { expandGroup: true });
|
|
69541
|
+
return;
|
|
69542
|
+
}
|
|
69440
69543
|
const { selectedElementId, selectedElementIds, elements } = usePlayerStore.getState();
|
|
69441
69544
|
const selectionKeys = new Set(selectedElementIds);
|
|
69442
69545
|
if (selectedElementId) selectionKeys.add(selectedElementId);
|
|
69443
|
-
|
|
69444
|
-
|
|
69445
|
-
if (el) {
|
|
69446
|
-
event.preventDefault();
|
|
69447
|
-
void cb.handleTimelineElementDelete(el);
|
|
69448
|
-
return;
|
|
69449
|
-
}
|
|
69450
|
-
}
|
|
69451
|
-
const domSel = cb.domEditSelectionRef.current;
|
|
69452
|
-
if (domSel) {
|
|
69546
|
+
const selected = elements.filter((e) => selectionKeys.has(e.key ?? e.id));
|
|
69547
|
+
if (selected.length > 0) {
|
|
69453
69548
|
event.preventDefault();
|
|
69454
|
-
void cb.
|
|
69549
|
+
void cb.handleTimelineElementsDelete(selected);
|
|
69455
69550
|
}
|
|
69456
69551
|
return;
|
|
69457
69552
|
}
|
|
@@ -69461,7 +69556,7 @@ function dispatchPlainKey(event, key2, cb) {
|
|
|
69461
69556
|
}
|
|
69462
69557
|
}
|
|
69463
69558
|
function useAppHotkeys({
|
|
69464
|
-
|
|
69559
|
+
handleTimelineElementsDelete,
|
|
69465
69560
|
handleTimelineElementSplit,
|
|
69466
69561
|
handleDomEditElementDelete,
|
|
69467
69562
|
domEditSelectionRef,
|
|
@@ -69486,7 +69581,6 @@ function useAppHotkeys({
|
|
|
69486
69581
|
activeCompPath,
|
|
69487
69582
|
forceReloadSdkSession
|
|
69488
69583
|
}) {
|
|
69489
|
-
const previewHotkeyWindowRef = useRef126(null);
|
|
69490
69584
|
const previewHistoryCleanupRef = useRef126(null);
|
|
69491
69585
|
const readHistoryFile = useCallback119(
|
|
69492
69586
|
(path) => path === STUDIO_MOTION_PATH ? readOptionalProjectFile(path) : readProjectFile(path),
|
|
@@ -69545,7 +69639,7 @@ function useAppHotkeys({
|
|
|
69545
69639
|
const handleRedo = useCallback119(() => applyHistory("redo"), [applyHistory]);
|
|
69546
69640
|
const cbRef = useRef126(null);
|
|
69547
69641
|
cbRef.current = {
|
|
69548
|
-
|
|
69642
|
+
handleTimelineElementsDelete,
|
|
69549
69643
|
handleTimelineElementSplit,
|
|
69550
69644
|
handleDomEditElementDelete,
|
|
69551
69645
|
handleUndo,
|
|
@@ -69575,31 +69669,6 @@ function useAppHotkeys({
|
|
|
69575
69669
|
window.addEventListener("keydown", handleAppKeyDown, true);
|
|
69576
69670
|
return () => window.removeEventListener("keydown", handleAppKeyDown, true);
|
|
69577
69671
|
}, [handleAppKeyDown]);
|
|
69578
|
-
const syncPreviewTimelineHotkey = useCallback119(
|
|
69579
|
-
(iframe) => {
|
|
69580
|
-
const nextWindow = iframeContentWindow(iframe);
|
|
69581
|
-
if (previewHotkeyWindowRef.current === nextWindow) return;
|
|
69582
|
-
safeRemoveListener(
|
|
69583
|
-
previewHotkeyWindowRef.current,
|
|
69584
|
-
"keydown",
|
|
69585
|
-
handleAppKeyDown
|
|
69586
|
-
);
|
|
69587
|
-
previewHotkeyWindowRef.current = nextWindow;
|
|
69588
|
-
safeAddListener(nextWindow, "keydown", handleAppKeyDown, true);
|
|
69589
|
-
},
|
|
69590
|
-
[handleAppKeyDown]
|
|
69591
|
-
);
|
|
69592
|
-
useEffect99(
|
|
69593
|
-
() => () => {
|
|
69594
|
-
safeRemoveListener(
|
|
69595
|
-
previewHotkeyWindowRef.current,
|
|
69596
|
-
"keydown",
|
|
69597
|
-
handleAppKeyDown
|
|
69598
|
-
);
|
|
69599
|
-
previewHotkeyWindowRef.current = null;
|
|
69600
|
-
},
|
|
69601
|
-
[handleAppKeyDown]
|
|
69602
|
-
);
|
|
69603
69672
|
const handleHistoryHotkey = useCallback119((event) => {
|
|
69604
69673
|
if (!(event.metaKey || event.ctrlKey) || shouldIgnoreHistoryShortcut(event.target)) return;
|
|
69605
69674
|
handleUndoRedoKey(
|
|
@@ -69608,7 +69677,7 @@ function useAppHotkeys({
|
|
|
69608
69677
|
() => void cbRef.current.handleRedo()
|
|
69609
69678
|
);
|
|
69610
69679
|
}, []);
|
|
69611
|
-
const
|
|
69680
|
+
const syncPreviewHotkeys = useCallback119(
|
|
69612
69681
|
(iframe) => {
|
|
69613
69682
|
previewHistoryCleanupRef.current?.();
|
|
69614
69683
|
previewHistoryCleanupRef.current = null;
|
|
@@ -69621,14 +69690,17 @@ function useAppHotkeys({
|
|
|
69621
69690
|
}
|
|
69622
69691
|
if (!win && !doc) return;
|
|
69623
69692
|
const handler = handleHistoryHotkey;
|
|
69693
|
+
const appHandler = handleAppKeyDown;
|
|
69624
69694
|
safeAddListener(win, "keydown", handler, true);
|
|
69695
|
+
safeAddListener(win, "keydown", appHandler, true);
|
|
69625
69696
|
doc?.addEventListener("keydown", handleHistoryHotkey, true);
|
|
69626
69697
|
previewHistoryCleanupRef.current = () => {
|
|
69627
69698
|
safeRemoveListener(win, "keydown", handler);
|
|
69699
|
+
safeRemoveListener(win, "keydown", appHandler);
|
|
69628
69700
|
doc?.removeEventListener("keydown", handleHistoryHotkey, true);
|
|
69629
69701
|
};
|
|
69630
69702
|
},
|
|
69631
|
-
[handleHistoryHotkey]
|
|
69703
|
+
[handleAppKeyDown, handleHistoryHotkey]
|
|
69632
69704
|
);
|
|
69633
69705
|
useEffect99(
|
|
69634
69706
|
() => () => {
|
|
@@ -69640,8 +69712,7 @@ function useAppHotkeys({
|
|
|
69640
69712
|
return {
|
|
69641
69713
|
handleUndo,
|
|
69642
69714
|
handleRedo,
|
|
69643
|
-
|
|
69644
|
-
syncPreviewHistoryHotkey
|
|
69715
|
+
syncPreviewHotkeys
|
|
69645
69716
|
};
|
|
69646
69717
|
}
|
|
69647
69718
|
|
|
@@ -71207,7 +71278,7 @@ function findUrlSelectionElement(doc, target, fallbackSourceFile, activeCompPath
|
|
|
71207
71278
|
}
|
|
71208
71279
|
async function buildOptionalDomSelection(element, buildDomSelection) {
|
|
71209
71280
|
if (!element) return null;
|
|
71210
|
-
return buildDomSelection(element, { preferClipAncestor: false });
|
|
71281
|
+
return buildDomSelection(element, { preferClipAncestor: false, skipSourceProbe: true });
|
|
71211
71282
|
}
|
|
71212
71283
|
async function resolveUrlSelections({
|
|
71213
71284
|
doc,
|
|
@@ -75568,6 +75639,7 @@ function getVisibleLayers(layers, collapsed) {
|
|
|
75568
75639
|
|
|
75569
75640
|
// src/components/editor/LayersPanel.tsx
|
|
75570
75641
|
import { jsx as jsx175, jsxs as jsxs145 } from "react/jsx-runtime";
|
|
75642
|
+
var LAYERS_PANEL_MAX_ROWS = 80;
|
|
75571
75643
|
var TAG_ICONS = {
|
|
75572
75644
|
video: "Vi",
|
|
75573
75645
|
audio: "Au",
|
|
@@ -75652,11 +75724,13 @@ var LayersPanel = memo43(function LayersPanel2() {
|
|
|
75652
75724
|
const root = doc.querySelector("[data-composition-id]") ?? doc.documentElement ?? null;
|
|
75653
75725
|
if (!root) return;
|
|
75654
75726
|
if (activeGroupElement && !activeGroupElement.isConnected) setActiveGroupElement(null);
|
|
75655
|
-
const items = collectDomEditLayerItems(
|
|
75656
|
-
|
|
75657
|
-
isMasterView,
|
|
75658
|
-
|
|
75659
|
-
|
|
75727
|
+
const items = collectDomEditLayerItems(
|
|
75728
|
+
root,
|
|
75729
|
+
{ activeCompositionPath: activeCompPath, isMasterView, activeGroupElement },
|
|
75730
|
+
// How many rows this panel is willing to render, nothing more. Hit-testing
|
|
75731
|
+
// callers deliberately take the whole document instead.
|
|
75732
|
+
LAYERS_PANEL_MAX_ROWS
|
|
75733
|
+
);
|
|
75660
75734
|
setLayers(sortLayersByZIndex(items));
|
|
75661
75735
|
}, [previewIframeRef, activeCompPath, isMasterView, activeGroupElement, setActiveGroupElement]);
|
|
75662
75736
|
useEffect114(() => {
|
|
@@ -82607,11 +82681,9 @@ function StudioApp() {
|
|
|
82607
82681
|
const clearDomSelectionRef = useRef157(() => {
|
|
82608
82682
|
});
|
|
82609
82683
|
const domEditSelectionBridgeRef = useRef157(null);
|
|
82610
|
-
const handleDomEditElementDeleteRef = useRef157(
|
|
82611
|
-
|
|
82612
|
-
|
|
82613
|
-
);
|
|
82614
|
-
const domEditDeleteBridge = (s) => handleDomEditElementDeleteRef.current(s);
|
|
82684
|
+
const handleDomEditElementDeleteRef = useRef157(async () => {
|
|
82685
|
+
});
|
|
82686
|
+
const domEditDeleteBridge = (s, o) => handleDomEditElementDeleteRef.current(s, o);
|
|
82615
82687
|
const resetKeyframesRef = useRef157(() => false);
|
|
82616
82688
|
const deleteSelectedKeyframesRef = useRef157(() => {
|
|
82617
82689
|
});
|
|
@@ -82629,7 +82701,7 @@ function StudioApp() {
|
|
|
82629
82701
|
previewIframeRef
|
|
82630
82702
|
});
|
|
82631
82703
|
const appHotkeys = useAppHotkeys({
|
|
82632
|
-
|
|
82704
|
+
handleTimelineElementsDelete: timelineEditing.handleTimelineElementsDelete,
|
|
82633
82705
|
handleTimelineElementSplit: timelineEditing.handleTimelineElementSplit,
|
|
82634
82706
|
handleDomEditElementDelete: domEditDeleteBridge,
|
|
82635
82707
|
domEditSelectionRef: domEditSelectionBridgeRef,
|
|
@@ -82673,6 +82745,7 @@ function StudioApp() {
|
|
|
82673
82745
|
setRightCollapsed: panelLayout.setRightCollapsed,
|
|
82674
82746
|
setRightPanelTab: panelLayout.setRightPanelTab,
|
|
82675
82747
|
showToast,
|
|
82748
|
+
isRecordingRef: isGestureRecordingRef,
|
|
82676
82749
|
refreshPreviewDocumentVersion,
|
|
82677
82750
|
queueDomEditSave: previewPersistence.queueDomEditSave,
|
|
82678
82751
|
readProjectFile: fileManager.readProjectFile,
|
|
@@ -82689,7 +82762,7 @@ function StudioApp() {
|
|
|
82689
82762
|
previewDocumentVersion,
|
|
82690
82763
|
rightPanelTab: panelLayout.rightPanelTab,
|
|
82691
82764
|
applyStudioManualEditsToPreviewRef: previewPersistence.applyStudioManualEditsToPreviewRef,
|
|
82692
|
-
|
|
82765
|
+
syncPreviewHotkeys: appHotkeys.syncPreviewHotkeys,
|
|
82693
82766
|
reloadPreview,
|
|
82694
82767
|
setRefreshKey,
|
|
82695
82768
|
openSourceForSelection: fileManager.openSourceForSelection,
|
|
@@ -82755,7 +82828,6 @@ function StudioApp() {
|
|
|
82755
82828
|
isGestureRecordingRef
|
|
82756
82829
|
});
|
|
82757
82830
|
handleToggleRecordingRef.current = handleToggleRecording;
|
|
82758
|
-
const recordingToggle = handleToggleRecording;
|
|
82759
82831
|
const canvasRectRef = useRef157(null);
|
|
82760
82832
|
useLayoutEffect9(() => {
|
|
82761
82833
|
if (gestureState !== "recording" || !previewIframe) {
|
|
@@ -82768,8 +82840,7 @@ function StudioApp() {
|
|
|
82768
82840
|
(iframe) => {
|
|
82769
82841
|
previewIframeRef.current = iframe;
|
|
82770
82842
|
setPreviewIframe(iframe);
|
|
82771
|
-
appHotkeys.
|
|
82772
|
-
appHotkeys.syncPreviewHistoryHotkey(iframe);
|
|
82843
|
+
appHotkeys.syncPreviewHotkeys(iframe);
|
|
82773
82844
|
resetConsoleErrors();
|
|
82774
82845
|
refreshPreviewDocumentVersion();
|
|
82775
82846
|
},
|
|
@@ -82920,7 +82991,7 @@ function StudioApp() {
|
|
|
82920
82991
|
},
|
|
82921
82992
|
recordingState: gestureState,
|
|
82922
82993
|
recordingDuration: gestureRecording.recordingDuration,
|
|
82923
|
-
onToggleRecording:
|
|
82994
|
+
onToggleRecording: handleToggleRecording,
|
|
82924
82995
|
sdkSession: sdkHandle.session,
|
|
82925
82996
|
publishSdkSession: sdkHandle.publish,
|
|
82926
82997
|
forceReloadSdkSession: sdkHandle.forceReload,
|
|
@@ -82954,7 +83025,7 @@ function StudioApp() {
|
|
|
82954
83025
|
shouldShowSelectedDomBounds,
|
|
82955
83026
|
isGestureRecording: gestureState === "recording",
|
|
82956
83027
|
recordingState: gestureState,
|
|
82957
|
-
onToggleRecording:
|
|
83028
|
+
onToggleRecording: handleToggleRecording,
|
|
82958
83029
|
blockPreview,
|
|
82959
83030
|
gestureOverlay: gestureState === "recording" && previewIframe ? /* @__PURE__ */ jsx206(
|
|
82960
83031
|
GestureTrailOverlay,
|