@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,7 @@
|
|
|
1
|
+
// THE MOTION PRESETS' STAMP, on demand: `stampMotionPreset` and its catalog
|
|
2
|
+
// are a chunk of their own, kept out of the entry's budget like the Motion
|
|
3
|
+
// section that offers them, and fetched at idle with it
|
|
4
|
+
// (`prefetchInspectorSections`). The store's `applyMotionPreset` and
|
|
5
|
+
// `previewMotion` import this module when first used; by then the idle fetch
|
|
6
|
+
// has usually landed, so a pick waits on nothing.
|
|
7
|
+
export { stampMotionPreset } from "@dailies-studio/shot/doc";
|
package/src/state/panelSize.ts
CHANGED
|
@@ -9,9 +9,58 @@
|
|
|
9
9
|
// which is passed in per drag — a dock taller than the window is a dock with
|
|
10
10
|
// no stage behind it.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
import type { ShotEditorState } from "./types.js";
|
|
13
|
+
import { componentEditOpen, workspaceOf } from "./workspace.js";
|
|
14
|
+
import type { BoardRightPanel } from "./workspace.js";
|
|
15
|
+
import { foldedDockContentH } from "../panels/timeline/model.js";
|
|
16
|
+
|
|
17
|
+
export const RAIL_WIDTH = { min: 168, max: 460, default: 224 } as const;
|
|
13
18
|
export const DOCK_HEIGHT = { min: 120, max: 640, default: 300 } as const;
|
|
14
19
|
|
|
20
|
+
/**
|
|
21
|
+
* The dock's OTHER dimension: how wide one frame is drawn, in CSS px.
|
|
22
|
+
*
|
|
23
|
+
* It sits beside the panel bounds for the reason they are here at all: the
|
|
24
|
+
* store's clamp, the initial state, the wheel zoom, the slider and the tests
|
|
25
|
+
* were four separate restatements of `0.2`, `60` and `6`, which is three
|
|
26
|
+
* numbers with four owners. `setDockPpf` is the one writer and it reads this.
|
|
27
|
+
*
|
|
28
|
+
* The floor is where a frame is a fifth of a pixel, which is about as far out
|
|
29
|
+
* as a ten-minute document can be fitted; the ceiling is 60px a frame, where
|
|
30
|
+
* one second fills a laptop's lane and there is nothing left to see by going
|
|
31
|
+
* further. The default is the zoom a document opens at before `fit` measures
|
|
32
|
+
* the lane it actually has.
|
|
33
|
+
*/
|
|
34
|
+
export const DOCK_PPF = { min: 0.2, max: 60, default: 6 } as const;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The inspector, which was a hardcoded 288 in CSS and draggable nowhere.
|
|
38
|
+
*
|
|
39
|
+
* 288 was too narrow for its own contents and there was no way to say so: the
|
|
40
|
+
* camera's Zoom / Roll / Focus row had ~66px per field, so `.numfield-label`
|
|
41
|
+
* hit its 14px floor and the three labels rendered "Z…", "R…", "F…". The panel
|
|
42
|
+
* had been WORKED AROUND rather than widened — `SceneDocSection` carries a
|
|
43
|
+
* comment about shortening a label because "`.insp-label` is capped at 60% of a
|
|
44
|
+
* 288px pill" — which is the sign a constant is wrong rather than a label.
|
|
45
|
+
*
|
|
46
|
+
* 320 was the first answer, chosen while the panel still had to fit THREE
|
|
47
|
+
* labelled pills in a row. It does not any more: `.numfield-label` is
|
|
48
|
+
* `flex: none` and the two-pill rule holds the row to two, so the width that
|
|
49
|
+
* was buying a third column is now buying nothing but a narrower stage. On a
|
|
50
|
+
* 1366 laptop that column is a twentieth of the screen.
|
|
51
|
+
*
|
|
52
|
+
* 288 with 8/10 padding leaves 252px across a row: 123px per pill in a
|
|
53
|
+
* two-pill row, of which ~61px is label — nine characters at 12px, and the
|
|
54
|
+
* longest label the panel has is "Spread".
|
|
55
|
+
*
|
|
56
|
+
* 304 is the Paper redesign's column (2026-10-04). Its rows put the label
|
|
57
|
+
* OUTSIDE the field and add a tick slider to the axis rows, which is what the
|
|
58
|
+
* extra 16px pays for. Bounds: 264 is where the inputs reach their 24px floor
|
|
59
|
+
* and there is nothing left to give; 480 is where the panel stops being a
|
|
60
|
+
* rail and starts taking the stage's width for a column of controls.
|
|
61
|
+
*/
|
|
62
|
+
export const INSPECTOR_WIDTH = { min: 264, max: 480, default: 304 } as const;
|
|
63
|
+
|
|
15
64
|
/** Clamp to whole pixels. Whole, because a fractional panel width puts every
|
|
16
65
|
* box positioned off it on a half pixel and the seams stop being crisp. */
|
|
17
66
|
export function clampSize(value: number, min: number, max: number): number {
|
|
@@ -19,8 +68,329 @@ export function clampSize(value: number, min: number, max: number): number {
|
|
|
19
68
|
return Math.round(Math.min(max, Math.max(min, value)));
|
|
20
69
|
}
|
|
21
70
|
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
|
|
25
|
-
|
|
71
|
+
/**
|
|
72
|
+
* The docked shell's three bar heights, for the arithmetic that needs them.
|
|
73
|
+
* They mirror `--topbar-h`, `--panel-head-h` and `--dock-head-h` in
|
|
74
|
+
* packages/ui/src/tokens.css, pinned by rowMetrics.test.ts.
|
|
75
|
+
*
|
|
76
|
+
* THE TOP BAR is the window's first row. THE PANEL HEAD is the second: the
|
|
77
|
+
* canvas bar and both column heads, so one hairline crosses the window under
|
|
78
|
+
* them. THE DOCK HEAD is the timeline's head and transport, which is also the
|
|
79
|
+
* whole bottom row when the dock is collapsed.
|
|
80
|
+
*/
|
|
81
|
+
export const TOPBAR_H = 44;
|
|
82
|
+
export const PANEL_HEAD_H = 40;
|
|
83
|
+
export const DOCK_HEAD_H = 40;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The tool footer's height: the docked row under the canvas cell that holds
|
|
87
|
+
* the tools. It mirrors `--tool-footer-h` in styles/shell.css `:root`, pinned
|
|
88
|
+
* by rowMetrics.test.ts.
|
|
89
|
+
*
|
|
90
|
+
* A ROW, NOT A FLOAT. The tools used to ride a pill over the bottom of the
|
|
91
|
+
* picture, so the canvas cell lost nothing to them and only the stage's inset
|
|
92
|
+
* did. The footer is a grid track of its own, so it takes its height from the
|
|
93
|
+
* canvas, and the dock's ceiling has to pay for it while it is shown.
|
|
94
|
+
*/
|
|
95
|
+
export const TOOL_FOOTER_H = 48;
|
|
96
|
+
|
|
97
|
+
/** The state `toolFooterShown` reads. */
|
|
98
|
+
export type ToolFooterFields = Pick<
|
|
99
|
+
ShotEditorState,
|
|
100
|
+
| "name"
|
|
101
|
+
| "doc"
|
|
102
|
+
| "editingDef"
|
|
103
|
+
| "materialWorkspace"
|
|
104
|
+
| "codeComponent"
|
|
105
|
+
| "componentsTab"
|
|
106
|
+
| "storyboardOpen"
|
|
107
|
+
> &
|
|
108
|
+
Partial<Pick<ShotEditorState, "componentsOpen">>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Whether the tool footer is on screen. ONE ANSWER for every reader: App
|
|
112
|
+
* mounts the row and sets its track and its inset edge from it, and
|
|
113
|
+
* `fitShell` charges the dock's ceiling for it. Readers asking different
|
|
114
|
+
* versions of the question is how a row ends up drawn with nothing in it, or
|
|
115
|
+
* a dock sized for a footer that is not there.
|
|
116
|
+
*
|
|
117
|
+
* A LOADED DOCUMENT. With no document there is no timeline either, and a row
|
|
118
|
+
* of tools over a canvas that has nothing to draw into is noise.
|
|
119
|
+
*
|
|
120
|
+
* AT EVERY LEVEL OF THE STAGE: the Project context, a shot and a definition.
|
|
121
|
+
* The footer is not only the tools any more. Its right half is the view track
|
|
122
|
+
* (Video, 3D, Camera, Split), which applies at every level, and in the Project
|
|
123
|
+
* context its left half names the shot under the playhead (ToolFooter.tsx).
|
|
124
|
+
* The TOOLS still answer to the narrower question: ToolDockBar renders only
|
|
125
|
+
* inside a shot or a definition, for the reason argued there.
|
|
126
|
+
*
|
|
127
|
+
* ONLY IN THE STAGE WORKSPACE. The three modes show their own content in the
|
|
128
|
+
* canvas cell, and the tools address the film's canvas, which none of them is.
|
|
129
|
+
* The one exception is Components' Edit tab on a definition
|
|
130
|
+
* (`componentEditOpen`): it edits the definition's layers, so the tools are
|
|
131
|
+
* there while editing inside one.
|
|
132
|
+
*/
|
|
133
|
+
export function toolFooterShown(s: ToolFooterFields): boolean {
|
|
134
|
+
return (
|
|
135
|
+
s.name !== null &&
|
|
136
|
+
s.doc !== null &&
|
|
137
|
+
(workspaceOf(s) === "stage" || componentEditOpen(s))
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The smallest canvas the docked shell leaves, whatever the author dragged.
|
|
143
|
+
*
|
|
144
|
+
* WIDTH: the canvas cell's two docked rows have to fit it. The canvas bar
|
|
145
|
+
* above the picture is one row of place, panes and zoom, and the tool footer
|
|
146
|
+
* under it is one `nowrap` row: the 377px tools, then the view track and the
|
|
147
|
+
* Clean view eye, which compact and fold to fit (tool-footer.css has the
|
|
148
|
+
* measured widths). 640 (616 of content inside the footer's 12px padding)
|
|
149
|
+
* holds the tools beside the COMPACT track; the full one needs a 660 column,
|
|
150
|
+
* and the folded picker fits down to 522.
|
|
151
|
+
* It also holds every canvas bar but the crowded ones that canvas.css gives
|
|
152
|
+
* way for. HEIGHT: enough picture between
|
|
153
|
+
* the canvas bar and the footer to judge a frame.
|
|
154
|
+
*/
|
|
155
|
+
export const CANVAS_MIN = { width: 640, height: 240 } as const;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* The dock's ceiling for a given window: what is left once the top bar, the
|
|
159
|
+
* panel head, the smallest canvas and (when it is shown) the tool footer have
|
|
160
|
+
* taken theirs, inside the dock's own bounds.
|
|
161
|
+
*
|
|
162
|
+
* THE FOOTER IS AN ARGUMENT, not a constant, because it is not always there:
|
|
163
|
+
* the modes collapse its row, and charging them for it would cost a 768px
|
|
164
|
+
* laptop 48px of storyboard strip for nothing. Every level of the stage
|
|
165
|
+
* workspace pays it, the Project context included. At 1366 by 768 the
|
|
166
|
+
* ceiling is 396 with the footer (768 - 44 - 40 - 240 - 48) and 444
|
|
167
|
+
* without it.
|
|
168
|
+
*/
|
|
169
|
+
export function dockCeiling(viewportHeight: number, footer = false): number {
|
|
170
|
+
const vh = Number.isFinite(viewportHeight) ? viewportHeight : 0;
|
|
171
|
+
return clampSize(
|
|
172
|
+
vh - TOPBAR_H - PANEL_HEAD_H - CANVAS_MIN.height - (footer ? TOOL_FOOTER_H : 0),
|
|
173
|
+
DOCK_HEIGHT.min,
|
|
174
|
+
DOCK_HEIGHT.max,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** What the grid lays out, as opposed to what the author stored. */
|
|
179
|
+
export interface ShellFit {
|
|
180
|
+
railWidth: number;
|
|
181
|
+
inspectorWidth: number;
|
|
182
|
+
/** The bottom row: the dock's height, or its head when it is collapsed. */
|
|
183
|
+
dockRow: number;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The docked shell's tracks for a window, from the sizes the author stored.
|
|
188
|
+
*
|
|
189
|
+
* DISPLAY ONLY. The stored sizes are the author's and are never rewritten
|
|
190
|
+
* here: a window too small for them shows the fitted sizes, and the stored
|
|
191
|
+
* ones come back the moment the window can hold them. The setters keep only
|
|
192
|
+
* each panel's own bounds (layoutPrefs.ts relies on that).
|
|
193
|
+
*
|
|
194
|
+
* THE RAIL GIVES FIRST, then the inspector, each down to its own minimum,
|
|
195
|
+
* until the canvas has `CANVAS_MIN.width`. Below both minimums the canvas
|
|
196
|
+
* takes the deficit: the chrome does not shrink past what its rows need.
|
|
197
|
+
*
|
|
198
|
+
* A COLLAPSED COLUMN STILL COUNTS. Its track keeps its width because the
|
|
199
|
+
* timeline's name column and meters sit under it, so collapsing a panel never
|
|
200
|
+
* moves a bar under the pointer, and the canvas simply spans over it.
|
|
201
|
+
*
|
|
202
|
+
* THE DOCK PAYS FOR THE TOOL FOOTER only while the footer is shown, which is
|
|
203
|
+
* why the footer's fields ride in with the sizes: `toolFooterShown` is the
|
|
204
|
+
* same question App asks before it mounts the row.
|
|
205
|
+
*/
|
|
206
|
+
export function fitShell(
|
|
207
|
+
viewportWidth: number,
|
|
208
|
+
viewportHeight: number,
|
|
209
|
+
stored: { railWidth: number; inspectorWidth: number; dockHeight: number; dockCollapsed: boolean } & ToolFooterFields &
|
|
210
|
+
Partial<Pick<ShotEditorState, "enteredScene" | "dockMode">>,
|
|
211
|
+
): ShellFit {
|
|
212
|
+
const ceiling = dockCeiling(viewportHeight, toolFooterShown(stored));
|
|
213
|
+
return {
|
|
214
|
+
...fitColumns(viewportWidth, stored),
|
|
215
|
+
dockRow: stored.dockCollapsed
|
|
216
|
+
? DOCK_HEAD_H
|
|
217
|
+
: Math.min(stored.dockHeight, ceiling, foldedDockRow(viewportWidth, viewportHeight, stored)),
|
|
218
|
+
};
|
|
26
219
|
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* AN UNTOUCHED DOCK IS AS TALL AS ITS FOLDED ROWS. The first look at a shot is
|
|
223
|
+
* Shot, Camera and Sound, and a 300px dock under three rows is stage taken for
|
|
224
|
+
* nothing, so the row the grid gives the dock stops at the head plus the
|
|
225
|
+
* folded content (`foldedDockContentH`).
|
|
226
|
+
*
|
|
227
|
+
* Only the Rows view, and only while `dockHeight` is still exactly what
|
|
228
|
+
* `layoutFor` gave this window (the refit's own "untouched" test): a dragged
|
|
229
|
+
* height is the author's and always wins, and Graph and Sound need the room
|
|
230
|
+
* their own views draw. A definition keeps the shot's height (its Actions rows
|
|
231
|
+
* scroll), so entering a component never moves the dock. Infinity means "no
|
|
232
|
+
* opinion".
|
|
233
|
+
*/
|
|
234
|
+
function foldedDockRow(
|
|
235
|
+
viewportWidth: number,
|
|
236
|
+
viewportHeight: number,
|
|
237
|
+
s: { dockHeight: number } & ToolFooterFields & Partial<Pick<ShotEditorState, "enteredScene" | "dockMode">>,
|
|
238
|
+
): number {
|
|
239
|
+
if (s.doc === null || (s.dockMode ?? "rows") !== "rows") return Infinity;
|
|
240
|
+
if (s.dockHeight !== layoutFor(viewportWidth, viewportHeight).dockHeight) return Infinity;
|
|
241
|
+
return Math.max(DOCK_HEIGHT.min, DOCK_HEAD_H + foldedDockContentH(s.doc, s.enteredScene ?? null));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** `fitShell`'s two side columns: the rail gives first, then the inspector,
|
|
245
|
+
* each down to its own minimum, until the canvas has `CANVAS_MIN.width`. */
|
|
246
|
+
function fitColumns(
|
|
247
|
+
viewportWidth: number,
|
|
248
|
+
stored: { railWidth: number; inspectorWidth: number },
|
|
249
|
+
): { railWidth: number; inspectorWidth: number } {
|
|
250
|
+
const vw = Number.isFinite(viewportWidth) ? viewportWidth : 0;
|
|
251
|
+
let rail = stored.railWidth;
|
|
252
|
+
let inspector = stored.inspectorWidth;
|
|
253
|
+
let over = rail + inspector - Math.max(0, vw - CANVAS_MIN.width);
|
|
254
|
+
if (over > 0) {
|
|
255
|
+
const cut = Math.min(over, Math.max(0, rail - RAIL_WIDTH.min));
|
|
256
|
+
rail -= cut;
|
|
257
|
+
over -= cut;
|
|
258
|
+
}
|
|
259
|
+
if (over > 0) inspector -= Math.min(over, Math.max(0, inspector - INSPECTOR_WIDTH.min));
|
|
260
|
+
return { railWidth: rail, inspectorWidth: inspector };
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** The board's right cell at its DISPLAY widths (S1, S3, Paper SB1): the
|
|
264
|
+
* Plan panel, the inspector, comments and the agent at the inspector's 304,
|
|
265
|
+
* the component sheet at 400. Never written to `inspectorWidth`, so Studio
|
|
266
|
+
* keeps the author's own width. */
|
|
267
|
+
export const BOARD_PANEL_W = { panel: 304, component: 400 } as const;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* The board's side columns as drawn. THE BOARD IS ONE FULL-WIDTH CANVAS: no
|
|
271
|
+
* left rail, ever, and a right cell only while `boardRightPanel` names an
|
|
272
|
+
* occupant. That cell draws at its display width, giving way down to the
|
|
273
|
+
* inspector's minimum when the window leaves the canvas under
|
|
274
|
+
* `CANVAS_MIN.width`.
|
|
275
|
+
*/
|
|
276
|
+
export function boardColumns(
|
|
277
|
+
viewportWidth: number,
|
|
278
|
+
panel: BoardRightPanel,
|
|
279
|
+
): { railWidth: number; inspectorWidth: number } {
|
|
280
|
+
if (panel === null) return { railWidth: 0, inspectorWidth: 0 };
|
|
281
|
+
const vw = Number.isFinite(viewportWidth) ? viewportWidth : 0;
|
|
282
|
+
const want = panel === "component" ? BOARD_PANEL_W.component : BOARD_PANEL_W.panel;
|
|
283
|
+
return { railWidth: 0, inspectorWidth: Math.max(INSPECTOR_WIDTH.min, Math.min(want, vw - CANVAS_MIN.width)) };
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* A layout the author already chose, as far as storage remembers it.
|
|
288
|
+
*
|
|
289
|
+
* Every field optional and read one by one: an author who dragged only the
|
|
290
|
+
* rail keeps their rail and still gets a fitted dock, and a storage value that
|
|
291
|
+
* failed to parse is simply an absent field rather than a whole layout thrown
|
|
292
|
+
* away. Declared beside `layoutFor` because the two are read together and this
|
|
293
|
+
* is the module both the store and `layoutPrefs.ts` already depend on.
|
|
294
|
+
*/
|
|
295
|
+
export interface BootLayoutPrefs {
|
|
296
|
+
railWidth?: number;
|
|
297
|
+
inspectorWidth?: number;
|
|
298
|
+
dockHeight?: number;
|
|
299
|
+
railCollapsed?: boolean;
|
|
300
|
+
inspectorCollapsed?: boolean;
|
|
301
|
+
dockCollapsed?: boolean;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* What the three panels should START at on a given window.
|
|
306
|
+
*
|
|
307
|
+
* ── WHY A FUNCTION AND NOT THREE MORE CONSTANTS ─────────────────────────
|
|
308
|
+
*
|
|
309
|
+
* The defaults above are one number each, and they were chosen on a desktop.
|
|
310
|
+
* The docked columns and the bottom row are subtracted from the canvas at
|
|
311
|
+
* EVERY window size, on a 2560 monitor and on a 1366 laptop alike, so a
|
|
312
|
+
* desktop's numbers leave a laptop a small picture.
|
|
313
|
+
*
|
|
314
|
+
* A FRACTION FOR THE DOCK, A BREAKPOINT FOR THE RAIL. The dock is the panel
|
|
315
|
+
* whose useful height really is proportional: it is a strip of rows, and 30%
|
|
316
|
+
* of the window shows about as many of them at any size. The rail is not —
|
|
317
|
+
* it holds names, and a name needs the width it needs — so it steps once,
|
|
318
|
+
* at the width below which the two side rails start costing more than they
|
|
319
|
+
* carry. The inspector does not move at all: 304 is already the width its
|
|
320
|
+
* own rows need, and taking more from a laptop would only make the rows worse.
|
|
321
|
+
*
|
|
322
|
+
* NEVER LARGER THAN THE DESKTOP DEFAULT. This function makes a small window
|
|
323
|
+
* smaller, never a large one bigger: an author who wants more dock on a big
|
|
324
|
+
* monitor drags for it, and a boot that silently spent 30% of a 1440p screen
|
|
325
|
+
* on the timeline would be taking that decision away from them.
|
|
326
|
+
*
|
|
327
|
+
* This is a BOOT value, applied once by `bootLayout` and re-applied on resize
|
|
328
|
+
* only to a panel the author has not touched. It is deliberately not folded
|
|
329
|
+
* into the constants above, which remain the answer to "what does this panel
|
|
330
|
+
* want" — the reset-to-default of a drag still lands there. `fitShell` is the
|
|
331
|
+
* other half: what a window too small for the stored sizes lays out.
|
|
332
|
+
*/
|
|
333
|
+
export function layoutFor(
|
|
334
|
+
viewportWidth: number,
|
|
335
|
+
viewportHeight: number,
|
|
336
|
+
): { railWidth: number; inspectorWidth: number; dockHeight: number } {
|
|
337
|
+
const vw = Number.isFinite(viewportWidth) ? viewportWidth : 0;
|
|
338
|
+
const vh = Number.isFinite(viewportHeight) ? viewportHeight : 0;
|
|
339
|
+
return {
|
|
340
|
+
railWidth: vw > 0 && vw < 1440 ? 200 : RAIL_WIDTH.default,
|
|
341
|
+
inspectorWidth: INSPECTOR_WIDTH.default,
|
|
342
|
+
// Clamped to the DEFAULT rather than to DOCK_HEIGHT.max, per the rule
|
|
343
|
+
// above: 30% of a 1440p window is 432px of timeline nobody asked for.
|
|
344
|
+
//
|
|
345
|
+
// AND NEVER PAST THE FOOTER'S CEILING, so the fit is a number
|
|
346
|
+
// `setDockHeight` keeps verbatim in every context. Under a ~531px window
|
|
347
|
+
// 30% is more than `dockCeiling(vh, true)` allows, and a fit the setter
|
|
348
|
+
// clamps is a fit nobody can recognise afterwards: the resize refit and
|
|
349
|
+
// `authorLayout` both read "not the fitted number" as "the author dragged
|
|
350
|
+
// it", so the dock stopped refitting and its clamp was saved as a
|
|
351
|
+
// preference. The modes' taller ceiling costs nothing here: a window that
|
|
352
|
+
// short has no dock to spare.
|
|
353
|
+
dockHeight:
|
|
354
|
+
vh > 0
|
|
355
|
+
? Math.min(
|
|
356
|
+
clampSize(Math.round(vh * 0.3), DOCK_HEIGHT.min, DOCK_HEIGHT.default),
|
|
357
|
+
dockCeiling(vh, true),
|
|
358
|
+
)
|
|
359
|
+
: DOCK_HEIGHT.default,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* The material mode's preview: THE OBJECT, the hole at the right of the
|
|
365
|
+
* canvas cell, and nothing else in it.
|
|
366
|
+
*
|
|
367
|
+
* THE STORED WIDTH, not the drawn one. The hole draws at most half the canvas
|
|
368
|
+
* cell (`--material-preview-w` in styles/modes/material.css), and the seam's
|
|
369
|
+
* drag caps what it stores at that same half (`setMaterialColumnWidth`'s
|
|
370
|
+
* `ceiling`), so a narrow window shows less without rewriting the number.
|
|
371
|
+
*
|
|
372
|
+
* PIXELS, for the reason at the top of this file: a width the author dragged
|
|
373
|
+
* must not move on the next window resize.
|
|
374
|
+
*
|
|
375
|
+
* Every pixel of the hole is subject. The camera fits the subject to the
|
|
376
|
+
* SMALLER axis of the hole (see `isolationExtent`), so while it stays a tall
|
|
377
|
+
* narrow slot the width is the whole budget. 560 is roughly 30% of a 1920
|
|
378
|
+
* window, which is what it takes to read a material rather than identify one.
|
|
379
|
+
*
|
|
380
|
+
* Bounds: under 280 the hole is narrower than the graph's own node cards and
|
|
381
|
+
* stops being a preview; 960 is where it starts eating the graph it exists to
|
|
382
|
+
* annotate.
|
|
383
|
+
*/
|
|
384
|
+
export const MATERIAL_COLUMN = { min: 280, max: 960, default: 560 } as const;
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* A code component's live preview, beside the code pane in the canvas cell.
|
|
388
|
+
* Stored in pixels for the same reason, and drawn no wider than the cell
|
|
389
|
+
* leaves after the code pane's own minimum (`CODE_PANE_MIN`, code.css's
|
|
390
|
+
* `min-width`), which the seam's drag passes as its ceiling.
|
|
391
|
+
*
|
|
392
|
+
* 420 is the width the pane always had. Under 240 the loop readout and the
|
|
393
|
+
* picture stop fitting; 1400 is a whole laptop canvas cell.
|
|
394
|
+
*/
|
|
395
|
+
export const CODE_LIVE_WIDTH = { min: 240, max: 1400, default: 420 } as const;
|
|
396
|
+
export const CODE_PANE_MIN = 360;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// What an author's unsent sync batches change, in words, for the dialog a
|
|
2
|
+
// delete under live sync shows (R10, Paper page 21 "Renamed or deleted"):
|
|
3
|
+
//
|
|
4
|
+
// One board. opacity 0 → 1
|
|
5
|
+
// CardBoard scale 1 → 1.1
|
|
6
|
+
// Badge fill #34D399 → #FF7A3D
|
|
7
|
+
//
|
|
8
|
+
// One line per thing changed, however many ops it took: the ops collapse by
|
|
9
|
+
// owner and field, and the values are read from the documents before and
|
|
10
|
+
// after, so a drag of fifty mints is one line.
|
|
11
|
+
import { applyOps } from "@dailies-studio/shot/doc";
|
|
12
|
+
import type { Doc3D, SyncOp } from "@dailies-studio/shot/doc";
|
|
13
|
+
|
|
14
|
+
export interface PendingSummary {
|
|
15
|
+
/** At most `max` lines, the owner column padded so the list aligns, then
|
|
16
|
+
* "and N more" when there are more. */
|
|
17
|
+
lines: string[];
|
|
18
|
+
/** How many things changed. */
|
|
19
|
+
count: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The ordered lists whose items are layers or scenes: an `ins` or `rm` in
|
|
23
|
+
* one is the other half of a `new` or `del`, or a move. */
|
|
24
|
+
const SEQS = new Set(["layers", "roots", "scenes"]);
|
|
25
|
+
|
|
26
|
+
type Rec = Record<string, unknown>;
|
|
27
|
+
const rec = (v: unknown): Rec | null => (typeof v === "object" && v !== null ? (v as Rec) : null);
|
|
28
|
+
|
|
29
|
+
function at(doc: Doc3D, p: readonly string[]): unknown {
|
|
30
|
+
let v: unknown = doc;
|
|
31
|
+
for (const k of p) v = rec(v)?.[k];
|
|
32
|
+
return v;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A layer's or scene's display name in either document. */
|
|
36
|
+
function nameOf(docs: readonly Doc3D[], id: string): string {
|
|
37
|
+
for (const doc of docs) {
|
|
38
|
+
const scene = rec(doc.scenesById)?.[id];
|
|
39
|
+
if (scene !== undefined) return String(rec(scene)?.["name"] ?? id);
|
|
40
|
+
for (const table of [doc.scenesById, rec(doc)?.["components"]]) {
|
|
41
|
+
for (const owner of Object.values(rec(table) ?? {})) {
|
|
42
|
+
const layer = rec(rec(rec(owner)?.["layersById"])?.[id]);
|
|
43
|
+
if (layer !== null) return String(layer["label"] ?? id);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return id;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function value(v: unknown): string | null {
|
|
51
|
+
if (typeof v === "number") return String(Math.round(v * 1000) / 1000);
|
|
52
|
+
if (typeof v === "string") return v.length <= 24 ? v : null;
|
|
53
|
+
if (typeof v === "boolean") return v ? "on" : "off";
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The field a path names, short: its last key, with the one before when
|
|
58
|
+
* the last says little alone (`position.x`, `stops.0`). */
|
|
59
|
+
function fieldOf(p: readonly string[]): string {
|
|
60
|
+
const last = p[p.length - 1] ?? "";
|
|
61
|
+
return last.length <= 1 || /^\d+$/.test(last) ? p.slice(-2).join(".") : last;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function describePending(base: Doc3D, ops: readonly SyncOp[], max = 6): PendingSummary {
|
|
65
|
+
let after = base;
|
|
66
|
+
try {
|
|
67
|
+
after = applyOps(base, ops).doc;
|
|
68
|
+
} catch {
|
|
69
|
+
// Names then come from the base; values read as "changed".
|
|
70
|
+
}
|
|
71
|
+
const docs = [after, base];
|
|
72
|
+
/** owner + field → [owner, what]. Insertion order is first-change order. */
|
|
73
|
+
const out = new Map<string, [string, string]>();
|
|
74
|
+
const put = (owner: string, field: string, what: string, weak = false): void => {
|
|
75
|
+
const key = `${owner}\u0000${field}`;
|
|
76
|
+
if (weak && out.has(key)) return;
|
|
77
|
+
// A layer added or removed is one line, not one per field it carries.
|
|
78
|
+
const whole = out.get(`${owner}\u0000`)?.[1];
|
|
79
|
+
if (field !== "" && (whole === "added" || whole === "removed")) return;
|
|
80
|
+
out.set(key, [owner, what]);
|
|
81
|
+
};
|
|
82
|
+
for (const op of ops) {
|
|
83
|
+
const p = op.p;
|
|
84
|
+
const list = op.op === "ins" || op.op === "rm" || op.op === "mv";
|
|
85
|
+
if (list && SEQS.has(p[p.length - 2] ?? "")) {
|
|
86
|
+
// An item of a layer or scene list: added or removed by its `new` or
|
|
87
|
+
// `del`, otherwise moved.
|
|
88
|
+
put(nameOf(docs, p[p.length - 1]!), "", "moved", true);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const li = p.lastIndexOf("layersById");
|
|
92
|
+
const owned = li >= 0 ? { id: p[li + 1], rest: p.slice(li + 2) } : p[0] === "scenesById" ? { id: p[1], rest: p.slice(2) } : null;
|
|
93
|
+
const owner = owned?.id === undefined ? "Project" : nameOf(docs, owned.id);
|
|
94
|
+
const rest = owned?.id === undefined ? p : owned.rest;
|
|
95
|
+
if (rest.length === 0) {
|
|
96
|
+
put(owner, "", op.op === "del" ? "removed" : op.op === "new" ? "added" : "changed");
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (list) {
|
|
100
|
+
const name = p[p.length - 2] ?? "";
|
|
101
|
+
put(owner, name, op.op === "ins" ? `added to ${name}` : op.op === "rm" ? `removed from ${name}` : `reordered ${name}`);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const field = fieldOf(rest);
|
|
105
|
+
const now = value(at(after, p));
|
|
106
|
+
if ((field === "label" || field === "name") && now !== null && op.op !== "del") {
|
|
107
|
+
put(owner, field, `renamed "${now}"`);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const was = value(at(base, p));
|
|
111
|
+
put(owner, field, was !== null && now !== null ? `${field} ${was} → ${now}` : `${field} changed`);
|
|
112
|
+
}
|
|
113
|
+
const rows = [...out.values()];
|
|
114
|
+
const shown = rows.slice(0, max);
|
|
115
|
+
const width = Math.max(0, ...shown.map(([owner]) => owner.length)) + 2;
|
|
116
|
+
const lines = shown.map(([owner, what]) => owner.padEnd(width) + what);
|
|
117
|
+
if (rows.length > max) lines.push(`and ${rows.length - max} more`);
|
|
118
|
+
return { lines, count: rows.length };
|
|
119
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// THE ONE ANSWER TO "MAY THE TRANSPORT START", so the guard and the buttons
|
|
2
|
+
// cannot drift.
|
|
3
|
+
//
|
|
4
|
+
// `setPlaying` is the single route to playback (Space through `handleKey`, the
|
|
5
|
+
// Play menu row, the Play control in the dock and Code Studio's preview strip,
|
|
6
|
+
// and WebMCP), and it refuses a start for two reasons: the board, and an
|
|
7
|
+
// export lock. The menu row and the Play control grey themselves for the same
|
|
8
|
+
// reasons, and until this file existed each of them restated the rule in its
|
|
9
|
+
// own expression. The dock's own comment already claimed they were one rule,
|
|
10
|
+
// that "the greying-out is the button agreeing with the guard rather than a
|
|
11
|
+
// second rule"; this is that claim made literal, and it is the same move as
|
|
12
|
+
// the label, enum and route consolidation one directory over.
|
|
13
|
+
//
|
|
14
|
+
// A SCENE STILL LOADING IS NOT A REFUSAL (bridge v51). Play is always
|
|
15
|
+
// pressable then: the press is queued (`playIntent`), the control says it is
|
|
16
|
+
// waiting (`SCENE_WAITING`), and the transport starts by itself once the stage
|
|
17
|
+
// is ready (`stageReady`). A second press cancels the wait (`playOn`).
|
|
18
|
+
//
|
|
19
|
+
// IT ANSWERS FOR A START ONLY. Every caller pairs it with `!playOn`. A
|
|
20
|
+
// transport already running, or a queued Play, must always be stoppable: an
|
|
21
|
+
// export that begins later would otherwise leave the author with a running
|
|
22
|
+
// clock and a dead pause button.
|
|
23
|
+
//
|
|
24
|
+
// The string it returns is the refusal the author reads, in the error strip
|
|
25
|
+
// from `setPlaying` and as the button's own title. There is no separate code
|
|
26
|
+
// for the reason because nothing branches on which reason it was.
|
|
27
|
+
import type { ShotEditorState } from "./types.js";
|
|
28
|
+
import { workspaceOf } from "./workspace.js";
|
|
29
|
+
|
|
30
|
+
/** The board's refusal, one sentence for Space, the menu row and WebMCP. */
|
|
31
|
+
export const BOARD_DOES_NOT_PLAY = "The storyboard doesn't play. Open Studio to play the film.";
|
|
32
|
+
|
|
33
|
+
/** The Play control's title while a queued Play waits for the scene
|
|
34
|
+
* (`playIntent` armed) or for the stage to hand over (starting). A wait, not
|
|
35
|
+
* a refusal: it plays by itself. */
|
|
36
|
+
export const SCENE_WAITING = "Getting the scene ready to play. Space cancels.";
|
|
37
|
+
|
|
38
|
+
/** How far a Play pass has drawn, in whole percent. The one rounding for the
|
|
39
|
+
* Play control's title, the store's progress writes and WebMCP's answer. */
|
|
40
|
+
export function preparingPercent({ done, total }: { readonly done: number; readonly total: number }): number {
|
|
41
|
+
return total > 0 ? Math.floor((done * 100) / total) : 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The Play control's title while a Play pass draws (`playIntent` preparing). */
|
|
45
|
+
export function preparingTitle(intent: { readonly done: number; readonly total: number }): string {
|
|
46
|
+
return `Preparing playback, ${preparingPercent(intent)}%. Space cancels.`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** IS PLAY ON: the transport running, or a queued Play waiting to start it.
|
|
50
|
+
* Every toggle calls `setPlaying(!playOn(state))`, so a second press cancels
|
|
51
|
+
* the wait. */
|
|
52
|
+
export function playOn(state: Pick<ShotEditorState, "playing" | "playIntent">): boolean {
|
|
53
|
+
return state.playing || state.playIntent !== null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** IS THE STAGE READY TO PLAY: it owes the open subject no presentation
|
|
57
|
+
* (`stageBusy`, bridge v51), and a stage on its way has reported in. Ready
|
|
58
|
+
* with no stage expected at all: a bare store, a unit test and SSR. */
|
|
59
|
+
export function stageReady(state: Pick<ShotEditorState, "stageBusy" | "stageExpected" | "stageInfo">): boolean {
|
|
60
|
+
return !state.stageBusy && !(state.stageExpected && state.stageInfo === null);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function playHold(state: ShotEditorState): string | null {
|
|
64
|
+
// THE BOARD PLANS, IT DOES NOT PLAY. A Shot there is a few stills and the
|
|
65
|
+
// author's notes about it, so the transport stays at rest and the scrubber
|
|
66
|
+
// is the only way through the Shot. Code Studio opened over the board is
|
|
67
|
+
// its own workspace, and plays.
|
|
68
|
+
if (workspaceOf(state) === "storyboard") return BOARD_DOES_NOT_PLAY;
|
|
69
|
+
// A capture loop owns the clock while an export runs. The stage defers chrome
|
|
70
|
+
// seeks, so playback would not move the picture: it would only overwrite the
|
|
71
|
+
// frame the export restores at the end and play the preview audio over it.
|
|
72
|
+
if (state.exportLock !== null) {
|
|
73
|
+
return `playback is held while the ${
|
|
74
|
+
state.exportLock.where === "browser" ? "in-browser" : "studio server"
|
|
75
|
+
} export renders. Cancel it to play`;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|