@hyperframes/studio 0.6.0-alpha.9 → 0.6.1
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-CzwFysqv.js +418 -0
- package/dist/assets/index-D1JDq7Gg.css +1 -0
- package/dist/assets/index-hYc4aP7M.js +117 -0
- package/dist/favicon.svg +14 -0
- package/dist/index.html +3 -2
- package/package.json +9 -9
- package/src/App.tsx +421 -4303
- package/src/captions/components/CaptionOverlay.tsx +13 -246
- package/src/captions/components/CaptionOverlayUtils.ts +221 -0
- package/src/components/AskAgentModal.tsx +120 -0
- package/src/components/StudioHeader.tsx +133 -0
- package/src/components/StudioLeftSidebar.tsx +125 -0
- package/src/components/StudioPreviewArea.tsx +167 -0
- package/src/components/StudioRightPanel.tsx +198 -0
- package/src/components/TimelineToolbar.tsx +89 -0
- package/src/components/editor/DomEditOverlay.tsx +88 -993
- package/src/components/editor/EaseCurveEditor.tsx +221 -0
- package/src/components/editor/FileTree.tsx +13 -621
- package/src/components/editor/FileTreeIcons.tsx +128 -0
- package/src/components/editor/FileTreeNodes.tsx +496 -0
- package/src/components/editor/MotionPanel.tsx +16 -390
- package/src/components/editor/MotionPanelFields.tsx +185 -0
- package/src/components/editor/PropertyPanel.test.ts +0 -49
- package/src/components/editor/PropertyPanel.tsx +132 -2763
- package/src/components/editor/domEditOverlayGeometry.ts +211 -0
- package/src/components/editor/domEditOverlayGestures.ts +138 -0
- package/src/components/editor/domEditOverlayStartGesture.ts +155 -0
- package/src/components/editor/domEditing.ts +44 -1117
- package/src/components/editor/domEditingAgentPrompt.ts +97 -0
- package/src/components/editor/domEditingDom.ts +266 -0
- package/src/components/editor/domEditingElement.ts +329 -0
- package/src/components/editor/domEditingLayers.ts +460 -0
- package/src/components/editor/domEditingTypes.ts +125 -0
- package/src/components/editor/manualEditingAvailability.test.ts +2 -2
- package/src/components/editor/manualEditingAvailability.ts +1 -1
- package/src/components/editor/manualEdits.ts +84 -1049
- package/src/components/editor/manualEditsDom.ts +436 -0
- package/src/components/editor/manualEditsParsing.ts +280 -0
- package/src/components/editor/manualEditsSnapshot.ts +333 -0
- package/src/components/editor/manualEditsTypes.ts +141 -0
- package/src/components/editor/propertyPanelColor.tsx +371 -0
- package/src/components/editor/propertyPanelFill.tsx +421 -0
- package/src/components/editor/propertyPanelFont.tsx +455 -0
- package/src/components/editor/propertyPanelHelpers.ts +401 -0
- package/src/components/editor/propertyPanelPrimitives.tsx +357 -0
- package/src/components/editor/propertyPanelSections.tsx +453 -0
- package/src/components/editor/propertyPanelStyleSections.tsx +411 -0
- package/src/components/editor/studioMotion.ts +47 -434
- package/src/components/editor/studioMotionOps.ts +299 -0
- package/src/components/editor/studioMotionTypes.ts +168 -0
- package/src/components/editor/useDomEditOverlayGestures.ts +393 -0
- package/src/components/editor/useDomEditOverlayRects.ts +207 -0
- package/src/components/nle/NLELayout.tsx +68 -155
- package/src/components/nle/NLEPreview.tsx +3 -0
- package/src/components/nle/useCompositionStack.ts +126 -0
- package/src/components/renders/RenderQueue.tsx +102 -31
- package/src/components/renders/useRenderQueue.ts +8 -2
- package/src/components/sidebar/LeftSidebar.tsx +186 -186
- package/src/contexts/DomEditContext.tsx +137 -0
- package/src/contexts/FileManagerContext.tsx +110 -0
- package/src/contexts/PanelLayoutContext.tsx +68 -0
- package/src/contexts/StudioContext.tsx +135 -0
- package/src/hooks/useAppHotkeys.ts +326 -0
- package/src/hooks/useAskAgentModal.ts +162 -0
- package/src/hooks/useCaptionDetection.ts +132 -0
- package/src/hooks/useCompositionDimensions.ts +25 -0
- package/src/hooks/useConsoleErrorCapture.ts +60 -0
- package/src/hooks/useDomEditCommits.ts +437 -0
- package/src/hooks/useDomEditSession.ts +342 -0
- package/src/hooks/useDomEditTextCommits.ts +330 -0
- package/src/hooks/useDomSelection.ts +398 -0
- package/src/hooks/useFileManager.ts +431 -0
- package/src/hooks/useFrameCapture.ts +77 -0
- package/src/hooks/useLintModal.ts +35 -0
- package/src/hooks/useManifestPersistence.ts +492 -0
- package/src/hooks/usePanelLayout.ts +68 -0
- package/src/hooks/usePreviewInteraction.ts +153 -0
- package/src/hooks/useRenderClipContent.ts +124 -0
- package/src/hooks/useTimelineEditing.ts +472 -0
- package/src/hooks/useToast.ts +20 -0
- package/src/player/components/Player.tsx +33 -2
- package/src/player/components/Timeline.test.ts +0 -8
- package/src/player/components/Timeline.tsx +196 -1518
- package/src/player/components/TimelineCanvas.tsx +434 -0
- package/src/player/components/TimelineClip.tsx +9 -244
- package/src/player/components/TimelineEmptyState.tsx +102 -0
- package/src/player/components/TimelineRuler.tsx +90 -0
- package/src/player/components/timelineIcons.tsx +49 -0
- package/src/player/components/timelineLayout.ts +215 -0
- package/src/player/components/timelineUtils.ts +211 -0
- package/src/player/components/useTimelineClipDrag.ts +388 -0
- package/src/player/components/useTimelinePlayhead.ts +200 -0
- package/src/player/components/useTimelineRangeSelection.ts +135 -0
- package/src/player/hooks/usePlaybackKeyboard.ts +171 -0
- package/src/player/hooks/useTimelinePlayer.ts +105 -1371
- package/src/player/hooks/useTimelineSyncCallbacks.ts +288 -0
- package/src/player/lib/playbackAdapter.ts +145 -0
- package/src/player/lib/playbackShortcuts.ts +68 -0
- package/src/player/lib/playbackTypes.ts +60 -0
- package/src/player/lib/timelineDOM.ts +373 -0
- package/src/player/lib/timelineElementHelpers.ts +303 -0
- package/src/player/lib/timelineIframeHelpers.ts +269 -0
- package/src/utils/domEditHelpers.ts +50 -0
- package/src/utils/studioFontHelpers.ts +83 -0
- package/src/utils/studioHelpers.ts +214 -0
- package/src/utils/studioPreviewHelpers.ts +185 -0
- package/src/utils/timelineDiscovery.ts +1 -1
- package/dist/assets/hyperframes-player-DjsVzYFP.js +0 -418
- package/dist/assets/index-14zH9lqh.css +0 -1
- package/dist/assets/index-DYCiFGWQ.js +0 -108
- package/src/player/components/TimelineClip.test.ts +0 -92
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo, type ReactNode } from "react";
|
|
2
|
+
import type { useDomEditSession } from "../hooks/useDomEditSession";
|
|
3
|
+
|
|
4
|
+
type DomEditValue = ReturnType<typeof useDomEditSession>;
|
|
5
|
+
|
|
6
|
+
const DomEditContext = createContext<DomEditValue | null>(null);
|
|
7
|
+
|
|
8
|
+
export function useDomEditContext(): DomEditValue {
|
|
9
|
+
const ctx = useContext(DomEditContext);
|
|
10
|
+
if (!ctx) throw new Error("useDomEditContext must be used within DomEditProvider");
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function DomEditProvider({
|
|
15
|
+
value: {
|
|
16
|
+
domEditSelection,
|
|
17
|
+
domEditGroupSelections,
|
|
18
|
+
domEditHoverSelection,
|
|
19
|
+
agentModalOpen,
|
|
20
|
+
agentModalAnchorPoint,
|
|
21
|
+
copiedAgentPrompt,
|
|
22
|
+
agentPromptSelectionContext,
|
|
23
|
+
domEditSelectionRef,
|
|
24
|
+
handleTimelineElementSelect,
|
|
25
|
+
handlePreviewCanvasMouseDown,
|
|
26
|
+
handlePreviewCanvasPointerMove,
|
|
27
|
+
handlePreviewCanvasPointerLeave,
|
|
28
|
+
applyDomSelection,
|
|
29
|
+
clearDomSelection,
|
|
30
|
+
handleDomStyleCommit,
|
|
31
|
+
handleDomPathOffsetCommit,
|
|
32
|
+
handleDomGroupPathOffsetCommit,
|
|
33
|
+
handleDomBoxSizeCommit,
|
|
34
|
+
handleDomRotationCommit,
|
|
35
|
+
handleDomManualEditsReset,
|
|
36
|
+
handleDomMotionCommit,
|
|
37
|
+
handleDomMotionClear,
|
|
38
|
+
handleDomTextCommit,
|
|
39
|
+
handleDomTextFieldStyleCommit,
|
|
40
|
+
handleDomAddTextField,
|
|
41
|
+
handleDomRemoveTextField,
|
|
42
|
+
handleAskAgent,
|
|
43
|
+
handleAgentModalSubmit,
|
|
44
|
+
handleBlockedDomMove,
|
|
45
|
+
handleDomManualDragStart,
|
|
46
|
+
handleDomEditElementDelete,
|
|
47
|
+
buildDomSelectionForTimelineElement,
|
|
48
|
+
resolveImportedFontAsset,
|
|
49
|
+
setAgentModalOpen,
|
|
50
|
+
setAgentPromptSelectionContext,
|
|
51
|
+
setAgentModalAnchorPoint,
|
|
52
|
+
},
|
|
53
|
+
children,
|
|
54
|
+
}: {
|
|
55
|
+
value: DomEditValue;
|
|
56
|
+
children: ReactNode;
|
|
57
|
+
}) {
|
|
58
|
+
const stable = useMemo<DomEditValue>(
|
|
59
|
+
() => ({
|
|
60
|
+
domEditSelection,
|
|
61
|
+
domEditGroupSelections,
|
|
62
|
+
domEditHoverSelection,
|
|
63
|
+
agentModalOpen,
|
|
64
|
+
agentModalAnchorPoint,
|
|
65
|
+
copiedAgentPrompt,
|
|
66
|
+
agentPromptSelectionContext,
|
|
67
|
+
domEditSelectionRef,
|
|
68
|
+
handleTimelineElementSelect,
|
|
69
|
+
handlePreviewCanvasMouseDown,
|
|
70
|
+
handlePreviewCanvasPointerMove,
|
|
71
|
+
handlePreviewCanvasPointerLeave,
|
|
72
|
+
applyDomSelection,
|
|
73
|
+
clearDomSelection,
|
|
74
|
+
handleDomStyleCommit,
|
|
75
|
+
handleDomPathOffsetCommit,
|
|
76
|
+
handleDomGroupPathOffsetCommit,
|
|
77
|
+
handleDomBoxSizeCommit,
|
|
78
|
+
handleDomRotationCommit,
|
|
79
|
+
handleDomManualEditsReset,
|
|
80
|
+
handleDomMotionCommit,
|
|
81
|
+
handleDomMotionClear,
|
|
82
|
+
handleDomTextCommit,
|
|
83
|
+
handleDomTextFieldStyleCommit,
|
|
84
|
+
handleDomAddTextField,
|
|
85
|
+
handleDomRemoveTextField,
|
|
86
|
+
handleAskAgent,
|
|
87
|
+
handleAgentModalSubmit,
|
|
88
|
+
handleBlockedDomMove,
|
|
89
|
+
handleDomManualDragStart,
|
|
90
|
+
handleDomEditElementDelete,
|
|
91
|
+
buildDomSelectionForTimelineElement,
|
|
92
|
+
resolveImportedFontAsset,
|
|
93
|
+
setAgentModalOpen,
|
|
94
|
+
setAgentPromptSelectionContext,
|
|
95
|
+
setAgentModalAnchorPoint,
|
|
96
|
+
}),
|
|
97
|
+
[
|
|
98
|
+
domEditSelection,
|
|
99
|
+
domEditGroupSelections,
|
|
100
|
+
domEditHoverSelection,
|
|
101
|
+
agentModalOpen,
|
|
102
|
+
agentModalAnchorPoint,
|
|
103
|
+
copiedAgentPrompt,
|
|
104
|
+
agentPromptSelectionContext,
|
|
105
|
+
domEditSelectionRef,
|
|
106
|
+
handleTimelineElementSelect,
|
|
107
|
+
handlePreviewCanvasMouseDown,
|
|
108
|
+
handlePreviewCanvasPointerMove,
|
|
109
|
+
handlePreviewCanvasPointerLeave,
|
|
110
|
+
applyDomSelection,
|
|
111
|
+
clearDomSelection,
|
|
112
|
+
handleDomStyleCommit,
|
|
113
|
+
handleDomPathOffsetCommit,
|
|
114
|
+
handleDomGroupPathOffsetCommit,
|
|
115
|
+
handleDomBoxSizeCommit,
|
|
116
|
+
handleDomRotationCommit,
|
|
117
|
+
handleDomManualEditsReset,
|
|
118
|
+
handleDomMotionCommit,
|
|
119
|
+
handleDomMotionClear,
|
|
120
|
+
handleDomTextCommit,
|
|
121
|
+
handleDomTextFieldStyleCommit,
|
|
122
|
+
handleDomAddTextField,
|
|
123
|
+
handleDomRemoveTextField,
|
|
124
|
+
handleAskAgent,
|
|
125
|
+
handleAgentModalSubmit,
|
|
126
|
+
handleBlockedDomMove,
|
|
127
|
+
handleDomManualDragStart,
|
|
128
|
+
handleDomEditElementDelete,
|
|
129
|
+
buildDomSelectionForTimelineElement,
|
|
130
|
+
resolveImportedFontAsset,
|
|
131
|
+
setAgentModalOpen,
|
|
132
|
+
setAgentPromptSelectionContext,
|
|
133
|
+
setAgentModalAnchorPoint,
|
|
134
|
+
],
|
|
135
|
+
);
|
|
136
|
+
return <DomEditContext value={stable}>{children}</DomEditContext>;
|
|
137
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo, type ReactNode } from "react";
|
|
2
|
+
import type { useFileManager } from "../hooks/useFileManager";
|
|
3
|
+
|
|
4
|
+
type FileManagerValue = ReturnType<typeof useFileManager>;
|
|
5
|
+
|
|
6
|
+
const FileManagerContext = createContext<FileManagerValue | null>(null);
|
|
7
|
+
|
|
8
|
+
export function useFileManagerContext(): FileManagerValue {
|
|
9
|
+
const ctx = useContext(FileManagerContext);
|
|
10
|
+
if (!ctx) throw new Error("useFileManagerContext must be used within FileManagerProvider");
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function FileManagerProvider({
|
|
15
|
+
value: {
|
|
16
|
+
editingFile,
|
|
17
|
+
setEditingFile,
|
|
18
|
+
projectDir,
|
|
19
|
+
fileTree,
|
|
20
|
+
setFileTree,
|
|
21
|
+
editingPathRef,
|
|
22
|
+
projectIdRef,
|
|
23
|
+
saveTimerRef,
|
|
24
|
+
importedFontAssetsRef,
|
|
25
|
+
readProjectFile,
|
|
26
|
+
writeProjectFile,
|
|
27
|
+
readOptionalProjectFile,
|
|
28
|
+
handleFileSelect,
|
|
29
|
+
handleContentChange,
|
|
30
|
+
refreshFileTree,
|
|
31
|
+
uploadProjectFiles,
|
|
32
|
+
handleCreateFile,
|
|
33
|
+
handleCreateFolder,
|
|
34
|
+
handleDeleteFile,
|
|
35
|
+
handleRenameFile,
|
|
36
|
+
handleDuplicateFile,
|
|
37
|
+
handleMoveFile,
|
|
38
|
+
handleImportFiles,
|
|
39
|
+
handleImportFonts,
|
|
40
|
+
compositions,
|
|
41
|
+
assets,
|
|
42
|
+
fontAssets,
|
|
43
|
+
},
|
|
44
|
+
children,
|
|
45
|
+
}: {
|
|
46
|
+
value: FileManagerValue;
|
|
47
|
+
children: ReactNode;
|
|
48
|
+
}) {
|
|
49
|
+
const stable = useMemo<FileManagerValue>(
|
|
50
|
+
() => ({
|
|
51
|
+
editingFile,
|
|
52
|
+
setEditingFile,
|
|
53
|
+
projectDir,
|
|
54
|
+
fileTree,
|
|
55
|
+
setFileTree,
|
|
56
|
+
editingPathRef,
|
|
57
|
+
projectIdRef,
|
|
58
|
+
saveTimerRef,
|
|
59
|
+
importedFontAssetsRef,
|
|
60
|
+
readProjectFile,
|
|
61
|
+
writeProjectFile,
|
|
62
|
+
readOptionalProjectFile,
|
|
63
|
+
handleFileSelect,
|
|
64
|
+
handleContentChange,
|
|
65
|
+
refreshFileTree,
|
|
66
|
+
uploadProjectFiles,
|
|
67
|
+
handleCreateFile,
|
|
68
|
+
handleCreateFolder,
|
|
69
|
+
handleDeleteFile,
|
|
70
|
+
handleRenameFile,
|
|
71
|
+
handleDuplicateFile,
|
|
72
|
+
handleMoveFile,
|
|
73
|
+
handleImportFiles,
|
|
74
|
+
handleImportFonts,
|
|
75
|
+
compositions,
|
|
76
|
+
assets,
|
|
77
|
+
fontAssets,
|
|
78
|
+
}),
|
|
79
|
+
[
|
|
80
|
+
editingFile,
|
|
81
|
+
setEditingFile,
|
|
82
|
+
projectDir,
|
|
83
|
+
fileTree,
|
|
84
|
+
setFileTree,
|
|
85
|
+
editingPathRef,
|
|
86
|
+
projectIdRef,
|
|
87
|
+
saveTimerRef,
|
|
88
|
+
importedFontAssetsRef,
|
|
89
|
+
readProjectFile,
|
|
90
|
+
writeProjectFile,
|
|
91
|
+
readOptionalProjectFile,
|
|
92
|
+
handleFileSelect,
|
|
93
|
+
handleContentChange,
|
|
94
|
+
refreshFileTree,
|
|
95
|
+
uploadProjectFiles,
|
|
96
|
+
handleCreateFile,
|
|
97
|
+
handleCreateFolder,
|
|
98
|
+
handleDeleteFile,
|
|
99
|
+
handleRenameFile,
|
|
100
|
+
handleDuplicateFile,
|
|
101
|
+
handleMoveFile,
|
|
102
|
+
handleImportFiles,
|
|
103
|
+
handleImportFonts,
|
|
104
|
+
compositions,
|
|
105
|
+
assets,
|
|
106
|
+
fontAssets,
|
|
107
|
+
],
|
|
108
|
+
);
|
|
109
|
+
return <FileManagerContext value={stable}>{children}</FileManagerContext>;
|
|
110
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo, type ReactNode } from "react";
|
|
2
|
+
import type { usePanelLayout } from "../hooks/usePanelLayout";
|
|
3
|
+
|
|
4
|
+
type PanelLayoutValue = ReturnType<typeof usePanelLayout>;
|
|
5
|
+
|
|
6
|
+
const PanelLayoutContext = createContext<PanelLayoutValue | null>(null);
|
|
7
|
+
|
|
8
|
+
export function usePanelLayoutContext(): PanelLayoutValue {
|
|
9
|
+
const ctx = useContext(PanelLayoutContext);
|
|
10
|
+
if (!ctx) throw new Error("usePanelLayoutContext must be used within PanelLayoutProvider");
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function PanelLayoutProvider({
|
|
15
|
+
value: {
|
|
16
|
+
leftWidth,
|
|
17
|
+
setLeftWidth,
|
|
18
|
+
rightWidth,
|
|
19
|
+
leftCollapsed,
|
|
20
|
+
setLeftCollapsed,
|
|
21
|
+
rightCollapsed,
|
|
22
|
+
setRightCollapsed,
|
|
23
|
+
rightPanelTab,
|
|
24
|
+
setRightPanelTab,
|
|
25
|
+
toggleLeftSidebar,
|
|
26
|
+
handlePanelResizeStart,
|
|
27
|
+
handlePanelResizeMove,
|
|
28
|
+
handlePanelResizeEnd,
|
|
29
|
+
},
|
|
30
|
+
children,
|
|
31
|
+
}: {
|
|
32
|
+
value: PanelLayoutValue;
|
|
33
|
+
children: ReactNode;
|
|
34
|
+
}) {
|
|
35
|
+
const stable = useMemo<PanelLayoutValue>(
|
|
36
|
+
() => ({
|
|
37
|
+
leftWidth,
|
|
38
|
+
setLeftWidth,
|
|
39
|
+
rightWidth,
|
|
40
|
+
leftCollapsed,
|
|
41
|
+
setLeftCollapsed,
|
|
42
|
+
rightCollapsed,
|
|
43
|
+
setRightCollapsed,
|
|
44
|
+
rightPanelTab,
|
|
45
|
+
setRightPanelTab,
|
|
46
|
+
toggleLeftSidebar,
|
|
47
|
+
handlePanelResizeStart,
|
|
48
|
+
handlePanelResizeMove,
|
|
49
|
+
handlePanelResizeEnd,
|
|
50
|
+
}),
|
|
51
|
+
[
|
|
52
|
+
leftWidth,
|
|
53
|
+
setLeftWidth,
|
|
54
|
+
rightWidth,
|
|
55
|
+
leftCollapsed,
|
|
56
|
+
setLeftCollapsed,
|
|
57
|
+
rightCollapsed,
|
|
58
|
+
setRightCollapsed,
|
|
59
|
+
rightPanelTab,
|
|
60
|
+
setRightPanelTab,
|
|
61
|
+
toggleLeftSidebar,
|
|
62
|
+
handlePanelResizeStart,
|
|
63
|
+
handlePanelResizeMove,
|
|
64
|
+
handlePanelResizeEnd,
|
|
65
|
+
],
|
|
66
|
+
);
|
|
67
|
+
return <PanelLayoutContext value={stable}>{children}</PanelLayoutContext>;
|
|
68
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo, type ReactNode } from "react";
|
|
2
|
+
import type { TimelineElement } from "../player";
|
|
3
|
+
import type { CompositionDimensions } from "../components/renders/RenderQueue";
|
|
4
|
+
|
|
5
|
+
export interface StudioContextValue {
|
|
6
|
+
projectId: string;
|
|
7
|
+
activeCompPath: string | null;
|
|
8
|
+
setActiveCompPath: (path: string | null) => void;
|
|
9
|
+
showToast: (message: string, tone?: "error" | "info") => void;
|
|
10
|
+
previewIframeRef: React.MutableRefObject<HTMLIFrameElement | null>;
|
|
11
|
+
captionEditMode: boolean;
|
|
12
|
+
compositionLoading: boolean;
|
|
13
|
+
refreshKey: number;
|
|
14
|
+
setRefreshKey: React.Dispatch<React.SetStateAction<number>>;
|
|
15
|
+
currentTime: number;
|
|
16
|
+
timelineElements: TimelineElement[];
|
|
17
|
+
isPlaying: boolean;
|
|
18
|
+
editHistory: {
|
|
19
|
+
canUndo: boolean;
|
|
20
|
+
canRedo: boolean;
|
|
21
|
+
undoLabel: string | undefined;
|
|
22
|
+
redoLabel: string | undefined;
|
|
23
|
+
};
|
|
24
|
+
handleUndo: () => Promise<void>;
|
|
25
|
+
handleRedo: () => Promise<void>;
|
|
26
|
+
renderQueue: {
|
|
27
|
+
jobs: unknown[];
|
|
28
|
+
isRendering: boolean;
|
|
29
|
+
deleteRender: (jobId: string) => void;
|
|
30
|
+
clearCompleted: () => void;
|
|
31
|
+
startRender: (options: unknown) => Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
compositionDimensions: CompositionDimensions | null;
|
|
34
|
+
waitForPendingDomEditSaves: () => Promise<void>;
|
|
35
|
+
handlePreviewIframeRef: (iframe: HTMLIFrameElement | null) => void;
|
|
36
|
+
refreshPreviewDocumentVersion: () => void;
|
|
37
|
+
timelineVisible: boolean;
|
|
38
|
+
toggleTimelineVisibility: () => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const StudioContext = createContext<StudioContextValue | null>(null);
|
|
42
|
+
|
|
43
|
+
export function useStudioContext(): StudioContextValue {
|
|
44
|
+
const ctx = useContext(StudioContext);
|
|
45
|
+
if (!ctx) throw new Error("useStudioContext must be used within StudioProvider");
|
|
46
|
+
return ctx;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function StudioProvider({
|
|
50
|
+
value,
|
|
51
|
+
children,
|
|
52
|
+
}: {
|
|
53
|
+
value: StudioContextValue;
|
|
54
|
+
children: ReactNode;
|
|
55
|
+
}) {
|
|
56
|
+
const {
|
|
57
|
+
projectId,
|
|
58
|
+
activeCompPath,
|
|
59
|
+
setActiveCompPath,
|
|
60
|
+
showToast,
|
|
61
|
+
previewIframeRef,
|
|
62
|
+
captionEditMode,
|
|
63
|
+
compositionLoading,
|
|
64
|
+
refreshKey,
|
|
65
|
+
setRefreshKey,
|
|
66
|
+
currentTime,
|
|
67
|
+
timelineElements,
|
|
68
|
+
isPlaying,
|
|
69
|
+
editHistory,
|
|
70
|
+
handleUndo,
|
|
71
|
+
handleRedo,
|
|
72
|
+
renderQueue,
|
|
73
|
+
compositionDimensions,
|
|
74
|
+
waitForPendingDomEditSaves,
|
|
75
|
+
handlePreviewIframeRef,
|
|
76
|
+
refreshPreviewDocumentVersion,
|
|
77
|
+
timelineVisible,
|
|
78
|
+
toggleTimelineVisibility,
|
|
79
|
+
} = value;
|
|
80
|
+
|
|
81
|
+
const stable = useMemo<StudioContextValue>(
|
|
82
|
+
() => ({
|
|
83
|
+
projectId,
|
|
84
|
+
activeCompPath,
|
|
85
|
+
setActiveCompPath,
|
|
86
|
+
showToast,
|
|
87
|
+
previewIframeRef,
|
|
88
|
+
captionEditMode,
|
|
89
|
+
compositionLoading,
|
|
90
|
+
refreshKey,
|
|
91
|
+
setRefreshKey,
|
|
92
|
+
currentTime,
|
|
93
|
+
timelineElements,
|
|
94
|
+
isPlaying,
|
|
95
|
+
editHistory,
|
|
96
|
+
handleUndo,
|
|
97
|
+
handleRedo,
|
|
98
|
+
renderQueue,
|
|
99
|
+
compositionDimensions,
|
|
100
|
+
waitForPendingDomEditSaves,
|
|
101
|
+
handlePreviewIframeRef,
|
|
102
|
+
refreshPreviewDocumentVersion,
|
|
103
|
+
timelineVisible,
|
|
104
|
+
toggleTimelineVisibility,
|
|
105
|
+
}),
|
|
106
|
+
// Representative subset of deps that actually change — stable callbacks
|
|
107
|
+
// (showToast, setActiveCompPath, etc.) are included for correctness but
|
|
108
|
+
// won't trigger re-renders on their own.
|
|
109
|
+
[
|
|
110
|
+
projectId,
|
|
111
|
+
activeCompPath,
|
|
112
|
+
captionEditMode,
|
|
113
|
+
compositionLoading,
|
|
114
|
+
refreshKey,
|
|
115
|
+
currentTime,
|
|
116
|
+
isPlaying,
|
|
117
|
+
compositionDimensions,
|
|
118
|
+
timelineVisible,
|
|
119
|
+
editHistory,
|
|
120
|
+
timelineElements,
|
|
121
|
+
renderQueue,
|
|
122
|
+
setActiveCompPath,
|
|
123
|
+
showToast,
|
|
124
|
+
previewIframeRef,
|
|
125
|
+
setRefreshKey,
|
|
126
|
+
handleUndo,
|
|
127
|
+
handleRedo,
|
|
128
|
+
waitForPendingDomEditSaves,
|
|
129
|
+
handlePreviewIframeRef,
|
|
130
|
+
refreshPreviewDocumentVersion,
|
|
131
|
+
toggleTimelineVisibility,
|
|
132
|
+
],
|
|
133
|
+
);
|
|
134
|
+
return <StudioContext value={stable}>{children}</StudioContext>;
|
|
135
|
+
}
|