@dailies-studio/shot-editor 0.1.0 → 0.2.0
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/.vite/manifest.json +382 -0
- package/dist/assets/AgentPanel-CQejLbiX.js +2 -0
- package/dist/assets/AgentPanel-DJEphah0.css +1 -0
- package/dist/assets/AgentQuestionDialog-BqkD0kXF.js +1 -0
- package/dist/assets/CodeStudio-Dv4ihHpz.js +23 -0
- package/dist/assets/CommentsPanel-B4yhhT1T.js +1 -0
- package/dist/assets/ComponentLibraryRail-Ch_dsAru.js +1 -0
- package/dist/assets/ComponentStage-BRhRotyH.js +1 -0
- package/dist/assets/CurvePane-BjFVabKX.css +1 -0
- package/dist/assets/CurvePane-R22WzllJ.js +1 -0
- package/dist/assets/ExportDialog-CWLQWTmG.js +2 -0
- package/dist/assets/FontPicker-DWKaYL7F.js +1 -0
- package/dist/assets/FontPicker-v0IOIArM.css +1 -0
- package/dist/assets/GenerateDrawer-Bh3SqDKt.js +2 -0
- package/dist/assets/InsertDrawer-Ce1fod1L.js +1 -0
- package/dist/assets/LibraryBrowser-D9sEGz5w.js +2 -0
- package/dist/assets/MakeItYoursSection-CMO4319_.js +2 -0
- package/dist/assets/MaterialGraphCanvas-BFzl4wWR.js +23 -0
- package/dist/assets/MaterialGraphCanvas-BIUD59ik.css +1 -0
- package/dist/assets/MaterialWorkspace-CqTWqaRA.js +14 -0
- package/dist/assets/PreferencesDialog-CBf9_OoD.js +1 -0
- package/dist/assets/PresetsSection-CUEaoCVU.js +1 -0
- package/dist/assets/SoundHistory-BeS8EW1h.js +1 -0
- package/dist/assets/SoundMode-BmcZru3i.js +3 -0
- package/dist/assets/StockSounds-DdAUGRYK.js +1 -0
- package/dist/assets/TemplateFieldSection-CaeXpLFo.js +1 -0
- package/dist/assets/VersionHistoryPanel-CxG6XhNP.js +1 -0
- package/dist/assets/board-B88EPuLO.css +1 -0
- package/dist/assets/board-CL-he7SL.js +3 -0
- package/dist/assets/components-0oOSPN0l.js +1 -0
- package/dist/assets/googleFontRanges-gp32wJMo.js +1 -0
- package/dist/assets/googleFonts-BNon6M7X.js +1 -0
- package/dist/assets/iconsAndAliases-DL7gXP5j.js +1863 -0
- package/dist/assets/index-4F5NQmI8.css +1 -0
- package/dist/assets/index-BGHQGV5z.js +117 -0
- package/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/assets/libraryModel-CpIwfFha.js +1 -0
- package/dist/assets/lucide-6iK64tTB.js +9319 -0
- package/dist/assets/motionStamp-CH-Hew4E.js +1 -0
- package/dist/assets/takeMeasure-Tdg0TxEi.js +1 -0
- package/dist/assets/webmcp-BsB9gxWC.js +2 -0
- package/dist/index.html +34 -3
- package/package.json +12 -9
- package/src/addFamilies.ts +66 -0
- package/src/api.ts +1631 -55
- package/src/app/App.tsx +977 -198
- package/src/app/lazyPanel.tsx +137 -0
- package/src/app/lazySurfaces.tsx +203 -0
- package/src/audio/index.tsx +41 -10
- package/src/audio/meter.ts +485 -0
- package/src/audio/meterMath.ts +273 -0
- package/src/audio/meterStore.ts +155 -0
- package/src/audio/offlineMix.ts +289 -0
- package/src/audio/preview.ts +928 -118
- package/src/bridge.ts +15 -5
- package/src/bridgeTypes.ts +1611 -36
- package/src/channels.ts +17 -32
- package/src/fonts/googleFonts.ts +4 -0
- package/src/hostApi.ts +174 -0
- package/src/icons.tsx +770 -0
- package/src/layerWords.ts +61 -0
- package/src/main.tsx +56 -4
- package/src/panels/ResizeHandle.tsx +33 -43
- package/src/panels/agent/AgentDots.tsx +36 -0
- package/src/panels/agent/AgentPanel.tsx +119 -43
- package/src/panels/agent/AgentQuestionDialog.tsx +202 -0
- package/src/panels/agent/agent.css +113 -97
- package/src/panels/agent/agentGate.ts +35 -0
- package/src/panels/code/CodeDefaultsPanel.tsx +345 -0
- package/src/panels/code/CodeStudio.tsx +373 -0
- package/src/panels/code/FileTree.tsx +265 -0
- package/src/panels/code/codeBufferGuard.ts +52 -0
- package/src/panels/code/codeParts.tsx +321 -0
- package/src/panels/comments/CommentComposer.tsx +239 -0
- package/src/panels/comments/CommentThread.tsx +346 -0
- package/src/panels/comments/CommentsPanel.tsx +336 -0
- package/src/panels/comments/InboxButton.tsx +131 -0
- package/src/panels/comments/MentionMenu.tsx +98 -0
- package/src/panels/comments/parts.tsx +171 -0
- package/src/panels/export/ExportDialog.tsx +919 -96
- package/src/panels/export/ExportScrim.tsx +57 -0
- package/src/panels/files/AssetsTab.tsx +656 -0
- package/src/panels/files/FilePanel.tsx +1466 -216
- package/src/panels/files/LayerMarks.tsx +40 -0
- package/src/panels/files/LeftColumn.tsx +37 -0
- package/src/panels/files/McpSection.tsx +690 -47
- package/src/panels/files/MissingAssetsNotice.tsx +60 -0
- package/src/panels/files/assetDrag.ts +79 -0
- package/src/panels/files/resourceParts.tsx +255 -0
- package/src/panels/fonts/FontPicker.tsx +762 -0
- package/src/panels/fonts/faceCache.ts +207 -0
- package/src/panels/fonts/fontPicker.css +271 -0
- package/src/panels/fonts/pickerModel.ts +265 -0
- package/src/panels/fonts/pickerRequest.ts +46 -0
- package/src/panels/header/AccountAvatar.tsx +76 -0
- package/src/panels/header/AgentChip.tsx +77 -0
- package/src/panels/header/AppMenu.tsx +213 -0
- package/src/panels/header/Header.tsx +564 -84
- package/src/panels/header/HistoryControls.tsx +31 -5
- package/src/panels/header/PresenceStack.tsx +329 -0
- package/src/panels/header/ProjectTitle.tsx +232 -0
- package/src/panels/header/ShareButton.tsx +59 -0
- package/src/panels/header/StatusBadges.tsx +358 -27
- package/src/panels/header/SyncDeletedDialog.tsx +88 -0
- package/src/panels/header/ZoomControls.tsx +46 -15
- package/src/panels/header/agentHandoff.ts +52 -0
- package/src/panels/header/leave.ts +26 -0
- package/src/panels/help/HelpSection.tsx +189 -163
- package/src/panels/insert/InsertDrawer.tsx +723 -0
- package/src/panels/insert/iconSet.ts +109 -0
- package/src/panels/inspector/ExposeDot.tsx +117 -0
- package/src/panels/inspector/FramingRows.tsx +314 -44
- package/src/panels/inspector/InspectorFooter.tsx +91 -0
- package/src/panels/inspector/InspectorHead.tsx +425 -0
- package/src/panels/inspector/InspectorPanel.tsx +408 -124
- package/src/panels/inspector/KeyframeDot.tsx +373 -0
- package/src/panels/inspector/KeyframeSection.tsx +257 -0
- package/src/panels/inspector/MarkerSection.tsx +55 -11
- package/src/panels/inspector/ParamRow.tsx +84 -53
- package/src/panels/inspector/RightColumn.tsx +152 -0
- package/src/panels/inspector/TimeSection.tsx +866 -0
- package/src/panels/inspector/animate/EaseControl.tsx +244 -0
- package/src/panels/inspector/animate/PresetsSection.tsx +135 -0
- package/src/panels/inspector/animate/ShotSection.tsx +562 -48
- package/src/panels/inspector/design/AlignRow.tsx +95 -31
- package/src/panels/inspector/design/AppearanceSection.tsx +118 -9
- package/src/panels/inspector/design/ClonerSection.tsx +323 -62
- package/src/panels/inspector/design/ComponentSection.tsx +50 -43
- package/src/panels/inspector/design/CornerSection.tsx +45 -14
- package/src/panels/inspector/design/DefinitionProps.tsx +315 -0
- package/src/panels/inspector/design/DefinitionSection.tsx +136 -0
- package/src/panels/inspector/design/DeviceSection.tsx +210 -0
- package/src/panels/inspector/design/FillSection.tsx +83 -51
- package/src/panels/inspector/design/FontField.tsx +196 -0
- package/src/panels/inspector/design/HtmlSection.tsx +23 -12
- package/src/panels/inspector/design/InstanceSection.tsx +373 -154
- package/src/panels/inspector/design/MaskSection.tsx +84 -0
- package/src/panels/inspector/design/MaterialSection.tsx +177 -0
- package/src/panels/inspector/design/MediaSection.tsx +273 -120
- package/src/panels/inspector/design/MeshSection.tsx +910 -82
- package/src/panels/inspector/design/PaintRows.tsx +550 -0
- package/src/panels/inspector/design/PlateStyleSection.tsx +177 -0
- package/src/panels/inspector/design/ShadowSection.tsx +221 -48
- package/src/panels/inspector/design/SplineFollowSection.tsx +235 -0
- package/src/panels/inspector/design/StrokeSection.tsx +228 -43
- package/src/panels/inspector/design/TemplateFieldSection.tsx +57 -0
- package/src/panels/inspector/design/TransformSection.tsx +244 -50
- package/src/panels/inspector/design/TypographySection.tsx +679 -110
- package/src/panels/inspector/layout.ts +295 -0
- package/src/panels/inspector/propValue.ts +199 -0
- package/src/panels/inspector/scene/CameraSection.tsx +232 -22
- package/src/panels/inspector/scene/EffectsSection.tsx +722 -71
- package/src/panels/inspector/scene/MakeItYoursSection.tsx +180 -0
- package/src/panels/inspector/scene/SceneDocSection.tsx +191 -0
- package/src/panels/inspector/scene/SceneSection.tsx +219 -44
- package/src/panels/inspector/scene/TransitionSection.tsx +523 -72
- package/src/panels/inspector/storyboard/StoryboardReferenceSection.tsx +593 -0
- package/src/panels/inspector/storyboard/VideoStill.tsx +120 -0
- package/src/panels/inspector/timeModel.ts +190 -0
- package/src/panels/inspector/useDocWrite.ts +438 -146
- package/src/panels/library/LibraryBrowser.tsx +435 -0
- package/src/panels/library/LibraryGrid.tsx +190 -0
- package/src/panels/library/LibraryPreviewPanel.tsx +349 -0
- package/src/panels/library/LibraryRail.tsx +84 -0
- package/src/panels/library/LibrarySoundPanel.tsx +293 -0
- package/src/panels/library/SoundHistory.tsx +245 -0
- package/src/panels/library/StockSounds.tsx +390 -0
- package/src/panels/library/libraryModel.ts +147 -0
- package/src/panels/library/stockSearch.ts +77 -0
- package/src/panels/maskMarks.tsx +117 -0
- package/src/panels/material/MaterialCommentNode.tsx +54 -0
- package/src/panels/material/MaterialGraphCanvas.tsx +861 -0
- package/src/panels/material/MaterialGraphMenu.tsx +45 -0
- package/src/panels/material/MaterialGroupNode.tsx +56 -0
- package/src/panels/material/MaterialLibrary.tsx +253 -0
- package/src/panels/material/MaterialNode.tsx +453 -0
- package/src/panels/material/MaterialNodePalette.tsx +349 -0
- package/src/panels/material/MaterialParameterControls.tsx +525 -0
- package/src/panels/material/MaterialRerouteNode.tsx +42 -0
- package/src/panels/material/MaterialWorkspace.tsx +501 -0
- package/src/panels/material/NodePreview.tsx +70 -0
- package/src/panels/material/flowModel.ts +441 -0
- package/src/panels/material/parameterValues.ts +231 -0
- package/src/panels/material/previewScheduler.ts +235 -0
- package/src/panels/material/reactFlow.css +6 -0
- package/src/panels/material/socketGlyph.ts +85 -0
- package/src/panels/material/viewportMemory.ts +58 -0
- package/src/panels/preferences/PreferencesDialog.tsx +215 -0
- package/src/panels/share/ShareComponentDialog.tsx +247 -0
- package/src/panels/stage/StageMenu.tsx +35 -5
- package/src/panels/stage/StagePanel.tsx +338 -23
- package/src/panels/stage/cellSlots.tsx +70 -0
- package/src/panels/storyboard/BoardCanvas.tsx +739 -0
- package/src/panels/storyboard/BoardCursors.tsx +158 -0
- package/src/panels/storyboard/BoardDropDialog.tsx +161 -0
- package/src/panels/storyboard/BoardPlan.tsx +42 -0
- package/src/panels/storyboard/ComponentSheet.tsx +187 -0
- package/src/panels/storyboard/ComponentStage.tsx +235 -0
- package/src/panels/storyboard/MiniSketch.tsx +173 -0
- package/src/panels/storyboard/PartPicker.tsx +64 -0
- package/src/panels/storyboard/PlanPanel.tsx +617 -0
- package/src/panels/storyboard/ReferencePreview.tsx +217 -0
- package/src/panels/storyboard/ShotBrief.tsx +360 -0
- package/src/panels/storyboard/ShotCard.tsx +251 -0
- package/src/panels/storyboard/StagePreview.tsx +348 -0
- package/src/panels/storyboard/StillThumbs.tsx +162 -0
- package/src/panels/storyboard/StoryboardView.tsx +79 -0
- package/src/panels/storyboard/board.css +1065 -0
- package/src/panels/storyboard/board.ts +12 -0
- package/src/panels/storyboard/boardClipboard.ts +111 -0
- package/src/panels/storyboard/boardOrder.ts +68 -0
- package/src/panels/storyboard/boardRows.tsx +425 -0
- package/src/panels/storyboard/liveCap.ts +90 -0
- package/src/panels/storyboard/plan.css +295 -0
- package/src/panels/storyboard/posterCache.ts +133 -0
- package/src/panels/storyboard/shotboard/ComponentPicker.tsx +373 -0
- package/src/panels/storyboard/shotboard/ImagePicker.tsx +145 -0
- package/src/panels/storyboard/shotboard/ShotBoard.tsx +292 -0
- package/src/panels/storyboard/shotboard/SketchCanvas.tsx +443 -0
- package/src/panels/storyboard/shotboard/SketchInspector.tsx +471 -0
- package/src/panels/storyboard/shotboard/SketchItem.tsx +240 -0
- package/src/panels/storyboard/shotboard/SketchLayers.tsx +130 -0
- package/src/panels/storyboard/shotboard/SketchPlay.tsx +108 -0
- package/src/panels/storyboard/shotboard/SketchStrip.tsx +178 -0
- package/src/panels/storyboard/shotboard/SketchToolFooter.tsx +99 -0
- package/src/panels/storyboard/shotboard/sketch.css +1392 -0
- package/src/panels/storyboard/shotboard/sketchModel.ts +219 -0
- package/src/panels/storyboard/storyboardDrop.ts +164 -0
- package/src/panels/studio/ComponentLibraryRail.tsx +346 -0
- package/src/panels/studio/ComponentSidePanel.tsx +355 -0
- package/src/panels/studio/ComponentStudio.tsx +243 -0
- package/src/panels/studio/ComponentsHome.tsx +318 -0
- package/src/panels/studio/ComponentsPreview.tsx +179 -0
- package/src/panels/studio/EveryUse.tsx +244 -0
- package/src/panels/studio/ThisUsePanel.tsx +679 -0
- package/src/panels/studio/componentParts.tsx +341 -0
- package/src/panels/studio/components.ts +6 -0
- package/src/panels/studio/newCodeComponent.ts +66 -0
- package/src/panels/timeline/AudioFxButton.tsx +290 -0
- package/src/panels/timeline/AudioLane.tsx +674 -85
- package/src/panels/timeline/BlockRow.tsx +154 -85
- package/src/panels/timeline/ChannelRow.tsx +378 -129
- package/src/panels/timeline/CurvePane.tsx +508 -0
- package/src/panels/timeline/Filmstrip.tsx +361 -0
- package/src/panels/timeline/GenerateDrawer.tsx +407 -0
- package/src/panels/timeline/KeyStretch.tsx +115 -0
- package/src/panels/timeline/LifespanRow.tsx +730 -47
- package/src/panels/timeline/MarkerLane.tsx +46 -8
- package/src/panels/timeline/PlayButton.tsx +91 -0
- package/src/panels/timeline/PropertyPicker.tsx +254 -0
- package/src/panels/timeline/ShotRow.tsx +400 -0
- package/src/panels/timeline/SoundMode.tsx +1406 -0
- package/src/panels/timeline/TimelineDock.tsx +2338 -272
- package/src/panels/timeline/TransportVolume.tsx +163 -0
- package/src/panels/timeline/beatRuler.ts +74 -0
- package/src/panels/timeline/curveModel.ts +500 -0
- package/src/panels/timeline/duckUnderVoice.ts +68 -0
- package/src/panels/timeline/keyframeMenu.ts +138 -0
- package/src/panels/timeline/labelWidth.ts +49 -0
- package/src/panels/timeline/marquee.ts +155 -0
- package/src/panels/timeline/model.ts +1860 -199
- package/src/panels/timeline/snap.ts +125 -43
- package/src/panels/timeline/staggerPreview.tsx +92 -0
- package/src/panels/timeline/takeMeasure.ts +72 -0
- package/src/panels/timeline/useLive.ts +48 -0
- package/src/panels/timeline/viewport.ts +234 -0
- package/src/panels/toolbar/BackChip.tsx +116 -0
- package/src/panels/toolbar/CameraViewBar.tsx +118 -49
- package/src/panels/toolbar/CanvasBar.tsx +117 -0
- package/src/panels/toolbar/InsertButton.tsx +38 -0
- package/src/panels/toolbar/IsolationTrail.tsx +156 -0
- package/src/panels/toolbar/PanelToggles.tsx +86 -0
- package/src/panels/toolbar/ShadingBar.tsx +119 -26
- package/src/panels/toolbar/ToolDockBar.tsx +329 -80
- package/src/panels/toolbar/ToolFooter.tsx +102 -0
- package/src/panels/toolbar/ViewModeBar.tsx +247 -38
- package/src/panels/toolbar/WorkPlaneBar.tsx +94 -0
- package/src/panels/toolbar/useAddRows.tsx +326 -0
- package/src/panels/toolbar/useDismiss.ts +122 -0
- package/src/panels/versions/VersionHistoryPanel.tsx +274 -0
- package/src/panels/versions/versionModel.ts +103 -0
- package/src/panels/virtualWindow.ts +271 -0
- package/src/shotTokens.css +151 -60
- package/src/stage/FrustumGizmo.tsx +504 -84
- package/src/stage/GridPlane.tsx +225 -16
- package/src/stage/NodePreviews.tsx +628 -0
- package/src/stage/PerfHud.tsx +437 -47
- package/src/stage/SplitRenderer.tsx +816 -169
- package/src/stage/StageApp.tsx +4274 -486
- package/src/stage/StageRootBoundary.tsx +114 -0
- package/src/stage/StageTools.tsx +651 -151
- package/src/stage/TransformGizmo.tsx +696 -0
- package/src/stage/adaptivePresentation.ts +145 -0
- package/src/stage/bridgeClient.ts +2522 -41
- package/src/stage/exportWorker.ts +9 -0
- package/src/stage/feed.ts +305 -14
- package/src/stage/fontPreview.ts +176 -0
- package/src/stage/frustumGeometry.ts +319 -1
- package/src/stage/furnitureTokens.ts +33 -0
- package/src/stage/gizmoMath.ts +508 -16
- package/src/stage/gpuTimer.ts +276 -0
- package/src/stage/instanceModules.ts +194 -33
- package/src/stage/interactions/move.ts +24 -5
- package/src/stage/isolation.ts +291 -33
- package/src/stage/jsSelfProfiler.ts +325 -0
- package/src/stage/main.tsx +116 -16
- package/src/stage/modalState.ts +222 -23
- package/src/stage/moduleEpoch.ts +60 -0
- package/src/stage/motionPathStage.ts +279 -0
- package/src/stage/motionPreview.ts +74 -0
- package/src/stage/overlays/Overlays.tsx +1112 -159
- package/src/stage/overlays/Rulers.tsx +495 -0
- package/src/stage/panes.ts +159 -10
- package/src/stage/project.ts +68 -3
- package/src/stage/renderScaleController.ts +730 -0
- package/src/stage/rulers.ts +129 -0
- package/src/stage/sceneExtent.ts +75 -0
- package/src/stage/shading.ts +20 -0
- package/src/stage/splineStage.ts +632 -0
- package/src/stage/stagePerformanceTelemetry.ts +717 -0
- package/src/stage/stageTheme.ts +36 -0
- package/src/stage/stageWarmup.ts +11 -0
- package/src/stage/textAutoSize.ts +124 -0
- package/src/stage/tier1Export.ts +641 -0
- package/src/stage/tokenColor.ts +14 -9
- package/src/stage/view.ts +56 -9
- package/src/stage/workingView.ts +277 -33
- package/src/state/accountPrefs.ts +261 -0
- package/src/state/agentActions.ts +173 -15
- package/src/state/agentActivity.ts +198 -0
- package/src/state/agentQuestion.ts +239 -0
- package/src/state/bootOpen.ts +42 -0
- package/src/state/cameraVerbs.ts +139 -0
- package/src/state/clientId.ts +6 -1
- package/src/state/comments.ts +1099 -0
- package/src/state/context.tsx +19 -1
- package/src/state/editorPrefs.ts +220 -0
- package/src/state/errorReports.ts +121 -0
- package/src/state/fieldWrite.ts +161 -0
- package/src/state/fontRecents.ts +70 -0
- package/src/state/fonts.ts +656 -0
- package/src/state/graphClipboard.ts +414 -0
- package/src/state/imageThumbs.ts +216 -0
- package/src/state/insert.ts +444 -67
- package/src/state/isolationTrail.ts +92 -0
- package/src/state/keyMoves.ts +134 -0
- package/src/state/keyframeClipboard.ts +177 -0
- package/src/state/keymap.ts +1153 -117
- package/src/state/layoutPrefs.ts +272 -0
- package/src/state/layouts.ts +205 -0
- package/src/state/measureMedia.ts +167 -0
- package/src/state/menu.ts +2341 -28
- package/src/state/motionStamp.ts +7 -0
- package/src/state/panelSize.ts +375 -5
- package/src/state/pendingChanges.ts +119 -0
- package/src/state/playHold.ts +78 -0
- package/src/state/playbackPreparation.ts +562 -0
- package/src/state/posterCapture.ts +242 -0
- package/src/state/presence.ts +254 -0
- package/src/state/projectComponents.ts +160 -0
- package/src/state/renderEvents.ts +298 -18
- package/src/state/runtimeErrors.ts +46 -0
- package/src/state/selection.ts +12 -0
- package/src/state/shortcuts.ts +1606 -0
- package/src/state/sketchGuide.ts +51 -0
- package/src/state/splineRefs.ts +87 -0
- package/src/state/stageHealth.ts +259 -0
- package/src/state/stageWatchdog.ts +47 -0
- package/src/state/stillStage.ts +330 -0
- package/src/state/stillThumbs.ts +474 -0
- package/src/state/store.ts +23591 -2982
- package/src/state/storyboardModel.ts +528 -0
- package/src/state/sync.ts +1257 -0
- package/src/state/syncCache.ts +159 -0
- package/src/state/triangles.ts +13 -0
- package/src/state/types.ts +1698 -55
- package/src/state/unsavedGuard.ts +49 -0
- package/src/state/viewMode.ts +200 -0
- package/src/state/webmcp.ts +1128 -0
- package/src/state/workspace.ts +1147 -0
- package/src/styles/assets-tab.css +304 -0
- package/src/styles/canvas.css +545 -0
- package/src/styles/comments.css +1435 -0
- package/src/styles/controls.css +162 -0
- package/src/styles/dialogs.css +390 -0
- package/src/styles/insert-drawer.css +586 -0
- package/src/styles/inspector-board.css +207 -0
- package/src/styles/inspector-object.css +486 -0
- package/src/styles/inspector-shot.css +252 -0
- package/src/styles/inspector.css +360 -0
- package/src/styles/left-column.css +1628 -0
- package/src/styles/library-preview.css +575 -0
- package/src/styles/library.css +512 -0
- package/src/styles/modes/code.css +569 -0
- package/src/styles/modes/component.css +1561 -0
- package/src/styles/modes/material.css +1201 -0
- package/src/styles/modes/storyboard.css +518 -0
- package/src/styles/share-component.css +49 -0
- package/src/styles/shell.css +653 -0
- package/src/styles/shot-brief.css +360 -0
- package/src/styles/states.css +76 -0
- package/src/styles/sync.css +380 -0
- package/src/styles/timeline-graph.css +384 -0
- package/src/styles/timeline-meters.css +89 -0
- package/src/styles/timeline-rows.css +1959 -0
- package/src/styles/timeline-sound.css +1003 -0
- package/src/styles/timeline.css +754 -0
- package/src/styles/tool-footer.css +525 -0
- package/src/styles/topbar.css +886 -0
- package/src/styles/versions.css +262 -0
- package/src/styles.css +72 -2921
- package/src/tools.ts +108 -23
- package/dist/assets/index-B7notge7.css +0 -1
- package/dist/assets/index-BBE6Ta9L.js +0 -52
- package/src/panels/files/icons.tsx +0 -118
- package/src/panels/header/DocSwitcher.tsx +0 -85
- package/src/panels/header/TransportBar.tsx +0 -86
- package/src/panels/inspector/animate/BlockTiming.tsx +0 -341
- package/src/panels/inspector/animate/DuringBlocks.tsx +0 -85
- package/src/panels/inspector/animate/InOutPresets.tsx +0 -57
- package/src/panels/inspector/animate/ResolvedChannels.tsx +0 -150
- package/src/panels/inspector/animate/useBlocks.ts +0 -43
- package/src/panels/material/MaterialPicker.tsx +0 -172
- package/src/panels/timeline/SceneStrip.tsx +0 -145
- package/src/panels/toolbar/AddMenu.tsx +0 -230
- package/src/stage/MoveGizmo.tsx +0 -411
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// A VIDEO REFERENCE'S STILL: the video seeked to the card's frame, and
|
|
2
|
+
// "Extract still" beside it, which draws that frame to a canvas and uploads it
|
|
3
|
+
// as an image card in the same lane, carrying where it came from. Same-origin
|
|
4
|
+
// bytes, so the canvas is not tainted; drawn only after `seeked` with data in
|
|
5
|
+
// hand. It lives in the inspector: the lead is the one place a card is
|
|
6
|
+
// looked at up close.
|
|
7
|
+
//
|
|
8
|
+
// IT DRAWS THE LEAD BOX ITSELF, and a frame past the recording's end is said in
|
|
9
|
+
// its own row UNDER the box. The notice used to sit inside the 16:9 lead after
|
|
10
|
+
// a video 100% tall, and the lead clips, so the one message that explained a
|
|
11
|
+
// frozen still was never seen.
|
|
12
|
+
import { useEffect, useRef, useState } from "react";
|
|
13
|
+
import { useLocked } from "@dailies-studio/ui";
|
|
14
|
+
import { useStore } from "../../../state/context.js";
|
|
15
|
+
import { storyboardVideoSeconds } from "../../../state/storyboardModel.js";
|
|
16
|
+
|
|
17
|
+
const assetUrl = (path: string): string => `/studio/assets/${encodeURIComponent(path)}`;
|
|
18
|
+
|
|
19
|
+
export function VideoStill(props: { id: string; assetId: string; path: string; frame: number; fps: { num: number; den: number }; label: string }) {
|
|
20
|
+
const store = useStore();
|
|
21
|
+
const video = useRef<HTMLVideoElement | null>(null);
|
|
22
|
+
const [ready, setReady] = useState(false);
|
|
23
|
+
const [busy, setBusy] = useState(false);
|
|
24
|
+
const [error, setError] = useState<string | null>(null);
|
|
25
|
+
// Extract still WRITES (a new card, and its picture uploaded), so a
|
|
26
|
+
// viewer's locked panel takes it with the section's other write verbs.
|
|
27
|
+
const locked = useLocked();
|
|
28
|
+
const tolerance = Math.max(0.002, props.fps.den / props.fps.num / 2);
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const el = video.current;
|
|
32
|
+
if (el === null) return;
|
|
33
|
+
setReady(false);
|
|
34
|
+
setError(null);
|
|
35
|
+
const decoded = (): void => {
|
|
36
|
+
const seconds = storyboardVideoSeconds(props.frame, props.fps, el.duration);
|
|
37
|
+
if (seconds !== null && !el.seeking && el.readyState >= 2 && Math.abs(el.currentTime - seconds) <= tolerance) {
|
|
38
|
+
setReady(true);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const seek = (): void => {
|
|
42
|
+
const seconds = storyboardVideoSeconds(props.frame, props.fps, el.duration);
|
|
43
|
+
if (seconds === null) {
|
|
44
|
+
setError(`Frame ${props.frame} is outside this video's duration.`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
el.currentTime = seconds;
|
|
48
|
+
decoded();
|
|
49
|
+
};
|
|
50
|
+
el.addEventListener("seeked", decoded);
|
|
51
|
+
el.addEventListener("loadeddata", decoded);
|
|
52
|
+
el.addEventListener("loadedmetadata", seek);
|
|
53
|
+
if (el.readyState >= 1) seek();
|
|
54
|
+
return () => {
|
|
55
|
+
el.removeEventListener("loadedmetadata", seek);
|
|
56
|
+
el.removeEventListener("loadeddata", decoded);
|
|
57
|
+
el.removeEventListener("seeked", decoded);
|
|
58
|
+
};
|
|
59
|
+
}, [tolerance, props.frame, props.fps, props.path]);
|
|
60
|
+
|
|
61
|
+
const extract = async (): Promise<void> => {
|
|
62
|
+
const el = video.current;
|
|
63
|
+
if (el === null || !ready || busy || el.seeking || el.readyState < 2) return;
|
|
64
|
+
const seconds = storyboardVideoSeconds(props.frame, props.fps, el.duration);
|
|
65
|
+
if (seconds === null || Math.abs(el.currentTime - seconds) > tolerance) return;
|
|
66
|
+
// Capture identity, lane and provenance before either async boundary.
|
|
67
|
+
// The store registers the provenance with the new card in ONE edit.
|
|
68
|
+
const doc = store.getState().doc;
|
|
69
|
+
const item = doc?.resources?.references?.find((r) => r.id === props.id);
|
|
70
|
+
if (doc === null || item?.type !== "asset" || item.asset !== props.assetId || doc.assets[item.asset]?.path !== props.path) return;
|
|
71
|
+
const source = { frame: props.frame, asset: props.assetId };
|
|
72
|
+
const lane = item.part ?? null;
|
|
73
|
+
setBusy(true);
|
|
74
|
+
try {
|
|
75
|
+
const canvas = document.createElement("canvas");
|
|
76
|
+
canvas.width = el.videoWidth;
|
|
77
|
+
canvas.height = el.videoHeight;
|
|
78
|
+
const ctx = canvas.getContext("2d");
|
|
79
|
+
if (ctx === null) throw new Error("Could not read this video frame.");
|
|
80
|
+
ctx.drawImage(el, 0, 0);
|
|
81
|
+
const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, "image/png"));
|
|
82
|
+
if (blob === null) throw new Error("Could not encode this video frame.");
|
|
83
|
+
if (store.getState().doc?.id !== doc.id) return;
|
|
84
|
+
await store.addReferenceFromFile(new File([blob], `${props.label}-f${source.frame}.png`, { type: "image/png" }), lane, source);
|
|
85
|
+
} catch (e) {
|
|
86
|
+
store.reportError(e instanceof Error ? e.message : String(e));
|
|
87
|
+
} finally {
|
|
88
|
+
setBusy(false);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<>
|
|
94
|
+
<div className="insp-reference-lead">
|
|
95
|
+
<video
|
|
96
|
+
ref={video}
|
|
97
|
+
className="insp-video-still"
|
|
98
|
+
src={assetUrl(props.path)}
|
|
99
|
+
preload="metadata"
|
|
100
|
+
muted
|
|
101
|
+
playsInline
|
|
102
|
+
/>
|
|
103
|
+
<button
|
|
104
|
+
type="button"
|
|
105
|
+
className="btn"
|
|
106
|
+
disabled={!ready || busy || locked}
|
|
107
|
+
title="Save this frame as an image card in the same lane"
|
|
108
|
+
onClick={() => void extract()}
|
|
109
|
+
>
|
|
110
|
+
{busy ? "Saving…" : "Extract still"}
|
|
111
|
+
</button>
|
|
112
|
+
</div>
|
|
113
|
+
{error === null ? null : (
|
|
114
|
+
<div className="insp-notice is-warn" role="status">
|
|
115
|
+
{error}
|
|
116
|
+
</div>
|
|
117
|
+
)}
|
|
118
|
+
</>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// THE TIME SECTION'S ARITHMETIC, WITH NO REACT AND NO DOCUMENT WRITE IN IT.
|
|
2
|
+
//
|
|
3
|
+
// Everything here is a pure function over facts the caller already has, for the
|
|
4
|
+
// reason `panels/timeline/model.ts` exists one lane over: a number the panel
|
|
5
|
+
// derives inline is a number no test can reach, and this lane has paid for that
|
|
6
|
+
// before — a strip that drew a hold one frame off merely looked fine.
|
|
7
|
+
//
|
|
8
|
+
// ── WHAT IS DELIBERATELY NOT HERE ───────────────────────────────────────
|
|
9
|
+
//
|
|
10
|
+
// The clip arithmetic itself. `videoClipOf` (shot/media.ts) is THE seam for
|
|
11
|
+
// `(f - offsetFrames) * timeScale` and its header refuses a second copy by
|
|
12
|
+
// name, so this file consumes a `VideoClipInfo` and never rebuilds one. The
|
|
13
|
+
// EDITS are not here either: `trimLayer`, `slipLayer`, `retimeVideo` and
|
|
14
|
+
// `setVideoSource` already own the clamps, the refusals and the fade repair,
|
|
15
|
+
// and `writeLifespan` (panels/timeline/model.ts) already routes a video edge
|
|
16
|
+
// through them and a plain layer's edge around them. A second spelling of any
|
|
17
|
+
// of that would be the drift those files were written to stop.
|
|
18
|
+
//
|
|
19
|
+
// What is left is the three questions a PANEL asks that nothing else does:
|
|
20
|
+
// which edge actually ends this clip, where `out` would have to be for the
|
|
21
|
+
// recording to play through once, and what a linear gain reads as in dB.
|
|
22
|
+
import { MAX_AUDIO_GAIN, gainToDb } from "@dailies-studio/shot/doc";
|
|
23
|
+
import type { VideoClipInfo } from "@dailies-studio/shot/doc";
|
|
24
|
+
import type { Rational } from "@dailies-studio/engine";
|
|
25
|
+
import { timecode } from "../timeline/model.js";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* WHICH EDGE ACTUALLY ENDS THE CLIP.
|
|
29
|
+
*
|
|
30
|
+
* Three different things can stop a recording being on screen and an author
|
|
31
|
+
* looking at a bar cannot tell them apart:
|
|
32
|
+
*
|
|
33
|
+
* `out` the clip's own window end, which is the one they authored;
|
|
34
|
+
* `source` the footage running out (or, played backwards, reaching its own
|
|
35
|
+
* start) somewhere INSIDE that window, after which every remaining
|
|
36
|
+
* frame is the same frozen picture;
|
|
37
|
+
* `shot` the shot ending first, which cuts the window off wherever it is.
|
|
38
|
+
*
|
|
39
|
+
* The three are ranked by WHICH HAPPENS FIRST, because that is the one that
|
|
40
|
+
* decides what the viewer sees. A frozen tail is the expensive one to miss: the
|
|
41
|
+
* bar is full width, the export is the right length, and the last second of it
|
|
42
|
+
* is a still nobody noticed.
|
|
43
|
+
*/
|
|
44
|
+
export type ClipCloseKind = "out" | "source" | "shot";
|
|
45
|
+
|
|
46
|
+
export interface ClipClose {
|
|
47
|
+
kind: ClipCloseKind;
|
|
48
|
+
/** SCENE-LOCAL frame where it happens. For `source` this is the crossing,
|
|
49
|
+
* which is where the picture stops changing, not where the bar stops. */
|
|
50
|
+
frame: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* `timeScale` is passed rather than read off the clip, because `VideoClipInfo`
|
|
55
|
+
* deliberately does not carry it: the sign is what decides WHICH of the two
|
|
56
|
+
* crossings the seam reports is the tail one, and `videoClipOf`'s header says
|
|
57
|
+
* so ("a consumer that shades 'frozen from here' reads the sign of
|
|
58
|
+
* `timeScale`"). Asking the caller for the field it already read is cheaper
|
|
59
|
+
* than widening the seam's return for one consumer.
|
|
60
|
+
*
|
|
61
|
+
* THE CROSSING MAY LIE OUTSIDE THE WINDOW, which the seam also states, and both
|
|
62
|
+
* ends of that matter here:
|
|
63
|
+
*
|
|
64
|
+
* at or before `in` the WHOLE clip is one frozen picture. Nothing closes at
|
|
65
|
+
* the tail, so the tail is still the window's own end or the shot's — the
|
|
66
|
+
* caption must not claim an edge the viewer never reaches.
|
|
67
|
+
* at or after `out` the seam already answers null, so there is nothing to
|
|
68
|
+
* rank: the window ends before the footage does.
|
|
69
|
+
*/
|
|
70
|
+
export function closingEdge(
|
|
71
|
+
clip: VideoClipInfo,
|
|
72
|
+
sceneDurationFrames: number,
|
|
73
|
+
timeScale: number,
|
|
74
|
+
): ClipClose {
|
|
75
|
+
const shotEnd = Math.max(0, Math.trunc(sceneDurationFrames));
|
|
76
|
+
// Played backwards the source counts DOWN, so the frozen end is the t=0
|
|
77
|
+
// crossing (`leadFrom`) and not the run-out one. A zero or non-finite rate
|
|
78
|
+
// cannot reach the document (validate refuses it) and reads as forward here
|
|
79
|
+
// rather than as a fourth case.
|
|
80
|
+
const freeze = timeScale < 0 ? clip.leadFrom : clip.holdFrom;
|
|
81
|
+
const windowEnd = Math.min(clip.out, shotEnd);
|
|
82
|
+
if (freeze !== null && freeze > clip.in && freeze < windowEnd) {
|
|
83
|
+
return { kind: "source", frame: freeze };
|
|
84
|
+
}
|
|
85
|
+
// AT EQUALITY THE SHOT WINS. A window that ends exactly on the shot's last
|
|
86
|
+
// frame is bounded by the shot whatever the author typed, and a layer with no
|
|
87
|
+
// `lifetime` at all lands here by construction: its out IS the shot's end.
|
|
88
|
+
return clip.out >= shotEnd ? { kind: "shot", frame: shotEnd } : { kind: "out", frame: clip.out };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The caption, as ONE line of prose.
|
|
93
|
+
*
|
|
94
|
+
* Separate from the ranking above so the decision is testable without matching
|
|
95
|
+
* on a sentence, and so the sentence can be read for its own sake: it is the
|
|
96
|
+
* only place in the rail that names a frozen tail, and an author who cannot
|
|
97
|
+
* tell a hold from a still has no other way to find out.
|
|
98
|
+
*/
|
|
99
|
+
export function closingCaption(close: ClipClose, fps: Rational, timeScale: number): string {
|
|
100
|
+
const at = `frame ${formatFrame(close.frame)} (${timecode(close.frame, fps)})`;
|
|
101
|
+
if (close.kind === "shot") return `Ends with the shot, at ${at}.`;
|
|
102
|
+
if (close.kind === "out") return `Ends on its own out, at ${at}.`;
|
|
103
|
+
return timeScale < 0
|
|
104
|
+
? `Ends on the recording: it reaches its own start at ${at}, and the first frame holds to the out.`
|
|
105
|
+
: `Ends on the recording: it runs out at ${at}, and the last frame holds to the out.`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** A crossing is a BOUNDARY and may be fractional when the rate is
|
|
109
|
+
* (`videoClipOf` refuses to round it, because an op wants the true number).
|
|
110
|
+
* A caption is prose, so it shows at most one decimal and never `12.0000001`. */
|
|
111
|
+
function formatFrame(frame: number): string {
|
|
112
|
+
if (!Number.isFinite(frame)) return "?";
|
|
113
|
+
return Number.isInteger(frame) ? String(frame) : frame.toFixed(1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* WHERE `out` WOULD HAVE TO BE for the window to play the recording through
|
|
118
|
+
* once from where it currently starts, or null when there is no such frame.
|
|
119
|
+
*
|
|
120
|
+
* Null covers three real states and they are not errors:
|
|
121
|
+
* nobody has probed the asset, so its length is unknown (`sourceDurationFrames`
|
|
122
|
+
* is null, which the seam's own doc says is "unknown", never "empty");
|
|
123
|
+
* the rate is not usable (a document that never passed the save gate);
|
|
124
|
+
* the answer lands at or before `in`, which is a clip whose footage is already
|
|
125
|
+
* behind it — there is no natural length left to ask for.
|
|
126
|
+
*
|
|
127
|
+
* PLAYED BACKWARDS the recording ends when its own t=0 arrives, which is
|
|
128
|
+
* `offsetFrames` itself, so the forward `duration / rate` term does not apply.
|
|
129
|
+
* Both are the same statement — "run until the source clamps" — read through
|
|
130
|
+
* the sign.
|
|
131
|
+
*
|
|
132
|
+
* ROUNDED, because a lifetime is integer. The caller hands the result to
|
|
133
|
+
* `writeLifespan`, so the footage clamp and the scene clamp are applied by
|
|
134
|
+
* `trimLayer`, once, where they already live.
|
|
135
|
+
*/
|
|
136
|
+
export function naturalOutFrame(
|
|
137
|
+
clip: VideoClipInfo,
|
|
138
|
+
offsetFrames: number,
|
|
139
|
+
timeScale: number,
|
|
140
|
+
): number | null {
|
|
141
|
+
const duration = clip.sourceDurationFrames;
|
|
142
|
+
if (duration === null || !Number.isFinite(timeScale) || timeScale === 0) return null;
|
|
143
|
+
if (!Number.isFinite(offsetFrames)) return null;
|
|
144
|
+
const end = timeScale > 0 ? offsetFrames + duration / timeScale : offsetFrames;
|
|
145
|
+
if (!Number.isFinite(end)) return null;
|
|
146
|
+
const at = Math.round(end);
|
|
147
|
+
return at > clip.in ? at : null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Linear gain as dB, and back.
|
|
152
|
+
*
|
|
153
|
+
* `gainToDb` is the document plane's (audioLoudness.ts) and is imported rather
|
|
154
|
+
* than restated, because the loudness lane compares its answer against stored
|
|
155
|
+
* targets — two spellings of one conversion would make a level match by half a
|
|
156
|
+
* decibel and nothing would say which half.
|
|
157
|
+
*
|
|
158
|
+
* The inverse is not there because nothing in the data plane needed it: dB is
|
|
159
|
+
* how a MIXER FACE is labelled, and the document stores the linear number the
|
|
160
|
+
* engine multiplies by. So it lives here, next to the face that needs it, and
|
|
161
|
+
* the round trip is pinned by this file's test.
|
|
162
|
+
*
|
|
163
|
+
* SILENCE IS THE FLOOR, not minus infinity. `gainToDb(0)` answers -120 by
|
|
164
|
+
* contract, and anything at or below that reads back as a true 0 rather than
|
|
165
|
+
* as 1e-6: a muted-by-level clip must be able to come back.
|
|
166
|
+
*/
|
|
167
|
+
export const MIN_GAIN_DB = -120;
|
|
168
|
+
|
|
169
|
+
export function dbToGain(db: number): number {
|
|
170
|
+
if (!Number.isFinite(db) || db <= MIN_GAIN_DB) return 0;
|
|
171
|
+
return Math.pow(10, db / 20);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** The dB a field SHOWS for a stored gain: one decimal, which is the finest
|
|
175
|
+
* step a level fader is read at, and the floor rather than -Infinity. */
|
|
176
|
+
export function gainAsDb(gain: number): number {
|
|
177
|
+
const db = gainToDb(Number.isFinite(gain) ? gain : 1);
|
|
178
|
+
return Math.round(Math.max(MIN_GAIN_DB, db) * 10) / 10;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* The mixer's ceiling, in dB, and it is NOT `gainAsDb(MAX_AUDIO_GAIN)`.
|
|
183
|
+
*
|
|
184
|
+
* EXACT, deliberately. A level field's hard `max` is what every commit path
|
|
185
|
+
* clamps to, so rounding it to the one decimal the field DISPLAYS would put the
|
|
186
|
+
* ceiling at 6.0 dB — a gain of 1.9953 — and the top of the fader would be a
|
|
187
|
+
* number the author can see (2) and never reach. The display rounds; the limit
|
|
188
|
+
* does not.
|
|
189
|
+
*/
|
|
190
|
+
export const MAX_GAIN_DB = gainToDb(MAX_AUDIO_GAIN);
|