@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,137 @@
|
|
|
1
|
+
// ON-DEMAND PANELS: the chrome's load diet (docs/performance-chrome-load-2026-10.md).
|
|
2
|
+
//
|
|
3
|
+
// The entry chunk holds the shell and Studio. Every other workspace, dialog
|
|
4
|
+
// and drawer is a `lazyPanel`: its module (and whatever only it imports, the
|
|
5
|
+
// CodeMirror and React Flow stacks among them) is a chunk fetched the first
|
|
6
|
+
// time it renders. The shell that decides WHETHER it renders stays eager and
|
|
7
|
+
// returns null while it is not wanted, so a closed panel costs nothing.
|
|
8
|
+
//
|
|
9
|
+
// WHY NOT `React.lazy` ALONE. A lazy component suspends on its first render
|
|
10
|
+
// even when its module is already in memory, so a panel the idle prefetch has
|
|
11
|
+
// fetched would still flash its fallback for a frame, and every unit test
|
|
12
|
+
// that mounts a shell would have to await a panel it already imported. Here
|
|
13
|
+
// a loaded module renders in the same commit, and only a real fetch shows the
|
|
14
|
+
// fallback.
|
|
15
|
+
//
|
|
16
|
+
// A FAILED FETCH (a deploy replaced the chunk under an open tab, a dropped
|
|
17
|
+
// connection) throws with a sentence saying what to do, and the boundary's
|
|
18
|
+
// Try again fetches again. EVERY PANEL CARRIES ITS OWN `PanelBoundary`, named by
|
|
19
|
+
// its `label`: several call sites (the right column, the dialogs, the Insert
|
|
20
|
+
// drawer) have no boundary above them but the root's, and a throw there
|
|
21
|
+
// unmounts the whole editor, stage and all, for a chunk that did not arrive.
|
|
22
|
+
import { Suspense, use, useState, type ComponentType, type ReactNode } from "react";
|
|
23
|
+
import { PanelBoundary } from "@dailies-studio/ui";
|
|
24
|
+
|
|
25
|
+
export interface LazyPanel<P extends object> {
|
|
26
|
+
(props: P): ReactNode;
|
|
27
|
+
/** Fetch the module now; safe to call often. */
|
|
28
|
+
preload(): Promise<unknown>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Every chunk's `preload`, for `preloadPanels`. */
|
|
32
|
+
const preloads: (() => Promise<unknown>)[] = [];
|
|
33
|
+
|
|
34
|
+
export const PANEL_LOAD_FAILED = "This part of Dailies did not load. Reload the page to get the latest version.";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A chunk several panels come from. They share ONE fetch and one loaded
|
|
38
|
+
* module, so once any of them has loaded, every other renders at once: the
|
|
39
|
+
* board's right-column panels never wait on a chunk the board already has.
|
|
40
|
+
*/
|
|
41
|
+
export function lazyChunk<M>(load: () => Promise<M>): {
|
|
42
|
+
preload: () => Promise<M>;
|
|
43
|
+
/** A panel from this chunk. `label` names it on the crash card; `fallback`
|
|
44
|
+
* is drawn in its place while the fetch runs: the panel's own skeleton, so
|
|
45
|
+
* nothing around it moves when it lands. */
|
|
46
|
+
panel: <P extends object>(label: string, pick: (module: M) => ComponentType<P>, fallback?: ReactNode) => LazyPanel<P>;
|
|
47
|
+
} {
|
|
48
|
+
let loaded: { module: M } | null = null;
|
|
49
|
+
let pending: Promise<M> | null = null;
|
|
50
|
+
// ONE PROMISE PER ATTEMPT. A render that suspended on a fetch that then
|
|
51
|
+
// failed must meet the SAME rejected promise when React renders it again,
|
|
52
|
+
// or the error never reaches the boundary: a fresh fetch suspends again,
|
|
53
|
+
// and the panel refetches its chunk forever behind its skeleton. A failed
|
|
54
|
+
// attempt is forgotten only by the boundary's catch (so Try again fetches
|
|
55
|
+
// anew) and by a `preload` that failed (so the next open fetches anew).
|
|
56
|
+
const attempt = (): Promise<M> =>
|
|
57
|
+
(pending ??= load().then(
|
|
58
|
+
(module) => (loaded = { module }).module,
|
|
59
|
+
(cause: unknown) => {
|
|
60
|
+
throw new Error(PANEL_LOAD_FAILED, { cause });
|
|
61
|
+
},
|
|
62
|
+
));
|
|
63
|
+
const preload = (): Promise<M> => {
|
|
64
|
+
const tried = attempt();
|
|
65
|
+
tried.catch(() => {
|
|
66
|
+
if (pending === tried) pending = null;
|
|
67
|
+
});
|
|
68
|
+
return tried;
|
|
69
|
+
};
|
|
70
|
+
const forget = (): void => {
|
|
71
|
+
if (loaded === null) pending = null;
|
|
72
|
+
};
|
|
73
|
+
preloads.push(preload);
|
|
74
|
+
const panel = <P extends object>(
|
|
75
|
+
label: string,
|
|
76
|
+
pick: (module: M) => ComponentType<P>,
|
|
77
|
+
fallback: ReactNode = null,
|
|
78
|
+
): LazyPanel<P> => {
|
|
79
|
+
function Body(props: P) {
|
|
80
|
+
const Panel = pick(loaded === null ? use(attempt()) : loaded.module);
|
|
81
|
+
return <Panel {...props} />;
|
|
82
|
+
}
|
|
83
|
+
function Lazy(props: P) {
|
|
84
|
+
return (
|
|
85
|
+
<PanelBoundary label={label} onCatch={forget}>
|
|
86
|
+
<Suspense fallback={fallback}>
|
|
87
|
+
<Body {...props} />
|
|
88
|
+
</Suspense>
|
|
89
|
+
</PanelBoundary>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
return Object.assign(Lazy, { preload });
|
|
93
|
+
};
|
|
94
|
+
return { preload, panel };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** A panel that is a chunk of its own: `load` resolves to the component. */
|
|
98
|
+
export function lazyPanel<P extends object>(
|
|
99
|
+
label: string,
|
|
100
|
+
load: () => Promise<ComponentType<P>>,
|
|
101
|
+
fallback: ReactNode = null,
|
|
102
|
+
): LazyPanel<P> {
|
|
103
|
+
return lazyChunk(load).panel(label, (component) => component, fallback);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* True from the first render where `on` is true, for the rest of the
|
|
108
|
+
* component's life. A shell latches its panel: the chunk is fetched the first
|
|
109
|
+
* time the panel is wanted, and after that the panel stays mounted and gates
|
|
110
|
+
* itself, exactly as it did when it loaded with the entry, so its state and
|
|
111
|
+
* its close transition survive.
|
|
112
|
+
*/
|
|
113
|
+
export function useLatch(on: boolean): boolean {
|
|
114
|
+
const [latched, setLatched] = useState(on);
|
|
115
|
+
if (on && !latched) setLatched(true);
|
|
116
|
+
return latched || on;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Load every panel declared so far. Tests call it so a mounted shell renders
|
|
120
|
+
* its panels in the same commit, as a warm session does. */
|
|
121
|
+
export async function preloadPanels(): Promise<void> {
|
|
122
|
+
await Promise.all(preloads.map((preload) => preload()));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Run `work` once the page is idle after first paint, so a prefetch never
|
|
127
|
+
* competes with the boot. Returns a cancel. `requestIdleCallback` is missing
|
|
128
|
+
* in Safari and jsdom; a timeout stands in.
|
|
129
|
+
*/
|
|
130
|
+
export function whenIdle(work: () => void): () => void {
|
|
131
|
+
if (typeof window.requestIdleCallback === "function") {
|
|
132
|
+
const id = window.requestIdleCallback(work, { timeout: 4000 });
|
|
133
|
+
return () => window.cancelIdleCallback(id);
|
|
134
|
+
}
|
|
135
|
+
const id = window.setTimeout(work, 1500);
|
|
136
|
+
return () => window.clearTimeout(id);
|
|
137
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// WHAT LOADS ON DEMAND, in one list (docs/performance-chrome-load-2026-10.md).
|
|
2
|
+
//
|
|
3
|
+
// The /scene entry is the shell and Studio. Each surface here is a chunk the
|
|
4
|
+
// shell fetches the first time it is wanted (app/lazyPanel.tsx): the
|
|
5
|
+
// Storyboard, Components, Code Studio with CodeMirror, the material nodes
|
|
6
|
+
// with React Flow, the Library, Export, Version history, Preferences and
|
|
7
|
+
// Insert, the font picker, the inspector's two template sections, and the
|
|
8
|
+
// Agent and Comments panels. Timeline views that load when
|
|
9
|
+
// they open (Sound, Graph, Generate) are declared beside the dock that shows
|
|
10
|
+
// them (TimelineDock.tsx).
|
|
11
|
+
//
|
|
12
|
+
// Each export keeps the name of the panel it stands for, so a call site reads
|
|
13
|
+
// as it did when the panel loaded with the entry. A GATED one is that panel's
|
|
14
|
+
// eager shell: null until the panel is first wanted, then latched (`useLatch`)
|
|
15
|
+
// so the panel gates itself from there on. The others are mounted by a call
|
|
16
|
+
// site that already decides when.
|
|
17
|
+
//
|
|
18
|
+
// A FALLBACK IS THE PANEL'S OWN SKELETON, drawn in the panel's place while
|
|
19
|
+
// its chunk loads, so nothing around it moves when it lands. A LABEL names
|
|
20
|
+
// the panel on the crash card its own boundary draws when the chunk does not
|
|
21
|
+
// arrive (lazyPanel.tsx).
|
|
22
|
+
import { useSyncExternalStore } from "react";
|
|
23
|
+
import type { ComponentType, ReactNode } from "react";
|
|
24
|
+
import { useShotEditor, useStore } from "../state/context.js";
|
|
25
|
+
import type { ShotEditorState } from "../state/types.js";
|
|
26
|
+
import { workspaceOf } from "../state/workspace.js";
|
|
27
|
+
import { InCell } from "../panels/stage/cellSlots.js";
|
|
28
|
+
import { lazyChunk, lazyPanel, useLatch, type LazyPanel } from "./lazyPanel.js";
|
|
29
|
+
|
|
30
|
+
// One chunk each: a surface's panels share their imports, and the board's
|
|
31
|
+
// right-column panels must be ready the moment the board is.
|
|
32
|
+
const storyboard = lazyChunk(() => import("../panels/storyboard/board.js"));
|
|
33
|
+
const components = lazyChunk(() => import("../panels/studio/components.js"));
|
|
34
|
+
|
|
35
|
+
/** A shell: null until `wanted` first holds, then the panel, for good. */
|
|
36
|
+
function gated<P extends object>(Panel: LazyPanel<P>, wanted: (s: ShotEditorState) => boolean): ComponentType<P> {
|
|
37
|
+
return function Gate(props: P) {
|
|
38
|
+
return useLatch(useShotEditor(wanted)) ? <Panel {...props} /> : null;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Draws `children` only while `wanted` holds: a skeleton for a surface that
|
|
43
|
+
* was left before its chunk arrived must not stand over the next one. */
|
|
44
|
+
function While({ wanted, children }: { wanted: (s: ShotEditorState) => boolean; children: ReactNode }) {
|
|
45
|
+
return useShotEditor(wanted) ? children : null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const onBoard = (s: ShotEditorState): boolean => workspaceOf(s) === "storyboard";
|
|
49
|
+
const inComponents = (s: ShotEditorState): boolean => workspaceOf(s) === "components";
|
|
50
|
+
const inCode = (s: ShotEditorState): boolean => inComponents(s) && s.codeComponent !== null && s.componentsTab === "edit";
|
|
51
|
+
const inMaterial = (s: ShotEditorState): boolean => workspaceOf(s) === "material";
|
|
52
|
+
|
|
53
|
+
/** The board's skeleton: its bar and the empty desk, in the canvas cell. */
|
|
54
|
+
const BOARD_SKELETON = (
|
|
55
|
+
<While wanted={onBoard}>
|
|
56
|
+
<InCell name="centre">
|
|
57
|
+
<div className="board-skeleton" aria-busy="true">
|
|
58
|
+
<div className="panel-head" />
|
|
59
|
+
</div>
|
|
60
|
+
</InCell>
|
|
61
|
+
</While>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
/** A mode's skeleton: its left column with its head, and its canvas. */
|
|
65
|
+
function modeSkeleton(wanted: (s: ShotEditorState) => boolean): ReactNode {
|
|
66
|
+
return (
|
|
67
|
+
<While wanted={wanted}>
|
|
68
|
+
<InCell name="left">
|
|
69
|
+
<div className="mode-skeleton" aria-busy="true">
|
|
70
|
+
<div className="panel-head" />
|
|
71
|
+
</div>
|
|
72
|
+
</InCell>
|
|
73
|
+
<InCell name="centre">
|
|
74
|
+
<div className="mode-skeleton is-canvas" aria-busy="true" />
|
|
75
|
+
</InCell>
|
|
76
|
+
</While>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** A right-column panel that brings its own head: the head, on the column's
|
|
81
|
+
* ground. */
|
|
82
|
+
const HEAD_SKELETON = <div className="panel-head" aria-busy="true" />;
|
|
83
|
+
|
|
84
|
+
// ── THE STORYBOARD ──────────────────────────────────────────────────────────
|
|
85
|
+
export const StoryboardView = gated(
|
|
86
|
+
storyboard.panel("Storyboard", (m) => m.StoryboardView, BOARD_SKELETON),
|
|
87
|
+
onBoard,
|
|
88
|
+
);
|
|
89
|
+
export const ComponentSheet = storyboard.panel("Component sheet", (m) => m.ComponentSheet, HEAD_SKELETON);
|
|
90
|
+
export const PlanOccupant = storyboard.panel("Plan", (m) => m.PlanOccupant, HEAD_SKELETON);
|
|
91
|
+
export const SketchInspector = storyboard.panel("Sketch inspector", (m) => m.SketchInspector, HEAD_SKELETON);
|
|
92
|
+
/** The inspector's section for a board card (InspectorPanel), shown only on
|
|
93
|
+
* the board, so it rides in the board's chunk. */
|
|
94
|
+
export const StoryboardReferenceSection = storyboard.panel("Card", (m) => m.StoryboardReferenceSection);
|
|
95
|
+
|
|
96
|
+
/** Fetch the Storyboard while the page is idle, so the first switch to it is
|
|
97
|
+
* as quick as every later one. */
|
|
98
|
+
export const prefetchStoryboard = storyboard.preload;
|
|
99
|
+
|
|
100
|
+
// ── THE INSPECTOR'S ON-DEMAND SECTIONS, fetched at idle ────────────────────
|
|
101
|
+
/** "Template field" (one text, image or video layer), "Make it yours" (no
|
|
102
|
+
* selection, a Project with fields) and "Motion" (the motion presets, every
|
|
103
|
+
* layer), drawn by InspectorPanel. Each is a chunk of its own, kept out of
|
|
104
|
+
* the entry's budget, and fetched at idle like the Storyboard
|
|
105
|
+
* (`prefetchInspectorSections`, App.tsx), so a selection made after that
|
|
106
|
+
* draws it in the same commit; before it lands it draws nothing. */
|
|
107
|
+
export const TemplateFieldSection = lazyPanel("Template field", () =>
|
|
108
|
+
import("../panels/inspector/design/TemplateFieldSection.js").then((m) => m.TemplateFieldSection),
|
|
109
|
+
);
|
|
110
|
+
export const MakeItYoursSection = lazyPanel("Make it yours", () =>
|
|
111
|
+
import("../panels/inspector/scene/MakeItYoursSection.js").then((m) => m.MakeItYoursSection),
|
|
112
|
+
);
|
|
113
|
+
export const PresetsSection = lazyPanel("Motion", () =>
|
|
114
|
+
import("../panels/inspector/animate/PresetsSection.js").then((m) => m.PresetsSection),
|
|
115
|
+
);
|
|
116
|
+
export const prefetchInspectorSections = (): Promise<unknown> =>
|
|
117
|
+
Promise.all([
|
|
118
|
+
TemplateFieldSection.preload(),
|
|
119
|
+
MakeItYoursSection.preload(),
|
|
120
|
+
PresetsSection.preload(),
|
|
121
|
+
// The stamp the Motion section's picks run (`applyMotionPreset`).
|
|
122
|
+
import("../state/motionStamp.js"),
|
|
123
|
+
]);
|
|
124
|
+
|
|
125
|
+
// ── COMPONENTS AND CODE ─────────────────────────────────────────────────────
|
|
126
|
+
// Preview and the Studio share a chunk and load together, so the Preview
|
|
127
|
+
// shell, mounted for the whole workspace, draws the one skeleton.
|
|
128
|
+
export const ComponentsPreview = gated(
|
|
129
|
+
components.panel("Components", (m) => m.ComponentsPreview, modeSkeleton(inComponents)),
|
|
130
|
+
inComponents,
|
|
131
|
+
);
|
|
132
|
+
export const ComponentStudio = gated(
|
|
133
|
+
components.panel("Component studio", (m) => m.ComponentStudio),
|
|
134
|
+
inComponents,
|
|
135
|
+
);
|
|
136
|
+
export const CodeStudio = gated(
|
|
137
|
+
lazyPanel("Code studio", () => import("../panels/code/CodeStudio.js").then((m) => m.CodeStudio), modeSkeleton(inCode)),
|
|
138
|
+
inCode,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
// ── THE MATERIAL NODES ──────────────────────────────────────────────────────
|
|
142
|
+
export const MaterialWorkspace = gated(
|
|
143
|
+
lazyPanel("Material workspace", () => import("../panels/material/MaterialWorkspace.js").then((m) => m.MaterialWorkspace), modeSkeleton(inMaterial)),
|
|
144
|
+
inMaterial,
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// ── DIALOGS AND DRAWERS: on open ───────────────────────────────────────────
|
|
148
|
+
export const LibraryBrowser = gated(
|
|
149
|
+
lazyPanel("Library", () => import("../panels/library/LibraryBrowser.js").then((m) => m.LibraryBrowser)),
|
|
150
|
+
(s) => s.libraryBrowserOpen,
|
|
151
|
+
);
|
|
152
|
+
export const PreferencesDialog = gated(
|
|
153
|
+
lazyPanel("Preferences", () => import("../panels/preferences/PreferencesDialog.js").then((m) => m.PreferencesDialog)),
|
|
154
|
+
(s) => s.prefsOpen,
|
|
155
|
+
);
|
|
156
|
+
export const InsertDrawer = gated(
|
|
157
|
+
lazyPanel("Insert", () => import("../panels/insert/InsertDrawer.js").then((m) => m.InsertDrawer)),
|
|
158
|
+
(s) => s.insertDrawer !== null && !s.readOnly,
|
|
159
|
+
);
|
|
160
|
+
/** Mounted by App only while `exportOpen`. */
|
|
161
|
+
export const ExportDialog = lazyPanel("Export", () => import("../panels/export/ExportDialog.js").then((m) => m.ExportDialog));
|
|
162
|
+
/** Mounted by RightColumn only while `versionsOpen`; it takes the column,
|
|
163
|
+
* head and all. */
|
|
164
|
+
export const VersionHistoryPanel = lazyPanel(
|
|
165
|
+
"Version history",
|
|
166
|
+
() => import("../panels/versions/VersionHistoryPanel.js").then((m) => m.VersionHistoryPanel),
|
|
167
|
+
HEAD_SKELETON,
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const AgentQuestionPanel = lazyPanel("Agent question", () =>
|
|
171
|
+
import("../panels/agent/AgentQuestionDialog.js").then((m) => m.AgentQuestionDialog),
|
|
172
|
+
);
|
|
173
|
+
/** The agent's question to the person (state/agentQuestion.ts): its chunk
|
|
174
|
+
* loads the first time a question opens, or a studio server render starts
|
|
175
|
+
* for an export ask (the chunk reports it when it ends), and stays.
|
|
176
|
+
* Unconditional in App, whatever workspace is on screen. */
|
|
177
|
+
export function AgentQuestionDialog() {
|
|
178
|
+
const store = useStore();
|
|
179
|
+
const wanted = useSyncExternalStore(store.agentQuestion.subscribe, () => {
|
|
180
|
+
const s = store.agentQuestion.getState();
|
|
181
|
+
return s.open || s.exportAsk?.serverJob !== undefined;
|
|
182
|
+
});
|
|
183
|
+
return useLatch(wanted) ? <AgentQuestionPanel /> : null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ── THE FONT PICKER: on open ───────────────────────────────────────────────
|
|
187
|
+
/** Mounted by the inspector's Font field (FontField.tsx) only while open,
|
|
188
|
+
* inside the field box; its module owns the Popover. Preloaded as the pointer
|
|
189
|
+
* or focus reaches the field. Its skeleton is a ring in the box's accessory
|
|
190
|
+
* lane, where a write's progress sits. */
|
|
191
|
+
export const FontPicker = lazyPanel(
|
|
192
|
+
"Font picker",
|
|
193
|
+
() => import("../panels/fonts/FontPicker.js").then((m) => m.FontPicker),
|
|
194
|
+
<span className="field-accessory">
|
|
195
|
+
<span className="font-field-wait" aria-busy="true" />
|
|
196
|
+
</span>,
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// ── THE AGENT AND COMMENTS: on first open ──────────────────────────────────
|
|
200
|
+
/** Kept mounted by RightColumn after its first open, under an `<Activity>`. */
|
|
201
|
+
export const AgentPanel = lazyPanel("Agent", () => import("../panels/agent/AgentPanel.js").then((m) => m.AgentPanel));
|
|
202
|
+
/** Mounted by RightColumn while the Comments tab is the occupant. */
|
|
203
|
+
export const CommentsPanel = lazyPanel("Comments", () => import("../panels/comments/CommentsPanel.js").then((m) => m.CommentsPanel));
|
package/src/audio/index.tsx
CHANGED
|
@@ -10,11 +10,13 @@
|
|
|
10
10
|
// state (session, never document), so the dock head's controls and this bridge
|
|
11
11
|
// read one bit and cannot disagree.
|
|
12
12
|
import { useEffect } from "react";
|
|
13
|
+
import { MIX_SAMPLE_RATE } from "@dailies-studio/engine";
|
|
13
14
|
import { useStore } from "../state/context.js";
|
|
15
|
+
import { transportAudible } from "../state/types.js";
|
|
14
16
|
import { createAudioPreview } from "./preview.js";
|
|
15
17
|
import type { AudioContextLike, AudioPreview, AudioPreviewDeps } from "./preview.js";
|
|
16
18
|
|
|
17
|
-
export {
|
|
19
|
+
export { DRIFT_FRAMES, createAudioPreview } from "./preview.js";
|
|
18
20
|
export type {
|
|
19
21
|
AudioBufferLike,
|
|
20
22
|
AudioBufferSourceNodeLike,
|
|
@@ -26,17 +28,22 @@ export type {
|
|
|
26
28
|
TransportSnapshot,
|
|
27
29
|
} from "./preview.js";
|
|
28
30
|
|
|
29
|
-
async function fetchBytes(url: string): Promise<ArrayBuffer> {
|
|
30
|
-
const res = await fetch(url);
|
|
31
|
+
async function fetchBytes(url: string, priority?: "low"): Promise<ArrayBuffer> {
|
|
32
|
+
const res = await fetch(url, { priority: priority ?? "auto" });
|
|
31
33
|
if (!res.ok) throw new Error(`GET ${url} -> ${res.status}`);
|
|
32
34
|
return res.arrayBuffer();
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
/** ONE offline context decodes every clip, so a decode ahead needs no realtime
|
|
38
|
+
* context, and none exists before a press. At the export mix's rate. */
|
|
39
|
+
let decoder: OfflineAudioContext | null = null;
|
|
40
|
+
|
|
35
41
|
const browserDeps: AudioPreviewDeps = {
|
|
36
|
-
// Lazy: the first
|
|
42
|
+
// Lazy: the first press (a queued Play's arm, or the play edge) creates it.
|
|
37
43
|
createContext: () => new AudioContext() as unknown as AudioContextLike,
|
|
38
44
|
fetchBytes,
|
|
39
|
-
|
|
45
|
+
// A COPY, because `decodeAudioData` detaches the buffer it is handed.
|
|
46
|
+
decode: (bytes) => (decoder ??= new OfflineAudioContext(2, 1, MIX_SAMPLE_RATE)).decodeAudioData(bytes.slice(0)),
|
|
40
47
|
};
|
|
41
48
|
|
|
42
49
|
/** `create` is the test seam; production gets Web Audio. */
|
|
@@ -49,6 +56,35 @@ export function AudioPreviewBridge(props: { create?: () => AudioPreview } = {}):
|
|
|
49
56
|
let volume: number | null = null;
|
|
50
57
|
const push = (): void => {
|
|
51
58
|
const s = store.getState();
|
|
59
|
+
// THE TRANSPORT FIRST. An unmute reschedules against the snapshot the
|
|
60
|
+
// scheduler holds, so it has to hold THIS one: pushing the monitor bits
|
|
61
|
+
// first anchored a session on the frame from the PREVIOUS notification
|
|
62
|
+
// whenever the two changed together. The comment here used to argue the
|
|
63
|
+
// opposite order for the same reason, and had the dependency backwards.
|
|
64
|
+
preview.update({
|
|
65
|
+
playing: s.playing,
|
|
66
|
+
frame: s.frame,
|
|
67
|
+
doc: s.doc,
|
|
68
|
+
// ONE PREDICATE, and it is not this file's. A component context drives
|
|
69
|
+
// a definition-local clock and never moves `frame`; a shuttle rate
|
|
70
|
+
// other than 1 would need reversed buffers or a time stretcher. Both
|
|
71
|
+
// are "the picture's clock and the audio clock would disagree", which
|
|
72
|
+
// is why they are decided together in `transportAudible` (state/types
|
|
73
|
+
// .ts) rather than assembled here out of two field reads.
|
|
74
|
+
audible: transportAudible(s),
|
|
75
|
+
scene: s.enteredScene,
|
|
76
|
+
// Per-tab monitoring: the bridge is the one place solo reaches.
|
|
77
|
+
solo: s.soloTracks,
|
|
78
|
+
// A queued Play (bridge v51). The store notifies inside the `set`
|
|
79
|
+
// that arms it, which is the press, so the context wakes there.
|
|
80
|
+
armed: s.playIntent !== null,
|
|
81
|
+
// The instant the transport started, which the picture clock counts
|
|
82
|
+
// from too (Header.tsx).
|
|
83
|
+
origin: s.playOrigin,
|
|
84
|
+
// A stage attached that owes the open subject no picture: the ready
|
|
85
|
+
// edge the decode ahead waits for.
|
|
86
|
+
presented: s.stageInfo !== null && !s.stageBusy,
|
|
87
|
+
});
|
|
52
88
|
if (s.previewMuted !== muted) {
|
|
53
89
|
muted = s.previewMuted;
|
|
54
90
|
preview.setMasterMute(muted);
|
|
@@ -57,11 +93,6 @@ export function AudioPreviewBridge(props: { create?: () => AudioPreview } = {}):
|
|
|
57
93
|
volume = s.previewVolume;
|
|
58
94
|
preview.setMasterVolume(volume);
|
|
59
95
|
}
|
|
60
|
-
// AFTER the monitor bits: an unmute that reschedules must do so knowing
|
|
61
|
-
// the transport it is rescheduling against, and `update` is what records
|
|
62
|
-
// it. On the very first push both orders agree, because the scheduler
|
|
63
|
-
// starts paused.
|
|
64
|
-
preview.update({ playing: s.playing, frame: s.frame, doc: s.doc });
|
|
65
96
|
};
|
|
66
97
|
push();
|
|
67
98
|
const unsub = store.subscribe(push);
|