@hyperframes/studio 0.8.49 → 0.8.51
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-CqON2Rzo.js → hyperframes-player-Cn_PpHqP.js} +3 -3
- package/dist/assets/index-C05SNrvY.js +360 -0
- package/dist/assets/{index-mIgSsKqs.js → index-CPS3Cvj8.js} +1 -1
- package/dist/assets/{index-BGovDksE.js → index-Clrb11lj.js} +1 -1
- package/dist/assets/index-DUR9qzQM.css +1 -0
- package/dist/index.d.ts +29 -16
- package/dist/index.html +2 -2
- package/dist/index.js +7283 -8606
- package/dist/index.js.map +1 -1
- package/dist/styles/tailwind-preset.js.map +1 -1
- package/package.json +11 -12
- package/src/App.tsx +132 -143
- package/src/captions/components/CaptionAnimationPanel.tsx +4 -4
- package/src/captions/components/CaptionOverlayUtils.ts +2 -3
- package/src/captions/components/CaptionPropertyPanel.tsx +3 -3
- package/src/captions/components/CaptionTimeline.tsx +1 -1
- package/src/captions/components/shared.tsx +2 -2
- package/src/components/AskAgentModal.tsx +5 -5
- package/src/components/EditorShell.selectionSync.test.tsx +4 -0
- package/src/components/EditorShell.tsx +28 -7
- package/src/components/ExternalFileConflictBanner.tsx +16 -16
- package/src/components/LintModal.tsx +6 -16
- package/src/components/MediaPreview.tsx +2 -2
- package/src/components/SaveQueuePausedBanner.tsx +2 -2
- package/src/components/StudioHeader.tsx +2 -62
- package/src/components/StudioLeftSidebar.tsx +7 -4
- package/src/components/StudioOverlays.tsx +2 -6
- package/src/components/StudioRightPanel.tsx +4 -4
- package/src/components/StudioToast.tsx +2 -2
- package/src/components/TimelineToolbar.tsx +7 -7
- package/src/components/dock/Dock.test.tsx +192 -0
- package/src/components/dock/Dock.tsx +264 -0
- package/src/components/dock/dock.css +23 -0
- package/src/components/dock/dockLayout.ts +58 -0
- package/src/components/dock/dockLayoutSchema.ts +66 -0
- package/src/components/dock/dockLayoutStore.ts +91 -0
- package/src/components/dock/panelRegistry.ts +67 -0
- package/src/components/editor/AnimationCard.tsx +4 -4
- package/src/components/editor/AnimationCardParts.tsx +6 -6
- package/src/components/editor/BlockParamsPanel.tsx +4 -4
- package/src/components/editor/BorderRadiusEditor.tsx +1 -1
- package/src/components/editor/CanvasContextMenu.tsx +1 -1
- package/src/components/editor/ComputedTweenNotice.tsx +1 -1
- package/src/components/editor/DomEditOverlay.tsx +1 -1
- package/src/components/editor/EaseCurveSection.tsx +1 -1
- package/src/components/editor/EaseParamFields.tsx +5 -5
- package/src/components/editor/FileTree.tsx +4 -4
- package/src/components/editor/FileTreeIcons.tsx +1 -1
- package/src/components/editor/FileTreeNodes.tsx +13 -13
- package/src/components/editor/InlineTextToolbar.tsx +1 -1
- package/src/components/editor/InspectorHeaderActions.tsx +3 -3
- package/src/components/editor/KeyframeDiamond.tsx +1 -1
- package/src/components/editor/KeyframeEaseList.tsx +1 -1
- package/src/components/editor/LayersPanel.tsx +3 -3
- package/src/components/editor/MarqueeOverlay.tsx +1 -1
- package/src/components/editor/OffCanvasIndicators.tsx +1 -1
- package/src/components/editor/PreviewGuides.test.tsx +88 -0
- package/src/components/editor/PreviewGuides.tsx +125 -0
- package/src/components/editor/PromotableControl.tsx +2 -2
- package/src/components/editor/PropertyPanelEmptyState.tsx +7 -7
- package/src/components/editor/PropertyPanelFlatHeader.tsx +2 -2
- package/src/components/editor/SnapToolbar.test.tsx +21 -0
- package/src/components/editor/SnapToolbar.tsx +27 -3
- package/src/components/editor/TimelineFxPopover.tsx +1 -1
- package/src/components/editor/TopologyLens.tsx +4 -4
- package/src/components/editor/Transform3DCube.tsx +2 -2
- package/src/components/editor/audioFxRevealTarget.ts +1 -0
- package/src/components/editor/domEditing.test.ts +1 -1
- package/src/components/editor/domEditingAgentPrompt.test.ts +8 -6
- package/src/components/editor/domEditingAgentPrompt.ts +9 -3
- package/src/components/editor/previewGuidesStore.ts +26 -0
- package/src/components/editor/propertyPanelColor.tsx +11 -11
- package/src/components/editor/propertyPanelColorCurveGraph.tsx +1 -1
- package/src/components/editor/propertyPanelColorGradingControls.tsx +7 -9
- package/src/components/editor/propertyPanelColorGradingSection.tsx +6 -6
- package/src/components/editor/propertyPanelColorGradingSlider.tsx +5 -5
- package/src/components/editor/propertyPanelColorWheels.tsx +1 -1
- package/src/components/editor/propertyPanelCommitField.tsx +1 -1
- package/src/components/editor/propertyPanelFill.tsx +4 -4
- package/src/components/editor/propertyPanelFlatColorGradingAccessory.tsx +3 -3
- package/src/components/editor/propertyPanelFlatColorGradingSection.tsx +7 -7
- package/src/components/editor/propertyPanelFlatEffectsSection.tsx +4 -4
- package/src/components/editor/propertyPanelFlatMediaSection.tsx +3 -3
- package/src/components/editor/propertyPanelFlatOverlaysSection.tsx +1 -1
- package/src/components/editor/propertyPanelFlatPrimitives.tsx +10 -10
- package/src/components/editor/propertyPanelFlatSelectRow.tsx +3 -3
- package/src/components/editor/propertyPanelFlatTextSection.test.tsx +8 -9
- package/src/components/editor/propertyPanelFlatTextSection.tsx +5 -5
- package/src/components/editor/propertyPanelFlatToggle.tsx +1 -1
- package/src/components/editor/propertyPanelFont.tsx +5 -5
- package/src/components/editor/propertyPanelFxCarveModule.tsx +1 -1
- package/src/components/editor/propertyPanelFxControls.test.tsx +1 -1
- package/src/components/editor/propertyPanelFxControls.tsx +6 -6
- package/src/components/editor/propertyPanelFxEqModule.tsx +2 -2
- package/src/components/editor/propertyPanelFxPresetStyle.ts +2 -2
- package/src/components/editor/propertyPanelGradingNumberField.tsx +1 -1
- package/src/components/editor/propertyPanelMediaSection.tsx +1 -1
- package/src/components/editor/propertyPanelPrimitives.tsx +7 -7
- package/src/components/editor/propertyPanelSections.tsx +8 -8
- package/src/components/feedback/StudioFeedbackCard.tsx +7 -7
- package/src/components/feedback/feedbackTrigger.ts +0 -1
- package/src/components/nle/AssetPreviewOverlay.tsx +6 -2
- package/src/components/nle/CompositionBreadcrumb.tsx +3 -3
- package/src/components/nle/NLEPreview.test.ts +13 -0
- package/src/components/nle/NLEPreview.tsx +12 -7
- package/src/components/nle/PreviewOverlays.tsx +6 -6
- package/src/components/nle/PreviewPane.test.tsx +52 -0
- package/src/components/nle/PreviewPane.tsx +4 -2
- package/src/components/nle/TimelinePane.tsx +17 -3
- package/src/components/nle/TimelineResizeDivider.tsx +2 -2
- package/src/components/nle/useCanvasZOrderTimelineMirror.test.tsx +1 -1
- package/src/components/nle/useCanvasZOrderTimelineMirror.ts +3 -3
- package/src/components/panels/SlideshowPanel.tsx +2 -2
- package/src/components/panels/SlideshowSubPanels.tsx +20 -17
- package/src/components/panels/VariablesBindElement.tsx +2 -2
- package/src/components/panels/VariablesDeclarationForm.tsx +2 -2
- package/src/components/panels/VariablesOtherCompositions.tsx +1 -1
- package/src/components/panels/VariablesPanel.tsx +3 -3
- package/src/components/panels/VariablesValueControls.tsx +2 -2
- package/src/components/renders/FfmpegRequiredNotice.tsx +5 -5
- package/src/components/renders/RenderQueue.test.tsx +7 -0
- package/src/components/renders/RenderQueue.tsx +6 -6
- package/src/components/renders/RenderQueueItem.tsx +6 -6
- package/src/components/sidebar/AssetCard.tsx +8 -8
- package/src/components/sidebar/AssetContextMenu.tsx +8 -8
- package/src/components/sidebar/AssetsTab.tsx +2 -2
- package/src/components/sidebar/AudioRow.tsx +6 -6
- package/src/components/sidebar/BlocksTab.tsx +6 -6
- package/src/components/sidebar/CompositionsTab.tsx +5 -5
- package/src/components/sidebar/GlobalAssetsView.tsx +1 -1
- package/src/components/sidebar/LeftSidebar.lintBadge.test.tsx +58 -0
- package/src/components/sidebar/LeftSidebar.tsx +19 -5
- package/src/components/sidebar/PromptPreviewModal.tsx +3 -3
- package/src/components/ui/Button.test.tsx +60 -0
- package/src/components/ui/Button.tsx +4 -4
- package/src/components/ui/SearchInput.tsx +2 -2
- package/src/components/ui/Tooltip.tsx +1 -1
- package/src/hooks/appHotkeysDispatch.ts +11 -0
- package/src/hooks/timelineAudioGroupCreate.ts +2 -2
- package/src/hooks/timelineTrackVisibility.ts +8 -11
- package/src/hooks/useAppHotkeys.textEditing.test.tsx +1 -0
- package/src/hooks/useAppHotkeys.ts +4 -1
- package/src/hooks/useAskAgentModal.ts +2 -0
- package/src/hooks/useClipboard.test.ts +234 -0
- package/src/hooks/useClipboard.ts +264 -70
- package/src/hooks/useGroupCommits.test.ts +0 -1
- package/src/hooks/useLintModal.test.tsx +65 -0
- package/src/hooks/useLintModal.ts +3 -0
- package/src/hooks/useRazorSplit.history.test.tsx +0 -1
- package/src/hooks/useRazorSplit.test.ts +0 -2
- package/src/hooks/useRazorSplit.test.tsx +0 -1
- package/src/hooks/useSdkSession.lifecycle.test.tsx +49 -4
- package/src/hooks/useSdkSession.ts +43 -10
- package/src/hooks/useStudioContextValue.ts +5 -19
- package/src/hooks/useTimelineAssetDropOps.test.tsx +41 -1
- package/src/hooks/useTimelineAssetDropOps.ts +52 -11
- package/src/hooks/useTimelineEditing.test.tsx +0 -1
- package/src/main.tsx +9 -3
- package/src/player/components/AudioWaveform.tsx +1 -1
- package/src/player/components/AutomationSelectionMenu.tsx +2 -2
- package/src/player/components/ClipContextMenu.tsx +90 -10
- package/src/player/components/CompositionThumbnail.test.ts +0 -3
- package/src/player/components/CompositionThumbnail.tsx +3 -4
- package/src/player/components/EditModal.tsx +1 -1
- package/src/player/components/ImageThumbnail.tsx +1 -1
- package/src/player/components/KeyframeDiamondContextMenu.tsx +4 -4
- package/src/player/components/LayerDisclosureRow.tsx +2 -2
- package/src/player/components/PlayerControls.tsx +1 -1
- package/src/player/components/ShortcutsPanel.tsx +9 -9
- package/src/player/components/SpeedMenu.tsx +3 -5
- package/src/player/components/Timeline.tsx +16 -15
- package/src/player/components/TimelineCanvas.tsx +45 -8
- package/src/player/components/TimelineDiamondConnectors.tsx +1 -1
- package/src/player/components/TimelineEmptyState.tsx +5 -5
- package/src/player/components/TimelineFxButton.tsx +6 -6
- package/src/player/components/TimelineGestureOverlay.test.tsx +35 -1
- package/src/player/components/TimelineGestureOverlay.tsx +1 -1
- package/src/player/components/TimelineGroupHeader.tsx +5 -5
- package/src/player/components/TimelineGroupLaneLabels.tsx +1 -1
- package/src/player/components/TimelineGroupRow.tsx +1 -1
- package/src/player/components/TimelineLanes.test.tsx +54 -1
- package/src/player/components/TimelineLanes.tsx +2 -5
- package/src/player/components/TimelineLayerGroupHeader.tsx +2 -2
- package/src/player/components/TimelineOverlays.tsx +12 -0
- package/src/player/components/TimelineRuler.tsx +1 -1
- package/src/player/components/TimelineShortcutHint.tsx +1 -1
- package/src/player/components/TimelineTrackHeader.tsx +1 -1
- package/src/player/components/TimelineTrackPlainHeader.tsx +3 -3
- package/src/player/components/TimelineTypes.ts +6 -1
- package/src/player/components/TrackGapContextMenu.tsx +1 -1
- package/src/player/components/VideoThumbnail.tsx +4 -2
- package/src/player/components/VolumeControl.tsx +2 -2
- package/src/player/components/timelineAuthoredMoveTarget.ts +1 -2
- package/src/player/components/timelineCallbacks.ts +8 -8
- package/src/player/components/timelineClipChildren.test.ts +2 -2
- package/src/player/components/timelineClipChildren.tsx +2 -1
- package/src/player/components/timelineClipDragCommit.ts +2 -2
- package/src/player/components/timelineClipDragPreview.ts +51 -27
- package/src/player/components/timelineClipDragTypes.ts +3 -0
- package/src/player/components/timelineDragDrop.test.tsx +92 -1
- package/src/player/components/timelineDragDrop.ts +82 -33
- package/src/player/components/timelineEditCapabilities.ts +1 -2
- package/src/player/components/timelineEditing.test.ts +0 -16
- package/src/player/components/timelineGroupEditing.test.ts +1 -3
- package/src/player/components/timelineGroupEditing.ts +0 -1
- package/src/player/components/timelineLaneProps.ts +3 -0
- package/src/player/components/timelineSnapping.test.ts +27 -0
- package/src/player/components/timelineSnapping.ts +14 -1
- package/src/player/components/timelineTrackDisplay.ts +1 -1
- package/src/player/components/timelineTrackPersistPipeline.test.ts +0 -53
- package/src/player/components/trackHeaderLabelRows.tsx +4 -4
- package/src/player/components/useTimelineClipContextMenu.ts +32 -0
- package/src/player/components/useTimelineClipDrag.resize.test.tsx +136 -2
- package/src/player/components/useTimelineClipDrag.ts +30 -3
- package/src/player/components/useTimelineTrackDerivations.ts +1 -1
- package/src/player/hooks/timelineDomBinding.test.ts +0 -3
- package/src/player/hooks/timelineSyncHydration.test.ts +18 -0
- package/src/player/hooks/timelineSyncHydration.ts +37 -18
- package/src/player/hooks/useTimelinePlayer.test.ts +3 -20
- package/src/player/hooks/useTimelineRowElements.test.ts +28 -0
- package/src/player/hooks/useTimelineRowElements.ts +17 -0
- package/src/player/hooks/useTimelineSyncCallbacks.emptyManifest.test.tsx +41 -0
- package/src/player/hooks/useTimelineSyncCallbacks.ts +9 -10
- package/src/player/lib/describeClips.test.ts +95 -0
- package/src/player/lib/describeClips.ts +52 -0
- package/src/player/lib/timelineDOM.test.ts +0 -80
- package/src/player/lib/timelineDOM.ts +1 -61
- package/src/player/lib/timelineElementHelpers.ts +2 -53
- package/src/player/store/playerStore.ts +5 -0
- package/src/player/store/timelineElement.ts +1 -3
- package/src/shims/canvasBrowserStub.js +50 -0
- package/src/styles/iconTokens.ts +20 -0
- package/src/styles/palette-reset.css +6 -0
- package/src/styles/studio.css +24 -21
- package/src/styles/tailwind-preset.shared.js +3 -0
- package/src/styles/theme.css +213 -0
- package/src/styles/theme.test.ts +196 -0
- package/src/utils/clipboardPayload.test.ts +42 -2
- package/src/utils/clipboardPayload.ts +57 -32
- package/src/utils/previewSafeMargins.test.ts +34 -0
- package/src/utils/previewSafeMargins.ts +10 -0
- package/src/utils/razorSplitTransaction.test.ts +0 -1
- package/src/utils/sdkCanvasComposition.test.ts +77 -0
- package/src/utils/studioUiPreferences.test.ts +43 -0
- package/src/utils/studioUiPreferences.ts +34 -6
- package/src/utils/timelineDropTrackInsert.test.ts +134 -0
- package/src/utils/timelineDropTrackInsert.ts +83 -0
- package/src/utils/timelineElementSplit.test.ts +1 -2
- package/src/utils/timelineElementSplit.ts +0 -1
- package/src/webmcp/tools/lookTools.test.ts +40 -0
- package/src/webmcp/tools/lookTools.ts +32 -1
- package/dist/assets/index-B9LfWNyM.css +0 -1
- package/dist/assets/index-Bgmx2h7W.js +0 -441
- package/src/components/StudioGlobalDragOverlay.tsx +0 -24
- package/src/components/storyboard/AgentChatMessageButton.test.tsx +0 -47
- package/src/components/storyboard/AgentChatMessageButton.tsx +0 -45
- package/src/components/storyboard/FramePoster.test.tsx +0 -61
- package/src/components/storyboard/FramePoster.tsx +0 -86
- package/src/components/storyboard/StoryboardDirection.tsx +0 -45
- package/src/components/storyboard/StoryboardFrameFocus.tsx +0 -412
- package/src/components/storyboard/StoryboardFrameTile.tsx +0 -117
- package/src/components/storyboard/StoryboardGrid.tsx +0 -55
- package/src/components/storyboard/StoryboardLoaded.tsx +0 -307
- package/src/components/storyboard/StoryboardReviewGuide.tsx +0 -300
- package/src/components/storyboard/StoryboardScriptPanel.tsx +0 -26
- package/src/components/storyboard/StoryboardSourceEditor.tsx +0 -231
- package/src/components/storyboard/StoryboardStatusLegend.tsx +0 -21
- package/src/components/storyboard/StoryboardView.tsx +0 -169
- package/src/components/storyboard/StoryboardViewModeGuard.test.tsx +0 -187
- package/src/components/storyboard/frameComments.test.ts +0 -95
- package/src/components/storyboard/frameComments.ts +0 -115
- package/src/components/storyboard/frameStatus.ts +0 -36
- package/src/components/storyboard/storyboardReviewStage.test.ts +0 -40
- package/src/components/storyboard/storyboardReviewStage.ts +0 -45
- package/src/components/storyboard/useFrameComments.ts +0 -98
- package/src/contexts/ViewModeContext.tsx +0 -142
- package/src/hooks/useProjectSignaturePoll.test.tsx +0 -135
- package/src/hooks/useProjectSignaturePoll.ts +0 -68
- package/src/hooks/useStoryboard.ts +0 -99
- package/src/player/hooks/useExpandedTimelineElements.test.ts +0 -774
- package/src/player/hooks/useExpandedTimelineElements.ts +0 -460
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/styles/tailwind-preset.shared.js","../../src/styles/tailwind-preset.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../src/styles/tailwind-preset.shared.js","../../src/styles/tailwind-preset.ts"],"sourcesContent":["/** @deprecated Superseded by `src/styles/theme.css` (published as\n * `@hyperframes/studio/theme.css`); kept one more major for Tailwind v3\n * consumers. Values are byte-identical; theme.test.ts fails if they drift. */\nconst studioPreset = {\n theme: {\n extend: {\n colors: {\n studio: {\n bg: \"#0a0a0a\",\n surface: \"#141414\",\n border: \"#262626\",\n text: \"#e5e5e5\",\n muted: \"#737373\",\n accent: \"#3CE6AC\",\n },\n panel: {\n bg: \"#0C0C0E\",\n // Open inspector-section body — slightly lighter than headers (bg)\n // so the recessed scrollable region reads distinct.\n \"bg-inset\": \"#121214\",\n input: \"#161618\",\n surface: \"#18181B\",\n hover: \"#27272A\",\n border: \"#1E1E1E\",\n \"border-input\": \"#27272A\",\n hairline: \"#1A1A1C\",\n \"text-0\": \"#FAFAFA\",\n \"text-1\": \"#E4E4E7\",\n \"text-2\": \"#A1A1AA\",\n \"text-3\": \"#71717A\",\n \"text-4\": \"#52525B\",\n \"text-5\": \"#3F3F46\",\n accent: \"#3CE6AC\",\n danger: \"#EF4444\",\n media: \"#00E3FF\",\n container: \"#F5A623\",\n },\n },\n },\n },\n plugins: [],\n};\n\nexport default studioPreset;\n","import studioPreset from \"./tailwind-preset.shared.js\";\n\nexport default studioPreset;\n"],"mappings":";;;AAGA,IAAM,eAAe;AAAA,EACnB,OAAO;AAAA,IACL,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,QAAQ;AAAA,UACN,IAAI;AAAA,UACJ,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,OAAO;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,QACA,OAAO;AAAA,UACL,IAAI;AAAA;AAAA;AAAA,UAGJ,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,SAAS;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,gBAAgB;AAAA,UAChB,UAAU;AAAA,UACV,UAAU;AAAA,UACV,UAAU;AAAA,UACV,UAAU;AAAA,UACV,UAAU;AAAA,UACV,UAAU;AAAA,UACV,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,SAAS,CAAC;AACZ;AAEA,IAAO,iCAAQ;;;ACzCf,IAAO,0BAAQ;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/studio",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.51",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"import": "./dist/styles/tailwind-preset.js",
|
|
24
24
|
"types": "./dist/styles/tailwind-preset.d.ts"
|
|
25
25
|
},
|
|
26
|
+
"./theme.css": "./src/styles/theme.css",
|
|
26
27
|
"./package.json": "./package.json"
|
|
27
28
|
},
|
|
28
29
|
"publishConfig": {
|
|
@@ -44,32 +45,30 @@
|
|
|
44
45
|
"@phosphor-icons/react": "^2.1.10",
|
|
45
46
|
"@tanstack/react-virtual": "^3.14.6",
|
|
46
47
|
"bpm-detective": "^2.0.5",
|
|
47
|
-
"
|
|
48
|
+
"dockview-react": "8.3.1",
|
|
48
49
|
"gsap": "^3.13.0",
|
|
49
|
-
"marked": "^14.1.4",
|
|
50
50
|
"mediabunny": "^1.45.3",
|
|
51
|
-
"@hyperframes/
|
|
52
|
-
"@hyperframes/
|
|
53
|
-
"@hyperframes/
|
|
54
|
-
"@hyperframes/sdk": "0.8.
|
|
55
|
-
"@hyperframes/
|
|
51
|
+
"@hyperframes/core": "0.8.51",
|
|
52
|
+
"@hyperframes/player": "0.8.51",
|
|
53
|
+
"@hyperframes/studio-server": "0.8.51",
|
|
54
|
+
"@hyperframes/sdk": "0.8.51",
|
|
55
|
+
"@hyperframes/parsers": "0.8.51"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
58
59
|
"@types/react": "19",
|
|
59
60
|
"@types/react-dom": "19",
|
|
60
61
|
"@vitejs/plugin-react": "^4.0.0",
|
|
61
|
-
"autoprefixer": "^10.4.0",
|
|
62
62
|
"chokidar": "^4.0.3",
|
|
63
63
|
"fake-indexeddb": "^6.2.5",
|
|
64
|
-
"postcss": "^8.4.0",
|
|
65
64
|
"puppeteer-core": "^25.2.1",
|
|
66
|
-
"tailwindcss": "^3.
|
|
65
|
+
"tailwindcss": "^4.3.3",
|
|
67
66
|
"tsup": "^8.0.0",
|
|
68
67
|
"typescript": "^5.0.0",
|
|
69
68
|
"vite": "^6.4.2",
|
|
70
69
|
"vitest": "^4.1.11",
|
|
71
70
|
"zustand": "^5.0.0",
|
|
72
|
-
"@hyperframes/producer": "0.8.
|
|
71
|
+
"@hyperframes/producer": "0.8.51"
|
|
73
72
|
},
|
|
74
73
|
"peerDependencies": {
|
|
75
74
|
"react": "19",
|
package/src/App.tsx
CHANGED
|
@@ -53,8 +53,6 @@ import { StudioRightPanel } from "./components/StudioRightPanel";
|
|
|
53
53
|
import { TimelineToolbar } from "./components/TimelineToolbar";
|
|
54
54
|
import { StudioPlaybackProvider, StudioShellProvider } from "./contexts/StudioContext";
|
|
55
55
|
import { PanelLayoutProvider } from "./contexts/PanelLayoutContext";
|
|
56
|
-
import { ViewModeProvider, useViewModeState } from "./contexts/ViewModeContext";
|
|
57
|
-
import { StoryboardView } from "./components/storyboard/StoryboardView";
|
|
58
56
|
import { FileManagerProvider } from "./contexts/FileManagerContext";
|
|
59
57
|
import { DomEditProvider } from "./contexts/DomEditContext";
|
|
60
58
|
import { StudioSplash } from "./components/StudioSplash";
|
|
@@ -68,7 +66,6 @@ const getTimelineSelectionSet = () => usePlayerStore.getState().selectedElementI
|
|
|
68
66
|
export function StudioApp() {
|
|
69
67
|
const { projectId, resolving, waitingForServer } = useServerConnection();
|
|
70
68
|
const initialUrlStateRef = useRef(readStudioUrlStateFromWindow());
|
|
71
|
-
const viewModeValue = useViewModeState();
|
|
72
69
|
useStudioSessionStart(projectId, resolving, waitingForServer);
|
|
73
70
|
const [compIdToSrc, setCompIdToSrc] = useState<Map<string, string>>(new Map());
|
|
74
71
|
const [previewIframe, setPreviewIframe] = useState<HTMLIFrameElement | null>(null);
|
|
@@ -211,7 +208,7 @@ export function StudioApp() {
|
|
|
211
208
|
const domEditDeleteBridge: DomEditDelete = (s, o) => handleDomEditElementDeleteRef.current(s, o);
|
|
212
209
|
const resetKeyframesRef = useRef<() => boolean>(() => false);
|
|
213
210
|
const deleteSelectedKeyframesRef = useRef<() => void>(() => {});
|
|
214
|
-
const { handleCopy, handlePaste, handleCut } = useClipboard({
|
|
211
|
+
const { handleCopy, handlePaste, handleCut, handleDuplicate, canPaste } = useClipboard({
|
|
215
212
|
projectId,
|
|
216
213
|
activeCompPath,
|
|
217
214
|
domEditSelectionRef: domEditSelectionBridgeRef,
|
|
@@ -219,7 +216,7 @@ export function StudioApp() {
|
|
|
219
216
|
writeProjectFile: fileManager.writeProjectFile,
|
|
220
217
|
recordEdit: editHistory.recordEdit,
|
|
221
218
|
reloadPreview,
|
|
222
|
-
|
|
219
|
+
handleTimelineElementsDelete: timelineEditing.handleTimelineElementsDelete,
|
|
223
220
|
handleDomEditElementDelete: domEditDeleteBridge,
|
|
224
221
|
previewIframeRef,
|
|
225
222
|
});
|
|
@@ -240,6 +237,7 @@ export function StudioApp() {
|
|
|
240
237
|
handleCopy,
|
|
241
238
|
handlePaste,
|
|
242
239
|
handleCut,
|
|
240
|
+
handleDuplicate,
|
|
243
241
|
onResetKeyframes: () => resetKeyframesRef.current(),
|
|
244
242
|
onDeleteSelectedKeyframes: () => deleteSelectedKeyframesRef.current(),
|
|
245
243
|
onAfterUndoRedo: () => invalidateGsapCacheRef.current(),
|
|
@@ -326,10 +324,8 @@ export function StudioApp() {
|
|
|
326
324
|
effectiveTimelineDuration,
|
|
327
325
|
});
|
|
328
326
|
const compositionDimensions = useCompositionDimensions(previewIframeRef);
|
|
329
|
-
const { lintModal, linting, handleLint, closeLintModal, findingsByFile } =
|
|
330
|
-
projectId,
|
|
331
|
-
refreshKey,
|
|
332
|
-
);
|
|
327
|
+
const { lintModal, linting, handleLint, closeLintModal, findingsByFile, hasLintError } =
|
|
328
|
+
useLintModal(projectId, refreshKey);
|
|
333
329
|
const frameCapture = useFrameCapture({
|
|
334
330
|
projectId,
|
|
335
331
|
activeCompPath,
|
|
@@ -341,7 +337,7 @@ export function StudioApp() {
|
|
|
341
337
|
setConsoleErrors,
|
|
342
338
|
resetErrors: resetConsoleErrors,
|
|
343
339
|
} = useConsoleErrorCapture(previewIframe);
|
|
344
|
-
const
|
|
340
|
+
const fileDrop = useGlobalFileDrop(timelineEditing.handleTimelineFileDrop);
|
|
345
341
|
const handleToggleRecordingRef = useRef<() => void>(() => {});
|
|
346
342
|
const domEditSessionRef = useRef(domEditSession);
|
|
347
343
|
domEditSessionRef.current = domEditSession;
|
|
@@ -440,143 +436,136 @@ export function StudioApp() {
|
|
|
440
436
|
return (
|
|
441
437
|
<StudioShellProvider value={studioCtxValue}>
|
|
442
438
|
<StudioPlaybackProvider value={studioCtxValue}>
|
|
443
|
-
<
|
|
444
|
-
<
|
|
445
|
-
<
|
|
446
|
-
<
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
439
|
+
<PanelLayoutProvider value={panelLayout}>
|
|
440
|
+
<FileManagerProvider value={fileManager}>
|
|
441
|
+
<DomEditProvider value={domEditSession}>
|
|
442
|
+
<div
|
|
443
|
+
className="flex flex-col h-full w-full bg-neutral-950 relative"
|
|
444
|
+
onDragOver={fileDrop.onDragOver}
|
|
445
|
+
onDrop={fileDrop.onDrop}
|
|
446
|
+
>
|
|
447
|
+
<StudioHeader
|
|
448
|
+
captureFrameHref={frameCapture.captureFrameHref}
|
|
449
|
+
captureFrameFilename={frameCapture.captureFrameFilename}
|
|
450
|
+
handleCaptureFrameClick={frameCapture.handleCaptureFrameClick}
|
|
451
|
+
refreshCaptureFrameTime={frameCapture.refreshCaptureFrameTime}
|
|
452
|
+
capturing={frameCapture.capturing}
|
|
453
|
+
inspectorButtonActive={inspectorButtonActive}
|
|
454
|
+
inspectorPanelActive={inspectorPanelActive}
|
|
455
|
+
onExport={() => {
|
|
456
|
+
void (async () => {
|
|
457
|
+
await previewPersistence.waitForPendingDomEditSaves();
|
|
458
|
+
await renderQueue.startRender(undefined);
|
|
459
|
+
})();
|
|
460
|
+
}}
|
|
461
|
+
/>
|
|
462
|
+
{previewPersistence.domEditSaveQueuePaused && !externalFileChanges.blocked && (
|
|
463
|
+
<SaveQueuePausedBanner
|
|
464
|
+
message={previewPersistence.domEditSaveQueuePaused}
|
|
465
|
+
onRetry={previewPersistence.resetDomEditSaveQueueBreaker}
|
|
468
466
|
/>
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
<ExternalFileConflictBanner coordinator={externalFileChanges} />
|
|
476
|
-
{viewModeValue.viewMode === "storyboard" && (
|
|
477
|
-
<StoryboardView
|
|
478
|
-
projectId={projectId}
|
|
467
|
+
)}
|
|
468
|
+
<ExternalFileConflictBanner coordinator={externalFileChanges} />
|
|
469
|
+
<EditorShell
|
|
470
|
+
left={
|
|
471
|
+
<StudioLeftSidebar
|
|
472
|
+
leftSidebarRef={leftSidebarRef}
|
|
479
473
|
onSelectComposition={handleSelectComposition}
|
|
474
|
+
onAddBlock={handleAddBlock}
|
|
475
|
+
onPreviewBlock={setBlockPreview}
|
|
476
|
+
onLint={handleLint}
|
|
477
|
+
linting={linting}
|
|
478
|
+
lintFindingCount={lintModal?.length ?? findingsByFile.size}
|
|
479
|
+
lintFindingsByFile={findingsByFile}
|
|
480
|
+
lintHasError={hasLintError}
|
|
481
|
+
onAddAssetToTimeline={handleAddAssetAtPlayhead}
|
|
482
|
+
onAddCompositionToTimeline={handleAddCompositionAtPlayhead}
|
|
480
483
|
/>
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
484
|
+
}
|
|
485
|
+
right={
|
|
486
|
+
panelLayout.effectiveRightCollapsed ? null : (
|
|
487
|
+
<StudioRightPanel
|
|
488
|
+
designPanelActive={designPanelActive}
|
|
489
|
+
activeBlockParams={activeBlockParams}
|
|
490
|
+
onCloseBlockParams={() => {
|
|
491
|
+
setActiveBlockParams(null);
|
|
492
|
+
panelLayout.setRightPanelTab("design");
|
|
493
|
+
}}
|
|
494
|
+
recordingState={gestureState}
|
|
495
|
+
recordingDuration={gestureRecording.recordingDuration}
|
|
496
|
+
onToggleRecording={handleToggleRecording}
|
|
497
|
+
sdkSession={sdkHandle.session}
|
|
498
|
+
publishSdkSession={sdkHandle.publish}
|
|
499
|
+
forceReloadSdkSession={sdkHandle.forceReload}
|
|
500
|
+
reloadPreview={reloadPreview}
|
|
501
|
+
recordEdit={editHistory.recordEdit}
|
|
502
|
+
onToggleElementHidden={timelineEditing.handleToggleElementHidden}
|
|
503
|
+
onAutoGroupCarveSources={timelineEditing.handleAutoGroupCarveSources}
|
|
504
|
+
onAddMediaOverlay={handleAddMediaOverlay}
|
|
496
505
|
/>
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
}
|
|
561
|
-
/>
|
|
562
|
-
<StudioOverlays
|
|
563
|
-
projectId={projectId}
|
|
564
|
-
projectDir={fileManager.projectDir}
|
|
565
|
-
lintModal={lintModal}
|
|
566
|
-
closeLintModal={closeLintModal}
|
|
567
|
-
consoleErrors={consoleErrors}
|
|
568
|
-
clearConsoleErrors={() => setConsoleErrors(null)}
|
|
569
|
-
domEditSession={domEditSession}
|
|
570
|
-
activeCompPath={activeCompPath}
|
|
571
|
-
dragOverlayActive={dragOverlay.active}
|
|
572
|
-
toasts={toasts}
|
|
573
|
-
dismissToast={dismissToast}
|
|
574
|
-
/>
|
|
575
|
-
</div>
|
|
576
|
-
</DomEditProvider>
|
|
577
|
-
</FileManagerProvider>
|
|
578
|
-
</PanelLayoutProvider>
|
|
579
|
-
</ViewModeProvider>
|
|
506
|
+
)
|
|
507
|
+
}
|
|
508
|
+
timelineToolbar={timelineToolbar}
|
|
509
|
+
renderClipContent={renderClipContent}
|
|
510
|
+
handleTimelineElementDelete={timelineEditing.handleTimelineElementDelete}
|
|
511
|
+
handleTimelineAssetDrop={timelineEditing.handleTimelineAssetDrop}
|
|
512
|
+
handleTimelineBlockDrop={handleTimelineBlockDrop}
|
|
513
|
+
handleTimelineCompositionDrop={timelineEditing.handleTimelineCompositionDrop}
|
|
514
|
+
handlePreviewBlockDrop={handlePreviewBlockDrop}
|
|
515
|
+
handleTimelineFileDrop={timelineEditing.handleTimelineFileDrop}
|
|
516
|
+
handleTimelineElementMove={timelineEditing.handleTimelineElementMove}
|
|
517
|
+
handleTimelineElementsMove={handleTimelineElementsMove}
|
|
518
|
+
handleTimelineElementResize={timelineEditing.handleTimelineElementResize}
|
|
519
|
+
handleTimelineGroupResize={timelineEditing.handleTimelineGroupResize}
|
|
520
|
+
handleToggleTrackHidden={timelineEditing.handleToggleTrackHidden}
|
|
521
|
+
setAudioGroupAttribute={timelineEditing.setAudioGroupAttribute}
|
|
522
|
+
handleGroupClips={timelineEditing.handleAutoGroupCarveSources}
|
|
523
|
+
setElementFxAttribute={timelineEditing.setElementFxAttribute}
|
|
524
|
+
handleBlockedTimelineEdit={timelineEditing.handleBlockedTimelineEdit}
|
|
525
|
+
handleTimelineElementSplit={timelineEditing.handleTimelineElementSplit}
|
|
526
|
+
handleRazorSplit={timelineEditing.handleRazorSplit}
|
|
527
|
+
handleRazorSplitAll={timelineEditing.handleRazorSplitAll}
|
|
528
|
+
onCopyClip={handleCopy}
|
|
529
|
+
onPasteClip={handlePaste}
|
|
530
|
+
onDuplicateClip={handleDuplicate}
|
|
531
|
+
canPasteClip={canPaste}
|
|
532
|
+
setCompIdToSrc={setCompIdToSrc}
|
|
533
|
+
setCompositionLoading={setCompositionLoading}
|
|
534
|
+
shouldShowMotionPath={shouldShowMotionPath}
|
|
535
|
+
shouldShowSelectedDomBounds={shouldShowSelectedDomBounds}
|
|
536
|
+
isGestureRecording={gestureState === "recording"}
|
|
537
|
+
recordingState={gestureState}
|
|
538
|
+
onToggleRecording={handleToggleRecording}
|
|
539
|
+
blockPreview={blockPreview}
|
|
540
|
+
gestureOverlay={
|
|
541
|
+
gestureState === "recording" && previewIframe ? (
|
|
542
|
+
<GestureTrailOverlay
|
|
543
|
+
samples={gestureRecording.samplesRef.current}
|
|
544
|
+
sampleCount={gestureRecording.samplesRef.current.length}
|
|
545
|
+
trail={gestureRecording.trailRef.current}
|
|
546
|
+
canvasRect={canvasRectRef.current!}
|
|
547
|
+
compositionSize={compositionDimensions ?? undefined}
|
|
548
|
+
mode="recording"
|
|
549
|
+
/>
|
|
550
|
+
) : undefined
|
|
551
|
+
}
|
|
552
|
+
/>
|
|
553
|
+
<StudioOverlays
|
|
554
|
+
projectId={projectId}
|
|
555
|
+
projectDir={fileManager.projectDir}
|
|
556
|
+
lintModal={lintModal}
|
|
557
|
+
closeLintModal={closeLintModal}
|
|
558
|
+
consoleErrors={consoleErrors}
|
|
559
|
+
clearConsoleErrors={() => setConsoleErrors(null)}
|
|
560
|
+
domEditSession={domEditSession}
|
|
561
|
+
activeCompPath={activeCompPath}
|
|
562
|
+
toasts={toasts}
|
|
563
|
+
dismissToast={dismissToast}
|
|
564
|
+
/>
|
|
565
|
+
</div>
|
|
566
|
+
</DomEditProvider>
|
|
567
|
+
</FileManagerProvider>
|
|
568
|
+
</PanelLayoutProvider>
|
|
580
569
|
</StudioPlaybackProvider>
|
|
581
570
|
</StudioShellProvider>
|
|
582
571
|
);
|
|
@@ -171,7 +171,7 @@ function AnimationPhase({
|
|
|
171
171
|
}}
|
|
172
172
|
className="flex-1 accent-studio-accent disabled:opacity-40"
|
|
173
173
|
/>
|
|
174
|
-
<span className="text-2xs text-neutral-400 font-mono w-8 text-right
|
|
174
|
+
<span className="text-2xs text-neutral-400 font-mono w-8 text-right shrink-0">
|
|
175
175
|
{intensity.toFixed(2)}
|
|
176
176
|
</span>
|
|
177
177
|
</div>
|
|
@@ -249,7 +249,7 @@ export const CaptionAnimationPanel = memo(function CaptionAnimationPanel() {
|
|
|
249
249
|
return (
|
|
250
250
|
<div className="flex flex-col h-full min-h-0">
|
|
251
251
|
{gated && (
|
|
252
|
-
<div className="
|
|
252
|
+
<div className="shrink-0 mx-3 mt-2 px-2 py-1.5 rounded-sm border border-amber-500/30 bg-amber-500/10">
|
|
253
253
|
<p className="text-2xs text-amber-300/90 leading-snug">
|
|
254
254
|
Animation editing isn't applied to playback or saved yet, so these controls are
|
|
255
255
|
disabled.
|
|
@@ -286,13 +286,13 @@ export const CaptionAnimationPanel = memo(function CaptionAnimationPanel() {
|
|
|
286
286
|
</div>
|
|
287
287
|
|
|
288
288
|
{/* Footer */}
|
|
289
|
-
<div className="
|
|
289
|
+
<div className="shrink-0 px-3 py-2 border-t border-neutral-800">
|
|
290
290
|
<button
|
|
291
291
|
type="button"
|
|
292
292
|
onClick={handleApplyToAll}
|
|
293
293
|
disabled={gated}
|
|
294
294
|
title={gated ? "Disabled until animation editing is applied to playback" : undefined}
|
|
295
|
-
className="w-full py-1.5 rounded border border-neutral-700 text-2xs text-neutral-300 hover:border-studio-accent/50 hover:text-studio-accent transition-colors disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:border-neutral-700 disabled:hover:text-neutral-300"
|
|
295
|
+
className="w-full py-1.5 rounded-sm border border-neutral-700 text-2xs text-neutral-300 hover:border-studio-accent/50 hover:text-studio-accent transition-colors disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:border-neutral-700 disabled:hover:text-neutral-300"
|
|
296
296
|
>
|
|
297
297
|
Apply to all groups
|
|
298
298
|
</button>
|
|
@@ -221,9 +221,8 @@ export function registerCaptionIframe(ref: React.RefObject<HTMLIFrameElement | n
|
|
|
221
221
|
|
|
222
222
|
/**
|
|
223
223
|
* True when the caption preview iframe is mounted AND visible. The caption
|
|
224
|
-
* store's isEditMode stays true while the preview is merely hidden
|
|
225
|
-
*
|
|
226
|
-
* the user can actually see the captions the undo would change.
|
|
224
|
+
* store's isEditMode stays true while the preview is merely hidden, so hotkeys must not
|
|
225
|
+
* route ⌘Z to the caption stack unless the user can see the captions the undo would change.
|
|
227
226
|
*/
|
|
228
227
|
export function isCaptionPreviewVisible(): boolean {
|
|
229
228
|
const iframe = registeredIframe?.current;
|
|
@@ -213,7 +213,7 @@ export const CaptionPropertyPanel = memo(function CaptionPropertyPanel({
|
|
|
213
213
|
return (
|
|
214
214
|
<div className="flex flex-col h-full min-h-0">
|
|
215
215
|
{/* Header */}
|
|
216
|
-
<div className="px-3 py-2 border-b border-neutral-800
|
|
216
|
+
<div className="px-3 py-2 border-b border-neutral-800 shrink-0">
|
|
217
217
|
<div className="flex items-center justify-between mb-1.5">
|
|
218
218
|
<span className="text-2xs text-neutral-500">{countLabel}</span>
|
|
219
219
|
</div>
|
|
@@ -225,7 +225,7 @@ export const CaptionPropertyPanel = memo(function CaptionPropertyPanel({
|
|
|
225
225
|
aria-selected={activeTab === "style"}
|
|
226
226
|
onClick={() => setActiveTab("style")}
|
|
227
227
|
className={[
|
|
228
|
-
"flex-1 py-0.5 rounded text-2xs font-medium transition-colors",
|
|
228
|
+
"flex-1 py-0.5 rounded-sm text-2xs font-medium transition-colors",
|
|
229
229
|
activeTab === "style"
|
|
230
230
|
? "bg-studio-accent/20 text-studio-accent border border-studio-accent/50"
|
|
231
231
|
: "text-neutral-500 border border-neutral-800 hover:text-neutral-300 hover:border-neutral-600",
|
|
@@ -239,7 +239,7 @@ export const CaptionPropertyPanel = memo(function CaptionPropertyPanel({
|
|
|
239
239
|
aria-selected={activeTab === "animation"}
|
|
240
240
|
onClick={() => setActiveTab("animation")}
|
|
241
241
|
className={[
|
|
242
|
-
"flex-1 py-0.5 rounded text-2xs font-medium transition-colors",
|
|
242
|
+
"flex-1 py-0.5 rounded-sm text-2xs font-medium transition-colors",
|
|
243
243
|
activeTab === "animation"
|
|
244
244
|
? "bg-studio-accent/20 text-studio-accent border border-studio-accent/50"
|
|
245
245
|
: "text-neutral-500 border border-neutral-800 hover:text-neutral-300 hover:border-neutral-600",
|
|
@@ -109,7 +109,7 @@ export const CaptionTimeline = memo(function CaptionTimeline({
|
|
|
109
109
|
tabIndex={0}
|
|
110
110
|
aria-label={`Caption word "${seg.text}"`}
|
|
111
111
|
aria-pressed={isSelected}
|
|
112
|
-
className={`absolute top-1 bottom-1 rounded flex items-center overflow-hidden cursor-pointer focus-visible:ring-1 focus-visible:ring-white outline-
|
|
112
|
+
className={`absolute top-1 bottom-1 rounded flex items-center overflow-hidden cursor-pointer focus-visible:ring-1 focus-visible:ring-white outline-hidden${
|
|
113
113
|
isSelected ? " ring-1 ring-white/50 z-10" : ""
|
|
114
114
|
}`}
|
|
115
115
|
style={{
|
|
@@ -2,7 +2,7 @@ import type React from "react";
|
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
|
|
4
4
|
export const inputCls =
|
|
5
|
-
"w-full bg-neutral-900 border border-neutral-800 rounded px-1.5 py-0.5 text-2xs text-neutral-200 font-mono outline-
|
|
5
|
+
"w-full bg-neutral-900 border border-neutral-800 rounded-sm px-1.5 py-0.5 text-2xs text-neutral-200 font-mono outline-hidden focus:border-studio-accent disabled:opacity-40 disabled:cursor-not-allowed";
|
|
6
6
|
|
|
7
7
|
export function Section({ label, children }: { label: string; children: React.ReactNode }) {
|
|
8
8
|
return (
|
|
@@ -20,7 +20,7 @@ export function Section({ label, children }: { label: string; children: React.Re
|
|
|
20
20
|
export function Row({ label, children }: { label: string; children: React.ReactNode }) {
|
|
21
21
|
return (
|
|
22
22
|
<div className="flex items-center gap-2">
|
|
23
|
-
<span className="text-2xs text-neutral-600 w-14 text-right
|
|
23
|
+
<span className="text-2xs text-neutral-600 w-14 text-right shrink-0">{label}</span>
|
|
24
24
|
<div className="flex-1 min-w-0">{children}</div>
|
|
25
25
|
</div>
|
|
26
26
|
);
|
|
@@ -66,8 +66,8 @@ export function AskAgentModal({
|
|
|
66
66
|
<div
|
|
67
67
|
className={
|
|
68
68
|
anchorPoint
|
|
69
|
-
? "hf-backdrop-in fixed inset-0 z-
|
|
70
|
-
: "hf-backdrop-in fixed inset-0 z-
|
|
69
|
+
? "hf-backdrop-in fixed inset-0 z-100 bg-black/60 backdrop-blur-xs"
|
|
70
|
+
: "hf-backdrop-in fixed inset-0 z-100 flex items-center justify-center bg-black/60 backdrop-blur-xs"
|
|
71
71
|
}
|
|
72
72
|
onClick={requestClose}
|
|
73
73
|
>
|
|
@@ -77,7 +77,7 @@ export function AskAgentModal({
|
|
|
77
77
|
aria-modal="true"
|
|
78
78
|
aria-label="Copy prompt to AI agent"
|
|
79
79
|
tabIndex={-1}
|
|
80
|
-
className={`w-[480px] rounded-2xl border border-neutral-800 bg-neutral-950 shadow-2xl outline-
|
|
80
|
+
className={`w-[480px] rounded-2xl border border-neutral-800 bg-neutral-950 shadow-2xl outline-hidden ${
|
|
81
81
|
anchorPoint ? "fixed" : ""
|
|
82
82
|
}`}
|
|
83
83
|
style={modalPositionStyle}
|
|
@@ -112,7 +112,7 @@ export function AskAgentModal({
|
|
|
112
112
|
<div className="px-5 py-4 space-y-3">
|
|
113
113
|
<textarea
|
|
114
114
|
ref={inputRef}
|
|
115
|
-
className="w-full h-24 px-3 py-2 rounded-lg border border-neutral-800 bg-neutral-900/60 text-sm text-neutral-200 placeholder-neutral-600 resize-none focus:outline-
|
|
115
|
+
className="w-full h-24 px-3 py-2 rounded-lg border border-neutral-800 bg-neutral-900/60 text-sm text-neutral-200 placeholder-neutral-600 resize-none focus:outline-hidden focus:border-studio-accent/60 focus:ring-1 focus:ring-studio-accent/30"
|
|
116
116
|
placeholder="Describe what you want to change…"
|
|
117
117
|
value={value}
|
|
118
118
|
onChange={(e) => setValue(e.target.value)}
|
|
@@ -127,7 +127,7 @@ export function AskAgentModal({
|
|
|
127
127
|
<summary className="text-[11px] text-neutral-500 cursor-pointer select-none hover:text-neutral-400">
|
|
128
128
|
Context included in prompt
|
|
129
129
|
</summary>
|
|
130
|
-
<pre className="mt-2 max-h-40 overflow-auto rounded-lg bg-neutral-900/80 px-3 py-2 text-[11px] leading-relaxed text-neutral-500 whitespace-pre-wrap break-
|
|
130
|
+
<pre className="mt-2 max-h-40 overflow-auto rounded-lg bg-neutral-900/80 px-3 py-2 text-[11px] leading-relaxed text-neutral-500 whitespace-pre-wrap wrap-break-word border border-neutral-800/50">
|
|
131
131
|
{contextPreview}
|
|
132
132
|
</pre>
|
|
133
133
|
</details>
|
|
@@ -86,6 +86,10 @@ describe("EditorShell timeline selection sync", () => {
|
|
|
86
86
|
handleTimelineElementSplit={vi.fn()}
|
|
87
87
|
handleRazorSplit={vi.fn()}
|
|
88
88
|
handleRazorSplitAll={vi.fn()}
|
|
89
|
+
onCopyClip={vi.fn(() => false)}
|
|
90
|
+
onPasteClip={vi.fn(async () => {})}
|
|
91
|
+
onDuplicateClip={vi.fn(async () => false)}
|
|
92
|
+
canPasteClip={vi.fn(() => false)}
|
|
89
93
|
setCompIdToSrc={vi.fn()}
|
|
90
94
|
setCompositionLoading={vi.fn()}
|
|
91
95
|
shouldShowMotionPath={false}
|