@hyperframes/studio 0.8.190 → 0.8.192
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{hyperframes-player-0HXJPmYC.js → hyperframes-player-ChN3cOr0.js} +3 -3
- package/dist/assets/{index-DsSfhjUS.js → index-BYbFcRR0.js} +1 -1
- package/dist/assets/{index-BYw97F07.js → index-CHu83hHM.js} +126 -125
- package/dist/assets/{index-B3vk3hfU.css → index-CYbvOVp-.css} +1 -1
- package/dist/{chunk-563JPIL4.js → chunk-6SXUUBPD.js} +9 -3
- package/dist/{chunk-FF5DM7BQ.js → chunk-7HZGKFFU.js} +18 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.html +2 -2
- package/dist/index.js +509 -282
- package/dist/player.js +2 -2
- package/dist/styles.css +1 -1
- package/dist/ui.d.ts +3 -1
- package/dist/ui.js +1 -1
- package/package.json +9 -8
- package/src/captions/parser.dom.test.ts +126 -0
- package/src/captions/parser.test.ts +71 -1
- package/src/captions/parser.ts +121 -65
- package/src/components/StudioRightPanels.tsx +9 -0
- package/src/components/dock/DockTab.tsx +2 -0
- package/src/components/dock/dockAccessibility.test.ts +3 -3
- package/src/components/dock/dockLayout.ts +1 -1
- package/src/components/dock/panelRegistry.ts +6 -0
- package/src/components/panels/MotionBlurPanel.test.tsx +177 -0
- package/src/components/panels/MotionBlurPanel.tsx +163 -0
- package/src/components/panels/motionBlurPanelModel.test.ts +143 -0
- package/src/components/panels/motionBlurPanelModel.ts +98 -0
- package/src/components/ui/Tooltip.test.tsx +32 -0
- package/src/components/ui/Tooltip.tsx +23 -3
- package/src/hooks/usePanelLayout.test.ts +1 -1
- package/src/player/components/TimelineClip.filmstrip.test.tsx +1 -1
- package/src/player/components/timelineMotionStyles.test.ts +1 -1
- package/src/styles/theme.css +1 -1
- package/src/utils/studioHelpers.ts +2 -1
- package/src/utils/studioUrlState.ts +8 -1
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
usePreviewVariablesStore,
|
|
49
49
|
whenPreviewBooted,
|
|
50
50
|
writeStudioUiPreferences
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-6SXUUBPD.js";
|
|
52
52
|
import {
|
|
53
53
|
Button,
|
|
54
54
|
ContextMenu,
|
|
@@ -80,7 +80,7 @@ import {
|
|
|
80
80
|
fieldBase,
|
|
81
81
|
fieldText,
|
|
82
82
|
popupSurface
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-7HZGKFFU.js";
|
|
84
84
|
import {
|
|
85
85
|
DOM_EDIT_LAYER_OBSERVER_INIT,
|
|
86
86
|
buildDefaultDomEditTextField,
|
|
@@ -36337,11 +36337,11 @@ function ownNodeTransform(node, ops, getStyle) {
|
|
|
36337
36337
|
const spin = individualRotateDegrees(style.rotate);
|
|
36338
36338
|
return spin === 0 ? own : ops.compose(ops.fromRotate(spin), own);
|
|
36339
36339
|
}
|
|
36340
|
-
function composeElementTransform(element, ops, getStyle,
|
|
36340
|
+
function composeElementTransform(element, ops, getStyle, memo64) {
|
|
36341
36341
|
const pending2 = [];
|
|
36342
36342
|
let above;
|
|
36343
36343
|
for (let node = element; node; node = node.parentElement) {
|
|
36344
|
-
above =
|
|
36344
|
+
above = memo64?.get(node);
|
|
36345
36345
|
if (above !== void 0) break;
|
|
36346
36346
|
pending2.push(node);
|
|
36347
36347
|
if (node.hasAttribute(COMPOSITION_ROOT_ATTR)) break;
|
|
@@ -36353,7 +36353,7 @@ function composeElementTransform(element, ops, getStyle, memo63) {
|
|
|
36353
36353
|
const own = ownNodeTransform(node, ops, getStyle);
|
|
36354
36354
|
acc = own === null ? null : ops.compose(acc, own);
|
|
36355
36355
|
}
|
|
36356
|
-
|
|
36356
|
+
memo64?.set(node, acc);
|
|
36357
36357
|
}
|
|
36358
36358
|
return acc;
|
|
36359
36359
|
}
|
|
@@ -36636,11 +36636,11 @@ function createOverlayMeasurePass() {
|
|
|
36636
36636
|
sourceBoundaryRect: /* @__PURE__ */ new Map()
|
|
36637
36637
|
};
|
|
36638
36638
|
}
|
|
36639
|
-
function readThroughPass(
|
|
36640
|
-
const answered =
|
|
36639
|
+
function readThroughPass(memo64, key2, compute) {
|
|
36640
|
+
const answered = memo64.get(key2);
|
|
36641
36641
|
if (answered !== void 0) return answered;
|
|
36642
36642
|
const value = compute();
|
|
36643
|
-
|
|
36643
|
+
memo64.set(key2, value);
|
|
36644
36644
|
return value;
|
|
36645
36645
|
}
|
|
36646
36646
|
|
|
@@ -51878,6 +51878,7 @@ function DockStripActions({
|
|
|
51878
51878
|
// src/components/dock/DockTab.tsx
|
|
51879
51879
|
import { useCallback as useCallback72, useSyncExternalStore as useSyncExternalStore9 } from "react";
|
|
51880
51880
|
import {
|
|
51881
|
+
Aperture,
|
|
51881
51882
|
BracketsCurly,
|
|
51882
51883
|
ChartBarHorizontal,
|
|
51883
51884
|
Code,
|
|
@@ -51903,7 +51904,8 @@ var TAB_ICONS = {
|
|
|
51903
51904
|
layers: Stack2,
|
|
51904
51905
|
renders: FilmSlate,
|
|
51905
51906
|
variables: BracketsCurly,
|
|
51906
|
-
slideshow: Presentation
|
|
51907
|
+
slideshow: Presentation,
|
|
51908
|
+
motionBlur: Aperture
|
|
51907
51909
|
};
|
|
51908
51910
|
function DockTab({ api }) {
|
|
51909
51911
|
const subscribe2 = useCallback72(
|
|
@@ -52041,7 +52043,7 @@ var MIN_SIDE_W = 200;
|
|
|
52041
52043
|
var MIN_SIDE_W_FLOOR = 120;
|
|
52042
52044
|
var DEFAULT_TIMELINE_H = 360;
|
|
52043
52045
|
var DEFAULT_LEFT = ["compositions", "assets", "code", "catalog"];
|
|
52044
|
-
var DEFAULT_RIGHT = ["design", "layers", "renders", "variables"];
|
|
52046
|
+
var DEFAULT_RIGHT = ["design", "layers", "renders", "variables", "motionBlur"];
|
|
52045
52047
|
function defaultSideWidths(viewportWidth) {
|
|
52046
52048
|
const floor = sideMinimumWidth(viewportWidth);
|
|
52047
52049
|
const left = Math.max(floor, Math.min(384, Math.round(viewportWidth * 0.257)));
|
|
@@ -72917,7 +72919,7 @@ var FileTree = memo43(function FileTree2({
|
|
|
72917
72919
|
});
|
|
72918
72920
|
|
|
72919
72921
|
// src/App.tsx
|
|
72920
|
-
import { useState as
|
|
72922
|
+
import { useState as useState165, useCallback as useCallback195, useRef as useRef190, useMemo as useMemo90 } from "react";
|
|
72921
72923
|
|
|
72922
72924
|
// src/hooks/useStableHandlers.ts
|
|
72923
72925
|
import { useRef as useRef117 } from "react";
|
|
@@ -88829,6 +88831,12 @@ function useClipboard({
|
|
|
88829
88831
|
// src/hooks/useCaptionDetection.ts
|
|
88830
88832
|
import { useEffect as useEffect129, useRef as useRef161 } from "react";
|
|
88831
88833
|
|
|
88834
|
+
// src/captions/parser.ts
|
|
88835
|
+
import {
|
|
88836
|
+
parseExpressionAt,
|
|
88837
|
+
tokenizer
|
|
88838
|
+
} from "acorn";
|
|
88839
|
+
|
|
88832
88840
|
// src/captions/types.ts
|
|
88833
88841
|
var DEFAULT_STYLE = {
|
|
88834
88842
|
fontFamily: "sans-serif",
|
|
@@ -88887,19 +88895,26 @@ var DEFAULT_ANIMATION_SET = {
|
|
|
88887
88895
|
|
|
88888
88896
|
// src/captions/parser.ts
|
|
88889
88897
|
function buildCaptionModel(transcript, options) {
|
|
88890
|
-
const {
|
|
88898
|
+
const { wordsPerGroup = 5 } = options;
|
|
88899
|
+
const wordGroups = [];
|
|
88900
|
+
for (let offset = 0; offset < transcript.length; offset += wordsPerGroup) {
|
|
88901
|
+
wordGroups.push(transcript.slice(offset, offset + wordsPerGroup));
|
|
88902
|
+
}
|
|
88903
|
+
return buildGroupedCaptionModel(wordGroups, options);
|
|
88904
|
+
}
|
|
88905
|
+
function buildGroupedCaptionModel(wordGroups, { width, height, duration }) {
|
|
88891
88906
|
const segments = /* @__PURE__ */ new Map();
|
|
88892
88907
|
const groups = /* @__PURE__ */ new Map();
|
|
88893
88908
|
const groupOrder = [];
|
|
88894
|
-
for (
|
|
88895
|
-
const
|
|
88896
|
-
const groupId = `group-${groupIdx / wordsPerGroup}`;
|
|
88909
|
+
for (const chunk2 of wordGroups) {
|
|
88910
|
+
const groupId = `group-${groups.size}`;
|
|
88897
88911
|
const segmentIds = [];
|
|
88898
88912
|
chunk2.forEach((word, wordIdx) => {
|
|
88899
|
-
const
|
|
88913
|
+
const segmentIndex = segments.size;
|
|
88914
|
+
const segmentId = `segment-${segmentIndex}`;
|
|
88900
88915
|
const segment = {
|
|
88901
88916
|
id: segmentId,
|
|
88902
|
-
wordId: word.id ?? `w${
|
|
88917
|
+
wordId: word.id ?? `w${segmentIndex}`,
|
|
88903
88918
|
text: word.text,
|
|
88904
88919
|
start: word.start,
|
|
88905
88920
|
end: word.end,
|
|
@@ -88938,15 +88953,33 @@ function buildCaptionModel(transcript, options) {
|
|
|
88938
88953
|
}
|
|
88939
88954
|
};
|
|
88940
88955
|
}
|
|
88956
|
+
var GROUP_SELECTOR = ".caption-group, .caption-line, .caption-block";
|
|
88957
|
+
var WORD_SELECTOR = ".word, .caption-word";
|
|
88958
|
+
function readTranscriptGroups(transcript, groupEls) {
|
|
88959
|
+
const wordGroups = [];
|
|
88960
|
+
let offset = 0;
|
|
88961
|
+
for (const group of groupEls) {
|
|
88962
|
+
if (group.parentElement?.closest(GROUP_SELECTOR)) continue;
|
|
88963
|
+
const size = group.querySelectorAll(WORD_SELECTOR).length;
|
|
88964
|
+
if (size === 0) continue;
|
|
88965
|
+
wordGroups.push(transcript.slice(offset, offset + size));
|
|
88966
|
+
offset += size;
|
|
88967
|
+
}
|
|
88968
|
+
return offset === transcript.length ? wordGroups : null;
|
|
88969
|
+
}
|
|
88941
88970
|
function extractTranscript(source) {
|
|
88942
|
-
const varPattern =
|
|
88943
|
-
const match =
|
|
88971
|
+
const varPattern = /\b(?:const|let|var)\s+(?:TRANSCRIPT|script)\s*=\s*(?=\[)/;
|
|
88972
|
+
const match = varPattern.exec(source);
|
|
88944
88973
|
if (!match) {
|
|
88945
88974
|
return [];
|
|
88946
88975
|
}
|
|
88947
|
-
const arrayLiteral = match[1];
|
|
88948
88976
|
try {
|
|
88949
|
-
|
|
88977
|
+
const options = { ecmaVersion: "latest" };
|
|
88978
|
+
const expression = parseExpressionAt(source, match.index + match[0].length, options);
|
|
88979
|
+
if (expression.type !== "ArrayExpression") return [];
|
|
88980
|
+
const nextToken = tokenizer(source.slice(expression.end), options).getToken();
|
|
88981
|
+
if (nextToken.type.label !== ";") return [];
|
|
88982
|
+
return parseTranscriptArray(readStaticValue(expression));
|
|
88950
88983
|
} catch {
|
|
88951
88984
|
return [];
|
|
88952
88985
|
}
|
|
@@ -88956,21 +88989,15 @@ function parseCaptionComposition(iframeDoc, iframeWin, source, compositionWidth,
|
|
|
88956
88989
|
if (transcript.length === 0) {
|
|
88957
88990
|
return null;
|
|
88958
88991
|
}
|
|
88959
|
-
const groupEls = iframeDoc.querySelectorAll(
|
|
88960
|
-
const wordEls = iframeDoc.querySelectorAll(
|
|
88961
|
-
|
|
88962
|
-
|
|
88963
|
-
wordsPerGroup = Math.round(wordEls.length / groupEls.length);
|
|
88964
|
-
if (wordsPerGroup < 1) {
|
|
88965
|
-
wordsPerGroup = 1;
|
|
88966
|
-
}
|
|
88967
|
-
}
|
|
88968
|
-
const model = buildCaptionModel(transcript, {
|
|
88992
|
+
const groupEls = iframeDoc.querySelectorAll(GROUP_SELECTOR);
|
|
88993
|
+
const wordEls = iframeDoc.querySelectorAll(WORD_SELECTOR);
|
|
88994
|
+
const wordGroups = readTranscriptGroups(transcript, groupEls);
|
|
88995
|
+
const options = {
|
|
88969
88996
|
width: compositionWidth,
|
|
88970
88997
|
height: compositionHeight,
|
|
88971
|
-
duration: compositionDuration
|
|
88972
|
-
|
|
88973
|
-
|
|
88998
|
+
duration: compositionDuration
|
|
88999
|
+
};
|
|
89000
|
+
const model = wordGroups ? buildGroupedCaptionModel(wordGroups, options) : buildCaptionModel(transcript, options);
|
|
88974
89001
|
const firstWordEl = wordEls.item(0);
|
|
88975
89002
|
const firstGroupEl = groupEls.item(0);
|
|
88976
89003
|
const styleSourceEl = firstWordEl ?? firstGroupEl;
|
|
@@ -89036,32 +89063,49 @@ function parseCaptionComposition(iframeDoc, iframeWin, source, compositionWidth,
|
|
|
89036
89063
|
}
|
|
89037
89064
|
return model;
|
|
89038
89065
|
}
|
|
89039
|
-
function
|
|
89040
|
-
|
|
89041
|
-
|
|
89042
|
-
|
|
89043
|
-
|
|
89044
|
-
|
|
89045
|
-
|
|
89046
|
-
|
|
89047
|
-
return
|
|
89048
|
-
|
|
89049
|
-
|
|
89050
|
-
|
|
89051
|
-
|
|
89066
|
+
function readStaticValue(node) {
|
|
89067
|
+
switch (node?.type) {
|
|
89068
|
+
case "Literal":
|
|
89069
|
+
if ("regex" in node || "bigint" in node) break;
|
|
89070
|
+
return node.value;
|
|
89071
|
+
case "UnaryExpression":
|
|
89072
|
+
return readSignedNumber(node);
|
|
89073
|
+
case "ArrayExpression":
|
|
89074
|
+
return node.elements.map(readStaticValue);
|
|
89075
|
+
case "ObjectExpression":
|
|
89076
|
+
return Object.fromEntries(node.properties.map(readStaticProperty));
|
|
89077
|
+
}
|
|
89078
|
+
throw new SyntaxError("Transcript values must be static literals");
|
|
89079
|
+
}
|
|
89080
|
+
function readSignedNumber(node) {
|
|
89081
|
+
if (node.operator !== "-" && node.operator !== "+" || node.argument.type !== "Literal" || typeof node.argument.value !== "number") {
|
|
89082
|
+
throw new SyntaxError("Transcript unary expressions must be signed numeric literals");
|
|
89083
|
+
}
|
|
89084
|
+
return node.operator === "-" ? -node.argument.value : node.argument.value;
|
|
89085
|
+
}
|
|
89086
|
+
function readStaticProperty(property) {
|
|
89087
|
+
if (property.type !== "Property" || property.kind !== "init" || property.method || property.shorthand || property.computed) {
|
|
89088
|
+
throw new SyntaxError("Transcript properties must be static data");
|
|
89089
|
+
}
|
|
89090
|
+
const key2 = property.key.type === "Identifier" ? property.key.name : readStaticValue(property.key);
|
|
89091
|
+
if (typeof key2 !== "string" && typeof key2 !== "number") {
|
|
89092
|
+
throw new SyntaxError("Transcript property keys must be names or literals");
|
|
89052
89093
|
}
|
|
89094
|
+
return [key2, readStaticValue(property.value)];
|
|
89095
|
+
}
|
|
89096
|
+
function parseTranscriptArray(parsed) {
|
|
89053
89097
|
if (!Array.isArray(parsed)) {
|
|
89054
89098
|
return [];
|
|
89055
89099
|
}
|
|
89056
89100
|
const words = [];
|
|
89057
|
-
|
|
89058
|
-
|
|
89059
|
-
|
|
89101
|
+
const items = parsed;
|
|
89102
|
+
for (const item of items) {
|
|
89103
|
+
if (item !== null && typeof item === "object" && "text" in item && typeof item.text === "string" && "start" in item && typeof item.start === "number" && "end" in item && typeof item.end === "number") {
|
|
89060
89104
|
words.push({
|
|
89061
|
-
...typeof
|
|
89062
|
-
text:
|
|
89063
|
-
start:
|
|
89064
|
-
end:
|
|
89105
|
+
..."id" in item && typeof item.id === "string" ? { id: item.id } : {},
|
|
89106
|
+
text: item.text,
|
|
89107
|
+
start: item.start,
|
|
89108
|
+
end: item.end
|
|
89065
89109
|
});
|
|
89066
89110
|
}
|
|
89067
89111
|
}
|
|
@@ -89517,7 +89561,14 @@ function useToast() {
|
|
|
89517
89561
|
import { useCallback as useCallback160, useEffect as useEffect132, useRef as useRef166, useState as useState132 } from "react";
|
|
89518
89562
|
|
|
89519
89563
|
// src/utils/studioUrlState.ts
|
|
89520
|
-
var VALID_TABS = [
|
|
89564
|
+
var VALID_TABS = [
|
|
89565
|
+
"layers",
|
|
89566
|
+
"design",
|
|
89567
|
+
"renders",
|
|
89568
|
+
"slideshow",
|
|
89569
|
+
"variables",
|
|
89570
|
+
"motionBlur"
|
|
89571
|
+
];
|
|
89521
89572
|
function resolveMasterCompositionPath(compositions) {
|
|
89522
89573
|
if (compositions.includes("index.html")) return "index.html";
|
|
89523
89574
|
return compositions.find((p) => p.endsWith(".html")) ?? null;
|
|
@@ -91778,7 +91829,7 @@ function useGestureTrailOverlay({
|
|
|
91778
91829
|
}
|
|
91779
91830
|
|
|
91780
91831
|
// src/hooks/useStudioSidePanels.tsx
|
|
91781
|
-
import { useMemo as
|
|
91832
|
+
import { useMemo as useMemo89 } from "react";
|
|
91782
91833
|
|
|
91783
91834
|
// src/components/StudioLeftPanels.tsx
|
|
91784
91835
|
import { memo as memo51, useCallback as useCallback172 } from "react";
|
|
@@ -94413,7 +94464,7 @@ function CodeBody({
|
|
|
94413
94464
|
}
|
|
94414
94465
|
|
|
94415
94466
|
// src/components/StudioRightPanels.tsx
|
|
94416
|
-
import { memo as
|
|
94467
|
+
import { memo as memo62, useCallback as useCallback190 } from "react";
|
|
94417
94468
|
|
|
94418
94469
|
// src/components/editor/LayersPanel.tsx
|
|
94419
94470
|
import { memo as memo52, useState as useState148, useCallback as useCallback174, useEffect as useEffect146, useRef as useRef179 } from "react";
|
|
@@ -98574,8 +98625,175 @@ var VariablesPanel = memo60(function VariablesPanel2({
|
|
|
98574
98625
|
] });
|
|
98575
98626
|
});
|
|
98576
98627
|
|
|
98628
|
+
// src/components/panels/MotionBlurPanel.tsx
|
|
98629
|
+
import { memo as memo61, useCallback as useCallback185, useEffect as useEffect154, useMemo as useMemo87, useReducer as useReducer2, useRef as useRef185, useState as useState161 } from "react";
|
|
98630
|
+
|
|
98631
|
+
// src/components/panels/motionBlurPanelModel.ts
|
|
98632
|
+
import {
|
|
98633
|
+
MOTION_BLUR_ATTR,
|
|
98634
|
+
MOTION_BLUR_LIMITS,
|
|
98635
|
+
motionBlurAttributeEdits,
|
|
98636
|
+
readMotionBlurSettings
|
|
98637
|
+
} from "@hyperframes/core/motion-blur-settings";
|
|
98638
|
+
function findCompositionRoot(roots) {
|
|
98639
|
+
const root = roots.find((el) => "data-composition-id" in el.attributes) ?? roots[0];
|
|
98640
|
+
return root ? { id: root.id, attributes: root.attributes } : null;
|
|
98641
|
+
}
|
|
98642
|
+
var settingsOf = (attributes) => readMotionBlurSettings((name) => attributes[name] ?? null);
|
|
98643
|
+
function changedEdits(attributes, next) {
|
|
98644
|
+
return Object.entries(motionBlurAttributeEdits(next)).filter(([name, value]) => (attributes[name] ?? null) !== value).map(([name, value]) => ({ name, value }));
|
|
98645
|
+
}
|
|
98646
|
+
function withEdits(attributes, edits) {
|
|
98647
|
+
const next = { ...attributes };
|
|
98648
|
+
for (const { name, value } of edits) {
|
|
98649
|
+
if (value === null) delete next[name];
|
|
98650
|
+
else next[name] = value;
|
|
98651
|
+
}
|
|
98652
|
+
return next;
|
|
98653
|
+
}
|
|
98654
|
+
function readPreviewRootAttributes(iframe) {
|
|
98655
|
+
try {
|
|
98656
|
+
const root = iframe?.contentDocument?.querySelector("[data-composition-id]");
|
|
98657
|
+
if (!root) return null;
|
|
98658
|
+
const found = {};
|
|
98659
|
+
for (const name of Object.values(MOTION_BLUR_ATTR)) {
|
|
98660
|
+
const value = root.getAttribute(name);
|
|
98661
|
+
if (value !== null) found[name] = value;
|
|
98662
|
+
}
|
|
98663
|
+
return found;
|
|
98664
|
+
} catch {
|
|
98665
|
+
return null;
|
|
98666
|
+
}
|
|
98667
|
+
}
|
|
98668
|
+
var sameAttributes = (a, b) => a === b || a !== null && b !== null && Object.keys({ ...a, ...b }).every((name) => a[name] === b[name]);
|
|
98669
|
+
var BLUR_LEVELS = [
|
|
98670
|
+
{ level: "off", label: "Off" },
|
|
98671
|
+
{ level: "subtle", label: "Subtle" },
|
|
98672
|
+
{ level: "strong", label: "Strong" }
|
|
98673
|
+
];
|
|
98674
|
+
var LEVEL_SETTINGS = {
|
|
98675
|
+
subtle: { shutterDeg: MOTION_BLUR_LIMITS.shutterDeg.default, samples: null },
|
|
98676
|
+
strong: {
|
|
98677
|
+
shutterDeg: MOTION_BLUR_LIMITS.shutterDeg.max,
|
|
98678
|
+
samples: MOTION_BLUR_LIMITS.samples.max
|
|
98679
|
+
}
|
|
98680
|
+
};
|
|
98681
|
+
var STRONG_ABOVE = (LEVEL_SETTINGS.subtle.shutterDeg + LEVEL_SETTINGS.strong.shutterDeg) / 2;
|
|
98682
|
+
function levelOf(settings) {
|
|
98683
|
+
if (!settings.enabled) return "off";
|
|
98684
|
+
return settings.shutterDeg > STRONG_ABOVE ? "strong" : "subtle";
|
|
98685
|
+
}
|
|
98686
|
+
function patchForLevel(level) {
|
|
98687
|
+
return level === "off" ? { enabled: false } : { enabled: true, ...LEVEL_SETTINGS[level] };
|
|
98688
|
+
}
|
|
98689
|
+
|
|
98690
|
+
// src/components/panels/MotionBlurPanel.tsx
|
|
98691
|
+
import { jsx as jsx244, jsxs as jsxs193 } from "react/jsx-runtime";
|
|
98692
|
+
var POLL_MS2 = 500;
|
|
98693
|
+
var SETTLE_MS = 1500;
|
|
98694
|
+
var NothingToChange = class extends Error {
|
|
98695
|
+
};
|
|
98696
|
+
function useLivePreviewAttributes(previewIframeRef, refreshKey) {
|
|
98697
|
+
const [live, setLive] = useState161(null);
|
|
98698
|
+
const holdUntil = useRef185(0);
|
|
98699
|
+
useEffect154(() => {
|
|
98700
|
+
const read2 = () => {
|
|
98701
|
+
const found = readPreviewRootAttributes(previewIframeRef.current);
|
|
98702
|
+
if (found && Date.now() >= holdUntil.current) {
|
|
98703
|
+
setLive((current) => sameAttributes(current, found) ? current : found);
|
|
98704
|
+
}
|
|
98705
|
+
};
|
|
98706
|
+
read2();
|
|
98707
|
+
const timer = setInterval(read2, POLL_MS2);
|
|
98708
|
+
return () => clearInterval(timer);
|
|
98709
|
+
}, [previewIframeRef, refreshKey]);
|
|
98710
|
+
const hold = useCallback185((next) => {
|
|
98711
|
+
holdUntil.current = Date.now() + SETTLE_MS;
|
|
98712
|
+
setLive(next);
|
|
98713
|
+
}, []);
|
|
98714
|
+
return [live, hold];
|
|
98715
|
+
}
|
|
98716
|
+
var MotionBlurPanel = memo61(function MotionBlurPanel2({
|
|
98717
|
+
sdkSession,
|
|
98718
|
+
publishSdkSession,
|
|
98719
|
+
reloadPreview,
|
|
98720
|
+
recordEdit
|
|
98721
|
+
}) {
|
|
98722
|
+
const { activeCompPath, previewIframeRef, showToast } = useStudioShellContext();
|
|
98723
|
+
const { refreshKey } = useStudioPlaybackContext();
|
|
98724
|
+
const { readProjectFile, writeProjectFile, compositions } = useFileManagerContext();
|
|
98725
|
+
const [, rerender] = useReducer2((n) => n + 1, 0);
|
|
98726
|
+
const [live, hold] = useLivePreviewAttributes(previewIframeRef, refreshKey);
|
|
98727
|
+
useEffect154(() => sdkSession?.on("change", rerender), [sdkSession]);
|
|
98728
|
+
const root = sdkSession ? findCompositionRoot(sdkSession.getRootElements()) : null;
|
|
98729
|
+
const attributes = live ?? root?.attributes ?? null;
|
|
98730
|
+
const settings = useMemo87(() => attributes ? settingsOf(attributes) : null, [attributes]);
|
|
98731
|
+
const isMain = activeCompPath == null || activeCompPath === resolveMasterCompositionPath(compositions);
|
|
98732
|
+
const persist2 = useVariablesPersist({
|
|
98733
|
+
sdkSession,
|
|
98734
|
+
activeCompPath,
|
|
98735
|
+
readProjectFile,
|
|
98736
|
+
writeProjectFile,
|
|
98737
|
+
recordEdit,
|
|
98738
|
+
reloadPreview,
|
|
98739
|
+
publishSdkSession
|
|
98740
|
+
});
|
|
98741
|
+
const apply = useCallback185(
|
|
98742
|
+
async (patch) => {
|
|
98743
|
+
if (!attributes) return;
|
|
98744
|
+
let applied = [];
|
|
98745
|
+
try {
|
|
98746
|
+
await persist2("Edit motion blur", (session) => {
|
|
98747
|
+
const target = findCompositionRoot(session.getRootElements());
|
|
98748
|
+
if (!target) return;
|
|
98749
|
+
const next = { ...settingsOf(target.attributes), ...patch };
|
|
98750
|
+
applied = changedEdits(target.attributes, next);
|
|
98751
|
+
if (applied.length === 0) throw new NothingToChange();
|
|
98752
|
+
for (const e of applied) {
|
|
98753
|
+
session.dispatch({
|
|
98754
|
+
type: "setAttribute",
|
|
98755
|
+
target: target.id,
|
|
98756
|
+
name: e.name,
|
|
98757
|
+
value: e.value
|
|
98758
|
+
});
|
|
98759
|
+
}
|
|
98760
|
+
});
|
|
98761
|
+
hold((current2) => withEdits(current2 ?? attributes, applied));
|
|
98762
|
+
rerender();
|
|
98763
|
+
} catch (err) {
|
|
98764
|
+
if (err instanceof NothingToChange) return;
|
|
98765
|
+
showToast(err instanceof Error ? err.message : String(err), "error");
|
|
98766
|
+
}
|
|
98767
|
+
},
|
|
98768
|
+
[attributes, persist2, hold, showToast]
|
|
98769
|
+
);
|
|
98770
|
+
if (!settings) {
|
|
98771
|
+
return /* @__PURE__ */ jsx244("p", { className: "p-3 text-[10px] leading-relaxed text-neutral-500", children: "Open a composition to set up motion blur." });
|
|
98772
|
+
}
|
|
98773
|
+
const locked = !isMain;
|
|
98774
|
+
const current = locked ? null : levelOf(settings);
|
|
98775
|
+
return /* @__PURE__ */ jsxs193("div", { className: "flex h-full flex-col gap-3 overflow-y-auto p-3 text-[11px] text-neutral-300", children: [
|
|
98776
|
+
/* @__PURE__ */ jsx244("span", { className: "text-[12px] font-medium text-neutral-100", children: "Motion blur" }),
|
|
98777
|
+
/* @__PURE__ */ jsx244("div", { role: "radiogroup", "aria-label": "Motion blur", className: "flex gap-1.5", children: BLUR_LEVELS.map(({ level, label }) => /* @__PURE__ */ jsx244(
|
|
98778
|
+
Button,
|
|
98779
|
+
{
|
|
98780
|
+
role: "radio",
|
|
98781
|
+
"aria-checked": current === level,
|
|
98782
|
+
size: "sm",
|
|
98783
|
+
variant: current === level ? "secondary" : "ghost",
|
|
98784
|
+
className: "flex-1",
|
|
98785
|
+
disabled: locked,
|
|
98786
|
+
onClick: () => void apply(patchForLevel(level)),
|
|
98787
|
+
children: label
|
|
98788
|
+
},
|
|
98789
|
+
level
|
|
98790
|
+
)) }),
|
|
98791
|
+
locked ? /* @__PURE__ */ jsx244("p", { className: "text-[10px] leading-relaxed text-amber-400/90", children: "Motion blur is read from the main composition. Open it to change this setting." }) : null
|
|
98792
|
+
] });
|
|
98793
|
+
});
|
|
98794
|
+
|
|
98577
98795
|
// src/hooks/useSlideshowPersist.ts
|
|
98578
|
-
import { useCallback as
|
|
98796
|
+
import { useCallback as useCallback186 } from "react";
|
|
98579
98797
|
|
|
98580
98798
|
// src/utils/setSlideshowManifest.ts
|
|
98581
98799
|
import {
|
|
@@ -98632,7 +98850,7 @@ function useSlideshowPersist({
|
|
|
98632
98850
|
publishSdkSession,
|
|
98633
98851
|
coalesceKey
|
|
98634
98852
|
}) {
|
|
98635
|
-
return
|
|
98853
|
+
return useCallback186(
|
|
98636
98854
|
async (manifest) => {
|
|
98637
98855
|
if (!sdkSession) return;
|
|
98638
98856
|
const path = activeCompPath ?? "index.html";
|
|
@@ -98665,15 +98883,15 @@ function useSlideshowPersist({
|
|
|
98665
98883
|
}
|
|
98666
98884
|
|
|
98667
98885
|
// src/hooks/useSlideshowTabState.ts
|
|
98668
|
-
import { useMemo as
|
|
98886
|
+
import { useMemo as useMemo88 } from "react";
|
|
98669
98887
|
import { SLIDESHOW_ISLAND_TYPE as SLIDESHOW_ISLAND_TYPE2, slideshowIslandRegex as slideshowIslandRegex2 } from "@hyperframes/core/slideshow";
|
|
98670
98888
|
function useSlideshowTabState(params) {
|
|
98671
98889
|
const { editingFileContent, previewIframeRef, refreshKey, slideshowVisible } = params;
|
|
98672
|
-
const isSlideshowComposition =
|
|
98890
|
+
const isSlideshowComposition = useMemo88(() => {
|
|
98673
98891
|
if (!editingFileContent || !editingFileContent.includes(SLIDESHOW_ISLAND_TYPE2)) return false;
|
|
98674
98892
|
return slideshowIslandRegex2("i").test(editingFileContent);
|
|
98675
98893
|
}, [editingFileContent]);
|
|
98676
|
-
const slideshowScenes =
|
|
98894
|
+
const slideshowScenes = useMemo88(() => {
|
|
98677
98895
|
try {
|
|
98678
98896
|
const win = previewIframeRef.current?.contentWindow;
|
|
98679
98897
|
return (win?.__clipManifest?.scenes ?? []).map((s) => ({
|
|
@@ -98690,8 +98908,8 @@ function useSlideshowTabState(params) {
|
|
|
98690
98908
|
}
|
|
98691
98909
|
|
|
98692
98910
|
// src/components/DesignPanelPromoteProvider.tsx
|
|
98693
|
-
import { useCallback as
|
|
98694
|
-
import { jsx as
|
|
98911
|
+
import { useCallback as useCallback187 } from "react";
|
|
98912
|
+
import { jsx as jsx245 } from "react/jsx-runtime";
|
|
98695
98913
|
function DesignPanelPromoteProvider({
|
|
98696
98914
|
selection,
|
|
98697
98915
|
projectId,
|
|
@@ -98709,7 +98927,7 @@ function DesignPanelPromoteProvider({
|
|
|
98709
98927
|
publishSdkSession: handle.publish,
|
|
98710
98928
|
activeCompPath: targetPath
|
|
98711
98929
|
});
|
|
98712
|
-
const persist2 =
|
|
98930
|
+
const persist2 = useCallback187(
|
|
98713
98931
|
async (label, mutate) => {
|
|
98714
98932
|
const committed = await rawPersist(label, mutate);
|
|
98715
98933
|
if (committed) forceReloadSharedSdkSession?.();
|
|
@@ -98717,11 +98935,11 @@ function DesignPanelPromoteProvider({
|
|
|
98717
98935
|
},
|
|
98718
98936
|
[rawPersist, forceReloadSharedSdkSession]
|
|
98719
98937
|
);
|
|
98720
|
-
const handlePersistError =
|
|
98938
|
+
const handlePersistError = useCallback187(
|
|
98721
98939
|
(error) => showToast(getStudioSaveErrorMessage(error), "error"),
|
|
98722
98940
|
[showToast]
|
|
98723
98941
|
);
|
|
98724
|
-
return /* @__PURE__ */
|
|
98942
|
+
return /* @__PURE__ */ jsx245(
|
|
98725
98943
|
VariablePromoteProvider,
|
|
98726
98944
|
{
|
|
98727
98945
|
session: handle.session,
|
|
@@ -98734,7 +98952,7 @@ function DesignPanelPromoteProvider({
|
|
|
98734
98952
|
}
|
|
98735
98953
|
|
|
98736
98954
|
// src/hooks/useRemoveBackground.ts
|
|
98737
|
-
import { useCallback as
|
|
98955
|
+
import { useCallback as useCallback188, useEffect as useEffect155, useRef as useRef186 } from "react";
|
|
98738
98956
|
|
|
98739
98957
|
// src/components/studioMediaJobs.ts
|
|
98740
98958
|
var MEDIA_JOB_RECONNECT_TIMEOUT_MS = 15e3;
|
|
@@ -98840,14 +99058,14 @@ function waitForMediaJob(jobId, onProgress, signal) {
|
|
|
98840
99058
|
|
|
98841
99059
|
// src/hooks/useRemoveBackground.ts
|
|
98842
99060
|
function useRemoveBackground(projectId, refreshFileTree, showToast) {
|
|
98843
|
-
const abortRef =
|
|
98844
|
-
|
|
99061
|
+
const abortRef = useRef186(null);
|
|
99062
|
+
useEffect155(
|
|
98845
99063
|
() => () => {
|
|
98846
99064
|
abortRef.current?.abort();
|
|
98847
99065
|
},
|
|
98848
99066
|
[]
|
|
98849
99067
|
);
|
|
98850
|
-
return
|
|
99068
|
+
return useCallback188(
|
|
98851
99069
|
// fallow-ignore-next-line complexity
|
|
98852
99070
|
async (inputPath, options) => {
|
|
98853
99071
|
const response = await studioApiFetch(
|
|
@@ -98886,7 +99104,7 @@ function useRemoveBackground(projectId, refreshFileTree, showToast) {
|
|
|
98886
99104
|
}
|
|
98887
99105
|
|
|
98888
99106
|
// src/hooks/useApplyColorGradingScope.ts
|
|
98889
|
-
import { useCallback as
|
|
99107
|
+
import { useCallback as useCallback189 } from "react";
|
|
98890
99108
|
|
|
98891
99109
|
// src/components/editor/colorGradingScopePatch.ts
|
|
98892
99110
|
var MEDIA_TAG_RE = /<\s*(video|img)\b(?:[^>"']|"[^"]*"|'[^']*')*>/gi;
|
|
@@ -98990,7 +99208,7 @@ function useApplyColorGradingScope(recordEdit, reloadPreview) {
|
|
|
98990
99208
|
const { projectId, activeCompPath, showToast, waitForPendingDomEditSaves } = useStudioShellContext();
|
|
98991
99209
|
const { domEditSelection } = useDomEditContext();
|
|
98992
99210
|
const { readProjectFile, writeProjectFile, compositions } = useFileManagerContext();
|
|
98993
|
-
return
|
|
99211
|
+
return useCallback189(
|
|
98994
99212
|
async (scope, value) => applyColorGradingScopeUpdate({
|
|
98995
99213
|
scope,
|
|
98996
99214
|
value,
|
|
@@ -99026,9 +99244,9 @@ function useApplyColorGradingScope(recordEdit, reloadPreview) {
|
|
|
99026
99244
|
}
|
|
99027
99245
|
|
|
99028
99246
|
// src/components/StudioRightPanels.tsx
|
|
99029
|
-
import { Fragment as Fragment66, jsx as
|
|
99247
|
+
import { Fragment as Fragment66, jsx as jsx246, jsxs as jsxs194 } from "react/jsx-runtime";
|
|
99030
99248
|
var seekToTime = (t2) => usePlayerStore.getState().requestSeek(t2);
|
|
99031
|
-
var StudioRightPanels =
|
|
99249
|
+
var StudioRightPanels = memo62(function StudioRightPanels2({
|
|
99032
99250
|
activeBlockParams,
|
|
99033
99251
|
onCloseBlockParams,
|
|
99034
99252
|
onDismissBlockParams,
|
|
@@ -99138,11 +99356,11 @@ var StudioRightPanels = memo61(function StudioRightPanels2({
|
|
|
99138
99356
|
useCaptionDesignFocus(captionEditMode);
|
|
99139
99357
|
const handleApplyColorGradingScope = useApplyColorGradingScope(recordEdit, reloadPreview);
|
|
99140
99358
|
const handleRemoveBackground = useRemoveBackground(projectId, refreshFileTree, showToast);
|
|
99141
|
-
const setAttributeWhileDragging =
|
|
99359
|
+
const setAttributeWhileDragging = useCallback190(
|
|
99142
99360
|
(attr, value) => handleDomAttributeLiveCommit(attr, value, void 0, { previewOnly: true }),
|
|
99143
99361
|
[handleDomAttributeLiveCommit]
|
|
99144
99362
|
);
|
|
99145
|
-
const handleHideAllSelected =
|
|
99363
|
+
const handleHideAllSelected = useCallback190(() => {
|
|
99146
99364
|
if (!canHideSelections(domEditGroupSelections)) {
|
|
99147
99365
|
showToast("Audio can't be hidden. Use the group's own controls", "info");
|
|
99148
99366
|
return;
|
|
@@ -99151,11 +99369,11 @@ var StudioRightPanels = memo61(function StudioRightPanels2({
|
|
|
99151
99369
|
const keys = timelineKeysForSelections(domEditGroupSelections, elements, activeCompPath);
|
|
99152
99370
|
if (keys.length > 0) void onToggleElementHidden?.(keys, true);
|
|
99153
99371
|
}, [domEditGroupSelections, showToast, activeCompPath, onToggleElementHidden]);
|
|
99154
|
-
const convertToKeyframes =
|
|
99372
|
+
const convertToKeyframes = useCallback190(
|
|
99155
99373
|
(animId, duration) => handleGsapConvertToKeyframes(animId, void 0, duration),
|
|
99156
99374
|
[handleGsapConvertToKeyframes]
|
|
99157
99375
|
);
|
|
99158
|
-
const propertyPanel = /* @__PURE__ */
|
|
99376
|
+
const propertyPanel = /* @__PURE__ */ jsx246(
|
|
99159
99377
|
DesignPanelPromoteProvider,
|
|
99160
99378
|
{
|
|
99161
99379
|
selection: domEditGroupSelections.length > 1 ? null : domEditSelection,
|
|
@@ -99167,7 +99385,7 @@ var StudioRightPanels = memo61(function StudioRightPanels2({
|
|
|
99167
99385
|
recordEdit,
|
|
99168
99386
|
reloadPreview,
|
|
99169
99387
|
forceReloadSharedSdkSession: forceReloadSdkSession,
|
|
99170
|
-
children: /* @__PURE__ */
|
|
99388
|
+
children: /* @__PURE__ */ jsx246(
|
|
99171
99389
|
PropertyPanel,
|
|
99172
99390
|
{
|
|
99173
99391
|
projectId,
|
|
@@ -99238,9 +99456,9 @@ var StudioRightPanels = memo61(function StudioRightPanels2({
|
|
|
99238
99456
|
);
|
|
99239
99457
|
let designBody = propertyPanel;
|
|
99240
99458
|
if (captionEditMode) {
|
|
99241
|
-
designBody = /* @__PURE__ */
|
|
99459
|
+
designBody = /* @__PURE__ */ jsx246(CaptionPropertyPanel, { iframeRef: previewIframeRef });
|
|
99242
99460
|
} else if (activeBlockParams) {
|
|
99243
|
-
designBody = /* @__PURE__ */
|
|
99461
|
+
designBody = /* @__PURE__ */ jsx246(
|
|
99244
99462
|
BlockParamsPanel,
|
|
99245
99463
|
{
|
|
99246
99464
|
blockName: activeBlockParams.blockName,
|
|
@@ -99252,18 +99470,18 @@ var StudioRightPanels = memo61(function StudioRightPanels2({
|
|
|
99252
99470
|
}
|
|
99253
99471
|
);
|
|
99254
99472
|
}
|
|
99255
|
-
return /* @__PURE__ */
|
|
99256
|
-
/* @__PURE__ */
|
|
99257
|
-
/* @__PURE__ */
|
|
99258
|
-
/* @__PURE__ */
|
|
99473
|
+
return /* @__PURE__ */ jsxs194(Fragment66, { children: [
|
|
99474
|
+
/* @__PURE__ */ jsx246(Dock.Panel, { id: "design", children: designBody }),
|
|
99475
|
+
/* @__PURE__ */ jsx246(Dock.Panel, { id: "layers", children: /* @__PURE__ */ jsx246(LayersPanel, {}) }),
|
|
99476
|
+
/* @__PURE__ */ jsx246(
|
|
99259
99477
|
Dock.Panel,
|
|
99260
99478
|
{
|
|
99261
99479
|
id: "renders",
|
|
99262
99480
|
title: renderJobs.length > 0 ? `Renders (${renderJobs.length})` : void 0,
|
|
99263
|
-
children: /* @__PURE__ */
|
|
99481
|
+
children: /* @__PURE__ */ jsx246(RenderQueuePanel, {})
|
|
99264
99482
|
}
|
|
99265
99483
|
),
|
|
99266
|
-
/* @__PURE__ */
|
|
99484
|
+
/* @__PURE__ */ jsx246(Dock.Panel, { id: "variables", children: /* @__PURE__ */ jsx246(
|
|
99267
99485
|
VariablesPanel,
|
|
99268
99486
|
{
|
|
99269
99487
|
sdkSession,
|
|
@@ -99272,7 +99490,16 @@ var StudioRightPanels = memo61(function StudioRightPanels2({
|
|
|
99272
99490
|
recordEdit
|
|
99273
99491
|
}
|
|
99274
99492
|
) }),
|
|
99275
|
-
/* @__PURE__ */
|
|
99493
|
+
/* @__PURE__ */ jsx246(Dock.Panel, { id: "motionBlur", children: /* @__PURE__ */ jsx246(
|
|
99494
|
+
MotionBlurPanel,
|
|
99495
|
+
{
|
|
99496
|
+
sdkSession,
|
|
99497
|
+
publishSdkSession,
|
|
99498
|
+
reloadPreview,
|
|
99499
|
+
recordEdit
|
|
99500
|
+
}
|
|
99501
|
+
) }),
|
|
99502
|
+
/* @__PURE__ */ jsx246(Dock.Panel, { id: "slideshow", children: /* @__PURE__ */ jsx246(
|
|
99276
99503
|
SlideshowPanel,
|
|
99277
99504
|
{
|
|
99278
99505
|
scenes: slideshowScenes,
|
|
@@ -99284,21 +99511,21 @@ var StudioRightPanels = memo61(function StudioRightPanels2({
|
|
|
99284
99511
|
});
|
|
99285
99512
|
|
|
99286
99513
|
// src/hooks/useStudioSidePanels.tsx
|
|
99287
|
-
import { Fragment as Fragment67, jsx as
|
|
99514
|
+
import { Fragment as Fragment67, jsx as jsx247, jsxs as jsxs195 } from "react/jsx-runtime";
|
|
99288
99515
|
function useStudioSidePanels(left, right, projectId) {
|
|
99289
99516
|
const stableLeft = useStableHandlers(left, projectId);
|
|
99290
99517
|
const stableRight = useStableHandlers(right, projectId);
|
|
99291
|
-
return
|
|
99292
|
-
() => /* @__PURE__ */
|
|
99293
|
-
/* @__PURE__ */
|
|
99294
|
-
/* @__PURE__ */
|
|
99518
|
+
return useMemo89(
|
|
99519
|
+
() => /* @__PURE__ */ jsxs195(Fragment67, { children: [
|
|
99520
|
+
/* @__PURE__ */ jsx247(StudioLeftPanels, { ...stableLeft }),
|
|
99521
|
+
/* @__PURE__ */ jsx247(StudioRightPanels, { ...stableRight })
|
|
99295
99522
|
] }),
|
|
99296
99523
|
[stableLeft, stableRight]
|
|
99297
99524
|
);
|
|
99298
99525
|
}
|
|
99299
99526
|
|
|
99300
99527
|
// src/components/TimelineToolbar.tsx
|
|
99301
|
-
import { memo as
|
|
99528
|
+
import { memo as memo63, useEffect as useEffect157, useRef as useRef187 } from "react";
|
|
99302
99529
|
import {
|
|
99303
99530
|
ArrowsOutLineHorizontal,
|
|
99304
99531
|
Image as Image3,
|
|
@@ -99308,9 +99535,9 @@ import {
|
|
|
99308
99535
|
} from "@phosphor-icons/react";
|
|
99309
99536
|
|
|
99310
99537
|
// src/hooks/useKeyframeKeyboard.ts
|
|
99311
|
-
import { useEffect as
|
|
99538
|
+
import { useEffect as useEffect156, useCallback as useCallback191 } from "react";
|
|
99312
99539
|
function useKeyframeKeyboard({ enabled, onAddKeyframe }) {
|
|
99313
|
-
const handler =
|
|
99540
|
+
const handler = useCallback191(
|
|
99314
99541
|
(e) => {
|
|
99315
99542
|
if (!enabled || !onAddKeyframe) return;
|
|
99316
99543
|
if (isTypingTarget(document.activeElement)) return;
|
|
@@ -99322,7 +99549,7 @@ function useKeyframeKeyboard({ enabled, onAddKeyframe }) {
|
|
|
99322
99549
|
},
|
|
99323
99550
|
[enabled, onAddKeyframe]
|
|
99324
99551
|
);
|
|
99325
|
-
|
|
99552
|
+
useEffect156(() => {
|
|
99326
99553
|
if (!enabled) return;
|
|
99327
99554
|
window.addEventListener("keydown", handler, { capture: true });
|
|
99328
99555
|
return () => window.removeEventListener("keydown", handler, { capture: true });
|
|
@@ -99330,9 +99557,9 @@ function useKeyframeKeyboard({ enabled, onAddKeyframe }) {
|
|
|
99330
99557
|
}
|
|
99331
99558
|
|
|
99332
99559
|
// src/components/icons/AudioMetersIcon.tsx
|
|
99333
|
-
import { jsx as
|
|
99560
|
+
import { jsx as jsx248 } from "react/jsx-runtime";
|
|
99334
99561
|
function AudioMetersIcon({ size = 16 }) {
|
|
99335
|
-
return /* @__PURE__ */
|
|
99562
|
+
return /* @__PURE__ */ jsx248(
|
|
99336
99563
|
"svg",
|
|
99337
99564
|
{
|
|
99338
99565
|
width: size,
|
|
@@ -99343,15 +99570,15 @@ function AudioMetersIcon({ size = 16 }) {
|
|
|
99343
99570
|
strokeWidth: 1.5,
|
|
99344
99571
|
strokeLinecap: "round",
|
|
99345
99572
|
"aria-hidden": "true",
|
|
99346
|
-
children: /* @__PURE__ */
|
|
99573
|
+
children: /* @__PURE__ */ jsx248("path", { d: "M2.5 13h2m-2-3h2M7 13h2m-2-3h2m-2-3h2m-2-3h2M11.5 13h2m-2-3h2m-2-3h2" })
|
|
99347
99574
|
}
|
|
99348
99575
|
);
|
|
99349
99576
|
}
|
|
99350
99577
|
|
|
99351
99578
|
// src/components/icons/RippleEditIcon.tsx
|
|
99352
|
-
import { jsx as
|
|
99579
|
+
import { jsx as jsx249, jsxs as jsxs196 } from "react/jsx-runtime";
|
|
99353
99580
|
function RippleEditIcon({ size = 16 }) {
|
|
99354
|
-
return /* @__PURE__ */
|
|
99581
|
+
return /* @__PURE__ */ jsxs196(
|
|
99355
99582
|
"svg",
|
|
99356
99583
|
{
|
|
99357
99584
|
width: size,
|
|
@@ -99364,20 +99591,20 @@ function RippleEditIcon({ size = 16 }) {
|
|
|
99364
99591
|
strokeLinejoin: "round",
|
|
99365
99592
|
"aria-hidden": "true",
|
|
99366
99593
|
children: [
|
|
99367
|
-
/* @__PURE__ */
|
|
99368
|
-
/* @__PURE__ */
|
|
99369
|
-
/* @__PURE__ */
|
|
99594
|
+
/* @__PURE__ */ jsx249("rect", { x: "1.5", y: "8", width: "4", height: "5", rx: "0.5" }),
|
|
99595
|
+
/* @__PURE__ */ jsx249("rect", { x: "10.5", y: "8", width: "4", height: "5", rx: "0.5" }),
|
|
99596
|
+
/* @__PURE__ */ jsx249("path", { d: "M13 4H6m2-2L6 4l2 2" })
|
|
99370
99597
|
]
|
|
99371
99598
|
}
|
|
99372
99599
|
);
|
|
99373
99600
|
}
|
|
99374
99601
|
|
|
99375
99602
|
// src/components/TimelineHistoryButtons.tsx
|
|
99376
|
-
import { Fragment as Fragment68, jsx as
|
|
99603
|
+
import { Fragment as Fragment68, jsx as jsx250, jsxs as jsxs197 } from "react/jsx-runtime";
|
|
99377
99604
|
function HistoryButton({ action, can, label, onClick }) {
|
|
99378
99605
|
const Icon = action === "undo" ? RotateCcw : RotateCw;
|
|
99379
99606
|
const enabled = Boolean(onClick) && can;
|
|
99380
|
-
return /* @__PURE__ */
|
|
99607
|
+
return /* @__PURE__ */ jsx250(Tooltip, { label: historyTooltipLabel(action, label), children: /* @__PURE__ */ jsx250(
|
|
99381
99608
|
"button",
|
|
99382
99609
|
{
|
|
99383
99610
|
type: "button",
|
|
@@ -99388,7 +99615,7 @@ function HistoryButton({ action, can, label, onClick }) {
|
|
|
99388
99615
|
trackStudioEvent("toolbar_action", { action });
|
|
99389
99616
|
void onClick?.();
|
|
99390
99617
|
},
|
|
99391
|
-
children: /* @__PURE__ */
|
|
99618
|
+
children: /* @__PURE__ */ jsx250(Icon, { size: 16 })
|
|
99392
99619
|
}
|
|
99393
99620
|
) });
|
|
99394
99621
|
}
|
|
@@ -99396,8 +99623,8 @@ function TimelineHistoryButtons(props) {
|
|
|
99396
99623
|
const shell = useStudioShellContextOptional();
|
|
99397
99624
|
const onUndo = props.onUndo ?? shell?.handleUndo;
|
|
99398
99625
|
const onRedo = props.onRedo ?? shell?.handleRedo;
|
|
99399
|
-
return /* @__PURE__ */
|
|
99400
|
-
/* @__PURE__ */
|
|
99626
|
+
return /* @__PURE__ */ jsxs197(Fragment68, { children: [
|
|
99627
|
+
/* @__PURE__ */ jsx250(
|
|
99401
99628
|
HistoryButton,
|
|
99402
99629
|
{
|
|
99403
99630
|
action: "undo",
|
|
@@ -99406,7 +99633,7 @@ function TimelineHistoryButtons(props) {
|
|
|
99406
99633
|
onClick: onUndo
|
|
99407
99634
|
}
|
|
99408
99635
|
),
|
|
99409
|
-
/* @__PURE__ */
|
|
99636
|
+
/* @__PURE__ */ jsx250(
|
|
99410
99637
|
HistoryButton,
|
|
99411
99638
|
{
|
|
99412
99639
|
action: "redo",
|
|
@@ -99420,9 +99647,9 @@ function TimelineHistoryButtons(props) {
|
|
|
99420
99647
|
|
|
99421
99648
|
// src/components/TimelineToolPicker.tsx
|
|
99422
99649
|
import { ArrowLineLeft, ArrowLineRight, CaretDown } from "@phosphor-icons/react";
|
|
99423
|
-
import { jsx as
|
|
99650
|
+
import { jsx as jsx251, jsxs as jsxs198 } from "react/jsx-runtime";
|
|
99424
99651
|
function SelectIcon() {
|
|
99425
|
-
return /* @__PURE__ */
|
|
99652
|
+
return /* @__PURE__ */ jsx251("svg", { width: "16", height: "16", viewBox: "0 0 12 12", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx251("path", { d: "M2 0.5L10 6L6.5 6.5L8.5 11L6.5 11.5L4.5 7L2 9Z" }) });
|
|
99426
99653
|
}
|
|
99427
99654
|
function TimelineToolPicker({ showSelectAroundPlayhead = true }) {
|
|
99428
99655
|
const activeTool = usePlayerStore((s) => s.activeTool);
|
|
@@ -99431,14 +99658,14 @@ function TimelineToolPicker({ showSelectAroundPlayhead = true }) {
|
|
|
99431
99658
|
{
|
|
99432
99659
|
label: "Select",
|
|
99433
99660
|
shortcut: "V",
|
|
99434
|
-
icon: /* @__PURE__ */
|
|
99661
|
+
icon: /* @__PURE__ */ jsx251(SelectIcon, {}),
|
|
99435
99662
|
active: activeTool === "select",
|
|
99436
99663
|
run: () => store().setActiveTool("select")
|
|
99437
99664
|
},
|
|
99438
99665
|
{
|
|
99439
99666
|
label: "Split",
|
|
99440
99667
|
shortcut: "B",
|
|
99441
|
-
icon: /* @__PURE__ */
|
|
99668
|
+
icon: /* @__PURE__ */ jsx251(Scissors, { size: 16 }),
|
|
99442
99669
|
active: activeTool === "razor",
|
|
99443
99670
|
run: () => store().setActiveTool("razor")
|
|
99444
99671
|
}
|
|
@@ -99448,25 +99675,25 @@ function TimelineToolPicker({ showSelectAroundPlayhead = true }) {
|
|
|
99448
99675
|
{
|
|
99449
99676
|
label: "Select leftward",
|
|
99450
99677
|
shortcut: "[",
|
|
99451
|
-
icon: /* @__PURE__ */
|
|
99678
|
+
icon: /* @__PURE__ */ jsx251(ArrowLineLeft, { size: 16, "aria-hidden": "true" }),
|
|
99452
99679
|
active: false,
|
|
99453
99680
|
run: () => store().selectLeftward()
|
|
99454
99681
|
},
|
|
99455
99682
|
{
|
|
99456
99683
|
label: "Select rightward",
|
|
99457
99684
|
shortcut: "]",
|
|
99458
|
-
icon: /* @__PURE__ */
|
|
99685
|
+
icon: /* @__PURE__ */ jsx251(ArrowLineRight, { size: 16, "aria-hidden": "true" }),
|
|
99459
99686
|
active: false,
|
|
99460
99687
|
run: () => store().selectRightward()
|
|
99461
99688
|
}
|
|
99462
99689
|
);
|
|
99463
99690
|
}
|
|
99464
99691
|
const current = rows.find((row) => row.active) ?? rows[0];
|
|
99465
|
-
return /* @__PURE__ */
|
|
99692
|
+
return /* @__PURE__ */ jsx251(
|
|
99466
99693
|
Menu,
|
|
99467
99694
|
{
|
|
99468
99695
|
"aria-label": "Timeline tools",
|
|
99469
|
-
trigger: /* @__PURE__ */
|
|
99696
|
+
trigger: /* @__PURE__ */ jsxs198(
|
|
99470
99697
|
"button",
|
|
99471
99698
|
{
|
|
99472
99699
|
type: "button",
|
|
@@ -99474,18 +99701,18 @@ function TimelineToolPicker({ showSelectAroundPlayhead = true }) {
|
|
|
99474
99701
|
className: cn(flatIdle, "gap-0.5"),
|
|
99475
99702
|
children: [
|
|
99476
99703
|
current.icon,
|
|
99477
|
-
/* @__PURE__ */
|
|
99704
|
+
/* @__PURE__ */ jsx251(CaretDown, { size: 10, weight: "bold", "aria-hidden": "true" })
|
|
99478
99705
|
]
|
|
99479
99706
|
}
|
|
99480
99707
|
),
|
|
99481
|
-
children: rows.map((row) => /* @__PURE__ */
|
|
99708
|
+
children: rows.map((row) => /* @__PURE__ */ jsx251(
|
|
99482
99709
|
MenuItem,
|
|
99483
99710
|
{
|
|
99484
99711
|
shortcut: row.shortcut,
|
|
99485
99712
|
onClick: row.run,
|
|
99486
99713
|
"data-active": row.active || void 0,
|
|
99487
99714
|
className: row.active ? "bg-press text-text-0" : void 0,
|
|
99488
|
-
children: /* @__PURE__ */
|
|
99715
|
+
children: /* @__PURE__ */ jsxs198("span", { className: "flex items-center gap-2", children: [
|
|
99489
99716
|
row.icon,
|
|
99490
99717
|
row.label
|
|
99491
99718
|
] })
|
|
@@ -99497,17 +99724,17 @@ function TimelineToolPicker({ showSelectAroundPlayhead = true }) {
|
|
|
99497
99724
|
}
|
|
99498
99725
|
|
|
99499
99726
|
// src/components/LinkedSelectionToggle.tsx
|
|
99500
|
-
import { useCallback as
|
|
99727
|
+
import { useCallback as useCallback192, useState as useState162 } from "react";
|
|
99501
99728
|
import { createPortal as createPortal15 } from "react-dom";
|
|
99502
99729
|
import { LinkSimple } from "@phosphor-icons/react";
|
|
99503
|
-
import { Fragment as Fragment69, jsx as
|
|
99730
|
+
import { Fragment as Fragment69, jsx as jsx252, jsxs as jsxs199 } from "react/jsx-runtime";
|
|
99504
99731
|
function SyncIndicatorMenu({ x, y, onClose }) {
|
|
99505
99732
|
const menuRef = useContextMenuDismiss(onClose);
|
|
99506
99733
|
useMenuKeyboardNav(menuRef);
|
|
99507
99734
|
const visible = useLinkedClipPreferences((s) => s.syncIndicatorsVisible);
|
|
99508
99735
|
const setVisible = useLinkedClipPreferences((s) => s.setSyncIndicatorsVisible);
|
|
99509
99736
|
return createPortal15(
|
|
99510
|
-
/* @__PURE__ */
|
|
99737
|
+
/* @__PURE__ */ jsx252(
|
|
99511
99738
|
"div",
|
|
99512
99739
|
{
|
|
99513
99740
|
ref: menuRef,
|
|
@@ -99515,7 +99742,7 @@ function SyncIndicatorMenu({ x, y, onClose }) {
|
|
|
99515
99742
|
"aria-label": "Linked clips",
|
|
99516
99743
|
className: `${menuClasses.panel} fixed z-200 min-w-[200px]`,
|
|
99517
99744
|
style: { left: x, top: y },
|
|
99518
|
-
children: /* @__PURE__ */
|
|
99745
|
+
children: /* @__PURE__ */ jsxs199(
|
|
99519
99746
|
"button",
|
|
99520
99747
|
{
|
|
99521
99748
|
type: "button",
|
|
@@ -99527,7 +99754,7 @@ function SyncIndicatorMenu({ x, y, onClose }) {
|
|
|
99527
99754
|
onClose();
|
|
99528
99755
|
},
|
|
99529
99756
|
children: [
|
|
99530
|
-
/* @__PURE__ */
|
|
99757
|
+
/* @__PURE__ */ jsx252("span", { className: "w-3 text-studio-accent", children: visible ? "\u2713" : "" }),
|
|
99531
99758
|
"Show out-of-sync indicators"
|
|
99532
99759
|
]
|
|
99533
99760
|
}
|
|
@@ -99540,14 +99767,14 @@ function SyncIndicatorMenu({ x, y, onClose }) {
|
|
|
99540
99767
|
function LinkedSelectionToggle() {
|
|
99541
99768
|
const linkedSelection = useLinkedClipPreferences((s) => s.linkedSelection);
|
|
99542
99769
|
const setLinkedSelection = useLinkedClipPreferences((s) => s.setLinkedSelection);
|
|
99543
|
-
const [menuAt, setMenuAt] =
|
|
99544
|
-
const closeMenu =
|
|
99545
|
-
return /* @__PURE__ */
|
|
99546
|
-
/* @__PURE__ */
|
|
99770
|
+
const [menuAt, setMenuAt] = useState162(null);
|
|
99771
|
+
const closeMenu = useCallback192(() => setMenuAt(null), []);
|
|
99772
|
+
return /* @__PURE__ */ jsxs199(Fragment69, { children: [
|
|
99773
|
+
/* @__PURE__ */ jsx252(
|
|
99547
99774
|
Tooltip,
|
|
99548
99775
|
{
|
|
99549
99776
|
label: linkedSelection ? "Linked Selection on: a click selects both halves (\u2325-click for one)" : "Linked Selection off: a click selects one clip",
|
|
99550
|
-
children: /* @__PURE__ */
|
|
99777
|
+
children: /* @__PURE__ */ jsx252(
|
|
99551
99778
|
"button",
|
|
99552
99779
|
{
|
|
99553
99780
|
type: "button",
|
|
@@ -99559,17 +99786,17 @@ function LinkedSelectionToggle() {
|
|
|
99559
99786
|
"aria-label": "Linked Selection",
|
|
99560
99787
|
"aria-pressed": linkedSelection,
|
|
99561
99788
|
className: linkedSelection ? flatActive : flatIdle,
|
|
99562
|
-
children: /* @__PURE__ */
|
|
99789
|
+
children: /* @__PURE__ */ jsx252(LinkSimple, { size: 16, weight: "bold", "aria-hidden": "true" })
|
|
99563
99790
|
}
|
|
99564
99791
|
)
|
|
99565
99792
|
}
|
|
99566
99793
|
),
|
|
99567
|
-
menuAt && /* @__PURE__ */
|
|
99794
|
+
menuAt && /* @__PURE__ */ jsx252(SyncIndicatorMenu, { x: menuAt.x, y: menuAt.y, onClose: closeMenu })
|
|
99568
99795
|
] });
|
|
99569
99796
|
}
|
|
99570
99797
|
|
|
99571
99798
|
// src/components/TimelineToolbar.tsx
|
|
99572
|
-
import { Fragment as Fragment70, jsx as
|
|
99799
|
+
import { Fragment as Fragment70, jsx as jsx253, jsxs as jsxs200 } from "react/jsx-runtime";
|
|
99573
99800
|
var NO_KEYFRAME_TOGGLE = {
|
|
99574
99801
|
state: "none",
|
|
99575
99802
|
isMotionPath: false,
|
|
@@ -99613,7 +99840,7 @@ function useKeyframeToggle(session) {
|
|
|
99613
99840
|
const currentTime = usePlayerStore((s) => s.currentTime);
|
|
99614
99841
|
const selectedElementId = usePlayerStore((s) => s.selectedElementId);
|
|
99615
99842
|
const elements = usePlayerStore((s) => s.elements);
|
|
99616
|
-
const sessionRef =
|
|
99843
|
+
const sessionRef = useRef187(session);
|
|
99617
99844
|
sessionRef.current = session;
|
|
99618
99845
|
const onToggle = useEnableKeyframes(
|
|
99619
99846
|
sessionRef
|
|
@@ -99626,7 +99853,7 @@ function useKeyframeToggle(session) {
|
|
|
99626
99853
|
onToggle: session?.domEditSelection && !toggleState.pathEndpoint ? onToggle : void 0
|
|
99627
99854
|
};
|
|
99628
99855
|
}
|
|
99629
|
-
var TimelineToolbar =
|
|
99856
|
+
var TimelineToolbar = memo63(function TimelineToolbar2({
|
|
99630
99857
|
domEditSession,
|
|
99631
99858
|
onSplitElement,
|
|
99632
99859
|
splitShortcut = SPLIT_SHORTCUT_HINT,
|
|
@@ -99668,10 +99895,10 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99668
99895
|
enabled: showKeyframes && Boolean(onToggleKeyframe),
|
|
99669
99896
|
onAddKeyframe: onToggleKeyframe
|
|
99670
99897
|
});
|
|
99671
|
-
|
|
99898
|
+
useEffect157(() => {
|
|
99672
99899
|
if (!showKeyframes) setAutoKeyframeEnabled(false);
|
|
99673
99900
|
}, [showKeyframes, setAutoKeyframeEnabled]);
|
|
99674
|
-
|
|
99901
|
+
useEffect157(() => {
|
|
99675
99902
|
const onKeyDown = (e) => {
|
|
99676
99903
|
if (e.key !== "n" && e.key !== "N") return;
|
|
99677
99904
|
if (e.metaKey || e.ctrlKey || e.altKey) return;
|
|
@@ -99682,13 +99909,13 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99682
99909
|
window.addEventListener("keydown", onKeyDown);
|
|
99683
99910
|
return () => window.removeEventListener("keydown", onKeyDown);
|
|
99684
99911
|
}, []);
|
|
99685
|
-
return /* @__PURE__ */
|
|
99686
|
-
/* @__PURE__ */
|
|
99687
|
-
showHistory && /* @__PURE__ */
|
|
99688
|
-
/* @__PURE__ */
|
|
99689
|
-
/* @__PURE__ */
|
|
99690
|
-
/* @__PURE__ */
|
|
99691
|
-
/* @__PURE__ */
|
|
99912
|
+
return /* @__PURE__ */ jsx253("div", { className: "border-b border-neutral-800/60", children: /* @__PURE__ */ jsxs200("div", { className: "flex items-center justify-between px-2 py-0.5", children: [
|
|
99913
|
+
/* @__PURE__ */ jsxs200("div", { className: "flex items-center gap-0.5", children: [
|
|
99914
|
+
showHistory && /* @__PURE__ */ jsx253(TimelineHistoryButtons, { ...history2 }),
|
|
99915
|
+
/* @__PURE__ */ jsx253(TimelineToolPicker, { showSelectAroundPlayhead }),
|
|
99916
|
+
/* @__PURE__ */ jsx253("div", { "aria-hidden": "true", className: "mx-1 h-4 w-px bg-neutral-800" }),
|
|
99917
|
+
/* @__PURE__ */ jsx253(LinkedSelectionToggle, {}),
|
|
99918
|
+
/* @__PURE__ */ jsx253(Tooltip, { label: timelineSnapEnabled ? "Snapping on (N)" : "Snapping off (N)", children: /* @__PURE__ */ jsx253(
|
|
99692
99919
|
"button",
|
|
99693
99920
|
{
|
|
99694
99921
|
type: "button",
|
|
@@ -99696,14 +99923,14 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99696
99923
|
"aria-label": "Toggle timeline snapping",
|
|
99697
99924
|
"aria-pressed": timelineSnapEnabled,
|
|
99698
99925
|
className: timelineSnapEnabled ? flatActive : flatIdle,
|
|
99699
|
-
children: /* @__PURE__ */
|
|
99926
|
+
children: /* @__PURE__ */ jsx253(Magnet, { size: 16, weight: "bold", "aria-hidden": "true" })
|
|
99700
99927
|
}
|
|
99701
99928
|
) }),
|
|
99702
|
-
/* @__PURE__ */
|
|
99929
|
+
/* @__PURE__ */ jsx253(
|
|
99703
99930
|
Tooltip,
|
|
99704
99931
|
{
|
|
99705
99932
|
label: rippleEditEnabled ? "Ripple on: keeps the main track gapless" : "Ripple off: deleting a main-track clip leaves a gap",
|
|
99706
|
-
children: /* @__PURE__ */
|
|
99933
|
+
children: /* @__PURE__ */ jsx253(
|
|
99707
99934
|
"button",
|
|
99708
99935
|
{
|
|
99709
99936
|
type: "button",
|
|
@@ -99711,12 +99938,12 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99711
99938
|
"aria-label": "Toggle ripple edit",
|
|
99712
99939
|
"aria-pressed": rippleEditEnabled,
|
|
99713
99940
|
className: rippleEditEnabled ? flatActive : flatIdle,
|
|
99714
|
-
children: /* @__PURE__ */
|
|
99941
|
+
children: /* @__PURE__ */ jsx253(RippleEditIcon, { size: 16 })
|
|
99715
99942
|
}
|
|
99716
99943
|
)
|
|
99717
99944
|
}
|
|
99718
99945
|
),
|
|
99719
|
-
projectHasAudio && /* @__PURE__ */
|
|
99946
|
+
projectHasAudio && /* @__PURE__ */ jsx253(Tooltip, { label: audioMetersVisible ? "Hide audio meters" : "Show audio meters", children: /* @__PURE__ */ jsx253(
|
|
99720
99947
|
"button",
|
|
99721
99948
|
{
|
|
99722
99949
|
type: "button",
|
|
@@ -99724,15 +99951,15 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99724
99951
|
"aria-label": "Toggle audio meters",
|
|
99725
99952
|
"aria-pressed": audioMetersVisible,
|
|
99726
99953
|
className: audioMetersVisible ? flatActive : flatIdle,
|
|
99727
|
-
children: /* @__PURE__ */
|
|
99954
|
+
children: /* @__PURE__ */ jsx253(AudioMetersIcon, { size: 16 })
|
|
99728
99955
|
}
|
|
99729
99956
|
) }),
|
|
99730
|
-
showKeyframes && /* @__PURE__ */
|
|
99731
|
-
/* @__PURE__ */
|
|
99957
|
+
showKeyframes && /* @__PURE__ */ jsxs200(Fragment70, { children: [
|
|
99958
|
+
/* @__PURE__ */ jsx253(
|
|
99732
99959
|
Tooltip,
|
|
99733
99960
|
{
|
|
99734
99961
|
label: keyframePathEndpoint ? "Motion path endpoints cannot be removed" : !onToggleKeyframe ? "Select an animated element to add keyframes" : keyframeIsMotionPath ? keyframeWillExtend ? "Extend motion path to playhead (K)" : keyframeState === "active" ? "Remove waypoint from motion path (K)" : "Add waypoint to motion path (K)" : keyframeState === "active" ? "Remove keyframe at playhead (K)" : keyframeState === "inactive" ? keyframeWillExtend ? "Add keyframe at playhead, extends animation (K)" : "Add keyframe at playhead (K)" : "Add keyframe (K)",
|
|
99735
|
-
children: /* @__PURE__ */
|
|
99962
|
+
children: /* @__PURE__ */ jsx253(
|
|
99736
99963
|
"button",
|
|
99737
99964
|
{
|
|
99738
99965
|
type: "button",
|
|
@@ -99740,7 +99967,7 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99740
99967
|
onClick: onToggleKeyframe,
|
|
99741
99968
|
"aria-label": keyframePathEndpoint ? "Motion path endpoint" : keyframeIsMotionPath ? keyframeState === "active" ? "Remove motion path waypoint" : keyframeWillExtend ? "Extend motion path to playhead" : "Add motion path waypoint" : keyframeState === "active" ? "Remove keyframe at playhead" : "Add keyframe at playhead",
|
|
99742
99969
|
className: !onToggleKeyframe ? flatDisabled : `${flatBtn} active:scale-[0.98] hover:bg-hover ${keyframeState === "active" ? "text-accent-ink" : keyframeState === "inactive" ? "text-neutral-400 hover:text-accent-ink" : "text-neutral-600 hover:text-neutral-400"}`,
|
|
99743
|
-
children: /* @__PURE__ */
|
|
99970
|
+
children: /* @__PURE__ */ jsx253("svg", { width: "16", height: "16", viewBox: "0 0 10 10", fill: "currentColor", children: keyframeState === "active" ? /* @__PURE__ */ jsx253("path", { d: "M5 0.5L9.5 5L5 9.5L0.5 5Z" }) : /* @__PURE__ */ jsx253(
|
|
99744
99971
|
"path",
|
|
99745
99972
|
{
|
|
99746
99973
|
d: "M5 1.2L8.8 5L5 8.8L1.2 5Z",
|
|
@@ -99753,11 +99980,11 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99753
99980
|
)
|
|
99754
99981
|
}
|
|
99755
99982
|
),
|
|
99756
|
-
/* @__PURE__ */
|
|
99983
|
+
/* @__PURE__ */ jsx253(
|
|
99757
99984
|
Tooltip,
|
|
99758
99985
|
{
|
|
99759
99986
|
label: autoKeyframeEnabled ? "Auto-record manual edits as keyframes (click to turn off)" : "Manual edits will not be recorded as keyframes (click to turn on)",
|
|
99760
|
-
children: /* @__PURE__ */
|
|
99987
|
+
children: /* @__PURE__ */ jsx253(
|
|
99761
99988
|
"button",
|
|
99762
99989
|
{
|
|
99763
99990
|
type: "button",
|
|
@@ -99765,9 +99992,9 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99765
99992
|
"aria-label": "Auto-record manual edits as keyframes",
|
|
99766
99993
|
"aria-pressed": autoKeyframeEnabled,
|
|
99767
99994
|
className: `${flatBtn} active:scale-[0.98] hover:bg-hover ${autoKeyframeEnabled ? "text-danger-ink" : "text-neutral-600 hover:text-neutral-400"}`,
|
|
99768
|
-
children: /* @__PURE__ */
|
|
99769
|
-
/* @__PURE__ */
|
|
99770
|
-
/* @__PURE__ */
|
|
99995
|
+
children: /* @__PURE__ */ jsxs200("svg", { width: "16", height: "16", viewBox: "0 0 10 10", fill: "none", children: [
|
|
99996
|
+
/* @__PURE__ */ jsx253("path", { d: "M5 0.7L9.3 5L5 9.3L0.7 5Z", stroke: "currentColor", strokeWidth: "1" }),
|
|
99997
|
+
/* @__PURE__ */ jsx253(
|
|
99771
99998
|
"circle",
|
|
99772
99999
|
{
|
|
99773
100000
|
cx: "5",
|
|
@@ -99788,11 +100015,11 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99788
100015
|
const el = selectedElementId ? elements.find((e) => (e.key ?? e.id) === selectedElementId) : null;
|
|
99789
100016
|
const splittable = el != null && canSplitElement(el);
|
|
99790
100017
|
const canSplit = splittable && currentTime > el.start && currentTime < el.start + el.duration;
|
|
99791
|
-
return /* @__PURE__ */
|
|
100018
|
+
return /* @__PURE__ */ jsx253(
|
|
99792
100019
|
Tooltip,
|
|
99793
100020
|
{
|
|
99794
100021
|
label: canSplit ? `Split at playhead (${splitShortcut})` : splittable ? "Move the playhead inside the clip to split" : "Select a clip to split",
|
|
99795
|
-
children: /* @__PURE__ */
|
|
100022
|
+
children: /* @__PURE__ */ jsx253(
|
|
99796
100023
|
"button",
|
|
99797
100024
|
{
|
|
99798
100025
|
type: "button",
|
|
@@ -99802,7 +100029,7 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99802
100029
|
if (canSplit && el) onSplitElement(el, currentTime);
|
|
99803
100030
|
},
|
|
99804
100031
|
className: canSplit ? flatIdle : flatDisabled,
|
|
99805
|
-
children: /* @__PURE__ */
|
|
100032
|
+
children: /* @__PURE__ */ jsxs200(
|
|
99806
100033
|
"svg",
|
|
99807
100034
|
{
|
|
99808
100035
|
width: "16",
|
|
@@ -99815,8 +100042,8 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99815
100042
|
strokeLinejoin: "round",
|
|
99816
100043
|
"aria-hidden": "true",
|
|
99817
100044
|
children: [
|
|
99818
|
-
/* @__PURE__ */
|
|
99819
|
-
/* @__PURE__ */
|
|
100045
|
+
/* @__PURE__ */ jsx253("path", { d: "M5 3 L7 3 L7 13 L5 13" }),
|
|
100046
|
+
/* @__PURE__ */ jsx253("path", { d: "M11 3 L9 3 L9 13 L11 13" })
|
|
99820
100047
|
]
|
|
99821
100048
|
}
|
|
99822
100049
|
)
|
|
@@ -99828,11 +100055,11 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99828
100055
|
(() => {
|
|
99829
100056
|
if (!showAddBeat) return null;
|
|
99830
100057
|
const canAdd = beatAnalysisReady && canAddBeatAt(currentTime);
|
|
99831
|
-
return /* @__PURE__ */
|
|
100058
|
+
return /* @__PURE__ */ jsx253(
|
|
99832
100059
|
Tooltip,
|
|
99833
100060
|
{
|
|
99834
100061
|
label: !beatAnalysisReady ? "Add a music track with beat analysis to place beats" : canAdd ? "Add beat at playhead" : "A beat already exists at the playhead",
|
|
99835
|
-
children: /* @__PURE__ */
|
|
100062
|
+
children: /* @__PURE__ */ jsx253(
|
|
99836
100063
|
"button",
|
|
99837
100064
|
{
|
|
99838
100065
|
type: "button",
|
|
@@ -99842,7 +100069,7 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99842
100069
|
if (canAdd) addBeatAtCompositionTime(currentTime);
|
|
99843
100070
|
},
|
|
99844
100071
|
className: canAdd ? `${flatBtn} text-text-2 hover:bg-hover hover:text-accent-ink active:scale-[0.98]` : flatDisabled,
|
|
99845
|
-
children: /* @__PURE__ */
|
|
100072
|
+
children: /* @__PURE__ */ jsx253("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx253(
|
|
99846
100073
|
"path",
|
|
99847
100074
|
{
|
|
99848
100075
|
d: "M21 10C21 12.2091 16.9706 14 12 14M21 10C21 7.79086 16.9706 6 12 6C7.02944 6 3 7.79086 3 10M21 10V16C21 18.2091 16.9706 20 12 20M12 14C7.02944 14 3 12.2091 3 10M12 14V20M3 10V16C3 18.2091 7.02944 20 12 20M7 19.3264V13.3264M17 19.3264V13.3264M12 10L20 4",
|
|
@@ -99858,13 +100085,13 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99858
100085
|
);
|
|
99859
100086
|
})()
|
|
99860
100087
|
] }),
|
|
99861
|
-
/* @__PURE__ */
|
|
100088
|
+
/* @__PURE__ */ jsxs200("div", { className: "flex items-center gap-0.5", children: [
|
|
99862
100089
|
rightActions,
|
|
99863
|
-
/* @__PURE__ */
|
|
100090
|
+
/* @__PURE__ */ jsx253(
|
|
99864
100091
|
Tooltip,
|
|
99865
100092
|
{
|
|
99866
100093
|
label: thumbnailsVisible ? "Hide thumbnails: labels only" : "Show thumbnails: posters stay visible; richer previews appear on interaction",
|
|
99867
|
-
children: /* @__PURE__ */
|
|
100094
|
+
children: /* @__PURE__ */ jsx253(
|
|
99868
100095
|
"button",
|
|
99869
100096
|
{
|
|
99870
100097
|
type: "button",
|
|
@@ -99872,12 +100099,12 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99872
100099
|
"aria-pressed": thumbnailsVisible,
|
|
99873
100100
|
onClick: () => setThumbnailMode(thumbnailsVisible ? "hidden" : "adaptive"),
|
|
99874
100101
|
className: `h-7 px-2 rounded-md text-[11px] font-medium transition-colors ${thumbnailsVisible ? "bg-studio-accent/10 text-accent-ink" : "text-neutral-400 hover:bg-hover hover:text-neutral-200"}`,
|
|
99875
|
-
children: /* @__PURE__ */
|
|
100102
|
+
children: /* @__PURE__ */ jsx253(Image3, { size: 16, "aria-hidden": "true" })
|
|
99876
100103
|
}
|
|
99877
100104
|
)
|
|
99878
100105
|
}
|
|
99879
100106
|
),
|
|
99880
|
-
/* @__PURE__ */
|
|
100107
|
+
/* @__PURE__ */ jsx253(Tooltip, { label: "Fit timeline to width", children: /* @__PURE__ */ jsx253(
|
|
99881
100108
|
"button",
|
|
99882
100109
|
{
|
|
99883
100110
|
type: "button",
|
|
@@ -99885,20 +100112,20 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99885
100112
|
"aria-label": "Fit timeline to width",
|
|
99886
100113
|
"aria-pressed": zoomMode === "fit",
|
|
99887
100114
|
className: `h-7 px-2 rounded-md text-[11px] font-medium transition-colors ${zoomMode === "fit" ? "bg-studio-accent/10 text-accent-ink" : "text-neutral-400 hover:bg-hover hover:text-neutral-200"}`,
|
|
99888
|
-
children: /* @__PURE__ */
|
|
100115
|
+
children: /* @__PURE__ */ jsx253(ArrowsOutLineHorizontal, { size: 16, "aria-hidden": "true" })
|
|
99889
100116
|
}
|
|
99890
100117
|
) }),
|
|
99891
|
-
/* @__PURE__ */
|
|
100118
|
+
/* @__PURE__ */ jsx253(Tooltip, { label: "Zoom out", children: /* @__PURE__ */ jsx253(
|
|
99892
100119
|
"button",
|
|
99893
100120
|
{
|
|
99894
100121
|
type: "button",
|
|
99895
100122
|
"aria-label": "Zoom out",
|
|
99896
100123
|
onClick: () => zoomTimelineStep("out"),
|
|
99897
100124
|
className: flatIdle,
|
|
99898
|
-
children: /* @__PURE__ */
|
|
100125
|
+
children: /* @__PURE__ */ jsx253(MagnifyingGlassMinus, { size: 16, "aria-hidden": "true" })
|
|
99899
100126
|
}
|
|
99900
100127
|
) }),
|
|
99901
|
-
/* @__PURE__ */
|
|
100128
|
+
/* @__PURE__ */ jsx253(
|
|
99902
100129
|
"input",
|
|
99903
100130
|
{
|
|
99904
100131
|
type: "range",
|
|
@@ -99913,17 +100140,17 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99913
100140
|
className: "mx-1 h-6 w-[96px] cursor-pointer appearance-none bg-transparent [&::-webkit-slider-runnable-track]:h-[2px] [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-neutral-700 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-[10px] [&::-webkit-slider-thumb]:h-[10px] [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-text-0 [&::-webkit-slider-thumb]:-mt-1 [&::-webkit-slider-thumb]:shadow-[0_0_0_2px_#0a0a0a,0_1px_3px_rgba(0,0,0,0.5)] [&::-webkit-slider-thumb]:cursor-grab [&::-webkit-slider-thumb:active]:cursor-grabbing"
|
|
99914
100141
|
}
|
|
99915
100142
|
),
|
|
99916
|
-
/* @__PURE__ */
|
|
100143
|
+
/* @__PURE__ */ jsx253(Tooltip, { label: "Zoom in", children: /* @__PURE__ */ jsx253(
|
|
99917
100144
|
"button",
|
|
99918
100145
|
{
|
|
99919
100146
|
type: "button",
|
|
99920
100147
|
"aria-label": "Zoom in",
|
|
99921
100148
|
onClick: () => zoomTimelineStep("in"),
|
|
99922
100149
|
className: flatIdle,
|
|
99923
|
-
children: /* @__PURE__ */
|
|
100150
|
+
children: /* @__PURE__ */ jsx253(MagnifyingGlassPlus, { size: 16, "aria-hidden": "true" })
|
|
99924
100151
|
}
|
|
99925
100152
|
) }),
|
|
99926
|
-
/* @__PURE__ */
|
|
100153
|
+
/* @__PURE__ */ jsx253(
|
|
99927
100154
|
"span",
|
|
99928
100155
|
{
|
|
99929
100156
|
className: "ml-1 w-[38px] text-right font-mono text-[11px] tabular-nums text-neutral-500 select-none",
|
|
@@ -99936,23 +100163,23 @@ var TimelineToolbar = memo62(function TimelineToolbar2({
|
|
|
99936
100163
|
});
|
|
99937
100164
|
|
|
99938
100165
|
// src/components/StudioSplash.tsx
|
|
99939
|
-
import { jsx as
|
|
100166
|
+
import { jsx as jsx254, jsxs as jsxs201 } from "react/jsx-runtime";
|
|
99940
100167
|
function StudioSplash({ waiting }) {
|
|
99941
|
-
return /* @__PURE__ */
|
|
99942
|
-
/* @__PURE__ */
|
|
99943
|
-
/* @__PURE__ */
|
|
100168
|
+
return /* @__PURE__ */ jsx254("div", { className: "h-full w-full bg-neutral-950 flex items-center justify-center", children: waiting ? /* @__PURE__ */ jsxs201("div", { className: "flex flex-col items-center gap-3 text-center px-6", role: "status", children: [
|
|
100169
|
+
/* @__PURE__ */ jsx254("div", { className: "w-4 h-4 rounded-full border-2 border-neutral-700 border-t-neutral-500 animate-spin motion-reduce:animate-none" }),
|
|
100170
|
+
/* @__PURE__ */ jsxs201("p", { className: "text-xs text-neutral-600", children: [
|
|
99944
100171
|
"Waiting for preview server\u2026 run",
|
|
99945
100172
|
" ",
|
|
99946
|
-
/* @__PURE__ */
|
|
100173
|
+
/* @__PURE__ */ jsx254("code", { className: "text-neutral-500 font-mono", children: "npm run dev" })
|
|
99947
100174
|
] })
|
|
99948
|
-
] }) : /* @__PURE__ */
|
|
99949
|
-
/* @__PURE__ */
|
|
99950
|
-
/* @__PURE__ */
|
|
100175
|
+
] }) : /* @__PURE__ */ jsxs201("div", { className: "flex flex-col items-center gap-3 text-center px-6", role: "status", children: [
|
|
100176
|
+
/* @__PURE__ */ jsx254("div", { className: "w-4 h-4 rounded-full bg-studio-accent animate-pulse motion-reduce:animate-none" }),
|
|
100177
|
+
/* @__PURE__ */ jsx254("p", { className: "text-xs text-neutral-600", children: "Connecting to project\u2026" })
|
|
99951
100178
|
] }) });
|
|
99952
100179
|
}
|
|
99953
100180
|
|
|
99954
100181
|
// src/hooks/useServerConnection.ts
|
|
99955
|
-
import { useEffect as
|
|
100182
|
+
import { useEffect as useEffect158, useState as useState163 } from "react";
|
|
99956
100183
|
async function resolveHashProject(id) {
|
|
99957
100184
|
try {
|
|
99958
100185
|
const res = await studioApiFetch(`/api/projects/${encodeURIComponent(id)}`);
|
|
@@ -99982,9 +100209,9 @@ function reportHashVerdict(stage, verdict) {
|
|
|
99982
100209
|
});
|
|
99983
100210
|
}
|
|
99984
100211
|
function useServerConnection() {
|
|
99985
|
-
const [projectId, setProjectId] =
|
|
99986
|
-
const [resolving, setResolving] =
|
|
99987
|
-
const [waitingForServer, setWaitingForServer] =
|
|
100212
|
+
const [projectId, setProjectId] = useState163(null);
|
|
100213
|
+
const [resolving, setResolving] = useState163(true);
|
|
100214
|
+
const [waitingForServer, setWaitingForServer] = useState163(false);
|
|
99988
100215
|
useMountEffect(() => {
|
|
99989
100216
|
const hashProjectId = parseProjectIdFromHash(window.location.hash);
|
|
99990
100217
|
let cancelled = false;
|
|
@@ -100026,7 +100253,7 @@ function useServerConnection() {
|
|
|
100026
100253
|
if (retryTimer !== null) clearTimeout(retryTimer);
|
|
100027
100254
|
};
|
|
100028
100255
|
});
|
|
100029
|
-
|
|
100256
|
+
useEffect158(() => {
|
|
100030
100257
|
const onHashChange = () => {
|
|
100031
100258
|
const next = parseProjectIdFromHash(window.location.hash);
|
|
100032
100259
|
if (!next || next === projectId) return;
|
|
@@ -100052,9 +100279,9 @@ function useServerConnection() {
|
|
|
100052
100279
|
}
|
|
100053
100280
|
|
|
100054
100281
|
// src/hooks/useStudioSessionStart.ts
|
|
100055
|
-
import { useEffect as
|
|
100282
|
+
import { useEffect as useEffect159 } from "react";
|
|
100056
100283
|
function useStudioSessionStart(projectId, resolving, waitingForServer) {
|
|
100057
|
-
|
|
100284
|
+
useEffect159(() => {
|
|
100058
100285
|
if (resolving || waitingForServer || hasFiredSessionStart()) return;
|
|
100059
100286
|
markSessionStartFired();
|
|
100060
100287
|
trackStudioSessionStart({ has_project: projectId != null });
|
|
@@ -100062,13 +100289,13 @@ function useStudioSessionStart(projectId, resolving, waitingForServer) {
|
|
|
100062
100289
|
}
|
|
100063
100290
|
|
|
100064
100291
|
// src/hooks/useTimelineAddAtPlayhead.ts
|
|
100065
|
-
import { useCallback as
|
|
100292
|
+
import { useCallback as useCallback193 } from "react";
|
|
100066
100293
|
function useTimelineAddAtPlayhead(addAsset, addComposition, projectId) {
|
|
100067
100294
|
const placement = () => ({ start: usePlayerStore.getState().currentTime, track: 0 });
|
|
100068
100295
|
return useStableHandlers(
|
|
100069
100296
|
{
|
|
100070
|
-
addAssetAtPlayhead:
|
|
100071
|
-
addCompositionAtPlayhead:
|
|
100297
|
+
addAssetAtPlayhead: useCallback193((path) => addAsset(path, placement()), [addAsset]),
|
|
100298
|
+
addCompositionAtPlayhead: useCallback193(
|
|
100072
100299
|
(path) => addComposition(path, placement()),
|
|
100073
100300
|
[addComposition]
|
|
100074
100301
|
)
|
|
@@ -100078,10 +100305,10 @@ function useTimelineAddAtPlayhead(addAsset, addComposition, projectId) {
|
|
|
100078
100305
|
}
|
|
100079
100306
|
|
|
100080
100307
|
// src/hooks/useActiveComposition.ts
|
|
100081
|
-
import { useState as
|
|
100308
|
+
import { useState as useState164 } from "react";
|
|
100082
100309
|
|
|
100083
100310
|
// src/hooks/useHydrateActiveCompPathFromUrl.ts
|
|
100084
|
-
import { useEffect as
|
|
100311
|
+
import { useEffect as useEffect160 } from "react";
|
|
100085
100312
|
function useHydrateActiveCompPathFromUrl({
|
|
100086
100313
|
hydrated,
|
|
100087
100314
|
fileTreeLoaded,
|
|
@@ -100090,7 +100317,7 @@ function useHydrateActiveCompPathFromUrl({
|
|
|
100090
100317
|
setActiveCompPath,
|
|
100091
100318
|
setHydrated
|
|
100092
100319
|
}) {
|
|
100093
|
-
|
|
100320
|
+
useEffect160(() => {
|
|
100094
100321
|
if (hydrated) return;
|
|
100095
100322
|
if (!fileTreeLoaded) return;
|
|
100096
100323
|
const nextCompPath = normalizeStudioCompositionPath(
|
|
@@ -100103,7 +100330,7 @@ function useHydrateActiveCompPathFromUrl({
|
|
|
100103
100330
|
}
|
|
100104
100331
|
|
|
100105
100332
|
// src/hooks/useAutoOpenRootComposition.ts
|
|
100106
|
-
import { useEffect as
|
|
100333
|
+
import { useEffect as useEffect161, useRef as useRef188 } from "react";
|
|
100107
100334
|
function useAutoOpenRootComposition({
|
|
100108
100335
|
projectId,
|
|
100109
100336
|
activeCompPath,
|
|
@@ -100111,8 +100338,8 @@ function useAutoOpenRootComposition({
|
|
|
100111
100338
|
masterCompPath,
|
|
100112
100339
|
onSelectComposition
|
|
100113
100340
|
}) {
|
|
100114
|
-
const settledForProjectRef =
|
|
100115
|
-
|
|
100341
|
+
const settledForProjectRef = useRef188(void 0);
|
|
100342
|
+
useEffect161(() => {
|
|
100116
100343
|
if (settledForProjectRef.current === projectId) return;
|
|
100117
100344
|
if (!activeCompPathHydrated) return;
|
|
100118
100345
|
if (activeCompPath !== null) {
|
|
@@ -100126,14 +100353,14 @@ function useAutoOpenRootComposition({
|
|
|
100126
100353
|
}
|
|
100127
100354
|
|
|
100128
100355
|
// src/hooks/useCompositionContentLoader.ts
|
|
100129
|
-
import { useCallback as
|
|
100356
|
+
import { useCallback as useCallback194 } from "react";
|
|
100130
100357
|
function useCompositionContentLoader({
|
|
100131
100358
|
projectId,
|
|
100132
100359
|
setEditingFile,
|
|
100133
100360
|
setActiveCompPath,
|
|
100134
100361
|
showToast
|
|
100135
100362
|
}) {
|
|
100136
|
-
return
|
|
100363
|
+
return useCallback194(
|
|
100137
100364
|
(comp) => {
|
|
100138
100365
|
if (!projectId) return;
|
|
100139
100366
|
setActiveCompPath(comp.endsWith(".html") ? comp : null);
|
|
@@ -100153,14 +100380,14 @@ function useCompositionContentLoader({
|
|
|
100153
100380
|
}
|
|
100154
100381
|
|
|
100155
100382
|
// src/hooks/useResetSelectionOnProjectSwitch.ts
|
|
100156
|
-
import { useRef as
|
|
100383
|
+
import { useRef as useRef189 } from "react";
|
|
100157
100384
|
function useResetSelectionOnProjectSwitch({
|
|
100158
100385
|
projectId,
|
|
100159
100386
|
initialUrlStateRef,
|
|
100160
100387
|
setActiveCompPath,
|
|
100161
100388
|
setActiveCompPathHydrated
|
|
100162
100389
|
}) {
|
|
100163
|
-
const previousProjectIdRef =
|
|
100390
|
+
const previousProjectIdRef = useRef189(projectId);
|
|
100164
100391
|
if (previousProjectIdRef.current !== projectId) {
|
|
100165
100392
|
const isSwitch = previousProjectIdRef.current !== null;
|
|
100166
100393
|
previousProjectIdRef.current = projectId;
|
|
@@ -100182,8 +100409,8 @@ function useActiveComposition({
|
|
|
100182
100409
|
setEditingFile,
|
|
100183
100410
|
showToast
|
|
100184
100411
|
}) {
|
|
100185
|
-
const [activeCompPath, setActiveCompPath] =
|
|
100186
|
-
const [activeCompPathHydrated, setActiveCompPathHydrated] =
|
|
100412
|
+
const [activeCompPath, setActiveCompPath] = useState164(null);
|
|
100413
|
+
const [activeCompPathHydrated, setActiveCompPathHydrated] = useState164(
|
|
100187
100414
|
() => isHydratedFromUrlState(initialUrlStateRef.current)
|
|
100188
100415
|
);
|
|
100189
100416
|
useResetSelectionOnProjectSwitch({
|
|
@@ -100217,19 +100444,19 @@ function useActiveComposition({
|
|
|
100217
100444
|
}
|
|
100218
100445
|
|
|
100219
100446
|
// src/App.tsx
|
|
100220
|
-
import { jsx as
|
|
100447
|
+
import { jsx as jsx255, jsxs as jsxs202 } from "react/jsx-runtime";
|
|
100221
100448
|
var getTimelineSelectionSet = () => usePlayerStore.getState().selectedElementIds;
|
|
100222
100449
|
function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
100223
100450
|
const { projectId, resolving, waitingForServer } = useServerConnection();
|
|
100224
|
-
const initialUrlStateRef =
|
|
100451
|
+
const initialUrlStateRef = useRef190(readStudioUrlStateFromWindow());
|
|
100225
100452
|
useStudioSessionStart(projectId, resolving, waitingForServer);
|
|
100226
|
-
const [compIdToSrc, setCompIdToSrc] =
|
|
100453
|
+
const [compIdToSrc, setCompIdToSrc] = useState165(/* @__PURE__ */ new Map());
|
|
100227
100454
|
const previewIframe = useOwnPreviewIframe();
|
|
100228
|
-
const [compositionLoading, setCompositionLoading] =
|
|
100229
|
-
const [refreshKey, setRefreshKeyState] =
|
|
100455
|
+
const [compositionLoading, setCompositionLoading] = useState165(true);
|
|
100456
|
+
const [refreshKey, setRefreshKeyState] = useState165(0);
|
|
100230
100457
|
const [previewDocumentVersion, refreshPreviewDocumentVersion] = usePreviewDocumentVersion();
|
|
100231
|
-
const [blockPreview, setBlockPreview] =
|
|
100232
|
-
const previewIframeRef =
|
|
100458
|
+
const [blockPreview, setBlockPreview] = useState165(null);
|
|
100459
|
+
const previewIframeRef = useRef190(null);
|
|
100233
100460
|
const captionEditMode = useCaptionStore((s) => s.isEditMode);
|
|
100234
100461
|
const captionHasSelection = useCaptionStore((s) => s.selectedSegmentIds.size > 0);
|
|
100235
100462
|
const captionSync = useCaptionSync(projectId);
|
|
@@ -100248,14 +100475,14 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100248
100475
|
rightPanelTab: initialUrlStateRef.current.rightPanelTab
|
|
100249
100476
|
});
|
|
100250
100477
|
const editHistory = useStableHandlers(usePersistentEditHistory({ projectId }), projectId);
|
|
100251
|
-
const handleDomZIndexReorderCommitRef =
|
|
100252
|
-
const pendingTimelineEditPathRef =
|
|
100253
|
-
const isGestureRecordingRef =
|
|
100254
|
-
const setRefreshKey =
|
|
100478
|
+
const handleDomZIndexReorderCommitRef = useRef190(null);
|
|
100479
|
+
const pendingTimelineEditPathRef = useRef190(/* @__PURE__ */ new Set());
|
|
100480
|
+
const isGestureRecordingRef = useRef190(false);
|
|
100481
|
+
const setRefreshKey = useCallback195((next) => {
|
|
100255
100482
|
requestPreviewReload();
|
|
100256
100483
|
setRefreshKeyState(next);
|
|
100257
100484
|
}, []);
|
|
100258
|
-
const reloadPreview =
|
|
100485
|
+
const reloadPreview = useCallback195(() => setRefreshKey((k) => k + 1), [setRefreshKey]);
|
|
100259
100486
|
const fileManagerResult = useFileManager({
|
|
100260
100487
|
projectId,
|
|
100261
100488
|
showToast,
|
|
@@ -100263,7 +100490,7 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100263
100490
|
setRefreshKey
|
|
100264
100491
|
});
|
|
100265
100492
|
const fileManager = useStableHandlers(fileManagerResult, projectId);
|
|
100266
|
-
const masterCompPath =
|
|
100493
|
+
const masterCompPath = useMemo90(
|
|
100267
100494
|
() => resolveMasterCompositionPath(fileManager.compositions),
|
|
100268
100495
|
[fileManager.compositions]
|
|
100269
100496
|
);
|
|
@@ -100284,7 +100511,7 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100284
100511
|
fileManager.fileTreeLoaded,
|
|
100285
100512
|
fileManager.refreshFileTree
|
|
100286
100513
|
);
|
|
100287
|
-
const activeCompPathRef =
|
|
100514
|
+
const activeCompPathRef = useRef190(activeCompPath);
|
|
100288
100515
|
activeCompPathRef.current = activeCompPath;
|
|
100289
100516
|
const renderQueue = useStableHandlers(useRenderQueue(projectId, activeCompPathRef), projectId);
|
|
100290
100517
|
const previewPersistenceResult = usePreviewPersistence({
|
|
@@ -100307,9 +100534,9 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100307
100534
|
reloadPreview,
|
|
100308
100535
|
onOutsideChange: editHistory.noteOutsideChange
|
|
100309
100536
|
});
|
|
100310
|
-
const invalidateGsapCacheRef =
|
|
100537
|
+
const invalidateGsapCacheRef = useRef190(() => {
|
|
100311
100538
|
});
|
|
100312
|
-
const invalidateGsapCache =
|
|
100539
|
+
const invalidateGsapCache = useCallback195(() => invalidateGsapCacheRef.current(), []);
|
|
100313
100540
|
const timelineEditing = useTimelineEditing({
|
|
100314
100541
|
projectId,
|
|
100315
100542
|
activeCompPath,
|
|
@@ -100365,20 +100592,20 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100365
100592
|
handleAddMediaOverlay,
|
|
100366
100593
|
handlePreviewBlockDrop
|
|
100367
100594
|
} = useStableHandlers(blockHandlersResult, projectId);
|
|
100368
|
-
const dismissBlockParams =
|
|
100595
|
+
const dismissBlockParams = useCallback195(() => setActiveBlockParams(null), [setActiveBlockParams]);
|
|
100369
100596
|
const setRightPanelTab = useDismissingTabSetter(panelLayout.setRightPanelTab, dismissBlockParams);
|
|
100370
|
-
const layout =
|
|
100597
|
+
const layout = useMemo90(
|
|
100371
100598
|
() => ({ ...panelLayout, setRightPanelTab }),
|
|
100372
100599
|
[panelLayout, setRightPanelTab]
|
|
100373
100600
|
);
|
|
100374
|
-
const clearDomSelectionRef =
|
|
100601
|
+
const clearDomSelectionRef = useRef190(() => {
|
|
100375
100602
|
});
|
|
100376
|
-
const domEditSelectionBridgeRef =
|
|
100377
|
-
const handleDomEditElementDeleteRef =
|
|
100603
|
+
const domEditSelectionBridgeRef = useRef190(null);
|
|
100604
|
+
const handleDomEditElementDeleteRef = useRef190(async () => {
|
|
100378
100605
|
});
|
|
100379
100606
|
const domEditDeleteBridge = (s, o) => handleDomEditElementDeleteRef.current(s, o);
|
|
100380
|
-
const resetKeyframesRef =
|
|
100381
|
-
const deleteSelectedKeyframesRef =
|
|
100607
|
+
const resetKeyframesRef = useRef190(() => false);
|
|
100608
|
+
const deleteSelectedKeyframesRef = useRef190(() => {
|
|
100382
100609
|
});
|
|
100383
100610
|
const { handleCopy: handleCopy2, handlePaste: handlePaste2, handleCut, handleDuplicate, canPaste } = useClipboard({
|
|
100384
100611
|
projectId,
|
|
@@ -100508,9 +100735,9 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100508
100735
|
const frameCapture = useStableHandlers(frameCaptureResult, projectId);
|
|
100509
100736
|
const { consoleErrors, setConsoleErrors } = useConsoleErrorCapture(previewIframe);
|
|
100510
100737
|
const fileDrop = useGlobalFileDrop(timelineEditing.handleTimelineFileDrop);
|
|
100511
|
-
const handleToggleRecordingRef =
|
|
100738
|
+
const handleToggleRecordingRef = useRef190(() => {
|
|
100512
100739
|
});
|
|
100513
|
-
const domEditSessionRef =
|
|
100740
|
+
const domEditSessionRef = useRef190(domEditSession);
|
|
100514
100741
|
domEditSessionRef.current = domEditSession;
|
|
100515
100742
|
const { gestureState, gestureRecording, handleToggleRecording } = useGestureCommit({
|
|
100516
100743
|
projectId,
|
|
@@ -100526,7 +100753,7 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100526
100753
|
previewIframe,
|
|
100527
100754
|
compositionDimensions
|
|
100528
100755
|
);
|
|
100529
|
-
const handlePreviewIframeRef =
|
|
100756
|
+
const handlePreviewIframeRef = useCallback195(
|
|
100530
100757
|
(iframe) => {
|
|
100531
100758
|
previewIframeRef.current = iframe;
|
|
100532
100759
|
usePreviewIframeStore.getState().setIframe(iframe);
|
|
@@ -100587,8 +100814,8 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100587
100814
|
handlePreviewIframeRef,
|
|
100588
100815
|
refreshPreviewDocumentVersion
|
|
100589
100816
|
});
|
|
100590
|
-
const timelineToolbar =
|
|
100591
|
-
() => /* @__PURE__ */
|
|
100817
|
+
const timelineToolbar = useMemo90(
|
|
100818
|
+
() => /* @__PURE__ */ jsx255(
|
|
100592
100819
|
TimelineToolbar,
|
|
100593
100820
|
{
|
|
100594
100821
|
domEditSession: toolbarSession,
|
|
@@ -100597,10 +100824,10 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100597
100824
|
),
|
|
100598
100825
|
[toolbarSession, timelineEditing.handleTimelineElementSplit]
|
|
100599
100826
|
);
|
|
100600
|
-
const handleExport =
|
|
100827
|
+
const handleExport = useCallback195(() => {
|
|
100601
100828
|
void previewPersistence.waitForPendingDomEditSaves().then(() => renderQueue.startRender(void 0));
|
|
100602
100829
|
}, [previewPersistence, renderQueue]);
|
|
100603
|
-
const clearConsoleErrors =
|
|
100830
|
+
const clearConsoleErrors = useCallback195(() => setConsoleErrors(null), [setConsoleErrors]);
|
|
100604
100831
|
const panels = useStudioSidePanels(
|
|
100605
100832
|
{
|
|
100606
100833
|
onSelectComposition: handleSelectComposition,
|
|
@@ -100636,15 +100863,15 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100636
100863
|
projectId
|
|
100637
100864
|
);
|
|
100638
100865
|
if (resolving || waitingForServer || !projectId)
|
|
100639
|
-
return /* @__PURE__ */
|
|
100640
|
-
return /* @__PURE__ */
|
|
100866
|
+
return /* @__PURE__ */ jsx255(StudioSplash, { waiting: waitingForServer });
|
|
100867
|
+
return /* @__PURE__ */ jsx255(StudioShellProvider, { value: studioCtxValue, children: /* @__PURE__ */ jsx255(StudioPlaybackProvider, { value: studioCtxValue, children: /* @__PURE__ */ jsx255(PanelLayoutProvider, { value: layout, children: /* @__PURE__ */ jsx255(FileManagerProvider, { value: fileManager, children: /* @__PURE__ */ jsx255(DomEditProvider, { value: domEditSession, children: /* @__PURE__ */ jsxs202(
|
|
100641
100868
|
"div",
|
|
100642
100869
|
{
|
|
100643
100870
|
className: "flex flex-col h-full w-full bg-neutral-950 relative",
|
|
100644
100871
|
onDragOver: fileDrop.onDragOver,
|
|
100645
100872
|
onDrop: fileDrop.onDrop,
|
|
100646
100873
|
children: [
|
|
100647
|
-
/* @__PURE__ */
|
|
100874
|
+
/* @__PURE__ */ jsx255(
|
|
100648
100875
|
StudioHeader,
|
|
100649
100876
|
{
|
|
100650
100877
|
captureFrameHref: frameCapture.captureFrameHref,
|
|
@@ -100657,17 +100884,17 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100657
100884
|
onExport: handleExport
|
|
100658
100885
|
}
|
|
100659
100886
|
),
|
|
100660
|
-
previewPersistence.domEditSaveQueuePaused && !externalFileChanges.blocked && /* @__PURE__ */
|
|
100887
|
+
previewPersistence.domEditSaveQueuePaused && !externalFileChanges.blocked && /* @__PURE__ */ jsx255(
|
|
100661
100888
|
SaveQueuePausedBanner,
|
|
100662
100889
|
{
|
|
100663
100890
|
message: previewPersistence.domEditSaveQueuePaused,
|
|
100664
100891
|
onRetry: previewPersistence.resetDomEditSaveQueueBreaker
|
|
100665
100892
|
}
|
|
100666
100893
|
),
|
|
100667
|
-
/* @__PURE__ */
|
|
100668
|
-
sdkHandle.unreachableProject && /* @__PURE__ */
|
|
100669
|
-
sdkHandle.compositionMissing && activeCompPath && /* @__PURE__ */
|
|
100670
|
-
/* @__PURE__ */
|
|
100894
|
+
/* @__PURE__ */ jsx255(ExternalFileConflictBanner, { coordinator: externalFileChanges }),
|
|
100895
|
+
sdkHandle.unreachableProject && /* @__PURE__ */ jsx255(ProjectUnreachableBanner, { projectId: sdkHandle.unreachableProject }),
|
|
100896
|
+
sdkHandle.compositionMissing && activeCompPath && /* @__PURE__ */ jsx255(CompositionMissingBanner, { path: activeCompPath }),
|
|
100897
|
+
/* @__PURE__ */ jsx255(
|
|
100671
100898
|
EditorShell,
|
|
100672
100899
|
{
|
|
100673
100900
|
readOnlyPreview,
|
|
@@ -100711,7 +100938,7 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100711
100938
|
gestureOverlay
|
|
100712
100939
|
}
|
|
100713
100940
|
),
|
|
100714
|
-
/* @__PURE__ */
|
|
100941
|
+
/* @__PURE__ */ jsx255(
|
|
100715
100942
|
StudioOverlays,
|
|
100716
100943
|
{
|
|
100717
100944
|
projectId,
|
|
@@ -100732,35 +100959,35 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
|
|
|
100732
100959
|
}
|
|
100733
100960
|
|
|
100734
100961
|
// src/hooks/useElementPicker.ts
|
|
100735
|
-
import { useState as
|
|
100962
|
+
import { useState as useState166, useCallback as useCallback196, useRef as useRef191 } from "react";
|
|
100736
100963
|
function useElementPicker(iframeRef, options) {
|
|
100737
|
-
const [isPickMode, setIsPickMode] =
|
|
100738
|
-
const [pickedElement, setPickedElement] =
|
|
100739
|
-
const activeOverrideRef =
|
|
100740
|
-
const getActiveIframe =
|
|
100964
|
+
const [isPickMode, setIsPickMode] = useState166(false);
|
|
100965
|
+
const [pickedElement, setPickedElement] = useState166(null);
|
|
100966
|
+
const activeOverrideRef = useRef191(null);
|
|
100967
|
+
const getActiveIframe = useCallback196(() => {
|
|
100741
100968
|
return activeOverrideRef.current ?? iframeRef.current;
|
|
100742
100969
|
}, [iframeRef]);
|
|
100743
|
-
const setActiveIframe =
|
|
100970
|
+
const setActiveIframe = useCallback196((el) => {
|
|
100744
100971
|
activeOverrideRef.current = el;
|
|
100745
100972
|
}, []);
|
|
100746
|
-
const enablePick =
|
|
100973
|
+
const enablePick = useCallback196(() => {
|
|
100747
100974
|
try {
|
|
100748
100975
|
postRuntimeControlMessage(getActiveIframe()?.contentWindow, "enable-pick-mode");
|
|
100749
100976
|
setIsPickMode(true);
|
|
100750
100977
|
} catch {
|
|
100751
100978
|
}
|
|
100752
100979
|
}, [getActiveIframe]);
|
|
100753
|
-
const disablePick =
|
|
100980
|
+
const disablePick = useCallback196(() => {
|
|
100754
100981
|
try {
|
|
100755
100982
|
postRuntimeControlMessage(getActiveIframe()?.contentWindow, "disable-pick-mode");
|
|
100756
100983
|
} catch {
|
|
100757
100984
|
}
|
|
100758
100985
|
setIsPickMode(false);
|
|
100759
100986
|
}, [getActiveIframe]);
|
|
100760
|
-
const clearPick =
|
|
100987
|
+
const clearPick = useCallback196(() => {
|
|
100761
100988
|
setPickedElement(null);
|
|
100762
100989
|
}, []);
|
|
100763
|
-
const windowsThatWerePrimary =
|
|
100990
|
+
const windowsThatWerePrimary = useRef191(/* @__PURE__ */ new WeakSet());
|
|
100764
100991
|
useMountEffect(() => {
|
|
100765
100992
|
const handleMessage = (e) => {
|
|
100766
100993
|
const data = e.data;
|
|
@@ -100787,11 +101014,11 @@ function useElementPicker(iframeRef, options) {
|
|
|
100787
101014
|
window.addEventListener("message", handleMessage);
|
|
100788
101015
|
return () => window.removeEventListener("message", handleMessage);
|
|
100789
101016
|
});
|
|
100790
|
-
const optionsRef =
|
|
101017
|
+
const optionsRef = useRef191(options);
|
|
100791
101018
|
optionsRef.current = options;
|
|
100792
|
-
const pendingWritesRef =
|
|
101019
|
+
const pendingWritesRef = useRef191(/* @__PURE__ */ new Map());
|
|
100793
101020
|
settlePendingWrites(pendingWritesRef.current, options?.workspaceFiles);
|
|
100794
|
-
const syncToSource =
|
|
101021
|
+
const syncToSource = useCallback196(
|
|
100795
101022
|
(picked, live, iframe, op) => {
|
|
100796
101023
|
const opts = optionsRef.current;
|
|
100797
101024
|
if (!opts?.workspaceFiles || !opts.onSyncFiles) return;
|
|
@@ -100805,7 +101032,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
100805
101032
|
},
|
|
100806
101033
|
[]
|
|
100807
101034
|
);
|
|
100808
|
-
const setStyle =
|
|
101035
|
+
const setStyle = useCallback196(
|
|
100809
101036
|
(prop, value) => {
|
|
100810
101037
|
const activeIframe = getActiveIframe();
|
|
100811
101038
|
if (!pickedElement?.selector || !activeIframe) return;
|
|
@@ -100831,7 +101058,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
100831
101058
|
},
|
|
100832
101059
|
[pickedElement, getActiveIframe, syncToSource]
|
|
100833
101060
|
);
|
|
100834
|
-
const setDataAttr =
|
|
101061
|
+
const setDataAttr = useCallback196(
|
|
100835
101062
|
(attr, value) => {
|
|
100836
101063
|
const activeIframe = getActiveIframe();
|
|
100837
101064
|
if (!pickedElement?.selector || !activeIframe) return;
|
|
@@ -100857,7 +101084,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
100857
101084
|
},
|
|
100858
101085
|
[pickedElement, getActiveIframe, syncToSource]
|
|
100859
101086
|
);
|
|
100860
|
-
const setTextContent =
|
|
101087
|
+
const setTextContent = useCallback196(
|
|
100861
101088
|
(text) => {
|
|
100862
101089
|
const activeIframe = getActiveIframe();
|
|
100863
101090
|
if (!pickedElement?.selector || !activeIframe) return;
|
|
@@ -100878,7 +101105,7 @@ function useElementPicker(iframeRef, options) {
|
|
|
100878
101105
|
},
|
|
100879
101106
|
[pickedElement, getActiveIframe, syncToSource]
|
|
100880
101107
|
);
|
|
100881
|
-
const activeIframeRef =
|
|
101108
|
+
const activeIframeRef = useRef191(null);
|
|
100882
101109
|
activeIframeRef.current = getActiveIframe();
|
|
100883
101110
|
return {
|
|
100884
101111
|
isPickMode,
|
|
@@ -101096,7 +101323,7 @@ function findElementBlock(html2, elementId2) {
|
|
|
101096
101323
|
}
|
|
101097
101324
|
|
|
101098
101325
|
// src/hooks/useDomStyleCommit.ts
|
|
101099
|
-
import { useCallback as
|
|
101326
|
+
import { useCallback as useCallback197, useMemo as useMemo91, useRef as useRef192, useState as useState167 } from "react";
|
|
101100
101327
|
var noop = () => {
|
|
101101
101328
|
};
|
|
101102
101329
|
function useDomStyleCommit({
|
|
@@ -101107,12 +101334,12 @@ function useDomStyleCommit({
|
|
|
101107
101334
|
activeCompPath = null,
|
|
101108
101335
|
showToast = noop
|
|
101109
101336
|
}) {
|
|
101110
|
-
const projectIdRef =
|
|
101337
|
+
const projectIdRef = useRef192(projectId);
|
|
101111
101338
|
projectIdRef.current = projectId;
|
|
101112
|
-
const [queue2] =
|
|
101339
|
+
const [queue2] = useState167(createDomEditSaveQueue);
|
|
101113
101340
|
useMountEffect(() => () => queue2.destroy());
|
|
101114
|
-
const versions =
|
|
101115
|
-
const editHistory =
|
|
101341
|
+
const versions = useRef192(/* @__PURE__ */ new Map()).current;
|
|
101342
|
+
const editHistory = useMemo91(() => ({ recordEdit }), [recordEdit]);
|
|
101116
101343
|
const persistDomEditOperations = useDomEditPersist({
|
|
101117
101344
|
activeCompPath,
|
|
101118
101345
|
previewIframeRef: iframeRef,
|
|
@@ -101123,7 +101350,7 @@ function useDomStyleCommit({
|
|
|
101123
101350
|
projectIdRef,
|
|
101124
101351
|
reloadPreview: noop
|
|
101125
101352
|
});
|
|
101126
|
-
const commitStyle =
|
|
101353
|
+
const commitStyle = useCallback197(
|
|
101127
101354
|
(selection, styles) => {
|
|
101128
101355
|
queue2.reset();
|
|
101129
101356
|
return projectIdRef.current ? commitDomStyles(
|
|
@@ -101144,7 +101371,7 @@ function useDomStyleCommit({
|
|
|
101144
101371
|
}
|
|
101145
101372
|
|
|
101146
101373
|
// src/hooks/useDomGeometryCommit.ts
|
|
101147
|
-
import { useCallback as
|
|
101374
|
+
import { useCallback as useCallback198, useMemo as useMemo92, useRef as useRef193, useState as useState168 } from "react";
|
|
101148
101375
|
var noop2 = () => {
|
|
101149
101376
|
};
|
|
101150
101377
|
var NO_SELECTED_ANIMATIONS = [];
|
|
@@ -101157,10 +101384,10 @@ function useDomGeometryCommit({
|
|
|
101157
101384
|
showToast = noop2,
|
|
101158
101385
|
reloadPreview
|
|
101159
101386
|
}) {
|
|
101160
|
-
const projectIdRef =
|
|
101387
|
+
const projectIdRef = useRef193(projectId);
|
|
101161
101388
|
projectIdRef.current = projectId;
|
|
101162
|
-
const pending2 =
|
|
101163
|
-
const editHistory =
|
|
101389
|
+
const pending2 = useRef193(/* @__PURE__ */ new Set()).current;
|
|
101390
|
+
const editHistory = useMemo92(() => ({ recordEdit }), [recordEdit]);
|
|
101164
101391
|
const { bump: bumpGsapCache } = useGsapCacheVersion();
|
|
101165
101392
|
const gsap3 = useGsapScriptCommits({
|
|
101166
101393
|
projectIdRef,
|
|
@@ -101172,7 +101399,7 @@ function useDomGeometryCommit({
|
|
|
101172
101399
|
showToast,
|
|
101173
101400
|
writeProjectFile
|
|
101174
101401
|
});
|
|
101175
|
-
const [queue2] =
|
|
101402
|
+
const [queue2] = useState168(createDomEditSaveQueue);
|
|
101176
101403
|
useMountEffect(() => () => queue2.destroy());
|
|
101177
101404
|
const persistDomEditOperations = useDomEditPersist({
|
|
101178
101405
|
activeCompPath,
|
|
@@ -101189,7 +101416,7 @@ function useDomGeometryCommit({
|
|
|
101189
101416
|
persistDomEditOperations,
|
|
101190
101417
|
showToast
|
|
101191
101418
|
});
|
|
101192
|
-
const commitWithFreshQueue =
|
|
101419
|
+
const commitWithFreshQueue = useCallback198(
|
|
101193
101420
|
(...args) => {
|
|
101194
101421
|
queue2.reset();
|
|
101195
101422
|
return commitPositionPatchToHtml(...args);
|
|
@@ -101228,7 +101455,7 @@ function useDomGeometryCommit({
|
|
|
101228
101455
|
setArcPath: gsap3.setArcPath,
|
|
101229
101456
|
updateArcSegment: gsap3.updateArcSegment
|
|
101230
101457
|
});
|
|
101231
|
-
const saved2 =
|
|
101458
|
+
const saved2 = useCallback198(
|
|
101232
101459
|
async (commit2, restore2 = noop2) => {
|
|
101233
101460
|
const refusal2 = !projectIdRef.current ? "No project is open" : !isPreviewBooted(projectIdRef.current) ? "The preview for this project has not loaded yet" : null;
|
|
101234
101461
|
if (refusal2) {
|
|
@@ -101246,7 +101473,7 @@ function useDomGeometryCommit({
|
|
|
101246
101473
|
},
|
|
101247
101474
|
[pending2, showToast]
|
|
101248
101475
|
);
|
|
101249
|
-
return
|
|
101476
|
+
return useMemo92(
|
|
101250
101477
|
() => ({
|
|
101251
101478
|
commitPathOffset: (selection, next, modifiers) => saved2(() => handleGsapAwarePathOffsetCommit(selection, next, modifiers)),
|
|
101252
101479
|
commitGroupPathOffset: (updates) => saved2(() => handleGsapAwareGroupPathOffsetCommit(updates)),
|