@hyperframes/studio 0.7.99 → 0.7.101
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-BY5RLMBA.js → hyperframes-player-BxSY8bs4.js} +1 -1
- package/dist/assets/{index-CQ07_DLG.js → index-BlRPDw0A.js} +1 -1
- package/dist/assets/{index-DMSqmZM6.js → index-DF06yGPO.js} +200 -200
- package/dist/assets/{index-DeXLAktv.js → index-Dkz5RbFX.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/index.js +473 -359
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/App.tsx +2 -2
- package/src/components/StudioHeader.test.ts +28 -0
- package/src/components/StudioHeader.tsx +21 -2
- package/src/components/StudioLeftSidebar.tsx +2 -2
- package/src/components/nle/NLEContext.tsx +16 -7
- package/src/components/nle/TimelineResizeDivider.tsx +4 -11
- package/src/components/sidebar/LeftSidebar.storage.test.ts +28 -0
- package/src/components/sidebar/LeftSidebar.tsx +18 -3
- package/src/contexts/PanelLayoutContext.tsx +6 -3
- package/src/hooks/gsapEditOutcome.ts +19 -1
- package/src/hooks/gsapKeyframeCacheHelpers.test.ts +47 -1
- package/src/hooks/gsapKeyframeCacheHelpers.ts +31 -3
- package/src/hooks/gsapResizeGeometrySweep.test.ts +289 -0
- package/src/hooks/gsapResizeIntercept.test.ts +2 -2
- package/src/hooks/gsapResizeIntercept.ts +37 -14
- package/src/hooks/gsapResizeMixedTween.test.ts +168 -0
- package/src/hooks/gsapResizeSweep.test.ts +274 -0
- package/src/hooks/useGsapAwareEditing.test.tsx +19 -2
- package/src/hooks/useGsapAwareEditing.ts +13 -5
- package/src/hooks/useGsapTweenCache.ts +16 -19
- package/src/hooks/usePanelLayout.test.ts +117 -0
- package/src/hooks/usePanelLayout.ts +121 -39
- package/src/player/components/Player.test.ts +13 -0
- package/src/player/components/Player.tsx +7 -1
- package/src/utils/clipboard.ts +1 -1
- package/src/utils/fitPanels.test.ts +164 -0
- package/src/utils/fitPanels.ts +151 -0
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
import { useCallback as useCallback50 } from "react";
|
|
33
33
|
|
|
34
34
|
// src/components/nle/PreviewPane.tsx
|
|
35
|
-
import { useCallback as
|
|
35
|
+
import { useCallback as useCallback34, useRef as useRef37, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
36
36
|
|
|
37
37
|
// src/player/components/Player.tsx
|
|
38
38
|
import { forwardRef as forwardRef2, useEffect as useEffect3, useRef as useRef2, useState as useState2 } from "react";
|
|
@@ -621,7 +621,7 @@ var Player = forwardRef2(
|
|
|
621
621
|
player.removeEventListener("error", handleError);
|
|
622
622
|
if (assetPollRef.current) clearInterval(assetPollRef.current);
|
|
623
623
|
assetPollRef.current = null;
|
|
624
|
-
|
|
624
|
+
player.remove();
|
|
625
625
|
if (retryPreviewRef.current === retryPreview) retryPreviewRef.current = null;
|
|
626
626
|
if (typeof ref === "function") {
|
|
627
627
|
} else if (ref) {
|
|
@@ -15465,7 +15465,7 @@ function copyWithSelection(text) {
|
|
|
15465
15465
|
} catch {
|
|
15466
15466
|
return false;
|
|
15467
15467
|
} finally {
|
|
15468
|
-
|
|
15468
|
+
textarea.remove();
|
|
15469
15469
|
}
|
|
15470
15470
|
}
|
|
15471
15471
|
function shouldCopyWithSelectionFirst() {
|
|
@@ -21608,8 +21608,8 @@ import {
|
|
|
21608
21608
|
createContext as createContext5,
|
|
21609
21609
|
useContext as useContext5,
|
|
21610
21610
|
useState as useState23,
|
|
21611
|
-
useCallback as
|
|
21612
|
-
useRef as
|
|
21611
|
+
useCallback as useCallback32,
|
|
21612
|
+
useRef as useRef36,
|
|
21613
21613
|
useEffect as useEffect26
|
|
21614
21614
|
} from "react";
|
|
21615
21615
|
|
|
@@ -21710,94 +21710,57 @@ function useCompositionStack({
|
|
|
21710
21710
|
};
|
|
21711
21711
|
}
|
|
21712
21712
|
|
|
21713
|
-
// src/
|
|
21714
|
-
|
|
21715
|
-
|
|
21713
|
+
// src/utils/fitPanels.ts
|
|
21714
|
+
var MIN_PREVIEW_W = 360;
|
|
21715
|
+
var MIN_PREVIEW_H = 200;
|
|
21716
|
+
var MIN_LEFT = 200;
|
|
21717
|
+
var MIN_RIGHT = 280;
|
|
21718
|
+
var RAIL_W = 42;
|
|
21716
21719
|
var MIN_TIMELINE_H = 100;
|
|
21717
|
-
var
|
|
21718
|
-
|
|
21719
|
-
|
|
21720
|
-
|
|
21721
|
-
|
|
21722
|
-
|
|
21723
|
-
|
|
21724
|
-
|
|
21725
|
-
|
|
21726
|
-
|
|
21727
|
-
|
|
21728
|
-
|
|
21729
|
-
(
|
|
21730
|
-
|
|
21731
|
-
|
|
21732
|
-
|
|
21733
|
-
|
|
21734
|
-
|
|
21735
|
-
|
|
21736
|
-
|
|
21737
|
-
|
|
21738
|
-
|
|
21739
|
-
|
|
21740
|
-
|
|
21741
|
-
|
|
21742
|
-
|
|
21743
|
-
|
|
21744
|
-
|
|
21745
|
-
|
|
21746
|
-
|
|
21747
|
-
|
|
21748
|
-
|
|
21749
|
-
|
|
21750
|
-
|
|
21751
|
-
|
|
21752
|
-
|
|
21753
|
-
|
|
21754
|
-
|
|
21755
|
-
|
|
21756
|
-
|
|
21757
|
-
|
|
21758
|
-
|
|
21759
|
-
|
|
21760
|
-
|
|
21761
|
-
const containerH = containerRef.current?.getBoundingClientRect().height ?? Infinity;
|
|
21762
|
-
const delta = e.key === "ArrowUp" ? 16 : -16;
|
|
21763
|
-
setTimelineH((prev) => {
|
|
21764
|
-
const next = Math.max(MIN_TIMELINE_H, Math.min(containerH - MIN_PREVIEW_H, prev + delta));
|
|
21765
|
-
persistTimelineH(next);
|
|
21766
|
-
return next;
|
|
21767
|
-
});
|
|
21768
|
-
},
|
|
21769
|
-
[disabled, containerRef, setTimelineH, persistTimelineH]
|
|
21770
|
-
);
|
|
21771
|
-
return (
|
|
21772
|
-
// Horizontal resize divider: 3px visible seam (h-[3px]), 10px pointer-capture
|
|
21773
|
-
// zone via the absolutely-positioned inner hit area so the layout gap stays
|
|
21774
|
-
// at 3px while draggability is preserved over the full band.
|
|
21775
|
-
/* @__PURE__ */ jsxs37(
|
|
21776
|
-
"div",
|
|
21777
|
-
{
|
|
21778
|
-
role: "separator",
|
|
21779
|
-
"aria-orientation": "horizontal",
|
|
21780
|
-
"aria-label": "Resize timeline (arrow keys)",
|
|
21781
|
-
"aria-valuenow": Math.round(timelineH),
|
|
21782
|
-
"aria-valuemin": MIN_TIMELINE_H,
|
|
21783
|
-
"aria-valuemax": Math.round(
|
|
21784
|
-
(containerRef.current?.getBoundingClientRect().height ?? 600) - MIN_PREVIEW_H
|
|
21785
|
-
),
|
|
21786
|
-
tabIndex: 0,
|
|
21787
|
-
className: "group relative h-[3px] flex-shrink-0 cursor-row-resize z-10 outline-none focus-visible:bg-studio-accent/20",
|
|
21788
|
-
style: { touchAction: "none" },
|
|
21789
|
-
onPointerDown: handlePointerDown,
|
|
21790
|
-
onPointerMove: handlePointerMove,
|
|
21791
|
-
onPointerUp: handlePointerUp,
|
|
21792
|
-
onPointerCancel: handlePointerUp,
|
|
21793
|
-
onKeyDown: handleKeyDown,
|
|
21794
|
-
children: [
|
|
21795
|
-
/* @__PURE__ */ jsx49("div", { className: "absolute inset-x-0 -top-[4px] h-[10px]" }),
|
|
21796
|
-
/* @__PURE__ */ jsx49("div", { className: "h-[3px] w-full bg-transparent transition-colors group-hover:bg-white/12 group-active:bg-white/18 group-focus-visible:bg-studio-accent/60" })
|
|
21797
|
-
]
|
|
21798
|
-
}
|
|
21799
|
-
)
|
|
21800
|
-
);
|
|
21720
|
+
var PANEL_SEAM_W = 6;
|
|
21721
|
+
var PANEL_MAX_RATIO = 0.4;
|
|
21722
|
+
var RAIL_LEFT_BELOW = 860;
|
|
21723
|
+
var RAIL_RIGHT_BELOW = 700;
|
|
21724
|
+
function railsEngaged(viewportWidth) {
|
|
21725
|
+
return viewportWidth < RAIL_LEFT_BELOW;
|
|
21726
|
+
}
|
|
21727
|
+
function clamp5(value, min, max) {
|
|
21728
|
+
return Math.max(min, Math.min(max, value));
|
|
21729
|
+
}
|
|
21730
|
+
function defaultPanelWidths(viewportWidth) {
|
|
21731
|
+
return {
|
|
21732
|
+
left: Math.max(MIN_LEFT, Math.min(384, Math.round(viewportWidth * 0.257))),
|
|
21733
|
+
right: Math.max(MIN_RIGHT, Math.min(424, Math.round(viewportWidth * 0.284)))
|
|
21734
|
+
};
|
|
21735
|
+
}
|
|
21736
|
+
function fitPanelWidths(viewportWidth, preferred, reopened = { left: false, right: false }) {
|
|
21737
|
+
const vw = Number.isFinite(viewportWidth) ? Math.max(0, viewportWidth) : 0;
|
|
21738
|
+
if (vw <= 0) {
|
|
21739
|
+
return { ...preferred, preview: 0, autoCollapseLeft: false, autoCollapseRight: false };
|
|
21740
|
+
}
|
|
21741
|
+
const autoCollapseLeft = vw < RAIL_LEFT_BELOW && !reopened.left;
|
|
21742
|
+
const autoCollapseRight = vw < RAIL_RIGHT_BELOW && !reopened.right;
|
|
21743
|
+
const cap = Math.floor(vw * PANEL_MAX_RATIO);
|
|
21744
|
+
const leftFloor = autoCollapseLeft ? RAIL_W : MIN_LEFT;
|
|
21745
|
+
const rightFloor = autoCollapseRight ? 0 : MIN_RIGHT;
|
|
21746
|
+
let left = autoCollapseLeft ? RAIL_W : clamp5(preferred.left, MIN_LEFT, Math.max(MIN_LEFT, cap));
|
|
21747
|
+
let right = autoCollapseRight ? 0 : clamp5(preferred.right, MIN_RIGHT, Math.max(MIN_RIGHT, cap));
|
|
21748
|
+
const budget = vw - MIN_PREVIEW_W - PANEL_SEAM_W;
|
|
21749
|
+
if (left + right > budget) right = Math.max(rightFloor, budget - left);
|
|
21750
|
+
if (left + right > budget) left = Math.max(leftFloor, budget - right);
|
|
21751
|
+
return {
|
|
21752
|
+
left,
|
|
21753
|
+
right,
|
|
21754
|
+
preview: Math.max(0, vw - left - right - PANEL_SEAM_W),
|
|
21755
|
+
autoCollapseLeft,
|
|
21756
|
+
autoCollapseRight
|
|
21757
|
+
};
|
|
21758
|
+
}
|
|
21759
|
+
function fitTimelineHeight(containerHeight, preferred) {
|
|
21760
|
+
const h = Number.isFinite(containerHeight) ? containerHeight : 0;
|
|
21761
|
+
const wanted = Number.isFinite(preferred) ? preferred : MIN_TIMELINE_H;
|
|
21762
|
+
if (h <= 0) return Math.max(MIN_TIMELINE_H, wanted);
|
|
21763
|
+
return clamp5(wanted, MIN_TIMELINE_H, Math.max(MIN_TIMELINE_H, h - MIN_PREVIEW_H));
|
|
21801
21764
|
}
|
|
21802
21765
|
|
|
21803
21766
|
// src/utils/assetPreviewStore.ts
|
|
@@ -21810,7 +21773,7 @@ var useAssetPreviewStore = create4((set) => ({
|
|
|
21810
21773
|
}));
|
|
21811
21774
|
|
|
21812
21775
|
// src/components/nle/NLEContext.tsx
|
|
21813
|
-
import { jsx as
|
|
21776
|
+
import { jsx as jsx49 } from "react/jsx-runtime";
|
|
21814
21777
|
var DEFAULT_TIMELINE_H = 360;
|
|
21815
21778
|
function shouldDisableTimelineWhileCompositionLoading(compositionLoading) {
|
|
21816
21779
|
return compositionLoading;
|
|
@@ -21843,13 +21806,13 @@ function NLEProvider({
|
|
|
21843
21806
|
useAssetPreviewStore.getState().clearPreviewAsset();
|
|
21844
21807
|
}, [projectId]);
|
|
21845
21808
|
const [previewCompositionSize, setPreviewCompositionSize] = useState23(null);
|
|
21846
|
-
const prevRefreshKeyRef =
|
|
21809
|
+
const prevRefreshKeyRef = useRef36(refreshKey);
|
|
21847
21810
|
useEffect26(() => {
|
|
21848
21811
|
if (refreshKey === prevRefreshKeyRef.current) return;
|
|
21849
21812
|
prevRefreshKeyRef.current = refreshKey;
|
|
21850
21813
|
refreshPlayer();
|
|
21851
21814
|
}, [refreshKey, refreshPlayer]);
|
|
21852
|
-
const onIframeLoad =
|
|
21815
|
+
const onIframeLoad = useCallback32(() => {
|
|
21853
21816
|
baseOnIframeLoad();
|
|
21854
21817
|
ensureMotionPathPluginLoaded(iframeRef.current);
|
|
21855
21818
|
onIframeRef?.(iframeRef.current);
|
|
@@ -21867,7 +21830,7 @@ function NLEProvider({
|
|
|
21867
21830
|
onCompositionChange
|
|
21868
21831
|
});
|
|
21869
21832
|
const iframeRef_ = iframeRef;
|
|
21870
|
-
const handleDrillDown =
|
|
21833
|
+
const handleDrillDown = useCallback32(
|
|
21871
21834
|
(element) => {
|
|
21872
21835
|
if (!element.compositionSrc) return;
|
|
21873
21836
|
usePlayerStore.getState().setSelectedElementId(null);
|
|
@@ -21894,9 +21857,9 @@ function NLEProvider({
|
|
|
21894
21857
|
},
|
|
21895
21858
|
[compIdToSrc, drillDown, iframeRef_]
|
|
21896
21859
|
);
|
|
21897
|
-
const compIdToSrcRef =
|
|
21860
|
+
const compIdToSrcRef = useRef36(compIdToSrc);
|
|
21898
21861
|
compIdToSrcRef.current = compIdToSrc;
|
|
21899
|
-
const onCompIdToSrcChangeRef =
|
|
21862
|
+
const onCompIdToSrcChangeRef = useRef36(onCompIdToSrcChange);
|
|
21900
21863
|
onCompIdToSrcChangeRef.current = onCompIdToSrcChange;
|
|
21901
21864
|
useEffect26(() => {
|
|
21902
21865
|
const controller = new AbortController();
|
|
@@ -21967,19 +21930,26 @@ function NLEProvider({
|
|
|
21967
21930
|
const stored = readStudioUiPreferences().timelineHeight;
|
|
21968
21931
|
return stored !== void 0 && stored >= MIN_TIMELINE_H ? stored : DEFAULT_TIMELINE_H;
|
|
21969
21932
|
});
|
|
21970
|
-
const persistTimelineH =
|
|
21933
|
+
const persistTimelineH = useCallback32((height) => {
|
|
21971
21934
|
writeStudioUiPreferences({ timelineHeight: Math.round(height) });
|
|
21972
21935
|
}, []);
|
|
21973
|
-
const containerRef =
|
|
21936
|
+
const containerRef = useRef36(null);
|
|
21974
21937
|
useEffect26(() => {
|
|
21975
|
-
const
|
|
21976
|
-
if (!
|
|
21977
|
-
const
|
|
21978
|
-
|
|
21938
|
+
const element = containerRef.current;
|
|
21939
|
+
if (!element || typeof ResizeObserver === "undefined") return;
|
|
21940
|
+
const reconcile = () => {
|
|
21941
|
+
const containerH = element.getBoundingClientRect().height;
|
|
21942
|
+
if (!containerH) return;
|
|
21943
|
+
setTimelineH((prev) => fitTimelineHeight(containerH, prev));
|
|
21944
|
+
};
|
|
21945
|
+
reconcile();
|
|
21946
|
+
const observer = new ResizeObserver(reconcile);
|
|
21947
|
+
observer.observe(element);
|
|
21948
|
+
return () => observer.disconnect();
|
|
21979
21949
|
}, []);
|
|
21980
|
-
const hasLoadedOnceRef =
|
|
21950
|
+
const hasLoadedOnceRef = useRef36(false);
|
|
21981
21951
|
const [compositionLoading, setCompositionLoadingRaw] = useState23(true);
|
|
21982
|
-
const setCompositionLoading =
|
|
21952
|
+
const setCompositionLoading = useCallback32((loading) => {
|
|
21983
21953
|
if (!loading) hasLoadedOnceRef.current = true;
|
|
21984
21954
|
if (loading && hasLoadedOnceRef.current) return;
|
|
21985
21955
|
setCompositionLoadingRaw(loading);
|
|
@@ -21989,7 +21959,7 @@ function NLEProvider({
|
|
|
21989
21959
|
useEffect26(() => {
|
|
21990
21960
|
onCompositionLoadingChange?.(compositionLoading);
|
|
21991
21961
|
}, [compositionLoading, onCompositionLoadingChange]);
|
|
21992
|
-
const onIframeRefStable =
|
|
21962
|
+
const onIframeRefStable = useRef36(onIframeRef);
|
|
21993
21963
|
onIframeRefStable.current = onIframeRef;
|
|
21994
21964
|
useEffect26(() => {
|
|
21995
21965
|
onIframeRefStable.current?.(iframeRef.current);
|
|
@@ -22018,11 +21988,11 @@ function NLEProvider({
|
|
|
22018
21988
|
previewCompositionSize,
|
|
22019
21989
|
setPreviewCompositionSize
|
|
22020
21990
|
};
|
|
22021
|
-
return /* @__PURE__ */
|
|
21991
|
+
return /* @__PURE__ */ jsx49(NLEContext.Provider, { value, children });
|
|
22022
21992
|
}
|
|
22023
21993
|
|
|
22024
21994
|
// src/components/nle/AssetPreviewOverlay.tsx
|
|
22025
|
-
import { useEffect as useEffect27, useCallback as
|
|
21995
|
+
import { useEffect as useEffect27, useCallback as useCallback33 } from "react";
|
|
22026
21996
|
|
|
22027
21997
|
// src/utils/assetPreviewDismiss.ts
|
|
22028
21998
|
var TIME_EPSILON_S = 1e-6;
|
|
@@ -22033,7 +22003,7 @@ function shouldDismissAssetPreview(openedTime, snapshot) {
|
|
|
22033
22003
|
}
|
|
22034
22004
|
|
|
22035
22005
|
// src/components/nle/AssetPreviewOverlay.tsx
|
|
22036
|
-
import { jsx as
|
|
22006
|
+
import { jsx as jsx50, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
22037
22007
|
function basename(path) {
|
|
22038
22008
|
return path.split("/").pop() ?? path;
|
|
22039
22009
|
}
|
|
@@ -22048,10 +22018,10 @@ function AssetPreviewMedia({
|
|
|
22048
22018
|
name
|
|
22049
22019
|
}) {
|
|
22050
22020
|
if (kind === "image") {
|
|
22051
|
-
return /* @__PURE__ */
|
|
22021
|
+
return /* @__PURE__ */ jsx50("img", { src: serveUrl, alt: name, className: "max-w-full max-h-[40vh] rounded object-contain" });
|
|
22052
22022
|
}
|
|
22053
22023
|
if (kind === "video") {
|
|
22054
|
-
return /* @__PURE__ */
|
|
22024
|
+
return /* @__PURE__ */ jsx50(
|
|
22055
22025
|
"video",
|
|
22056
22026
|
{
|
|
22057
22027
|
src: serveUrl,
|
|
@@ -22063,8 +22033,8 @@ function AssetPreviewMedia({
|
|
|
22063
22033
|
}
|
|
22064
22034
|
);
|
|
22065
22035
|
}
|
|
22066
|
-
return /* @__PURE__ */
|
|
22067
|
-
/* @__PURE__ */
|
|
22036
|
+
return /* @__PURE__ */ jsxs37("div", { className: "flex flex-col items-center gap-3 px-6 py-4", children: [
|
|
22037
|
+
/* @__PURE__ */ jsxs37(
|
|
22068
22038
|
"svg",
|
|
22069
22039
|
{
|
|
22070
22040
|
width: "40",
|
|
@@ -22075,20 +22045,20 @@ function AssetPreviewMedia({
|
|
|
22075
22045
|
strokeWidth: "1.5",
|
|
22076
22046
|
className: "text-neutral-500",
|
|
22077
22047
|
children: [
|
|
22078
|
-
/* @__PURE__ */
|
|
22079
|
-
/* @__PURE__ */
|
|
22080
|
-
/* @__PURE__ */
|
|
22048
|
+
/* @__PURE__ */ jsx50("path", { d: "M9 18V5l12-2v13", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
22049
|
+
/* @__PURE__ */ jsx50("circle", { cx: "6", cy: "18", r: "3" }),
|
|
22050
|
+
/* @__PURE__ */ jsx50("circle", { cx: "18", cy: "16", r: "3" })
|
|
22081
22051
|
]
|
|
22082
22052
|
}
|
|
22083
22053
|
),
|
|
22084
|
-
/* @__PURE__ */
|
|
22054
|
+
/* @__PURE__ */ jsx50("audio", { src: serveUrl, controls: true, className: "w-64" })
|
|
22085
22055
|
] });
|
|
22086
22056
|
}
|
|
22087
22057
|
function AssetPreviewOverlay() {
|
|
22088
22058
|
const previewAsset = useAssetPreviewStore((s) => s.previewAsset);
|
|
22089
22059
|
const previewProjectId = useAssetPreviewStore((s) => s.previewProjectId);
|
|
22090
22060
|
const clearPreviewAsset = useAssetPreviewStore((s) => s.clearPreviewAsset);
|
|
22091
|
-
const handleKeyDown =
|
|
22061
|
+
const handleKeyDown = useCallback33(
|
|
22092
22062
|
(e) => {
|
|
22093
22063
|
if (e.key === "Escape") clearPreviewAsset();
|
|
22094
22064
|
},
|
|
@@ -22114,20 +22084,20 @@ function AssetPreviewOverlay() {
|
|
|
22114
22084
|
if (!previewAsset || !previewProjectId) return null;
|
|
22115
22085
|
const serveUrl = resolveMediaPreviewUrl(previewAsset, previewProjectId);
|
|
22116
22086
|
const name = basename(previewAsset);
|
|
22117
|
-
return /* @__PURE__ */
|
|
22087
|
+
return /* @__PURE__ */ jsx50(
|
|
22118
22088
|
"div",
|
|
22119
22089
|
{
|
|
22120
22090
|
className: "absolute inset-0 z-50 flex flex-col items-center justify-center bg-black/20",
|
|
22121
22091
|
onClick: clearPreviewAsset,
|
|
22122
22092
|
role: "dialog",
|
|
22123
22093
|
"aria-label": `Preview: ${name}`,
|
|
22124
|
-
children: /* @__PURE__ */
|
|
22094
|
+
children: /* @__PURE__ */ jsxs37(
|
|
22125
22095
|
"div",
|
|
22126
22096
|
{
|
|
22127
22097
|
className: "relative flex flex-col items-center gap-2 max-w-[58%] rounded-lg border border-neutral-800 bg-neutral-950/95 p-2 pt-8 shadow-2xl",
|
|
22128
22098
|
onClick: (e) => e.stopPropagation(),
|
|
22129
22099
|
children: [
|
|
22130
|
-
/* @__PURE__ */
|
|
22100
|
+
/* @__PURE__ */ jsx50(
|
|
22131
22101
|
"button",
|
|
22132
22102
|
{
|
|
22133
22103
|
className: "absolute top-2 right-2 w-6 h-6 rounded-full bg-neutral-800 hover:bg-neutral-700 text-neutral-300 hover:text-white flex items-center justify-center transition-colors z-10",
|
|
@@ -22136,7 +22106,7 @@ function AssetPreviewOverlay() {
|
|
|
22136
22106
|
clearPreviewAsset();
|
|
22137
22107
|
},
|
|
22138
22108
|
"aria-label": "Close preview",
|
|
22139
|
-
children: /* @__PURE__ */
|
|
22109
|
+
children: /* @__PURE__ */ jsxs37(
|
|
22140
22110
|
"svg",
|
|
22141
22111
|
{
|
|
22142
22112
|
width: "12",
|
|
@@ -22147,15 +22117,15 @@ function AssetPreviewOverlay() {
|
|
|
22147
22117
|
fill: "none",
|
|
22148
22118
|
strokeLinecap: "round",
|
|
22149
22119
|
children: [
|
|
22150
|
-
/* @__PURE__ */
|
|
22151
|
-
/* @__PURE__ */
|
|
22120
|
+
/* @__PURE__ */ jsx50("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
22121
|
+
/* @__PURE__ */ jsx50("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
22152
22122
|
]
|
|
22153
22123
|
}
|
|
22154
22124
|
)
|
|
22155
22125
|
}
|
|
22156
22126
|
),
|
|
22157
|
-
/* @__PURE__ */
|
|
22158
|
-
/* @__PURE__ */
|
|
22127
|
+
/* @__PURE__ */ jsx50(AssetPreviewMedia, { kind: resolveAssetKind(previewAsset), serveUrl, name }),
|
|
22128
|
+
/* @__PURE__ */ jsx50("span", { className: "text-[12px] text-neutral-400 truncate max-w-full px-2 text-center", children: name })
|
|
22159
22129
|
]
|
|
22160
22130
|
}
|
|
22161
22131
|
)
|
|
@@ -22164,7 +22134,7 @@ function AssetPreviewOverlay() {
|
|
|
22164
22134
|
}
|
|
22165
22135
|
|
|
22166
22136
|
// src/components/nle/PreviewPane.tsx
|
|
22167
|
-
import { jsx as
|
|
22137
|
+
import { jsx as jsx51, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
22168
22138
|
function subscribeFullscreen(cb) {
|
|
22169
22139
|
document.addEventListener("fullscreenchange", cb);
|
|
22170
22140
|
return () => document.removeEventListener("fullscreenchange", cb);
|
|
@@ -22199,8 +22169,8 @@ function PreviewPane({
|
|
|
22199
22169
|
previewCompositionSize,
|
|
22200
22170
|
setPreviewCompositionSize
|
|
22201
22171
|
} = useNLEContext();
|
|
22202
|
-
const stageRefForDrop =
|
|
22203
|
-
const handleStageRef =
|
|
22172
|
+
const stageRefForDrop = useRef37(null);
|
|
22173
|
+
const handleStageRef = useCallback34((ref) => {
|
|
22204
22174
|
stageRefForDrop.current = ref.current;
|
|
22205
22175
|
}, []);
|
|
22206
22176
|
const {
|
|
@@ -22215,10 +22185,10 @@ function PreviewPane({
|
|
|
22215
22185
|
stageRef: stageRefForDrop,
|
|
22216
22186
|
onBlockDrop: onPreviewBlockDrop
|
|
22217
22187
|
});
|
|
22218
|
-
const containerRef =
|
|
22188
|
+
const containerRef = useRef37(null);
|
|
22219
22189
|
const fullscreenElement = useSyncExternalStore3(subscribeFullscreen, getFullscreenElement);
|
|
22220
22190
|
const isFullscreen = fullscreenElement === containerRef.current && fullscreenElement != null;
|
|
22221
|
-
const toggleFullscreen =
|
|
22191
|
+
const toggleFullscreen = useCallback34(() => {
|
|
22222
22192
|
if (!containerRef.current) return;
|
|
22223
22193
|
if (document.fullscreenElement) {
|
|
22224
22194
|
void document.exitFullscreen();
|
|
@@ -22228,14 +22198,14 @@ function PreviewPane({
|
|
|
22228
22198
|
}, []);
|
|
22229
22199
|
const currentLevel = compositionStack[compositionStack.length - 1];
|
|
22230
22200
|
const directUrl = compositionStack.length > 1 ? currentLevel.previewUrl : void 0;
|
|
22231
|
-
return /* @__PURE__ */
|
|
22201
|
+
return /* @__PURE__ */ jsxs38(
|
|
22232
22202
|
"div",
|
|
22233
22203
|
{
|
|
22234
22204
|
ref: containerRef,
|
|
22235
22205
|
className: `flex-1 min-h-0 flex flex-col overflow-hidden bg-neutral-950 ${isFullscreen ? "" : "rounded-lg border border-neutral-800/50"}`,
|
|
22236
22206
|
"data-studio-fullscreen-target": "",
|
|
22237
22207
|
children: [
|
|
22238
|
-
/* @__PURE__ */
|
|
22208
|
+
/* @__PURE__ */ jsxs38(
|
|
22239
22209
|
"div",
|
|
22240
22210
|
{
|
|
22241
22211
|
className: "flex-1 min-h-0 relative overflow-hidden",
|
|
@@ -22246,8 +22216,8 @@ function PreviewPane({
|
|
|
22246
22216
|
onDragLeave: handlePreviewDragLeave,
|
|
22247
22217
|
onDrop: handlePreviewDrop,
|
|
22248
22218
|
children: [
|
|
22249
|
-
/* @__PURE__ */
|
|
22250
|
-
/* @__PURE__ */
|
|
22219
|
+
/* @__PURE__ */ jsxs38("div", { className: "absolute inset-0 overflow-hidden", children: [
|
|
22220
|
+
/* @__PURE__ */ jsx51(
|
|
22251
22221
|
NLEPreview,
|
|
22252
22222
|
{
|
|
22253
22223
|
projectId,
|
|
@@ -22261,16 +22231,16 @@ function PreviewPane({
|
|
|
22261
22231
|
onCompositionSizeChange: setPreviewCompositionSize
|
|
22262
22232
|
}
|
|
22263
22233
|
),
|
|
22264
|
-
previewDragOver && /* @__PURE__ */
|
|
22265
|
-
/* @__PURE__ */
|
|
22234
|
+
previewDragOver && /* @__PURE__ */ jsx51("div", { className: "absolute inset-2 z-40 rounded-lg border-2 border-dashed border-studio-accent/50 bg-studio-accent/[0.04] pointer-events-none" }),
|
|
22235
|
+
/* @__PURE__ */ jsx51(AssetPreviewOverlay, {})
|
|
22266
22236
|
] }),
|
|
22267
22237
|
!isFullscreen && previewOverlay
|
|
22268
22238
|
]
|
|
22269
22239
|
}
|
|
22270
22240
|
),
|
|
22271
|
-
/* @__PURE__ */
|
|
22272
|
-
!isFullscreen && compositionStack.length > 1 && /* @__PURE__ */
|
|
22273
|
-
/* @__PURE__ */
|
|
22241
|
+
/* @__PURE__ */ jsxs38("div", { className: "flex-shrink-0", children: [
|
|
22242
|
+
!isFullscreen && compositionStack.length > 1 && /* @__PURE__ */ jsx51(CompositionBreadcrumb, { stack: compositionStack, onNavigate: handleNavigateComposition }),
|
|
22243
|
+
/* @__PURE__ */ jsx51(
|
|
22274
22244
|
PlayerControls,
|
|
22275
22245
|
{
|
|
22276
22246
|
onTogglePlay: togglePlay,
|
|
@@ -22288,6 +22258,91 @@ function PreviewPane({
|
|
|
22288
22258
|
|
|
22289
22259
|
// src/components/nle/TimelinePane.tsx
|
|
22290
22260
|
import { useCallback as useCallback36 } from "react";
|
|
22261
|
+
|
|
22262
|
+
// src/components/nle/TimelineResizeDivider.tsx
|
|
22263
|
+
import { useCallback as useCallback35, useRef as useRef38 } from "react";
|
|
22264
|
+
import { jsx as jsx52, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
22265
|
+
function TimelineResizeDivider({
|
|
22266
|
+
timelineH,
|
|
22267
|
+
setTimelineH,
|
|
22268
|
+
persistTimelineH,
|
|
22269
|
+
containerRef,
|
|
22270
|
+
disabled
|
|
22271
|
+
}) {
|
|
22272
|
+
const isDragging = useRef38(false);
|
|
22273
|
+
const timelineHRef = useRef38(timelineH);
|
|
22274
|
+
timelineHRef.current = timelineH;
|
|
22275
|
+
const handlePointerDown = useCallback35(
|
|
22276
|
+
(e) => {
|
|
22277
|
+
if (disabled) return;
|
|
22278
|
+
e.preventDefault();
|
|
22279
|
+
isDragging.current = true;
|
|
22280
|
+
e.target.setPointerCapture(e.pointerId);
|
|
22281
|
+
},
|
|
22282
|
+
[disabled]
|
|
22283
|
+
);
|
|
22284
|
+
const handlePointerMove = useCallback35(
|
|
22285
|
+
(e) => {
|
|
22286
|
+
if (disabled) return;
|
|
22287
|
+
if (!isDragging.current || !containerRef.current) return;
|
|
22288
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
22289
|
+
const mouseY = e.clientY - rect.top;
|
|
22290
|
+
setTimelineH(fitTimelineHeight(rect.height, rect.height - mouseY));
|
|
22291
|
+
},
|
|
22292
|
+
[disabled, containerRef, setTimelineH]
|
|
22293
|
+
);
|
|
22294
|
+
const handlePointerUp = useCallback35(() => {
|
|
22295
|
+
if (isDragging.current) persistTimelineH(timelineHRef.current);
|
|
22296
|
+
isDragging.current = false;
|
|
22297
|
+
}, [persistTimelineH]);
|
|
22298
|
+
const handleKeyDown = useCallback35(
|
|
22299
|
+
(e) => {
|
|
22300
|
+
if (disabled) return;
|
|
22301
|
+
if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
|
|
22302
|
+
e.preventDefault();
|
|
22303
|
+
const containerH = containerRef.current?.getBoundingClientRect().height ?? 0;
|
|
22304
|
+
const delta = e.key === "ArrowUp" ? 16 : -16;
|
|
22305
|
+
setTimelineH((prev) => {
|
|
22306
|
+
const next = fitTimelineHeight(containerH, prev + delta);
|
|
22307
|
+
persistTimelineH(next);
|
|
22308
|
+
return next;
|
|
22309
|
+
});
|
|
22310
|
+
},
|
|
22311
|
+
[disabled, containerRef, setTimelineH, persistTimelineH]
|
|
22312
|
+
);
|
|
22313
|
+
return (
|
|
22314
|
+
// Horizontal resize divider: 3px visible seam (h-[3px]), 10px pointer-capture
|
|
22315
|
+
// zone via the absolutely-positioned inner hit area so the layout gap stays
|
|
22316
|
+
// at 3px while draggability is preserved over the full band.
|
|
22317
|
+
/* @__PURE__ */ jsxs39(
|
|
22318
|
+
"div",
|
|
22319
|
+
{
|
|
22320
|
+
role: "separator",
|
|
22321
|
+
"aria-orientation": "horizontal",
|
|
22322
|
+
"aria-label": "Resize timeline (arrow keys)",
|
|
22323
|
+
"aria-valuenow": Math.round(timelineH),
|
|
22324
|
+
"aria-valuemin": MIN_TIMELINE_H,
|
|
22325
|
+
"aria-valuemax": Math.round(
|
|
22326
|
+
(containerRef.current?.getBoundingClientRect().height ?? 600) - MIN_PREVIEW_H
|
|
22327
|
+
),
|
|
22328
|
+
tabIndex: 0,
|
|
22329
|
+
className: "group relative h-[3px] flex-shrink-0 cursor-row-resize z-10 outline-none focus-visible:bg-studio-accent/20",
|
|
22330
|
+
style: { touchAction: "none" },
|
|
22331
|
+
onPointerDown: handlePointerDown,
|
|
22332
|
+
onPointerMove: handlePointerMove,
|
|
22333
|
+
onPointerUp: handlePointerUp,
|
|
22334
|
+
onPointerCancel: handlePointerUp,
|
|
22335
|
+
onKeyDown: handleKeyDown,
|
|
22336
|
+
children: [
|
|
22337
|
+
/* @__PURE__ */ jsx52("div", { className: "absolute inset-x-0 -top-[4px] h-[10px]" }),
|
|
22338
|
+
/* @__PURE__ */ jsx52("div", { className: "h-[3px] w-full bg-transparent transition-colors group-hover:bg-white/12 group-active:bg-white/18 group-focus-visible:bg-studio-accent/60" })
|
|
22339
|
+
]
|
|
22340
|
+
}
|
|
22341
|
+
)
|
|
22342
|
+
);
|
|
22343
|
+
}
|
|
22344
|
+
|
|
22345
|
+
// src/components/nle/TimelinePane.tsx
|
|
22291
22346
|
import { Fragment as Fragment15, jsx as jsx53, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
22292
22347
|
function forwardRebasedTimelineMoveElements(edits, coalesceKey, operation, onMoveElements, coalesceMs) {
|
|
22293
22348
|
return onMoveElements(
|
|
@@ -28696,7 +28751,19 @@ function scopedElementKey(element) {
|
|
|
28696
28751
|
return `${element.sourceFile || "index.html"}#${element.id}`;
|
|
28697
28752
|
}
|
|
28698
28753
|
function elementCacheKeys(sourceFile, elementId2) {
|
|
28699
|
-
|
|
28754
|
+
const id = typeof elementId2 === "string" ? elementId2 : coerceCacheKeyId(elementId2, sourceFile);
|
|
28755
|
+
return sourceFile === "index.html" ? [`index.html#${id}`, id] : [`${sourceFile}#${id}`, `index.html#${id}`, id];
|
|
28756
|
+
}
|
|
28757
|
+
function coerceCacheKeyId(elementId2, sourceFile) {
|
|
28758
|
+
trackStudioEvent("cache_key_non_string", {
|
|
28759
|
+
value_type: typeof elementId2,
|
|
28760
|
+
// An Element lands here as "HTMLDivElement", a boxed id as "Number" — enough
|
|
28761
|
+
// to name the producer without shipping user content to telemetry.
|
|
28762
|
+
constructor_name: elementId2?.constructor?.name ?? null,
|
|
28763
|
+
is_array: Array.isArray(elementId2),
|
|
28764
|
+
source_file: sourceFile
|
|
28765
|
+
});
|
|
28766
|
+
return String(elementId2);
|
|
28700
28767
|
}
|
|
28701
28768
|
function replaceKeyframeCacheForFile(sourceFile, entries, animationsByElement) {
|
|
28702
28769
|
publishKeyframeCache((draft) => {
|
|
@@ -33452,7 +33519,9 @@ function useGsapAnimationsForElement(projectId, sourceFile, target, version, ifr
|
|
|
33452
33519
|
}
|
|
33453
33520
|
if (allKeyframes.length === 0) {
|
|
33454
33521
|
const { keyframeCache } = usePlayerStore.getState();
|
|
33455
|
-
const hasCached =
|
|
33522
|
+
const hasCached = elementCacheKeys(sourceFile, elementId2).some(
|
|
33523
|
+
(key2) => keyframeCache.has(key2)
|
|
33524
|
+
);
|
|
33456
33525
|
if (!hasCached) clearKeyframeCacheForElement(sourceFile, elementId2);
|
|
33457
33526
|
return;
|
|
33458
33527
|
}
|
|
@@ -33464,8 +33533,9 @@ function useGsapAnimationsForElement(projectId, sourceFile, target, version, ifr
|
|
|
33464
33533
|
...easeEach ? { easeEach } : {}
|
|
33465
33534
|
};
|
|
33466
33535
|
publishKeyframeCache((draft) => {
|
|
33467
|
-
|
|
33468
|
-
|
|
33536
|
+
for (const key2 of elementCacheKeys(sourceFile, elementId2)) {
|
|
33537
|
+
draft.keyframeCache.set(key2, merged);
|
|
33538
|
+
}
|
|
33469
33539
|
});
|
|
33470
33540
|
}, [elementId2, sourceFile, animations, domClipChildrenKey]);
|
|
33471
33541
|
return { animations, multipleTimelines, unsupportedTimelinePattern };
|
|
@@ -33519,10 +33589,8 @@ function usePopulateKeyframeCacheForFile(projectId, sourceFile, version, iframeR
|
|
|
33519
33589
|
if (scanned.size === 0) return false;
|
|
33520
33590
|
publishKeyframeCache((draft) => {
|
|
33521
33591
|
for (const [id, data] of scanned) {
|
|
33522
|
-
const
|
|
33523
|
-
|
|
33524
|
-
const alreadyCached = draft.keyframeCache.has(cacheKey) || draft.keyframeCache.has(fallbackKey) || draft.keyframeCache.has(id);
|
|
33525
|
-
if (alreadyCached) continue;
|
|
33592
|
+
const keys = elementCacheKeys(sf, id);
|
|
33593
|
+
if (keys.some((key2) => draft.keyframeCache.has(key2))) continue;
|
|
33526
33594
|
const isPosOnly = data.keyframes.length === 1 && Object.keys(data.keyframes[0].properties).every((k) => k === "x" || k === "y");
|
|
33527
33595
|
if (isPosOnly) {
|
|
33528
33596
|
continue;
|
|
@@ -33532,9 +33600,7 @@ function usePopulateKeyframeCacheForFile(projectId, sourceFile, version, iframeR
|
|
|
33532
33600
|
keyframes: data.keyframes,
|
|
33533
33601
|
...data.easeEach ? { easeEach: data.easeEach } : {}
|
|
33534
33602
|
};
|
|
33535
|
-
draft.keyframeCache.set(
|
|
33536
|
-
if (sf !== "index.html") draft.keyframeCache.set(fallbackKey, entry);
|
|
33537
|
-
draft.keyframeCache.set(id, entry);
|
|
33603
|
+
for (const key2 of keys) draft.keyframeCache.set(key2, entry);
|
|
33538
33604
|
}
|
|
33539
33605
|
});
|
|
33540
33606
|
runtimeScanDoneRef.current = `kf-cache:${projectId}:${sf}:${version}`;
|
|
@@ -33554,7 +33620,7 @@ var NOOP_EPSILON_PCT2 = 0.1;
|
|
|
33554
33620
|
var EPSILON_TIME = 1e-4;
|
|
33555
33621
|
var MIN_TWEEN_DURATION = 0.01;
|
|
33556
33622
|
var round33 = (n) => Math.round(n * 1e3) / 1e3;
|
|
33557
|
-
var
|
|
33623
|
+
var clamp6 = (n, lo, hi) => Math.max(lo, Math.min(hi, n));
|
|
33558
33624
|
function resolveFlatTweenBoundaryRetime(opts) {
|
|
33559
33625
|
const { keyframeCount, draggedTweenPct, tweenStart, tweenEnd, dropAbsTime } = opts;
|
|
33560
33626
|
if (keyframeCount > 0) return null;
|
|
@@ -33585,7 +33651,7 @@ function resolveKeyframeRetime(opts) {
|
|
|
33585
33651
|
});
|
|
33586
33652
|
if (flatBoundary) return flatBoundary;
|
|
33587
33653
|
if (dropAbsTime >= tweenStart - EPSILON_TIME && dropAbsTime <= tweenEnd + EPSILON_TIME) {
|
|
33588
|
-
const toTweenPct = round33(
|
|
33654
|
+
const toTweenPct = round33(clamp6((dropAbsTime - tweenStart) / tweenDuration * 100, 0, 100));
|
|
33589
33655
|
if (Math.abs(toTweenPct - draggedTweenPct) < NOOP_EPSILON_PCT2) return { kind: "noop" };
|
|
33590
33656
|
return { kind: "move", toTweenPct };
|
|
33591
33657
|
}
|
|
@@ -39622,7 +39688,7 @@ function hasCssWord(value, word) {
|
|
|
39622
39688
|
function parsePercentToken(value, fallback) {
|
|
39623
39689
|
if (!value?.endsWith("%")) return fallback;
|
|
39624
39690
|
const parsed = parseCssNumber(value.slice(0, -1));
|
|
39625
|
-
return parsed == null ? fallback :
|
|
39691
|
+
return parsed == null ? fallback : clamp7(parsed, 0, 100);
|
|
39626
39692
|
}
|
|
39627
39693
|
function parseAngleToken(value) {
|
|
39628
39694
|
const trimmed = value?.trim().toLowerCase();
|
|
@@ -39644,13 +39710,13 @@ function trailingPercentStart(value) {
|
|
|
39644
39710
|
if (start === 0 || !isWhitespace(withoutUnit[start - 1])) return null;
|
|
39645
39711
|
return start;
|
|
39646
39712
|
}
|
|
39647
|
-
function
|
|
39713
|
+
function clamp7(value, min, max) {
|
|
39648
39714
|
return Math.min(max, Math.max(min, value));
|
|
39649
39715
|
}
|
|
39650
39716
|
var round = roundToCenti;
|
|
39651
39717
|
function parsePercent(value, fallback) {
|
|
39652
39718
|
const parsed = parseCssNumber(value);
|
|
39653
|
-
return parsed == null ? fallback :
|
|
39719
|
+
return parsed == null ? fallback : clamp7(parsed, 0, 100);
|
|
39654
39720
|
}
|
|
39655
39721
|
function parseColorStop(raw) {
|
|
39656
39722
|
const trimmed = raw.trim();
|
|
@@ -39681,7 +39747,7 @@ function normalizeStops(stops) {
|
|
|
39681
39747
|
}));
|
|
39682
39748
|
return result.map((stop) => ({
|
|
39683
39749
|
color: stop.color,
|
|
39684
|
-
position: round(
|
|
39750
|
+
position: round(clamp7(stop.position, 0, 100))
|
|
39685
39751
|
}));
|
|
39686
39752
|
}
|
|
39687
39753
|
function splitGradientArgs(value) {
|
|
@@ -39844,7 +39910,7 @@ function formatHex(channel) {
|
|
|
39844
39910
|
return channel.toString(16).padStart(2, "0");
|
|
39845
39911
|
}
|
|
39846
39912
|
function interpolateGradientStopColor(model, position) {
|
|
39847
|
-
const clampedPosition =
|
|
39913
|
+
const clampedPosition = clamp7(position, 0, 100);
|
|
39848
39914
|
const sortedStops = [...model.stops].sort((a, b) => a.position - b.position);
|
|
39849
39915
|
const exact = sortedStops.find((stop) => Math.abs(stop.position - clampedPosition) < 1e-3);
|
|
39850
39916
|
if (exact) return exact.color;
|
|
@@ -39868,7 +39934,7 @@ function interpolateGradientStopColor(model, position) {
|
|
|
39868
39934
|
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
|
|
39869
39935
|
}
|
|
39870
39936
|
function insertGradientStop(model, position) {
|
|
39871
|
-
const clampedPosition = round(
|
|
39937
|
+
const clampedPosition = round(clamp7(position, 0, 100));
|
|
39872
39938
|
const color = interpolateGradientStopColor(model, clampedPosition);
|
|
39873
39939
|
const nextStops = [...model.stops, { color, position: clampedPosition }].sort(
|
|
39874
39940
|
(a, b) => a.position - b.position
|
|
@@ -50734,7 +50800,7 @@ var FileTree = memo33(function FileTree2({
|
|
|
50734
50800
|
});
|
|
50735
50801
|
|
|
50736
50802
|
// src/App.tsx
|
|
50737
|
-
import { useState as useState133, useCallback as useCallback152, useRef as useRef142, useMemo as useMemo66, useEffect as
|
|
50803
|
+
import { useState as useState133, useCallback as useCallback152, useRef as useRef142, useMemo as useMemo66, useEffect as useEffect122, useLayoutEffect as useLayoutEffect9 } from "react";
|
|
50738
50804
|
|
|
50739
50805
|
// src/components/renders/useRenderQueue.ts
|
|
50740
50806
|
import { useState as useState77, useEffect as useEffect71, useCallback as useCallback65, useRef as useRef83, useMemo as useMemo46 } from "react";
|
|
@@ -52315,33 +52381,26 @@ function usePersistentEditHistory(options) {
|
|
|
52315
52381
|
}
|
|
52316
52382
|
|
|
52317
52383
|
// src/hooks/usePanelLayout.ts
|
|
52318
|
-
import { useState as useState82, useCallback as useCallback69, useRef as useRef90 } from "react";
|
|
52384
|
+
import { useState as useState82, useCallback as useCallback69, useRef as useRef90, useEffect as useEffect74 } from "react";
|
|
52385
|
+
var NO_OVERRIDE = { left: false, right: false };
|
|
52319
52386
|
function getInitialRightInspectorPanes(tab) {
|
|
52320
52387
|
if (tab === "layers") return { layers: true, design: false };
|
|
52321
52388
|
return { layers: false, design: true };
|
|
52322
52389
|
}
|
|
52323
|
-
function
|
|
52324
|
-
|
|
52390
|
+
function readViewportWidth() {
|
|
52391
|
+
return typeof window === "undefined" ? 1496 : window.innerWidth;
|
|
52392
|
+
}
|
|
52393
|
+
function getPreferredPanelWidths() {
|
|
52325
52394
|
const preferences = readStudioUiPreferences();
|
|
52326
|
-
const
|
|
52327
|
-
const rightDefault = Math.max(320, Math.min(424, Math.round(viewportWidth * 0.284)));
|
|
52395
|
+
const defaults = defaultPanelWidths(readViewportWidth());
|
|
52328
52396
|
return {
|
|
52329
|
-
left:
|
|
52330
|
-
|
|
52331
|
-
Math.min(Math.floor(viewportWidth * 0.5), preferences.leftWidth ?? leftDefault)
|
|
52332
|
-
),
|
|
52333
|
-
right: Math.max(160, Math.min(600, preferences.rightWidth ?? rightDefault))
|
|
52397
|
+
left: preferences.leftWidth ?? defaults.left,
|
|
52398
|
+
right: preferences.rightWidth ?? defaults.right
|
|
52334
52399
|
};
|
|
52335
52400
|
}
|
|
52336
|
-
function clampPanelWidth(side, width) {
|
|
52337
|
-
const max = side === "left" ? Math.floor(window.innerWidth * 0.5) : 600;
|
|
52338
|
-
return Math.max(160, Math.min(max, width));
|
|
52339
|
-
}
|
|
52340
52401
|
function usePanelLayout(initialState2) {
|
|
52341
|
-
const [
|
|
52342
|
-
const [
|
|
52343
|
-
const [rightWidth, setRightWidth] = useState82(initialPanelWidths.right);
|
|
52344
|
-
const panelWidthsRef = useRef90(initialPanelWidths);
|
|
52402
|
+
const [preferredWidths, setPreferredWidths] = useState82(getPreferredPanelWidths);
|
|
52403
|
+
const [viewportWidth, setViewportWidth] = useState82(readViewportWidth);
|
|
52345
52404
|
const [leftCollapsed, setLeftCollapsed] = useState82(
|
|
52346
52405
|
() => readStudioUiPreferences().leftCollapsed ?? false
|
|
52347
52406
|
);
|
|
@@ -52352,33 +52411,65 @@ function usePanelLayout(initialState2) {
|
|
|
52352
52411
|
const [rightInspectorPanes, setRightInspectorPanes] = useState82(
|
|
52353
52412
|
() => getInitialRightInspectorPanes(initialState2?.rightPanelTab)
|
|
52354
52413
|
);
|
|
52414
|
+
const [autoCollapseOverride, setAutoCollapseOverride] = useState82(NO_OVERRIDE);
|
|
52415
|
+
useEffect74(() => {
|
|
52416
|
+
if (typeof window === "undefined") return;
|
|
52417
|
+
const handleResize = () => {
|
|
52418
|
+
const width = window.innerWidth;
|
|
52419
|
+
setViewportWidth(width);
|
|
52420
|
+
if (!railsEngaged(width)) {
|
|
52421
|
+
setAutoCollapseOverride((prev) => prev.left || prev.right ? NO_OVERRIDE : prev);
|
|
52422
|
+
}
|
|
52423
|
+
};
|
|
52424
|
+
window.addEventListener("resize", handleResize);
|
|
52425
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
52426
|
+
}, []);
|
|
52427
|
+
const fitted = fitPanelWidths(viewportWidth, preferredWidths, autoCollapseOverride);
|
|
52428
|
+
const leftCollapsedByWidth = fitted.autoCollapseLeft;
|
|
52429
|
+
const rightCollapsedByWidth = fitted.autoCollapseRight;
|
|
52430
|
+
const fittedRef = useRef90(fitted);
|
|
52431
|
+
fittedRef.current = fitted;
|
|
52355
52432
|
const panelDragRef = useRef90(null);
|
|
52356
|
-
const
|
|
52357
|
-
|
|
52358
|
-
|
|
52359
|
-
|
|
52360
|
-
|
|
52433
|
+
const preferredRef = useRef90(preferredWidths);
|
|
52434
|
+
const setPreferred = useCallback69((side, width) => {
|
|
52435
|
+
const next = Math.max(0, Math.round(width));
|
|
52436
|
+
preferredRef.current = { ...preferredRef.current, [side]: next };
|
|
52437
|
+
setPreferredWidths(preferredRef.current);
|
|
52361
52438
|
return next;
|
|
52362
52439
|
}, []);
|
|
52440
|
+
const updatePanelWidth = useCallback69(
|
|
52441
|
+
(side, width) => {
|
|
52442
|
+
setPreferred(side, width);
|
|
52443
|
+
},
|
|
52444
|
+
[setPreferred]
|
|
52445
|
+
);
|
|
52363
52446
|
const commitPanelWidth = useCallback69(
|
|
52364
52447
|
(side, width) => {
|
|
52365
|
-
const
|
|
52366
|
-
|
|
52448
|
+
const candidate = { ...preferredRef.current, [side]: Math.max(0, Math.round(width)) };
|
|
52449
|
+
const settled = fitPanelWidths(readViewportWidth(), candidate)[side];
|
|
52450
|
+
setPreferred(side, settled);
|
|
52451
|
+
writeStudioUiPreferences(side === "left" ? { leftWidth: settled } : { rightWidth: settled });
|
|
52367
52452
|
},
|
|
52368
|
-
[
|
|
52453
|
+
[setPreferred]
|
|
52369
52454
|
);
|
|
52370
52455
|
const adjustPanelWidth = useCallback69(
|
|
52371
52456
|
(side, delta) => {
|
|
52372
|
-
commitPanelWidth(side,
|
|
52457
|
+
commitPanelWidth(side, preferredRef.current[side] + delta);
|
|
52373
52458
|
},
|
|
52374
52459
|
[commitPanelWidth]
|
|
52375
52460
|
);
|
|
52461
|
+
const effectiveLeftCollapsedRef = useRef90(false);
|
|
52462
|
+
effectiveLeftCollapsedRef.current = leftCollapsed || leftCollapsedByWidth;
|
|
52376
52463
|
const toggleLeftSidebar = useCallback69(() => {
|
|
52377
|
-
|
|
52378
|
-
|
|
52379
|
-
|
|
52380
|
-
|
|
52381
|
-
});
|
|
52464
|
+
const next = !effectiveLeftCollapsedRef.current;
|
|
52465
|
+
setLeftCollapsed(next);
|
|
52466
|
+
writeStudioUiPreferences({ leftCollapsed: next });
|
|
52467
|
+
trackStudioEvent("panel_toggle", { panel: "left_sidebar", collapsed: next });
|
|
52468
|
+
if (!next) setAutoCollapseOverride((prev) => ({ ...prev, left: true }));
|
|
52469
|
+
}, []);
|
|
52470
|
+
const setRightCollapsedWithOverride = useCallback69((collapsed) => {
|
|
52471
|
+
setRightCollapsed(collapsed);
|
|
52472
|
+
if (!collapsed) setAutoCollapseOverride((prev) => ({ ...prev, right: true }));
|
|
52382
52473
|
}, []);
|
|
52383
52474
|
const handlePanelResizeStart = useCallback69((side, e) => {
|
|
52384
52475
|
e.preventDefault();
|
|
@@ -52386,7 +52477,7 @@ function usePanelLayout(initialState2) {
|
|
|
52386
52477
|
panelDragRef.current = {
|
|
52387
52478
|
side,
|
|
52388
52479
|
startX: e.clientX,
|
|
52389
|
-
startW:
|
|
52480
|
+
startW: fittedRef.current[side]
|
|
52390
52481
|
};
|
|
52391
52482
|
}, []);
|
|
52392
52483
|
const handlePanelResizeMove = useCallback69(
|
|
@@ -52400,7 +52491,7 @@ function usePanelLayout(initialState2) {
|
|
|
52400
52491
|
);
|
|
52401
52492
|
const handlePanelResizeEnd = useCallback69(() => {
|
|
52402
52493
|
const side = panelDragRef.current?.side;
|
|
52403
|
-
if (side) commitPanelWidth(side,
|
|
52494
|
+
if (side) commitPanelWidth(side, preferredRef.current[side]);
|
|
52404
52495
|
panelDragRef.current = null;
|
|
52405
52496
|
}, [commitPanelWidth]);
|
|
52406
52497
|
const trackedSetRightPanelTab = useCallback69(
|
|
@@ -52426,13 +52517,22 @@ function usePanelLayout(initialState2) {
|
|
|
52426
52517
|
setRightInspectorPanes({ design: pane === "design", layers: pane === "layers" });
|
|
52427
52518
|
}, []);
|
|
52428
52519
|
return {
|
|
52429
|
-
leftWidth,
|
|
52430
|
-
rightWidth,
|
|
52520
|
+
leftWidth: fitted.left,
|
|
52521
|
+
rightWidth: fitted.right,
|
|
52431
52522
|
adjustPanelWidth,
|
|
52523
|
+
/**
|
|
52524
|
+
* User intent. Persisted to localStorage; never written by auto-collapse.
|
|
52525
|
+
* Deliberately read-only outside this hook: `toggleLeftSidebar` is the only
|
|
52526
|
+
* writer, so it cannot be flipped without also clearing the rail override
|
|
52527
|
+
* (which would open the sidebar and then immediately rail it again).
|
|
52528
|
+
*/
|
|
52432
52529
|
leftCollapsed,
|
|
52433
|
-
|
|
52530
|
+
/** User intent. Synced into the shareable URL; never written by auto-collapse. */
|
|
52434
52531
|
rightCollapsed,
|
|
52435
|
-
setRightCollapsed,
|
|
52532
|
+
setRightCollapsed: setRightCollapsedWithOverride,
|
|
52533
|
+
/** What the shell actually renders: intent OR the window forcing a rail. */
|
|
52534
|
+
effectiveLeftCollapsed: leftCollapsed || leftCollapsedByWidth,
|
|
52535
|
+
effectiveRightCollapsed: rightCollapsed || rightCollapsedByWidth,
|
|
52436
52536
|
rightPanelTab,
|
|
52437
52537
|
setRightPanelTab: trackedSetRightPanelTab,
|
|
52438
52538
|
rightInspectorPanes,
|
|
@@ -52483,13 +52583,13 @@ function createStudioWriteToken() {
|
|
|
52483
52583
|
}
|
|
52484
52584
|
|
|
52485
52585
|
// src/hooks/useFileTree.ts
|
|
52486
|
-
import { useState as useState83, useCallback as useCallback70, useEffect as
|
|
52586
|
+
import { useState as useState83, useCallback as useCallback70, useEffect as useEffect75, useMemo as useMemo48 } from "react";
|
|
52487
52587
|
function useFileTree({ projectId, projectIdRef }) {
|
|
52488
52588
|
const [projectDir, setProjectDir] = useState83(null);
|
|
52489
52589
|
const [fileTree, setFileTree] = useState83([]);
|
|
52490
52590
|
const [compositionPaths, setCompositionPaths] = useState83([]);
|
|
52491
52591
|
const [fileTreeLoaded, setFileTreeLoaded] = useState83(false);
|
|
52492
|
-
|
|
52592
|
+
useEffect75(() => {
|
|
52493
52593
|
if (!projectId) {
|
|
52494
52594
|
setFileTreeLoaded(false);
|
|
52495
52595
|
return;
|
|
@@ -53476,7 +53576,7 @@ function usePreviewPersistence({
|
|
|
53476
53576
|
}
|
|
53477
53577
|
|
|
53478
53578
|
// src/hooks/usePreviewDocumentVersion.ts
|
|
53479
|
-
import { useCallback as useCallback74, useEffect as
|
|
53579
|
+
import { useCallback as useCallback74, useEffect as useEffect76, useRef as useRef94, useState as useState86 } from "react";
|
|
53480
53580
|
function usePreviewDocumentVersion() {
|
|
53481
53581
|
const [previewDocumentVersion, setPreviewDocumentVersion] = useState86(0);
|
|
53482
53582
|
const refreshTimersRef = useRef94([]);
|
|
@@ -53489,7 +53589,7 @@ function usePreviewDocumentVersion() {
|
|
|
53489
53589
|
window.setTimeout(() => setPreviewDocumentVersion((v) => v + 1), 300)
|
|
53490
53590
|
);
|
|
53491
53591
|
}, []);
|
|
53492
|
-
|
|
53592
|
+
useEffect76(
|
|
53493
53593
|
() => () => {
|
|
53494
53594
|
for (const id of refreshTimersRef.current) clearTimeout(id);
|
|
53495
53595
|
},
|
|
@@ -55034,7 +55134,7 @@ function persistTimelineMoveEditsAtomically(edits, coalesceKey, operation, deps,
|
|
|
55034
55134
|
import { useCallback as useCallback102 } from "react";
|
|
55035
55135
|
|
|
55036
55136
|
// src/hooks/useAskAgentModal.ts
|
|
55037
|
-
import { useState as useState87, useCallback as useCallback80, useRef as useRef97, useEffect as
|
|
55137
|
+
import { useState as useState87, useCallback as useCallback80, useRef as useRef97, useEffect as useEffect77 } from "react";
|
|
55038
55138
|
function useAskAgentModal({
|
|
55039
55139
|
activeCompPath,
|
|
55040
55140
|
projectDir,
|
|
@@ -55115,13 +55215,13 @@ function useAskAgentModal({
|
|
|
55115
55215
|
showToast
|
|
55116
55216
|
]
|
|
55117
55217
|
);
|
|
55118
|
-
|
|
55218
|
+
useEffect77(() => {
|
|
55119
55219
|
setAgentPromptTagSnippet(void 0);
|
|
55120
55220
|
setAgentPromptSelectionContext(void 0);
|
|
55121
55221
|
setAgentModalAnchorPoint(null);
|
|
55122
55222
|
setCopiedAgentPrompt(false);
|
|
55123
55223
|
}, [domEditSelection]);
|
|
55124
|
-
|
|
55224
|
+
useEffect77(
|
|
55125
55225
|
() => () => {
|
|
55126
55226
|
if (copiedAgentTimerRef.current) clearTimeout(copiedAgentTimerRef.current);
|
|
55127
55227
|
},
|
|
@@ -55145,7 +55245,7 @@ function useAskAgentModal({
|
|
|
55145
55245
|
}
|
|
55146
55246
|
|
|
55147
55247
|
// src/hooks/useDomSelection.ts
|
|
55148
|
-
import { useState as useState88, useCallback as useCallback81, useRef as useRef98, useEffect as
|
|
55248
|
+
import { useState as useState88, useCallback as useCallback81, useRef as useRef98, useEffect as useEffect79 } from "react";
|
|
55149
55249
|
|
|
55150
55250
|
// src/utils/domEditHelpers.ts
|
|
55151
55251
|
function domEditSelectionsTargetSame(a, b) {
|
|
@@ -55178,7 +55278,7 @@ function seedDomEditGroupWithSelection(group, selection) {
|
|
|
55178
55278
|
}
|
|
55179
55279
|
|
|
55180
55280
|
// src/hooks/useStudioTestHooks.ts
|
|
55181
|
-
import { useEffect as
|
|
55281
|
+
import { useEffect as useEffect78 } from "react";
|
|
55182
55282
|
|
|
55183
55283
|
// src/player/lib/timelinePerformanceDiagnostics.ts
|
|
55184
55284
|
function readNonNegativeNumber(value) {
|
|
@@ -55261,7 +55361,7 @@ function useStudioTestHooks({
|
|
|
55261
55361
|
buildDomSelectionFromTarget,
|
|
55262
55362
|
applyDomSelection
|
|
55263
55363
|
}) {
|
|
55264
|
-
|
|
55364
|
+
useEffect78(() => {
|
|
55265
55365
|
if (!STUDIO_TEST_HOOKS_ENABLED || typeof window === "undefined") return;
|
|
55266
55366
|
const api = {
|
|
55267
55367
|
runtimeMode: STUDIO_RUNTIME_MODE,
|
|
@@ -55562,10 +55662,10 @@ function useDomSelection({
|
|
|
55562
55662
|
previewIframeRef
|
|
55563
55663
|
]
|
|
55564
55664
|
);
|
|
55565
|
-
|
|
55665
|
+
useEffect79(() => {
|
|
55566
55666
|
updateDomEditHoverSelection(null);
|
|
55567
55667
|
}, [activeCompPath, projectId, previewIframe, refreshKey, updateDomEditHoverSelection]);
|
|
55568
|
-
|
|
55668
|
+
useEffect79(() => {
|
|
55569
55669
|
const previous = compositionIdentityRef.current;
|
|
55570
55670
|
if (previous.activeCompPath === activeCompPath && previous.projectId === projectId) return;
|
|
55571
55671
|
compositionIdentityRef.current = { activeCompPath, projectId };
|
|
@@ -55573,7 +55673,7 @@ function useDomSelection({
|
|
|
55573
55673
|
setActiveGroupElementState(null);
|
|
55574
55674
|
applyDomSelection(null, { revealPanel: false });
|
|
55575
55675
|
}, [activeCompPath, projectId, applyDomSelection]);
|
|
55576
|
-
|
|
55676
|
+
useEffect79(() => {
|
|
55577
55677
|
if (!domEditHoverSelection) return;
|
|
55578
55678
|
const shouldClear = captionEditMode || domEditSelectionsTargetSame(domEditHoverSelection, domEditSelection) || domEditSelectionInGroup(domEditGroupSelections, domEditHoverSelection) || !domEditHoverSelection.element.isConnected;
|
|
55579
55679
|
if (shouldClear) updateDomEditHoverSelection(null);
|
|
@@ -55584,7 +55684,7 @@ function useDomSelection({
|
|
|
55584
55684
|
domEditGroupSelections,
|
|
55585
55685
|
updateDomEditHoverSelection
|
|
55586
55686
|
]);
|
|
55587
|
-
|
|
55687
|
+
useEffect79(() => {
|
|
55588
55688
|
if (!captionEditMode) return;
|
|
55589
55689
|
applyDomSelection(null, { revealPanel: false });
|
|
55590
55690
|
}, [applyDomSelection, captionEditMode]);
|
|
@@ -58330,7 +58430,7 @@ function useGsapKeyframeOps({
|
|
|
58330
58430
|
}
|
|
58331
58431
|
|
|
58332
58432
|
// src/hooks/useGsapPropertyDebounce.ts
|
|
58333
|
-
import { useCallback as useCallback92, useEffect as
|
|
58433
|
+
import { useCallback as useCallback92, useEffect as useEffect80, useRef as useRef103 } from "react";
|
|
58334
58434
|
import { parseGsapScriptAcorn } from "@hyperframes/core/gsap-parser-acorn";
|
|
58335
58435
|
var DEBOUNCE_MS = 150;
|
|
58336
58436
|
function mergeTweenProperties(sdkSession, animationId, edited, kind) {
|
|
@@ -58400,7 +58500,7 @@ function useGsapPropertyDebounce(commitMutationSafely, sdk) {
|
|
|
58400
58500
|
},
|
|
58401
58501
|
[flushPendingPropertyEdit]
|
|
58402
58502
|
);
|
|
58403
|
-
|
|
58503
|
+
useEffect80(() => {
|
|
58404
58504
|
return () => {
|
|
58405
58505
|
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
|
58406
58506
|
void flushPendingPropertyEdit();
|
|
@@ -58941,10 +59041,10 @@ function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef,
|
|
|
58941
59041
|
}
|
|
58942
59042
|
|
|
58943
59043
|
// src/hooks/useDomEditWiring.ts
|
|
58944
|
-
import { useCallback as useCallback98, useEffect as
|
|
59044
|
+
import { useCallback as useCallback98, useEffect as useEffect82, useRef as useRef107 } from "react";
|
|
58945
59045
|
|
|
58946
59046
|
// src/hooks/useDomEditPreviewSync.ts
|
|
58947
|
-
import { useEffect as
|
|
59047
|
+
import { useEffect as useEffect81, useRef as useRef105 } from "react";
|
|
58948
59048
|
function useDomEditPreviewSync({
|
|
58949
59049
|
previewIframe,
|
|
58950
59050
|
activeCompPath,
|
|
@@ -58960,7 +59060,7 @@ function useDomEditPreviewSync({
|
|
|
58960
59060
|
getSidebarTab,
|
|
58961
59061
|
gsapCacheVersion
|
|
58962
59062
|
}) {
|
|
58963
|
-
|
|
59063
|
+
useEffect81(() => {
|
|
58964
59064
|
if (!previewIframe) return;
|
|
58965
59065
|
const syncSelectionFromDocument = async () => {
|
|
58966
59066
|
if (captionEditMode) return;
|
|
@@ -59012,7 +59112,7 @@ function useDomEditPreviewSync({
|
|
|
59012
59112
|
]);
|
|
59013
59113
|
const openSourceRef = useRef105(openSourceForSelection);
|
|
59014
59114
|
openSourceRef.current = openSourceForSelection;
|
|
59015
|
-
|
|
59115
|
+
useEffect81(
|
|
59016
59116
|
// fallow-ignore-next-line complexity
|
|
59017
59117
|
() => {
|
|
59018
59118
|
if (!domEditSelection || !openSourceRef.current || !getSidebarTab) return;
|
|
@@ -59449,7 +59549,7 @@ function useDomEditWiring({
|
|
|
59449
59549
|
},
|
|
59450
59550
|
[openSourceForSelection, selectSidebarTab]
|
|
59451
59551
|
);
|
|
59452
|
-
|
|
59552
|
+
useEffect82(() => {
|
|
59453
59553
|
if (!domEditSelection?.id) return;
|
|
59454
59554
|
const { selectedElementId, elements, setSelectedElementId } = usePlayerStore.getState();
|
|
59455
59555
|
const matchKey = elements.find(
|
|
@@ -59459,7 +59559,7 @@ function useDomEditWiring({
|
|
|
59459
59559
|
if (key2 && key2 !== selectedElementId) setSelectedElementId(key2);
|
|
59460
59560
|
}, [domEditSelection?.id]);
|
|
59461
59561
|
const prevRefreshKeyRef = useRef107(refreshKey);
|
|
59462
|
-
|
|
59562
|
+
useEffect82(() => {
|
|
59463
59563
|
if (refreshKey !== prevRefreshKeyRef.current) {
|
|
59464
59564
|
prevRefreshKeyRef.current = refreshKey;
|
|
59465
59565
|
bumpGsapCache();
|
|
@@ -59597,7 +59697,7 @@ async function tryGsapResizeIntercept(selection, size, animations, iframe, commi
|
|
|
59597
59697
|
if (!anim || isInstantHold(anim)) {
|
|
59598
59698
|
const sel = selectorFromSelection(selection) ?? writeTargetSelector(selection);
|
|
59599
59699
|
if (!sel) return { status: "blocked", reason: "no-selector" };
|
|
59600
|
-
const sizeSet = anim ?? findSizeSetAnimation(workingAnimations, sel, selection.element);
|
|
59700
|
+
const sizeSet = resizeGroup === "size" ? anim ?? findSizeSetAnimation(workingAnimations, sel, selection.element) : findSizeSetAnimation(workingAnimations, sel, selection.element);
|
|
59601
59701
|
if (resizeGroup === "size") {
|
|
59602
59702
|
const animatedTween = pickClosestToPlayhead(
|
|
59603
59703
|
workingAnimations.filter((a) => !isInstantHold(a) && resolveTweenDuration(a) > 0)
|
|
@@ -59645,7 +59745,8 @@ async function tryGsapResizeIntercept(selection, size, animations, iframe, commi
|
|
|
59645
59745
|
const liveScaleY = rawLiveScaleY > 0 ? rawLiveScaleY : 1;
|
|
59646
59746
|
const newScaleX = roundTo3(size.width * liveScaleX / cssW);
|
|
59647
59747
|
const newScaleY = roundTo3(size.height * liveScaleY / cssH);
|
|
59648
|
-
|
|
59748
|
+
const uniformDrift = Math.abs(newScaleX - newScaleY) * cssH;
|
|
59749
|
+
nonUniformScale = uniformDrift > 0.5;
|
|
59649
59750
|
useScaleLonghands = nonUniformScale || tweenUsesScaleLonghands(anim);
|
|
59650
59751
|
resizeProps = useScaleLonghands ? { scaleX: newScaleX, scaleY: newScaleY } : { scale: newScaleX };
|
|
59651
59752
|
logResize("intercept-route", {
|
|
@@ -59671,9 +59772,9 @@ async function tryGsapResizeIntercept(selection, size, animations, iframe, commi
|
|
|
59671
59772
|
};
|
|
59672
59773
|
}
|
|
59673
59774
|
const finalizeScaleResizeCommit = async () => {
|
|
59674
|
-
if (!scaleDraftEl) return;
|
|
59775
|
+
if (!scaleDraftEl) return false;
|
|
59675
59776
|
clearStudioBoxSize(scaleDraftEl);
|
|
59676
|
-
if (!scaleDraftDropPoint || !selector) return;
|
|
59777
|
+
if (!scaleDraftDropPoint || !selector) return false;
|
|
59677
59778
|
if (committedScale) {
|
|
59678
59779
|
setElementGsapScale(scaleDraftEl, committedScale.x, committedScale.y);
|
|
59679
59780
|
}
|
|
@@ -59687,10 +59788,10 @@ async function tryGsapResizeIntercept(selection, size, animations, iframe, commi
|
|
|
59687
59788
|
setElementGsapPosition(scaleDraftEl, base2.x, base2.y);
|
|
59688
59789
|
const post = scaleDraftEl.getBoundingClientRect();
|
|
59689
59790
|
const residual = { x: scaleDraftDropPoint.x - post.x, y: scaleDraftDropPoint.y - post.y };
|
|
59690
|
-
if (!Number.isFinite(residual.x) || !Number.isFinite(residual.y)) return;
|
|
59791
|
+
if (!Number.isFinite(residual.x) || !Number.isFinite(residual.y)) return false;
|
|
59691
59792
|
if (Math.abs(residual.x) < 0.5 && Math.abs(residual.y) < 0.5) {
|
|
59692
59793
|
logResize("scale-finalize", { skipped: "already-on-drop-point", residual, base: base2 });
|
|
59693
|
-
return;
|
|
59794
|
+
return true;
|
|
59694
59795
|
}
|
|
59695
59796
|
const corrected = {
|
|
59696
59797
|
x: Math.round(base2.x + residual.x),
|
|
@@ -59718,13 +59819,14 @@ async function tryGsapResizeIntercept(selection, size, animations, iframe, commi
|
|
|
59718
59819
|
commitMutation,
|
|
59719
59820
|
fetchAnimations: fetchFallbackAnimations
|
|
59720
59821
|
});
|
|
59721
|
-
return;
|
|
59822
|
+
return true;
|
|
59722
59823
|
}
|
|
59723
59824
|
const existingSet = findExistingPositionWrite(currentAnimations, selector, selection.element);
|
|
59724
59825
|
await commitStaticGsapPosition(selection, delta, base2, selector, existingSet, {
|
|
59725
59826
|
commitMutation,
|
|
59726
59827
|
fetchAnimations: fetchFallbackAnimations
|
|
59727
59828
|
});
|
|
59829
|
+
return true;
|
|
59728
59830
|
};
|
|
59729
59831
|
if (!usePlayerStore.getState().autoKeyframeEnabled) {
|
|
59730
59832
|
if (activeKeyframePct != null) setActiveKeyframePct(null);
|
|
@@ -59737,8 +59839,7 @@ async function tryGsapResizeIntercept(selection, size, animations, iframe, commi
|
|
|
59737
59839
|
{ commitMutation, fetchAnimations: fetchFallbackAnimations },
|
|
59738
59840
|
"Resize animation"
|
|
59739
59841
|
);
|
|
59740
|
-
await finalizeScaleResizeCommit();
|
|
59741
|
-
return { status: "persisted" };
|
|
59842
|
+
return { status: "persisted", ownsDragOffset: await finalizeScaleResizeCommit() };
|
|
59742
59843
|
}
|
|
59743
59844
|
const ct = usePlayerStore.getState().currentTime;
|
|
59744
59845
|
const ts = resolveTweenStart(anim);
|
|
@@ -59817,8 +59918,7 @@ async function tryGsapResizeIntercept(selection, size, animations, iframe, commi
|
|
|
59817
59918
|
softReload: true
|
|
59818
59919
|
}
|
|
59819
59920
|
);
|
|
59820
|
-
await finalizeScaleResizeCommit();
|
|
59821
|
-
return { status: "persisted" };
|
|
59921
|
+
return { status: "persisted", ownsDragOffset: await finalizeScaleResizeCommit() };
|
|
59822
59922
|
}
|
|
59823
59923
|
const SIZE_PROPS = /* @__PURE__ */ new Set(["width", "height"]);
|
|
59824
59924
|
const backfillDefaults = {};
|
|
@@ -59837,8 +59937,7 @@ async function tryGsapResizeIntercept(selection, size, animations, iframe, commi
|
|
|
59837
59937
|
},
|
|
59838
59938
|
{ label: `Resize (keyframe ${pct}%)`, softReload: true }
|
|
59839
59939
|
);
|
|
59840
|
-
await finalizeScaleResizeCommit();
|
|
59841
|
-
return { status: "persisted" };
|
|
59940
|
+
return { status: "persisted", ownsDragOffset: await finalizeScaleResizeCommit() };
|
|
59842
59941
|
}
|
|
59843
59942
|
|
|
59844
59943
|
// src/hooks/useAnimatedPropertyCommit.ts
|
|
@@ -60338,11 +60437,13 @@ function useGsapAwareEditing({
|
|
|
60338
60437
|
makeFetchFallback(selection)
|
|
60339
60438
|
);
|
|
60340
60439
|
assertGsapEditPersisted(outcome);
|
|
60440
|
+
const ownsDragOffset = outcome.status === "persisted" && outcome.ownsDragOffset === true;
|
|
60341
60441
|
logResize("intercept-handled", {
|
|
60342
60442
|
scaleRoute,
|
|
60343
|
-
|
|
60443
|
+
ownsDragOffset,
|
|
60444
|
+
willForwardOffset: !!(offset && !ownsDragOffset)
|
|
60344
60445
|
});
|
|
60345
|
-
if (offset && !
|
|
60446
|
+
if (offset && !ownsDragOffset) {
|
|
60346
60447
|
const dragOutcome = await tryGsapDragIntercept(
|
|
60347
60448
|
selection,
|
|
60348
60449
|
offset,
|
|
@@ -60353,7 +60454,7 @@ function useGsapAwareEditing({
|
|
|
60353
60454
|
);
|
|
60354
60455
|
assertGsapEditPersisted(dragOutcome);
|
|
60355
60456
|
}
|
|
60356
|
-
logResizeSettle(selection.element,
|
|
60457
|
+
logResizeSettle(selection.element, ownsDragOffset ? "gsap-scale" : "gsap-size");
|
|
60357
60458
|
return;
|
|
60358
60459
|
} catch (error) {
|
|
60359
60460
|
trackGsapInteractionFailure(error, selection, "resize", "Resize animated layer");
|
|
@@ -60491,7 +60592,7 @@ function useGsapAwareEditing({
|
|
|
60491
60592
|
}
|
|
60492
60593
|
|
|
60493
60594
|
// src/hooks/useStudioSelectionPublisher.ts
|
|
60494
|
-
import { useEffect as
|
|
60595
|
+
import { useEffect as useEffect83, useRef as useRef108 } from "react";
|
|
60495
60596
|
|
|
60496
60597
|
// src/utils/studioSelectionSnapshot.ts
|
|
60497
60598
|
function round34(value) {
|
|
@@ -60584,7 +60685,7 @@ function useStudioSelectionPublisher({
|
|
|
60584
60685
|
}) {
|
|
60585
60686
|
const lastSelectionRefreshKeyRef = useRef108(refreshKey);
|
|
60586
60687
|
const pendingSelectionRefreshKeyRef = useRef108(null);
|
|
60587
|
-
|
|
60688
|
+
useEffect83(() => {
|
|
60588
60689
|
if (!projectId) return;
|
|
60589
60690
|
const selection = domEditSelection?.element.isConnected ? buildStudioSelectionSnapshot({
|
|
60590
60691
|
projectId,
|
|
@@ -60595,13 +60696,13 @@ function useStudioSelectionPublisher({
|
|
|
60595
60696
|
void putSelection(projectId, selection, controller.signal).catch(reportSelectionPublishError);
|
|
60596
60697
|
return () => controller.abort();
|
|
60597
60698
|
}, [domEditSelection, projectId]);
|
|
60598
|
-
|
|
60699
|
+
useEffect83(() => {
|
|
60599
60700
|
if (!projectId) return;
|
|
60600
60701
|
return () => {
|
|
60601
60702
|
void putSelection(projectId, null).catch(reportSelectionPublishError);
|
|
60602
60703
|
};
|
|
60603
60704
|
}, [projectId]);
|
|
60604
|
-
|
|
60705
|
+
useEffect83(() => {
|
|
60605
60706
|
if (lastSelectionRefreshKeyRef.current === refreshKey) return;
|
|
60606
60707
|
lastSelectionRefreshKeyRef.current = refreshKey;
|
|
60607
60708
|
pendingSelectionRefreshKeyRef.current = domEditSelectionRef.current ? refreshKey : null;
|
|
@@ -60610,7 +60711,7 @@ function useStudioSelectionPublisher({
|
|
|
60610
60711
|
void putSelection(projectId, null, controller.signal).catch(reportSelectionPublishError);
|
|
60611
60712
|
return () => controller.abort();
|
|
60612
60713
|
}, [domEditSelectionRef, projectId, refreshKey]);
|
|
60613
|
-
|
|
60714
|
+
useEffect83(() => {
|
|
60614
60715
|
if (pendingSelectionRefreshKeyRef.current === null) return;
|
|
60615
60716
|
pendingSelectionRefreshKeyRef.current = null;
|
|
60616
60717
|
const selection = domEditSelectionRef.current;
|
|
@@ -61127,23 +61228,23 @@ function useDomEditSession({
|
|
|
61127
61228
|
}
|
|
61128
61229
|
|
|
61129
61230
|
// src/hooks/useSdkSelectionSync.ts
|
|
61130
|
-
import { useEffect as
|
|
61231
|
+
import { useEffect as useEffect84 } from "react";
|
|
61131
61232
|
function toHfIds(group, primary) {
|
|
61132
61233
|
const source = group.length > 0 ? group : primary ? [primary] : [];
|
|
61133
61234
|
return source.flatMap((s) => s.hfId ? [s.hfId] : []);
|
|
61134
61235
|
}
|
|
61135
61236
|
function useSdkSelectionSync(session, domEditSelection, domEditGroupSelections) {
|
|
61136
|
-
|
|
61237
|
+
useEffect84(() => {
|
|
61137
61238
|
if (!session) return;
|
|
61138
61239
|
session.setSelection(toHfIds(domEditGroupSelections, domEditSelection));
|
|
61139
61240
|
}, [session, domEditSelection, domEditGroupSelections]);
|
|
61140
61241
|
}
|
|
61141
61242
|
|
|
61142
61243
|
// src/hooks/useStudioSdkSessions.ts
|
|
61143
|
-
import { useEffect as
|
|
61244
|
+
import { useEffect as useEffect86 } from "react";
|
|
61144
61245
|
|
|
61145
61246
|
// src/hooks/useSdkSession.ts
|
|
61146
|
-
import { useState as useState89, useEffect as
|
|
61247
|
+
import { useState as useState89, useEffect as useEffect85, useCallback as useCallback103, useRef as useRef109 } from "react";
|
|
61147
61248
|
import { openComposition as openComposition3 } from "@hyperframes/sdk";
|
|
61148
61249
|
|
|
61149
61250
|
// src/hooks/externalFileReloadBus.ts
|
|
@@ -61203,13 +61304,13 @@ function useSdkSession(projectId, activeCompPath) {
|
|
|
61203
61304
|
const [reloadToken, setReloadToken] = useState89(0);
|
|
61204
61305
|
const reloadTokenRef = useRef109(reloadToken);
|
|
61205
61306
|
reloadTokenRef.current = reloadToken;
|
|
61206
|
-
|
|
61307
|
+
useEffect85(
|
|
61207
61308
|
() => addExternalFileReloadListener((changedPath) => {
|
|
61208
61309
|
if (changedPath === activeCompPathRef.current) setReloadToken((token) => token + 1);
|
|
61209
61310
|
}),
|
|
61210
61311
|
[]
|
|
61211
61312
|
);
|
|
61212
|
-
|
|
61313
|
+
useEffect85(() => {
|
|
61213
61314
|
const generation = ++generationRef.current;
|
|
61214
61315
|
let cancelled = false;
|
|
61215
61316
|
const previous = ownedSessionRef.current;
|
|
@@ -61293,7 +61394,7 @@ function useSdkSession(projectId, activeCompPath) {
|
|
|
61293
61394
|
function useStudioSdkSessions(projectId, activeCompPath, masterCompPath) {
|
|
61294
61395
|
const sdkHandle = useSdkSession(projectId, activeCompPath ?? masterCompPath);
|
|
61295
61396
|
const editFlowSdkSession = activeCompPath ? sdkHandle.session : null;
|
|
61296
|
-
|
|
61397
|
+
useEffect86(() => {
|
|
61297
61398
|
usePreviewVariablesStore.getState().setValues(null);
|
|
61298
61399
|
}, [projectId, activeCompPath]);
|
|
61299
61400
|
return { sdkHandle, editFlowSdkSession };
|
|
@@ -61401,7 +61502,7 @@ async function deleteExternalConflictSnapshot(projectId, filePath) {
|
|
|
61401
61502
|
}
|
|
61402
61503
|
|
|
61403
61504
|
// src/hooks/useExternalFileChangeCoordinator.ts
|
|
61404
|
-
import { useCallback as useCallback104, useEffect as
|
|
61505
|
+
import { useCallback as useCallback104, useEffect as useEffect87, useRef as useRef110, useState as useState90 } from "react";
|
|
61405
61506
|
function testHotAdapter() {
|
|
61406
61507
|
const value = globalThis.__HF_STUDIO_HOT_TEST_ADAPTER__;
|
|
61407
61508
|
if (!value || typeof value !== "object") return null;
|
|
@@ -61458,19 +61559,19 @@ function useExternalFileChangeCoordinator({
|
|
|
61458
61559
|
const blockedRef = useRef110(blocked);
|
|
61459
61560
|
const snapshotWriteTailRef = useRef110(Promise.resolve());
|
|
61460
61561
|
blockedRef.current = blocked;
|
|
61461
|
-
|
|
61562
|
+
useEffect87(() => {
|
|
61462
61563
|
mountedRef.current = true;
|
|
61463
61564
|
return () => {
|
|
61464
61565
|
mountedRef.current = false;
|
|
61465
61566
|
generationRef.current += 1;
|
|
61466
61567
|
};
|
|
61467
61568
|
}, []);
|
|
61468
|
-
|
|
61569
|
+
useEffect87(() => {
|
|
61469
61570
|
generationRef.current += 1;
|
|
61470
61571
|
setBlocked(null);
|
|
61471
61572
|
lastEventIdentityRef.current = null;
|
|
61472
61573
|
}, [projectId, activeCompPath]);
|
|
61473
|
-
|
|
61574
|
+
useEffect87(() => {
|
|
61474
61575
|
if (!projectId || !recoveryFilePath || !loadConflictSnapshot) return;
|
|
61475
61576
|
const generation = ++generationRef.current;
|
|
61476
61577
|
let cancelled = false;
|
|
@@ -61621,7 +61722,7 @@ function useExternalFileChangeCoordinator({
|
|
|
61621
61722
|
reloadAcceptedGeneration
|
|
61622
61723
|
]
|
|
61623
61724
|
);
|
|
61624
|
-
|
|
61725
|
+
useEffect87(() => {
|
|
61625
61726
|
const handler = (payload) => processChange(payload);
|
|
61626
61727
|
const adapter = testHotAdapter();
|
|
61627
61728
|
if (adapter) {
|
|
@@ -62087,7 +62188,7 @@ function useBlockHandlers({
|
|
|
62087
62188
|
}
|
|
62088
62189
|
|
|
62089
62190
|
// src/hooks/useAppHotkeys.ts
|
|
62090
|
-
import { useCallback as useCallback107, useEffect as
|
|
62191
|
+
import { useCallback as useCallback107, useEffect as useEffect88, useRef as useRef112 } from "react";
|
|
62091
62192
|
function iframeContentWindow(iframe) {
|
|
62092
62193
|
try {
|
|
62093
62194
|
return iframe?.contentWindow ?? null;
|
|
@@ -62380,7 +62481,7 @@ function useAppHotkeys({
|
|
|
62380
62481
|
}
|
|
62381
62482
|
if (!isEditableTarget(event.target)) dispatchPlainKey(event, key2, cb);
|
|
62382
62483
|
}, []);
|
|
62383
|
-
|
|
62484
|
+
useEffect88(() => {
|
|
62384
62485
|
window.addEventListener("keydown", handleAppKeyDown, true);
|
|
62385
62486
|
return () => window.removeEventListener("keydown", handleAppKeyDown, true);
|
|
62386
62487
|
}, [handleAppKeyDown]);
|
|
@@ -62398,7 +62499,7 @@ function useAppHotkeys({
|
|
|
62398
62499
|
},
|
|
62399
62500
|
[handleAppKeyDown]
|
|
62400
62501
|
);
|
|
62401
|
-
|
|
62502
|
+
useEffect88(
|
|
62402
62503
|
() => () => {
|
|
62403
62504
|
safeRemoveListener(
|
|
62404
62505
|
previewHotkeyWindowRef.current,
|
|
@@ -62439,7 +62540,7 @@ function useAppHotkeys({
|
|
|
62439
62540
|
},
|
|
62440
62541
|
[handleHistoryHotkey]
|
|
62441
62542
|
);
|
|
62442
|
-
|
|
62543
|
+
useEffect88(
|
|
62443
62544
|
() => () => {
|
|
62444
62545
|
previewHistoryCleanupRef.current?.();
|
|
62445
62546
|
previewHistoryCleanupRef.current = null;
|
|
@@ -62697,7 +62798,7 @@ function useClipboard({
|
|
|
62697
62798
|
}
|
|
62698
62799
|
|
|
62699
62800
|
// src/hooks/useCaptionDetection.ts
|
|
62700
|
-
import { useEffect as
|
|
62801
|
+
import { useEffect as useEffect89 } from "react";
|
|
62701
62802
|
|
|
62702
62803
|
// src/captions/types.ts
|
|
62703
62804
|
var DEFAULT_STYLE = {
|
|
@@ -62949,7 +63050,7 @@ function useCaptionDetection({
|
|
|
62949
63050
|
captionSync,
|
|
62950
63051
|
setRightCollapsed
|
|
62951
63052
|
}) {
|
|
62952
|
-
|
|
63053
|
+
useEffect89(() => {
|
|
62953
63054
|
if (!projectId) return;
|
|
62954
63055
|
let activating = false;
|
|
62955
63056
|
const tryActivateCaptions = () => {
|
|
@@ -63029,7 +63130,7 @@ function useCaptionDetection({
|
|
|
63029
63130
|
window.removeEventListener("message", handleMessage);
|
|
63030
63131
|
};
|
|
63031
63132
|
}, [activeCompPath, projectId, compIdToSrc, captionSync, previewIframeRef]);
|
|
63032
|
-
|
|
63133
|
+
useEffect89(() => {
|
|
63033
63134
|
if (captionEditMode) {
|
|
63034
63135
|
setRightCollapsed(!captionHasSelection);
|
|
63035
63136
|
}
|
|
@@ -63466,7 +63567,7 @@ function useRenderClipContent({
|
|
|
63466
63567
|
}
|
|
63467
63568
|
|
|
63468
63569
|
// src/hooks/useConsoleErrorCapture.ts
|
|
63469
|
-
import { useCallback as useCallback112, useEffect as
|
|
63570
|
+
import { useCallback as useCallback112, useEffect as useEffect90, useRef as useRef116, useState as useState93 } from "react";
|
|
63470
63571
|
function useConsoleErrorCapture(previewIframe) {
|
|
63471
63572
|
const [consoleErrors, setConsoleErrors] = useState93(null);
|
|
63472
63573
|
const consoleErrorsRef = useRef116([]);
|
|
@@ -63474,7 +63575,7 @@ function useConsoleErrorCapture(previewIframe) {
|
|
|
63474
63575
|
consoleErrorsRef.current = [];
|
|
63475
63576
|
setConsoleErrors(null);
|
|
63476
63577
|
}, []);
|
|
63477
|
-
|
|
63578
|
+
useEffect90(() => {
|
|
63478
63579
|
if (!previewIframe) return;
|
|
63479
63580
|
let patchedWin = null;
|
|
63480
63581
|
let origConsoleError = null;
|
|
@@ -63663,7 +63764,7 @@ function useFrameCapture({
|
|
|
63663
63764
|
}
|
|
63664
63765
|
|
|
63665
63766
|
// src/hooks/useLintModal.ts
|
|
63666
|
-
import { useState as useState95, useCallback as useCallback114, useEffect as
|
|
63767
|
+
import { useState as useState95, useCallback as useCallback114, useEffect as useEffect91, useRef as useRef118, useMemo as useMemo54 } from "react";
|
|
63667
63768
|
function parseFinding(f) {
|
|
63668
63769
|
return {
|
|
63669
63770
|
severity: f.severity === "error" ? "error" : "warning",
|
|
@@ -63705,7 +63806,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
63705
63806
|
);
|
|
63706
63807
|
const handleLint = useCallback114(() => runLint(), [runLint]);
|
|
63707
63808
|
const prevProjectIdRef = useRef118(projectId);
|
|
63708
|
-
|
|
63809
|
+
useEffect91(() => {
|
|
63709
63810
|
if (projectId !== prevProjectIdRef.current) {
|
|
63710
63811
|
autoLintRanRef.current = false;
|
|
63711
63812
|
prevProjectIdRef.current = projectId;
|
|
@@ -63714,7 +63815,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
63714
63815
|
autoLintRanRef.current = true;
|
|
63715
63816
|
void runLint({ background: true });
|
|
63716
63817
|
}, [projectId, runLint]);
|
|
63717
|
-
|
|
63818
|
+
useEffect91(() => {
|
|
63718
63819
|
if (!projectId || !refreshKey) return;
|
|
63719
63820
|
const timer = setTimeout(() => void runLint({ background: true }), 1e3);
|
|
63720
63821
|
return () => clearTimeout(timer);
|
|
@@ -63737,7 +63838,7 @@ function useLintModal(projectId, refreshKey) {
|
|
|
63737
63838
|
);
|
|
63738
63839
|
const findingsByElement = useMemo54(() => groupFindings((f) => f.elementId), [groupFindings]);
|
|
63739
63840
|
const findingsByFile = useMemo54(() => groupFindings((f) => f.file), [groupFindings]);
|
|
63740
|
-
|
|
63841
|
+
useEffect91(() => {
|
|
63741
63842
|
usePlayerStore.getState().setLintFindingsByElement(findingsByElement);
|
|
63742
63843
|
}, [findingsByElement]);
|
|
63743
63844
|
return {
|
|
@@ -63835,7 +63936,7 @@ function useCompositionContentLoader({
|
|
|
63835
63936
|
}
|
|
63836
63937
|
|
|
63837
63938
|
// src/hooks/useStudioUrlState.ts
|
|
63838
|
-
import { useCallback as useCallback117, useEffect as
|
|
63939
|
+
import { useCallback as useCallback117, useEffect as useEffect92, useRef as useRef120, useState as useState97 } from "react";
|
|
63839
63940
|
|
|
63840
63941
|
// src/utils/studioUrlState.ts
|
|
63841
63942
|
var VALID_TABS = ["layers", "design", "renders", "slideshow", "variables"];
|
|
@@ -64011,7 +64112,7 @@ function useStudioUrlState({
|
|
|
64011
64112
|
},
|
|
64012
64113
|
[activeCompPath, applyDomSelection, buildDomSelectionFromTarget, previewIframeRef]
|
|
64013
64114
|
);
|
|
64014
|
-
|
|
64115
|
+
useEffect92(() => {
|
|
64015
64116
|
if (!projectId || hydratedSeekRef.current || compositionLoading) return;
|
|
64016
64117
|
const nextTime = duration > 0 ? clampNumber(initialState2.currentTime ?? 0, 0, duration) : Math.max(0, initialState2.currentTime ?? 0);
|
|
64017
64118
|
usePlayerStore.getState().requestSeek(nextTime);
|
|
@@ -64019,7 +64120,7 @@ function useStudioUrlState({
|
|
|
64019
64120
|
hydratedSeekRef.current = true;
|
|
64020
64121
|
}, [projectId, compositionLoading, duration, initialState2.currentTime]);
|
|
64021
64122
|
const selectionHydrationTime = selectionHydrated ? 0 : currentTime;
|
|
64022
|
-
|
|
64123
|
+
useEffect92(() => {
|
|
64023
64124
|
if (!projectId || hydratedSelectionRef.current || compositionLoading) return;
|
|
64024
64125
|
if (!hydratedSeekRef.current) return;
|
|
64025
64126
|
const targetTime = initialState2.currentTime;
|
|
@@ -64046,7 +64147,7 @@ function useStudioUrlState({
|
|
|
64046
64147
|
projectId,
|
|
64047
64148
|
refreshKey
|
|
64048
64149
|
]);
|
|
64049
|
-
|
|
64150
|
+
useEffect92(() => {
|
|
64050
64151
|
if (hydratedInitialTimeRef.current) return;
|
|
64051
64152
|
const targetTime = stableTimeRef.current;
|
|
64052
64153
|
if (targetTime == null) {
|
|
@@ -64056,7 +64157,7 @@ function useStudioUrlState({
|
|
|
64056
64157
|
if (Math.abs(currentTime - targetTime) > 0.05) return;
|
|
64057
64158
|
hydratedInitialTimeRef.current = true;
|
|
64058
64159
|
}, [currentTime]);
|
|
64059
|
-
|
|
64160
|
+
useEffect92(() => {
|
|
64060
64161
|
if (!activeCompPathHydrated) return;
|
|
64061
64162
|
if (!hydratedSeekRef.current) return;
|
|
64062
64163
|
if (!hydratedInitialTimeRef.current) return;
|
|
@@ -64067,12 +64168,12 @@ function useStudioUrlState({
|
|
|
64067
64168
|
}, 200);
|
|
64068
64169
|
return () => window.clearTimeout(handle);
|
|
64069
64170
|
}, [activeCompPathHydrated, buildUrlState, currentTime, duration, isPlaying, projectId]);
|
|
64070
|
-
|
|
64171
|
+
useEffect92(() => {
|
|
64071
64172
|
if (!activeCompPathHydrated) return;
|
|
64072
64173
|
if (!projectId) return;
|
|
64073
64174
|
replaceHash(buildStudioHash(projectId, buildUrlState()));
|
|
64074
64175
|
}, [activeCompPathHydrated, buildUrlState, projectId]);
|
|
64075
|
-
|
|
64176
|
+
useEffect92(() => {
|
|
64076
64177
|
if (!projectId) return;
|
|
64077
64178
|
const onHashChange = () => {
|
|
64078
64179
|
if (parseProjectIdFromHash(window.location.hash) !== projectId) return;
|
|
@@ -64205,9 +64306,10 @@ function PanelLayoutProvider({
|
|
|
64205
64306
|
rightWidth,
|
|
64206
64307
|
adjustPanelWidth,
|
|
64207
64308
|
leftCollapsed,
|
|
64208
|
-
setLeftCollapsed,
|
|
64209
64309
|
rightCollapsed,
|
|
64210
64310
|
setRightCollapsed,
|
|
64311
|
+
effectiveLeftCollapsed,
|
|
64312
|
+
effectiveRightCollapsed,
|
|
64211
64313
|
rightPanelTab,
|
|
64212
64314
|
setRightPanelTab,
|
|
64213
64315
|
rightInspectorPanes,
|
|
@@ -64226,9 +64328,10 @@ function PanelLayoutProvider({
|
|
|
64226
64328
|
rightWidth,
|
|
64227
64329
|
adjustPanelWidth,
|
|
64228
64330
|
leftCollapsed,
|
|
64229
|
-
setLeftCollapsed,
|
|
64230
64331
|
rightCollapsed,
|
|
64231
64332
|
setRightCollapsed,
|
|
64333
|
+
effectiveLeftCollapsed,
|
|
64334
|
+
effectiveRightCollapsed,
|
|
64232
64335
|
rightPanelTab,
|
|
64233
64336
|
setRightPanelTab,
|
|
64234
64337
|
rightInspectorPanes,
|
|
@@ -64244,9 +64347,10 @@ function PanelLayoutProvider({
|
|
|
64244
64347
|
rightWidth,
|
|
64245
64348
|
adjustPanelWidth,
|
|
64246
64349
|
leftCollapsed,
|
|
64247
|
-
setLeftCollapsed,
|
|
64248
64350
|
rightCollapsed,
|
|
64249
64351
|
setRightCollapsed,
|
|
64352
|
+
effectiveLeftCollapsed,
|
|
64353
|
+
effectiveRightCollapsed,
|
|
64250
64354
|
rightPanelTab,
|
|
64251
64355
|
setRightPanelTab,
|
|
64252
64356
|
rightInspectorPanes,
|
|
@@ -64266,7 +64370,7 @@ import {
|
|
|
64266
64370
|
createContext as createContext9,
|
|
64267
64371
|
useCallback as useCallback119,
|
|
64268
64372
|
useContext as useContext9,
|
|
64269
|
-
useEffect as
|
|
64373
|
+
useEffect as useEffect93,
|
|
64270
64374
|
useMemo as useMemo57,
|
|
64271
64375
|
useRef as useRef122,
|
|
64272
64376
|
useState as useState99
|
|
@@ -64304,7 +64408,7 @@ function useViewModeState() {
|
|
|
64304
64408
|
}
|
|
64305
64409
|
return true;
|
|
64306
64410
|
}, []);
|
|
64307
|
-
|
|
64411
|
+
useEffect93(() => {
|
|
64308
64412
|
const onPopState = () => {
|
|
64309
64413
|
const mode = readViewModeFromUrl();
|
|
64310
64414
|
if (mode !== viewMode && !canSetViewMode(mode)) {
|
|
@@ -64586,6 +64690,9 @@ function ViewModeToggle() {
|
|
|
64586
64690
|
}
|
|
64587
64691
|
);
|
|
64588
64692
|
}
|
|
64693
|
+
function shouldOpenInspector(effectiveRightCollapsed, inspectorPanelActive) {
|
|
64694
|
+
return effectiveRightCollapsed || !inspectorPanelActive;
|
|
64695
|
+
}
|
|
64589
64696
|
function StudioHeader({
|
|
64590
64697
|
captureFrameHref,
|
|
64591
64698
|
captureFrameFilename,
|
|
@@ -64597,7 +64704,7 @@ function StudioHeader({
|
|
|
64597
64704
|
onExport
|
|
64598
64705
|
}) {
|
|
64599
64706
|
const { projectId, editHistory, handleUndo, handleRedo, renderQueue } = useStudioShellContext();
|
|
64600
|
-
const {
|
|
64707
|
+
const { effectiveRightCollapsed, setRightCollapsed, setRightPanelTab } = usePanelLayoutContext();
|
|
64601
64708
|
const isRendering = renderQueue.isRendering;
|
|
64602
64709
|
return /* @__PURE__ */ jsxs118("div", { className: "flex items-center justify-between h-10 px-3 bg-neutral-900 border-b border-neutral-800 flex-shrink-0", children: [
|
|
64603
64710
|
/* @__PURE__ */ jsxs118("div", { className: "flex items-center gap-3", children: [
|
|
@@ -64707,7 +64814,7 @@ function StudioHeader({
|
|
|
64707
64814
|
{
|
|
64708
64815
|
type: "button",
|
|
64709
64816
|
onClick: () => {
|
|
64710
|
-
if (
|
|
64817
|
+
if (shouldOpenInspector(effectiveRightCollapsed, inspectorPanelActive)) {
|
|
64711
64818
|
trackStudioEvent("panel_toggle", { panel: "inspector", collapsed: false });
|
|
64712
64819
|
setRightPanelTab("design");
|
|
64713
64820
|
setRightCollapsed(false);
|
|
@@ -64766,10 +64873,10 @@ function StudioHeader({
|
|
|
64766
64873
|
}
|
|
64767
64874
|
|
|
64768
64875
|
// src/hooks/useGestureCommit.ts
|
|
64769
|
-
import { useState as useState101, useCallback as useCallback121, useRef as useRef125, useEffect as
|
|
64876
|
+
import { useState as useState101, useCallback as useCallback121, useRef as useRef125, useEffect as useEffect95 } from "react";
|
|
64770
64877
|
|
|
64771
64878
|
// src/hooks/useGestureRecording.ts
|
|
64772
|
-
import { useCallback as useCallback120, useEffect as
|
|
64879
|
+
import { useCallback as useCallback120, useEffect as useEffect94, useRef as useRef124, useState as useState100 } from "react";
|
|
64773
64880
|
function readBasePosition(element, iframeEl) {
|
|
64774
64881
|
let baseOpacity = 1;
|
|
64775
64882
|
let baseScale = 1;
|
|
@@ -64918,7 +65025,7 @@ function useGestureRecording() {
|
|
|
64918
65025
|
const refs = useRef124(createRecordingRefs());
|
|
64919
65026
|
const samplesRef = useRef124(refs.current.samples);
|
|
64920
65027
|
const trailRef = useRef124(refs.current.trail);
|
|
64921
|
-
|
|
65028
|
+
useEffect94(() => {
|
|
64922
65029
|
const r = refs.current;
|
|
64923
65030
|
return () => {
|
|
64924
65031
|
isRecordingRef.current = false;
|
|
@@ -65301,7 +65408,7 @@ function useGestureCommit({
|
|
|
65301
65408
|
const recordingStartTimeRef = useRef125(0);
|
|
65302
65409
|
const commitInFlightRef = useRef125(false);
|
|
65303
65410
|
const capturedSelectionRef = useRef125(null);
|
|
65304
|
-
|
|
65411
|
+
useEffect95(() => () => clearInterval(recordingAutoStopRef.current), []);
|
|
65305
65412
|
const stopAndCommitRecording = useCallback121(async () => {
|
|
65306
65413
|
clearInterval(recordingAutoStopRef.current);
|
|
65307
65414
|
if (commitInFlightRef.current) {
|
|
@@ -65646,7 +65753,7 @@ import {
|
|
|
65646
65753
|
} from "react";
|
|
65647
65754
|
|
|
65648
65755
|
// src/components/sidebar/CompositionsTab.tsx
|
|
65649
|
-
import { memo as memo37, useCallback as useCallback122, useEffect as
|
|
65756
|
+
import { memo as memo37, useCallback as useCallback122, useEffect as useEffect96, useRef as useRef126, useState as useState102 } from "react";
|
|
65650
65757
|
import { jsx as jsx144, jsxs as jsxs120 } from "react/jsx-runtime";
|
|
65651
65758
|
var DEFAULT_PREVIEW_STAGE = { width: 1920, height: 1080 };
|
|
65652
65759
|
var CARD_W = 80;
|
|
@@ -65764,10 +65871,10 @@ function CompCard({
|
|
|
65764
65871
|
});
|
|
65765
65872
|
const thumbnailOffsetX = (CARD_W - stageSize.width * previewScale) / 2;
|
|
65766
65873
|
const thumbnailOffsetY = (CARD_H - stageSize.height * previewScale) / 2;
|
|
65767
|
-
|
|
65874
|
+
useEffect96(() => {
|
|
65768
65875
|
if (hovered) requestIframePlaybackSync(true);
|
|
65769
65876
|
}, [hovered, requestIframePlaybackSync]);
|
|
65770
|
-
|
|
65877
|
+
useEffect96(() => {
|
|
65771
65878
|
return () => {
|
|
65772
65879
|
if (hoverTimer.current) clearTimeout(hoverTimer.current);
|
|
65773
65880
|
if (syncTimer.current) clearTimeout(syncTimer.current);
|
|
@@ -65943,7 +66050,7 @@ var CompositionsTab = memo37(function CompositionsTab2({
|
|
|
65943
66050
|
});
|
|
65944
66051
|
|
|
65945
66052
|
// src/components/sidebar/AssetsTab.tsx
|
|
65946
|
-
import { memo as memo38, useState as useState107, useCallback as useCallback125, useRef as useRef129, useMemo as useMemo60, useEffect as
|
|
66053
|
+
import { memo as memo38, useState as useState107, useCallback as useCallback125, useRef as useRef129, useMemo as useMemo60, useEffect as useEffect101 } from "react";
|
|
65947
66054
|
|
|
65948
66055
|
// src/components/sidebar/assetHelpers.ts
|
|
65949
66056
|
function getCategory(path) {
|
|
@@ -65993,7 +66100,7 @@ var CATEGORY_LABELS = {
|
|
|
65993
66100
|
var FILTER_ORDER = ["audio", "images", "video", "fonts"];
|
|
65994
66101
|
|
|
65995
66102
|
// src/components/sidebar/AudioRow.tsx
|
|
65996
|
-
import { useState as useState103, useRef as useRef127, useEffect as
|
|
66103
|
+
import { useState as useState103, useRef as useRef127, useEffect as useEffect97, useCallback as useCallback123 } from "react";
|
|
65997
66104
|
|
|
65998
66105
|
// src/components/sidebar/AssetContextMenu.tsx
|
|
65999
66106
|
import { jsx as jsx145, jsxs as jsxs121 } from "react/jsx-runtime";
|
|
@@ -66168,14 +66275,14 @@ function AudioRow({
|
|
|
66168
66275
|
clearPreviewAsset
|
|
66169
66276
|
]
|
|
66170
66277
|
);
|
|
66171
|
-
|
|
66278
|
+
useEffect97(() => {
|
|
66172
66279
|
return () => {
|
|
66173
66280
|
cancelAnimationFrame(animRef.current);
|
|
66174
66281
|
audioRef.current?.pause();
|
|
66175
66282
|
actxRef.current?.close();
|
|
66176
66283
|
};
|
|
66177
66284
|
}, []);
|
|
66178
|
-
|
|
66285
|
+
useEffect97(() => {
|
|
66179
66286
|
if (playing) {
|
|
66180
66287
|
const barCount = 24;
|
|
66181
66288
|
const loop = () => {
|
|
@@ -66313,7 +66420,7 @@ function AudioRow({
|
|
|
66313
66420
|
}
|
|
66314
66421
|
|
|
66315
66422
|
// src/components/sidebar/GlobalAssetsView.tsx
|
|
66316
|
-
import { useEffect as
|
|
66423
|
+
import { useEffect as useEffect98, useMemo as useMemo59, useState as useState104 } from "react";
|
|
66317
66424
|
import { jsx as jsx147, jsxs as jsxs123 } from "react/jsx-runtime";
|
|
66318
66425
|
function globalAssetRows(records, query = "") {
|
|
66319
66426
|
const q = query.trim().toLowerCase();
|
|
@@ -66329,7 +66436,7 @@ function globalAssetRows(records, query = "") {
|
|
|
66329
66436
|
}
|
|
66330
66437
|
function GlobalAssetsView({ searchQuery }) {
|
|
66331
66438
|
const [records, setRecords] = useState104(null);
|
|
66332
|
-
|
|
66439
|
+
useEffect98(() => {
|
|
66333
66440
|
let cancelled = false;
|
|
66334
66441
|
fetch("/api/assets/global").then((r) => r.ok ? r.json() : { assets: [] }).then((d) => {
|
|
66335
66442
|
if (!cancelled) setRecords(Array.isArray(d.assets) ? d.assets : []);
|
|
@@ -66372,10 +66479,10 @@ function GlobalAssetsView({ searchQuery }) {
|
|
|
66372
66479
|
}
|
|
66373
66480
|
|
|
66374
66481
|
// src/components/sidebar/AssetCard.tsx
|
|
66375
|
-
import { useState as useState106, useEffect as
|
|
66482
|
+
import { useState as useState106, useEffect as useEffect100, useRef as useRef128, useCallback as useCallback124 } from "react";
|
|
66376
66483
|
|
|
66377
66484
|
// src/components/ui/VideoFrameThumbnail.tsx
|
|
66378
|
-
import { useState as useState105, useEffect as
|
|
66485
|
+
import { useState as useState105, useEffect as useEffect99 } from "react";
|
|
66379
66486
|
import { jsx as jsx148 } from "react/jsx-runtime";
|
|
66380
66487
|
function VideoFrameThumbnail({
|
|
66381
66488
|
src,
|
|
@@ -66383,7 +66490,7 @@ function VideoFrameThumbnail({
|
|
|
66383
66490
|
}) {
|
|
66384
66491
|
const [frame, setFrame] = useState105(null);
|
|
66385
66492
|
const [failed2, setFailed] = useState105(false);
|
|
66386
|
-
|
|
66493
|
+
useEffect99(() => {
|
|
66387
66494
|
setFailed(false);
|
|
66388
66495
|
const video = document.createElement("video");
|
|
66389
66496
|
video.crossOrigin = "anonymous";
|
|
@@ -66436,7 +66543,7 @@ function openAssetContextMenu(e, setContextMenu) {
|
|
|
66436
66543
|
}
|
|
66437
66544
|
function useProbedDuration(src, skip) {
|
|
66438
66545
|
const [duration, setDuration] = useState106(void 0);
|
|
66439
|
-
|
|
66546
|
+
useEffect100(() => {
|
|
66440
66547
|
if (skip) return;
|
|
66441
66548
|
let cancelled = false;
|
|
66442
66549
|
let retryTimer;
|
|
@@ -66709,7 +66816,7 @@ var AssetsTab = memo38(function AssetsTab2({
|
|
|
66709
66816
|
const [manifest, setManifest] = useState107(/* @__PURE__ */ new Map());
|
|
66710
66817
|
const manifest404Ref = useRef129(/* @__PURE__ */ new Set());
|
|
66711
66818
|
const assetsKey = assets.join("|");
|
|
66712
|
-
|
|
66819
|
+
useEffect101(() => {
|
|
66713
66820
|
if (manifest404Ref.current.has(projectId)) return;
|
|
66714
66821
|
let cancelled = false;
|
|
66715
66822
|
fetch(`/api/projects/${projectId}/preview/.media/manifest.jsonl`).then((r) => {
|
|
@@ -67028,7 +67135,7 @@ var AssetsTab = memo38(function AssetsTab2({
|
|
|
67028
67135
|
});
|
|
67029
67136
|
|
|
67030
67137
|
// src/components/sidebar/BlocksTab.tsx
|
|
67031
|
-
import { memo as memo39, useState as useState108, useCallback as useCallback126, useRef as useRef130, useEffect as
|
|
67138
|
+
import { memo as memo39, useState as useState108, useCallback as useCallback126, useRef as useRef130, useEffect as useEffect102 } from "react";
|
|
67032
67139
|
import { createPortal as createPortal7 } from "react-dom";
|
|
67033
67140
|
import { jsx as jsx151, jsxs as jsxs126 } from "react/jsx-runtime";
|
|
67034
67141
|
var BlocksTab = memo39(function BlocksTab2({ onAddBlock, onPreviewBlock }) {
|
|
@@ -67257,7 +67364,7 @@ function BlockCard({
|
|
|
67257
67364
|
setHovered(false);
|
|
67258
67365
|
onPreview?.(null);
|
|
67259
67366
|
}, [onPreview]);
|
|
67260
|
-
|
|
67367
|
+
useEffect102(() => {
|
|
67261
67368
|
return () => {
|
|
67262
67369
|
if (hoverTimer.current) clearTimeout(hoverTimer.current);
|
|
67263
67370
|
};
|
|
@@ -67419,7 +67526,7 @@ function PromptPreviewModal({
|
|
|
67419
67526
|
const [value, setValue] = useState108(prompt);
|
|
67420
67527
|
const [copied, setCopied] = useState108(false);
|
|
67421
67528
|
const textareaRef = useRef130(null);
|
|
67422
|
-
|
|
67529
|
+
useEffect102(() => {
|
|
67423
67530
|
requestAnimationFrame(() => textareaRef.current?.focus());
|
|
67424
67531
|
}, []);
|
|
67425
67532
|
const handleCopy = useCallback126(() => {
|
|
@@ -67508,7 +67615,11 @@ function PromptPreviewModal({
|
|
|
67508
67615
|
import { Fragment as Fragment47, jsx as jsx152, jsxs as jsxs127 } from "react/jsx-runtime";
|
|
67509
67616
|
var STORAGE_KEY = "hf-studio-sidebar-tab";
|
|
67510
67617
|
function getPersistedTab() {
|
|
67511
|
-
|
|
67618
|
+
let stored = null;
|
|
67619
|
+
try {
|
|
67620
|
+
stored = safeLocalStorage()?.getItem(STORAGE_KEY) ?? null;
|
|
67621
|
+
} catch {
|
|
67622
|
+
}
|
|
67512
67623
|
if (stored === "assets") return "assets";
|
|
67513
67624
|
if (stored === "code") return "code";
|
|
67514
67625
|
if (stored === "blocks") return "blocks";
|
|
@@ -67551,7 +67662,10 @@ var LeftSidebar = memo40(
|
|
|
67551
67662
|
tabRef.current = tab;
|
|
67552
67663
|
const selectTab = useCallback127((t) => {
|
|
67553
67664
|
setTab(t);
|
|
67554
|
-
|
|
67665
|
+
try {
|
|
67666
|
+
safeLocalStorage()?.setItem(STORAGE_KEY, t);
|
|
67667
|
+
} catch {
|
|
67668
|
+
}
|
|
67555
67669
|
trackStudioEvent("tab_switch", { panel: "left_sidebar", tab: t });
|
|
67556
67670
|
}, []);
|
|
67557
67671
|
const getTab = useCallback127(() => tabRef.current, []);
|
|
@@ -67870,7 +67984,7 @@ function StudioLeftSidebar({
|
|
|
67870
67984
|
onAddCompositionToTimeline
|
|
67871
67985
|
}) {
|
|
67872
67986
|
const {
|
|
67873
|
-
|
|
67987
|
+
effectiveLeftCollapsed,
|
|
67874
67988
|
leftWidth,
|
|
67875
67989
|
adjustPanelWidth,
|
|
67876
67990
|
toggleLeftSidebar,
|
|
@@ -67903,7 +68017,7 @@ function StudioLeftSidebar({
|
|
|
67903
68017
|
},
|
|
67904
68018
|
[renderQueue, waitForPendingDomEditSaves]
|
|
67905
68019
|
);
|
|
67906
|
-
if (
|
|
68020
|
+
if (effectiveLeftCollapsed) {
|
|
67907
68021
|
return /* @__PURE__ */ jsx154("div", { className: "mr-0.5 flex w-10 flex-shrink-0 flex-col items-center rounded-lg border border-neutral-800/50 bg-neutral-950 pt-1", children: /* @__PURE__ */ jsx154(
|
|
67908
68022
|
"button",
|
|
67909
68023
|
{
|
|
@@ -68015,10 +68129,10 @@ function StudioLeftSidebar({
|
|
|
68015
68129
|
}
|
|
68016
68130
|
|
|
68017
68131
|
// src/components/StudioRightPanel.tsx
|
|
68018
|
-
import { useCallback as useCallback144, useEffect as
|
|
68132
|
+
import { useCallback as useCallback144, useEffect as useEffect109, useRef as useRef137 } from "react";
|
|
68019
68133
|
|
|
68020
68134
|
// src/components/editor/LayersPanel.tsx
|
|
68021
|
-
import { memo as memo41, useState as useState112, useCallback as useCallback130, useEffect as
|
|
68135
|
+
import { memo as memo41, useState as useState112, useCallback as useCallback130, useEffect as useEffect103, useRef as useRef133 } from "react";
|
|
68022
68136
|
|
|
68023
68137
|
// src/components/editor/useLayerDrag.ts
|
|
68024
68138
|
import { useRef as useRef132, useState as useState111, useCallback as useCallback129 } from "react";
|
|
@@ -68321,10 +68435,10 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
68321
68435
|
});
|
|
68322
68436
|
setLayers(sortLayersByZIndex(items));
|
|
68323
68437
|
}, [previewIframeRef, activeCompPath, isMasterView, activeGroupElement, setActiveGroupElement]);
|
|
68324
|
-
|
|
68438
|
+
useEffect103(() => {
|
|
68325
68439
|
collectLayers();
|
|
68326
68440
|
}, [collectLayers, refreshKey, zEditVersion]);
|
|
68327
|
-
|
|
68441
|
+
useEffect103(() => {
|
|
68328
68442
|
const iframe = previewIframeRef.current;
|
|
68329
68443
|
if (!iframe) return;
|
|
68330
68444
|
const handleLoad = () => {
|
|
@@ -68334,13 +68448,13 @@ var LayersPanel = memo41(function LayersPanel2() {
|
|
|
68334
68448
|
iframe.addEventListener("load", handleLoad);
|
|
68335
68449
|
return () => iframe.removeEventListener("load", handleLoad);
|
|
68336
68450
|
}, [previewIframeRef, collectLayers]);
|
|
68337
|
-
|
|
68451
|
+
useEffect103(() => {
|
|
68338
68452
|
if (!compositionLoading) {
|
|
68339
68453
|
const timer = setTimeout(collectLayers, 100);
|
|
68340
68454
|
return () => clearTimeout(timer);
|
|
68341
68455
|
}
|
|
68342
68456
|
}, [compositionLoading, collectLayers]);
|
|
68343
|
-
|
|
68457
|
+
useEffect103(() => {
|
|
68344
68458
|
const throttle = createRafThrottle(collectLayers, 100);
|
|
68345
68459
|
const unsubscribe = liveTime.subscribe(throttle.invoke);
|
|
68346
68460
|
return () => {
|
|
@@ -69186,7 +69300,7 @@ function ParamControl({
|
|
|
69186
69300
|
}
|
|
69187
69301
|
|
|
69188
69302
|
// src/components/renders/RenderQueue.tsx
|
|
69189
|
-
import { memo as memo46, useState as useState116, useRef as useRef134, useEffect as
|
|
69303
|
+
import { memo as memo46, useState as useState116, useRef as useRef134, useEffect as useEffect104, useLayoutEffect as useLayoutEffect8, useId as useId6 } from "react";
|
|
69190
69304
|
import { createPortal as createPortal8 } from "react-dom";
|
|
69191
69305
|
import { CANVAS_DIMENSIONS } from "@hyperframes/parsers";
|
|
69192
69306
|
|
|
@@ -69482,7 +69596,7 @@ function FormatInfoTooltip({ format }) {
|
|
|
69482
69596
|
const hide = () => {
|
|
69483
69597
|
timeoutRef.current = setTimeout(() => setOpen(false), 120);
|
|
69484
69598
|
};
|
|
69485
|
-
|
|
69599
|
+
useEffect104(() => () => clearTimeout(timeoutRef.current), []);
|
|
69486
69600
|
useLayoutEffect8(() => {
|
|
69487
69601
|
if (!open) return;
|
|
69488
69602
|
const el = triggerRef.current;
|
|
@@ -69496,7 +69610,7 @@ function FormatInfoTooltip({ format }) {
|
|
|
69496
69610
|
)
|
|
69497
69611
|
);
|
|
69498
69612
|
}, [open]);
|
|
69499
|
-
|
|
69613
|
+
useEffect104(() => {
|
|
69500
69614
|
if (!open) return;
|
|
69501
69615
|
const onKeyDown = (e) => {
|
|
69502
69616
|
if (e.key === "Escape") setOpen(false);
|
|
@@ -69708,7 +69822,7 @@ var RenderQueue = memo46(function RenderQueue2({
|
|
|
69708
69822
|
compositionDimensions
|
|
69709
69823
|
}) {
|
|
69710
69824
|
const listRef = useRef134(null);
|
|
69711
|
-
|
|
69825
|
+
useEffect104(() => {
|
|
69712
69826
|
if (listRef.current) {
|
|
69713
69827
|
listRef.current.scrollTo({ top: listRef.current.scrollHeight, behavior: "smooth" });
|
|
69714
69828
|
}
|
|
@@ -69816,7 +69930,7 @@ var RenderQueue = memo46(function RenderQueue2({
|
|
|
69816
69930
|
});
|
|
69817
69931
|
|
|
69818
69932
|
// src/components/panels/SlideshowPanel.tsx
|
|
69819
|
-
import { useState as useState118, useEffect as
|
|
69933
|
+
import { useState as useState118, useEffect as useEffect105, useCallback as useCallback136, useRef as useRef135 } from "react";
|
|
69820
69934
|
import { parseSlideshowManifest } from "@hyperframes/core/slideshow";
|
|
69821
69935
|
|
|
69822
69936
|
// src/components/panels/SlideshowSubPanels.tsx
|
|
@@ -70455,7 +70569,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
70455
70569
|
const { domEditSelection } = useDomEditSelectionContext();
|
|
70456
70570
|
const manifestRef = useRef135(manifest);
|
|
70457
70571
|
const notesCtrlRef = useRef135(makeSlideshowNotesController());
|
|
70458
|
-
|
|
70572
|
+
useEffect105(() => {
|
|
70459
70573
|
if (!compHtml) {
|
|
70460
70574
|
notesCtrlRef.current.flush();
|
|
70461
70575
|
setManifest({ slides: [] });
|
|
@@ -70489,7 +70603,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
70489
70603
|
},
|
|
70490
70604
|
[onPersistNotes]
|
|
70491
70605
|
);
|
|
70492
|
-
|
|
70606
|
+
useEffect105(() => {
|
|
70493
70607
|
const ctrl = notesCtrlRef.current;
|
|
70494
70608
|
return () => {
|
|
70495
70609
|
ctrl.flush();
|
|
@@ -70709,7 +70823,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
|
|
|
70709
70823
|
}
|
|
70710
70824
|
|
|
70711
70825
|
// src/components/panels/VariablesPanel.tsx
|
|
70712
|
-
import { memo as memo47, useCallback as useCallback140, useEffect as
|
|
70826
|
+
import { memo as memo47, useCallback as useCallback140, useEffect as useEffect107, useMemo as useMemo61, useState as useState122 } from "react";
|
|
70713
70827
|
|
|
70714
70828
|
// src/hooks/useVariablesPersist.ts
|
|
70715
70829
|
import { useCallback as useCallback137 } from "react";
|
|
@@ -70763,7 +70877,7 @@ function useVariablesPersist({
|
|
|
70763
70877
|
import { useCallback as useCallback139, useState as useState121 } from "react";
|
|
70764
70878
|
|
|
70765
70879
|
// src/hooks/useProjectCompositionVariables.ts
|
|
70766
|
-
import { useCallback as useCallback138, useEffect as
|
|
70880
|
+
import { useCallback as useCallback138, useEffect as useEffect106, useState as useState119 } from "react";
|
|
70767
70881
|
import { openComposition as openComposition4 } from "@hyperframes/sdk";
|
|
70768
70882
|
async function readGroup(path, readProjectFile) {
|
|
70769
70883
|
let content;
|
|
@@ -70787,7 +70901,7 @@ async function readGroup(path, readProjectFile) {
|
|
|
70787
70901
|
}
|
|
70788
70902
|
function useProjectCompositionVariables(fileTree, excludePath, readProjectFile, refreshKey) {
|
|
70789
70903
|
const [groups, setGroups] = useState119([]);
|
|
70790
|
-
|
|
70904
|
+
useEffect106(() => {
|
|
70791
70905
|
let cancelled = false;
|
|
70792
70906
|
const htmlFiles = fileTree.filter((p) => p.endsWith(".html") && p !== excludePath);
|
|
70793
70907
|
void (async () => {
|
|
@@ -71397,7 +71511,7 @@ var VariablesPanel = memo47(function VariablesPanel2({
|
|
|
71397
71511
|
const previewValues = usePreviewVariablesStore((s) => s.values);
|
|
71398
71512
|
const setPreviewValues = usePreviewVariablesStore((s) => s.setValues);
|
|
71399
71513
|
const [revision, setRevision] = useState122(0);
|
|
71400
|
-
|
|
71514
|
+
useEffect107(() => {
|
|
71401
71515
|
if (!sdkSession) return;
|
|
71402
71516
|
return sdkSession.on("change", () => setRevision((r) => r + 1));
|
|
71403
71517
|
}, [sdkSession]);
|
|
@@ -71767,7 +71881,7 @@ function useSlideshowPersist({
|
|
|
71767
71881
|
}
|
|
71768
71882
|
|
|
71769
71883
|
// src/hooks/useSlideshowTabState.ts
|
|
71770
|
-
import { useEffect as
|
|
71884
|
+
import { useEffect as useEffect108, useMemo as useMemo62 } from "react";
|
|
71771
71885
|
import { SLIDESHOW_ISLAND_TYPE as SLIDESHOW_ISLAND_TYPE2, slideshowIslandRegex as slideshowIslandRegex2 } from "@hyperframes/core/slideshow";
|
|
71772
71886
|
function useSlideshowTabState(params) {
|
|
71773
71887
|
const { editingFileContent, previewIframeRef, refreshKey, rightPanelTab, setRightPanelTab } = params;
|
|
@@ -71788,7 +71902,7 @@ function useSlideshowTabState(params) {
|
|
|
71788
71902
|
return [];
|
|
71789
71903
|
}
|
|
71790
71904
|
}, [previewIframeRef, rightPanelTab, refreshKey]);
|
|
71791
|
-
|
|
71905
|
+
useEffect108(() => {
|
|
71792
71906
|
if (rightPanelTab === "slideshow" && !isSlideshowComposition) {
|
|
71793
71907
|
setRightPanelTab("renders");
|
|
71794
71908
|
}
|
|
@@ -72226,7 +72340,7 @@ function StudioRightPanel({
|
|
|
72226
72340
|
handleInspectorSplitResizeEnd
|
|
72227
72341
|
} = useInspectorSplitResize();
|
|
72228
72342
|
const backgroundRemovalAbortRef = useRef137(null);
|
|
72229
|
-
|
|
72343
|
+
useEffect109(
|
|
72230
72344
|
() => () => {
|
|
72231
72345
|
backgroundRemovalAbortRef.current?.abort();
|
|
72232
72346
|
},
|
|
@@ -72594,7 +72708,7 @@ function StudioRightPanel({
|
|
|
72594
72708
|
}
|
|
72595
72709
|
|
|
72596
72710
|
// src/components/TimelineToolbar.tsx
|
|
72597
|
-
import { useEffect as
|
|
72711
|
+
import { useEffect as useEffect111, useRef as useRef138 } from "react";
|
|
72598
72712
|
import { Image as Image2, Magnet, MagnifyingGlassMinus, MagnifyingGlassPlus } from "@phosphor-icons/react";
|
|
72599
72713
|
|
|
72600
72714
|
// src/hooks/useEnableKeyframes.ts
|
|
@@ -72933,7 +73047,7 @@ function useEnableKeyframes(sessionRef) {
|
|
|
72933
73047
|
}
|
|
72934
73048
|
|
|
72935
73049
|
// src/hooks/useKeyframeKeyboard.ts
|
|
72936
|
-
import { useEffect as
|
|
73050
|
+
import { useEffect as useEffect110, useCallback as useCallback146 } from "react";
|
|
72937
73051
|
function isTextInput(el) {
|
|
72938
73052
|
if (!el) return false;
|
|
72939
73053
|
const tag = el.tagName;
|
|
@@ -73001,7 +73115,7 @@ function useKeyframeKeyboard({
|
|
|
73001
73115
|
onNudgeKeyframe
|
|
73002
73116
|
]
|
|
73003
73117
|
);
|
|
73004
|
-
|
|
73118
|
+
useEffect110(() => {
|
|
73005
73119
|
if (!enabled2) return;
|
|
73006
73120
|
window.addEventListener("keydown", handler, { capture: true });
|
|
73007
73121
|
return () => window.removeEventListener("keydown", handler, { capture: true });
|
|
@@ -73089,7 +73203,7 @@ function TimelineToolbar({ domEditSession, onSplitElement }) {
|
|
|
73089
73203
|
enabled: Boolean(onToggleKeyframe),
|
|
73090
73204
|
onAddKeyframe: onToggleKeyframe
|
|
73091
73205
|
});
|
|
73092
|
-
|
|
73206
|
+
useEffect111(() => {
|
|
73093
73207
|
const onKeyDown = (e) => {
|
|
73094
73208
|
if (e.key !== "n" && e.key !== "N") return;
|
|
73095
73209
|
if (e.metaKey || e.ctrlKey || e.altKey) return;
|
|
@@ -73367,7 +73481,7 @@ import { useState as useState131 } from "react";
|
|
|
73367
73481
|
import { Copy as Copy2, Check as Check2 } from "@phosphor-icons/react";
|
|
73368
73482
|
|
|
73369
73483
|
// src/hooks/useStoryboard.ts
|
|
73370
|
-
import { useCallback as useCallback147, useEffect as
|
|
73484
|
+
import { useCallback as useCallback147, useEffect as useEffect112, useRef as useRef139, useState as useState124 } from "react";
|
|
73371
73485
|
function useStoryboard(projectId) {
|
|
73372
73486
|
const [data, setData] = useState124(null);
|
|
73373
73487
|
const [loading, setLoading] = useState124(true);
|
|
@@ -73376,7 +73490,7 @@ function useStoryboard(projectId) {
|
|
|
73376
73490
|
const hasDataRef = useRef139(false);
|
|
73377
73491
|
const lastProjectRef = useRef139(null);
|
|
73378
73492
|
const reload = useCallback147(() => setReloadKey((k) => k + 1), []);
|
|
73379
|
-
|
|
73493
|
+
useEffect112(() => {
|
|
73380
73494
|
if (!projectId) return;
|
|
73381
73495
|
let cancelled = false;
|
|
73382
73496
|
if (lastProjectRef.current !== projectId) {
|
|
@@ -73408,7 +73522,7 @@ function useStoryboard(projectId) {
|
|
|
73408
73522
|
}
|
|
73409
73523
|
|
|
73410
73524
|
// src/hooks/useProjectSignaturePoll.ts
|
|
73411
|
-
import { useEffect as
|
|
73525
|
+
import { useEffect as useEffect113, useRef as useRef140 } from "react";
|
|
73412
73526
|
var POLL_INTERVAL_MS = 2e3;
|
|
73413
73527
|
async function fetchProjectSignature(projectId) {
|
|
73414
73528
|
try {
|
|
@@ -73425,7 +73539,7 @@ function useProjectSignaturePoll(projectId, currentSignature, onChange) {
|
|
|
73425
73539
|
const onChangeRef = useRef140(onChange);
|
|
73426
73540
|
signatureRef.current = currentSignature;
|
|
73427
73541
|
onChangeRef.current = onChange;
|
|
73428
|
-
|
|
73542
|
+
useEffect113(() => {
|
|
73429
73543
|
if (!projectId) return;
|
|
73430
73544
|
let disposed = false;
|
|
73431
73545
|
let inFlight = false;
|
|
@@ -73452,7 +73566,7 @@ function useProjectSignaturePoll(projectId, currentSignature, onChange) {
|
|
|
73452
73566
|
}
|
|
73453
73567
|
|
|
73454
73568
|
// src/components/storyboard/StoryboardLoaded.tsx
|
|
73455
|
-
import { useEffect as
|
|
73569
|
+
import { useEffect as useEffect119, useMemo as useMemo65, useState as useState130 } from "react";
|
|
73456
73570
|
|
|
73457
73571
|
// src/components/storyboard/StoryboardDirection.tsx
|
|
73458
73572
|
import { jsx as jsx172, jsxs as jsxs144 } from "react/jsx-runtime";
|
|
@@ -73475,7 +73589,7 @@ function StoryboardDirection({ globals, frameCount }) {
|
|
|
73475
73589
|
}
|
|
73476
73590
|
|
|
73477
73591
|
// src/components/storyboard/FramePoster.tsx
|
|
73478
|
-
import { useEffect as
|
|
73592
|
+
import { useEffect as useEffect114, useState as useState125 } from "react";
|
|
73479
73593
|
import { jsx as jsx173 } from "react/jsx-runtime";
|
|
73480
73594
|
function FramePoster({
|
|
73481
73595
|
projectId,
|
|
@@ -73486,7 +73600,7 @@ function FramePoster({
|
|
|
73486
73600
|
posterVersion
|
|
73487
73601
|
}) {
|
|
73488
73602
|
const [failed2, setFailed] = useState125(false);
|
|
73489
|
-
|
|
73603
|
+
useEffect114(() => setFailed(false), [src, seconds, posterVersion]);
|
|
73490
73604
|
if (failed2) {
|
|
73491
73605
|
return /* @__PURE__ */ jsx173("div", { className: "flex h-full w-full items-center justify-center text-[11px] text-neutral-600", children: "Preview unavailable" });
|
|
73492
73606
|
}
|
|
@@ -73685,7 +73799,7 @@ function StoryboardScriptPanel({ script }) {
|
|
|
73685
73799
|
}
|
|
73686
73800
|
|
|
73687
73801
|
// src/components/storyboard/StoryboardSourceEditor.tsx
|
|
73688
|
-
import { useCallback as useCallback148, useEffect as
|
|
73802
|
+
import { useCallback as useCallback148, useEffect as useEffect115, useMemo as useMemo63, useRef as useRef141, useState as useState126 } from "react";
|
|
73689
73803
|
import { marked } from "marked";
|
|
73690
73804
|
import DOMPurify from "dompurify";
|
|
73691
73805
|
import { jsx as jsx177, jsxs as jsxs147 } from "react/jsx-runtime";
|
|
@@ -73697,7 +73811,7 @@ function useEditableFile(path, onSaved) {
|
|
|
73697
73811
|
const [loading, setLoading] = useState126(true);
|
|
73698
73812
|
const [saving, setSaving] = useState126(false);
|
|
73699
73813
|
const [error, setError] = useState126(null);
|
|
73700
|
-
|
|
73814
|
+
useEffect115(() => {
|
|
73701
73815
|
if (!path) return;
|
|
73702
73816
|
let cancelled = false;
|
|
73703
73817
|
setLoading(true);
|
|
@@ -73735,7 +73849,7 @@ function hardenLinks(node) {
|
|
|
73735
73849
|
function useMarkdownPreview(source) {
|
|
73736
73850
|
const [debounced, setDebounced] = useState126(source);
|
|
73737
73851
|
const primed = useRef141(false);
|
|
73738
|
-
|
|
73852
|
+
useEffect115(() => {
|
|
73739
73853
|
if (!primed.current && source !== "") {
|
|
73740
73854
|
primed.current = true;
|
|
73741
73855
|
setDebounced(source);
|
|
@@ -73767,8 +73881,8 @@ function StoryboardSourceEditor({
|
|
|
73767
73881
|
const activePath = files.some((f) => f.path === selected) ? selected : files[0]?.path ?? "";
|
|
73768
73882
|
const file = useEditableFile(activePath, onSaved);
|
|
73769
73883
|
const previewHtml = useMarkdownPreview(file.content);
|
|
73770
|
-
|
|
73771
|
-
|
|
73884
|
+
useEffect115(() => onDirtyChange?.(file.dirty), [onDirtyChange, file.dirty]);
|
|
73885
|
+
useEffect115(() => {
|
|
73772
73886
|
if (!file.dirty) return;
|
|
73773
73887
|
const onBeforeUnload = (event) => {
|
|
73774
73888
|
event.preventDefault();
|
|
@@ -73840,11 +73954,11 @@ function StoryboardSourceEditor({
|
|
|
73840
73954
|
}
|
|
73841
73955
|
|
|
73842
73956
|
// src/components/storyboard/StoryboardFrameFocus.tsx
|
|
73843
|
-
import { useCallback as useCallback149, useEffect as
|
|
73957
|
+
import { useCallback as useCallback149, useEffect as useEffect117, useState as useState128 } from "react";
|
|
73844
73958
|
import { setFrameVoiceover } from "@hyperframes/core/storyboard";
|
|
73845
73959
|
|
|
73846
73960
|
// src/components/storyboard/AgentChatMessageButton.tsx
|
|
73847
|
-
import { useEffect as
|
|
73961
|
+
import { useEffect as useEffect116, useState as useState127 } from "react";
|
|
73848
73962
|
import { jsx as jsx178 } from "react/jsx-runtime";
|
|
73849
73963
|
var APPLY_STORYBOARD_FEEDBACK_MESSAGE = "Read the storyboard feedback I saved in .hyperframes/frame-comments.json and revise the frames.";
|
|
73850
73964
|
function AgentChatMessageButton({
|
|
@@ -73853,7 +73967,7 @@ function AgentChatMessageButton({
|
|
|
73853
73967
|
onCopied
|
|
73854
73968
|
}) {
|
|
73855
73969
|
const [copyState, setCopyState] = useState127("idle");
|
|
73856
|
-
|
|
73970
|
+
useEffect116(() => {
|
|
73857
73971
|
if (copyState !== "copied") return;
|
|
73858
73972
|
const timeout = window.setTimeout(() => setCopyState("again"), 3e3);
|
|
73859
73973
|
return () => window.clearTimeout(timeout);
|
|
@@ -73926,7 +74040,7 @@ function StoryboardFrameFocus({
|
|
|
73926
74040
|
const saved = await applyEdit((src) => setFrameVoiceover(src, frame.index, draft));
|
|
73927
74041
|
if (saved) setSavedVoiceover(draft);
|
|
73928
74042
|
}, [applyEdit, frame.index, draft]);
|
|
73929
|
-
|
|
74043
|
+
useEffect117(() => {
|
|
73930
74044
|
if (!dirty) return;
|
|
73931
74045
|
const onBeforeUnload = (e) => {
|
|
73932
74046
|
e.preventDefault();
|
|
@@ -73938,14 +74052,14 @@ function StoryboardFrameFocus({
|
|
|
73938
74052
|
() => !dirty || window.confirm("Discard unsaved voiceover changes?"),
|
|
73939
74053
|
[dirty]
|
|
73940
74054
|
);
|
|
73941
|
-
|
|
74055
|
+
useEffect117(() => registerViewModeGuard(confirmLeave), [confirmLeave, registerViewModeGuard]);
|
|
73942
74056
|
const handleBack = () => {
|
|
73943
74057
|
if (confirmLeave()) onBack();
|
|
73944
74058
|
};
|
|
73945
74059
|
const handleNavigate = (delta) => {
|
|
73946
74060
|
if (confirmLeave()) onNavigate(delta);
|
|
73947
74061
|
};
|
|
73948
|
-
|
|
74062
|
+
useEffect117(() => {
|
|
73949
74063
|
const onKey = (e) => {
|
|
73950
74064
|
const el = document.activeElement;
|
|
73951
74065
|
if (el instanceof HTMLTextAreaElement || el instanceof HTMLInputElement) return;
|
|
@@ -74417,7 +74531,7 @@ function progressLabel(summary) {
|
|
|
74417
74531
|
}
|
|
74418
74532
|
|
|
74419
74533
|
// src/components/storyboard/useFrameComments.ts
|
|
74420
|
-
import { useCallback as useCallback150, useEffect as
|
|
74534
|
+
import { useCallback as useCallback150, useEffect as useEffect118, useMemo as useMemo64, useState as useState129 } from "react";
|
|
74421
74535
|
|
|
74422
74536
|
// src/components/storyboard/frameComments.ts
|
|
74423
74537
|
var FRAME_COMMENTS_PATH = ".hyperframes/frame-comments.json";
|
|
@@ -74490,7 +74604,7 @@ function useFrameComments(frames) {
|
|
|
74490
74604
|
} catch {
|
|
74491
74605
|
}
|
|
74492
74606
|
}, [readOptionalProjectFile]);
|
|
74493
|
-
|
|
74607
|
+
useEffect118(() => {
|
|
74494
74608
|
void refreshPending();
|
|
74495
74609
|
const onFocus = () => void refreshPending();
|
|
74496
74610
|
window.addEventListener("focus", onFocus);
|
|
@@ -74551,10 +74665,10 @@ function StoryboardLoaded({
|
|
|
74551
74665
|
const [feedbackMessageCopied, setFeedbackMessageCopied] = useState130(false);
|
|
74552
74666
|
const comments = useFrameComments(data.frames);
|
|
74553
74667
|
const { refreshPending } = comments;
|
|
74554
|
-
|
|
74668
|
+
useEffect119(() => {
|
|
74555
74669
|
void refreshPending();
|
|
74556
74670
|
}, [data.signature, refreshPending]);
|
|
74557
|
-
|
|
74671
|
+
useEffect119(() => {
|
|
74558
74672
|
if (comments.draftCount > 0) setFeedbackMessageCopied(false);
|
|
74559
74673
|
}, [comments.draftCount]);
|
|
74560
74674
|
const saveFeedbackAndCopyMessage = async () => {
|
|
@@ -74903,7 +75017,7 @@ function StudioSplash({ waiting }) {
|
|
|
74903
75017
|
}
|
|
74904
75018
|
|
|
74905
75019
|
// src/hooks/useServerConnection.ts
|
|
74906
|
-
import { useEffect as
|
|
75020
|
+
import { useEffect as useEffect120, useState as useState132 } from "react";
|
|
74907
75021
|
function useServerConnection() {
|
|
74908
75022
|
const [projectId, setProjectId] = useState132(null);
|
|
74909
75023
|
const [resolving, setResolving] = useState132(true);
|
|
@@ -74944,7 +75058,7 @@ function useServerConnection() {
|
|
|
74944
75058
|
if (retryTimer !== null) clearTimeout(retryTimer);
|
|
74945
75059
|
};
|
|
74946
75060
|
});
|
|
74947
|
-
|
|
75061
|
+
useEffect120(() => {
|
|
74948
75062
|
const onHashChange = () => {
|
|
74949
75063
|
const next = parseProjectIdFromHash(window.location.hash);
|
|
74950
75064
|
if (next && next !== projectId) setProjectId(next);
|
|
@@ -74956,9 +75070,9 @@ function useServerConnection() {
|
|
|
74956
75070
|
}
|
|
74957
75071
|
|
|
74958
75072
|
// src/hooks/useStudioSessionStart.ts
|
|
74959
|
-
import { useEffect as
|
|
75073
|
+
import { useEffect as useEffect121 } from "react";
|
|
74960
75074
|
function useStudioSessionStart(projectId, resolving, waitingForServer) {
|
|
74961
|
-
|
|
75075
|
+
useEffect121(() => {
|
|
74962
75076
|
if (resolving || waitingForServer || hasFiredSessionStart()) return;
|
|
74963
75077
|
markSessionStartFired();
|
|
74964
75078
|
trackStudioSessionStart({ has_project: projectId != null });
|
|
@@ -75039,7 +75153,7 @@ function StudioApp() {
|
|
|
75039
75153
|
activeCompPath,
|
|
75040
75154
|
masterCompPath
|
|
75041
75155
|
);
|
|
75042
|
-
|
|
75156
|
+
useEffect122(() => {
|
|
75043
75157
|
if (activeCompPathHydrated) return;
|
|
75044
75158
|
if (!fileManager.fileTreeLoaded) return;
|
|
75045
75159
|
const nextCompPath = normalizeStudioCompositionPath(
|
|
@@ -75313,7 +75427,7 @@ function StudioApp() {
|
|
|
75313
75427
|
} = useInspectorState(
|
|
75314
75428
|
panelLayout.rightPanelTab,
|
|
75315
75429
|
panelLayout.rightInspectorPanes,
|
|
75316
|
-
panelLayout.
|
|
75430
|
+
panelLayout.effectiveRightCollapsed,
|
|
75317
75431
|
isPlaying,
|
|
75318
75432
|
domEditSession.domEditSelection,
|
|
75319
75433
|
gestureState === "recording"
|
|
@@ -75429,7 +75543,7 @@ function StudioApp() {
|
|
|
75429
75543
|
onAddCompositionToTimeline: handleAddCompositionAtPlayhead
|
|
75430
75544
|
}
|
|
75431
75545
|
),
|
|
75432
|
-
right: panelLayout.
|
|
75546
|
+
right: panelLayout.effectiveRightCollapsed ? null : /* @__PURE__ */ jsx184(
|
|
75433
75547
|
StudioRightPanel,
|
|
75434
75548
|
{
|
|
75435
75549
|
designPanelActive,
|