@remotion/studio 4.0.524 → 4.0.525

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.
Files changed (135) hide show
  1. package/dist/components/ActionTooltip.d.ts +2 -0
  2. package/dist/components/ActionTooltip.js +14 -4
  3. package/dist/components/AppLaunchButton.js +2 -0
  4. package/dist/components/AssetSelectorModal.d.ts +6 -0
  5. package/dist/components/AssetSelectorModal.js +174 -0
  6. package/dist/components/Canvas.js +15 -1
  7. package/dist/components/CheckboardToggle.js +2 -1
  8. package/dist/components/ColorPicker/AlphaSlider.js +1 -1
  9. package/dist/components/ColorPicker/HueSlider.js +1 -1
  10. package/dist/components/ColorPicker/SaturationValueArea.js +1 -1
  11. package/dist/components/CompositionSelector.js +1 -0
  12. package/dist/components/CompositionSelectorItem.js +1 -0
  13. package/dist/components/EditorGuides/Guide.js +1 -1
  14. package/dist/components/ElementInstallConfirmation.js +31 -23
  15. package/dist/components/FullscreenToggle.js +1 -1
  16. package/dist/components/GlobalKeybindings.js +14 -0
  17. package/dist/components/InspectorLocationCopy.js +1 -1
  18. package/dist/components/InspectorOpenInEditor.d.ts +1 -0
  19. package/dist/components/InspectorOpenInEditor.js +18 -15
  20. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +6 -7
  21. package/dist/components/InspectorPanel/CompositionMetadata.js +1 -0
  22. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -0
  23. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +4 -12
  24. package/dist/components/InspectorSequenceSection.js +18 -9
  25. package/dist/components/LoopToggle.js +2 -1
  26. package/dist/components/Menu/MenuItem.js +1 -2
  27. package/dist/components/MenuBuildIndicator.js +1 -1
  28. package/dist/components/Modals.js +2 -1
  29. package/dist/components/MuteToggle.js +2 -1
  30. package/dist/components/NewComposition/CodemodFooter.js +1 -0
  31. package/dist/components/NewComposition/DeleteComposition.js +42 -6
  32. package/dist/components/NewComposition/DeleteFolder.js +1 -0
  33. package/dist/components/NewComposition/DuplicateComposition.js +5 -0
  34. package/dist/components/NewComposition/InputDragger.js +2 -2
  35. package/dist/components/NewComposition/NewFolder.js +29 -2
  36. package/dist/components/NewComposition/RenameFolder.js +1 -0
  37. package/dist/components/NewComposition/duplicate-composition-api.d.ts +3 -2
  38. package/dist/components/NewComposition/duplicate-composition-api.js +9 -2
  39. package/dist/components/Notifications/NotificationCenter.d.ts +1 -0
  40. package/dist/components/Notifications/NotificationCenter.js +22 -1
  41. package/dist/components/OutlineToggle.js +2 -1
  42. package/dist/components/PlayPause.js +1 -1
  43. package/dist/components/Preview.js +0 -3
  44. package/dist/components/PreviewToolbar.js +3 -6
  45. package/dist/components/PreviewToolbarOverflowButton.js +2 -1
  46. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -1
  47. package/dist/components/RenderButton.js +40 -4
  48. package/dist/components/RenderModal/WebRenderModalBasic.js +1 -1
  49. package/dist/components/RenderModal/render-modals.js +3 -0
  50. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +1 -1
  51. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +1 -1
  52. package/dist/components/RenderQueue/actions.d.ts +2 -1
  53. package/dist/components/RenderQueue/actions.js +2 -1
  54. package/dist/components/RulersAndGuidesToggle.js +2 -1
  55. package/dist/components/SegmentedButton.d.ts +1 -0
  56. package/dist/components/SegmentedButton.js +9 -3
  57. package/dist/components/SelectedOutlineElement.js +16 -6
  58. package/dist/components/SelectedOutlinePolygon.js +4 -2
  59. package/dist/components/SettingsContext.d.ts +8 -0
  60. package/dist/components/SettingsContext.js +57 -2
  61. package/dist/components/SettingsModal.js +4 -1
  62. package/dist/components/SettingsModalFooter.js +1 -1
  63. package/dist/components/SidebarCollapserControls.js +1 -1
  64. package/dist/components/SkillsSettings.js +35 -4
  65. package/dist/components/SnappingToggle.js +2 -1
  66. package/dist/components/Splitter/SplitterHandle.js +1 -2
  67. package/dist/components/Tabs/vertical.d.ts +1 -1
  68. package/dist/components/Tabs/vertical.js +16 -2
  69. package/dist/components/Timeline/EasingEditorModal.js +2 -2
  70. package/dist/components/Timeline/TimelineAssetField.js +148 -9
  71. package/dist/components/Timeline/TimelineDragHandler.js +1 -2
  72. package/dist/components/Timeline/TimelineEffectItem.d.ts +1 -0
  73. package/dist/components/Timeline/TimelineEffectItem.js +2 -2
  74. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
  75. package/dist/components/Timeline/TimelineEffectPropItem.js +2 -2
  76. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  77. package/dist/components/Timeline/TimelineInOutDragHandler.js +1 -2
  78. package/dist/components/Timeline/TimelineSchemaField.js +8 -1
  79. package/dist/components/Timeline/TimelineSelection.d.ts +3 -1
  80. package/dist/components/Timeline/TimelineSelection.js +32 -5
  81. package/dist/components/Timeline/TimelineSequence.js +6 -6
  82. package/dist/components/Timeline/TimelineSequenceItem.js +12 -10
  83. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +3 -12
  84. package/dist/components/Timeline/TimelineTranslateField.js +25 -12
  85. package/dist/components/Timeline/TimelineZoomControls.js +1 -1
  86. package/dist/components/Timeline/get-sequence-context-menu-items.js +22 -6
  87. package/dist/components/Timeline/timeline-field-display-utils.js +4 -2
  88. package/dist/components/Timeline/timeline-translate-utils.d.ts +17 -0
  89. package/dist/components/Timeline/timeline-translate-utils.js +53 -12
  90. package/dist/components/Timeline/use-open-sequence-in-apps.d.ts +2 -0
  91. package/dist/components/Timeline/use-open-sequence-in-apps.js +17 -0
  92. package/dist/components/Timeline/use-timeline-asset-drop.js +17 -3
  93. package/dist/components/Timeline/use-timeline-keyframe-drag.js +4 -4
  94. package/dist/components/TimelineCombobox.js +1 -0
  95. package/dist/components/UndoRedoButtons.js +11 -0
  96. package/dist/components/composition-menu-items.js +56 -2
  97. package/dist/components/folder-menu-items.js +44 -0
  98. package/dist/components/get-open-in-menu-items.js +1 -1
  99. package/dist/components/import-assets.d.ts +24 -1
  100. package/dist/components/import-assets.js +3 -1
  101. package/dist/components/keyboard-shortcuts.d.ts +4 -4
  102. package/dist/components/keyboard-shortcuts.js +5 -0
  103. package/dist/esm/{LazyModels-hc33szyn.mjs → LazyModels-gfmpcy4h.mjs} +3 -3
  104. package/dist/esm/{LazyModels-sg40rjw6.mjs → LazyModels-m1rf06wh.mjs} +3 -3
  105. package/dist/esm/{TranscriptionModal-3ctnxpt6.mjs → TranscriptionModal-8pvrehg4.mjs} +6 -6
  106. package/dist/esm/{VideoMattingModal-b0r7e60n.mjs → VideoMattingModal-fefbzgka.mjs} +6 -6
  107. package/dist/esm/{index-yfrysr5f.mjs → index-0x13f28h.mjs} +17 -3
  108. package/dist/esm/{index-q2epbw93.mjs → index-1089795y.mjs} +2 -2
  109. package/dist/esm/{index-9qtvmwtx.mjs → index-41kqns5c.mjs} +4 -2
  110. package/dist/esm/{index-c37kme2v.mjs → index-ggqpre9v.mjs} +2202 -1719
  111. package/dist/esm/{index-wbmp5srk.mjs → index-hbezgbbq.mjs} +1 -1
  112. package/dist/esm/{index-2j3d1g81.mjs → index-jrw61pkj.mjs} +1 -1
  113. package/dist/esm/{index-1b9skrrd.mjs → index-mww32xc8.mjs} +3 -3
  114. package/dist/esm/{index-er3mh6em.mjs → index-s848rffx.mjs} +7123 -6588
  115. package/dist/esm/{index-q5xv20xx.mjs → index-tzxb8808.mjs} +1 -1
  116. package/dist/esm/{index-e3zwf3e7.mjs → index-vsxrxfpj.mjs} +1 -1
  117. package/dist/esm/index.mjs +2 -2
  118. package/dist/esm/internals.mjs +7 -7
  119. package/dist/esm/previewEntry.mjs +7 -7
  120. package/dist/helpers/get-git-menu-item.d.ts +4 -0
  121. package/dist/helpers/get-git-menu-item.js +8 -1
  122. package/dist/helpers/get-sequence-double-click-action.d.ts +3 -3
  123. package/dist/helpers/get-sequence-double-click-action.js +2 -2
  124. package/dist/helpers/pointer-session.d.ts +1 -0
  125. package/dist/helpers/pointer-session.js +10 -1
  126. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  127. package/dist/helpers/use-create-composition.js +5 -0
  128. package/dist/helpers/use-keybinding.d.ts +1 -1
  129. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -2
  130. package/dist/helpers/use-media-metadata.js +5 -1
  131. package/dist/helpers/use-menu-structure.js +5 -1
  132. package/dist/helpers/use-rename-composition.js +6 -1
  133. package/dist/state/modals.d.ts +13 -1
  134. package/dist/state/z-index.js +1 -3
  135. package/package.json +19 -19
@@ -209,6 +209,7 @@ const extendTimelineMarqueeSelection = ({ currentSelection, marqueeSelection, })
209
209
  exports.extendTimelineMarqueeSelection = extendTimelineMarqueeSelection;
210
210
  const defaultTimelineSelectionContextValue = {
211
211
  canSelect: false,
212
+ inspectorRevealRequest: null,
212
213
  revealRequest: null,
213
214
  selectedItems: [],
214
215
  isSelected: () => false,
@@ -542,9 +543,12 @@ const TimelineSelectionProvider = ({ children }) => {
542
543
  const marqueeSelectableItems = (0, react_1.useRef)(new Map());
543
544
  const marqueeRegistrationCounter = (0, react_1.useRef)(0);
544
545
  const [revealRequest, setRevealRequest] = (0, react_1.useState)(null);
546
+ const [inspectorRevealRequest, setInspectorRevealRequest] = (0, react_1.useState)(null);
547
+ const inspectorRevealTokenCounter = (0, react_1.useRef)(0);
545
548
  (0, react_1.useEffect)(() => {
546
549
  if (!canSelect) {
547
550
  selectionScope.current = null;
551
+ setInspectorRevealRequest(null);
548
552
  setRevealRequest(null);
549
553
  selectionController.clear();
550
554
  }
@@ -566,6 +570,13 @@ const TimelineSelectionProvider = ({ children }) => {
566
570
  });
567
571
  });
568
572
  }, []);
573
+ const requestRevealSelectionItemInInspector = (0, react_1.useCallback)((item) => {
574
+ inspectorRevealTokenCounter.current += 1;
575
+ setInspectorRevealRequest({
576
+ item,
577
+ token: inspectorRevealTokenCounter.current,
578
+ });
579
+ }, []);
569
580
  const expandParentsForSelectionItems = (0, react_1.useCallback)((items) => {
570
581
  for (const item of items) {
571
582
  if (item.type === 'guide') {
@@ -603,6 +614,12 @@ const TimelineSelectionProvider = ({ children }) => {
603
614
  if (options.reveal) {
604
615
  requestRevealSelectionItem(item);
605
616
  }
617
+ if (options.revealInInspector) {
618
+ requestRevealSelectionItemInInspector(item);
619
+ }
620
+ else {
621
+ setInspectorRevealRequest(null);
622
+ }
606
623
  if (selectionScope.current !== timelineSelectionScope) {
607
624
  selectionController.clear();
608
625
  }
@@ -611,6 +628,7 @@ const TimelineSelectionProvider = ({ children }) => {
611
628
  }, [
612
629
  canSelectItem,
613
630
  expandParentsForSelectionItem,
631
+ requestRevealSelectionItemInInspector,
614
632
  requestRevealSelectionItem,
615
633
  selectionController,
616
634
  timelineSelectionScope,
@@ -627,10 +645,17 @@ const TimelineSelectionProvider = ({ children }) => {
627
645
  if (options.reveal && items.length === 1) {
628
646
  requestRevealSelectionItem(items[0]);
629
647
  }
648
+ if (options.revealInInspector && items.length === 1) {
649
+ requestRevealSelectionItemInInspector(items[0]);
650
+ }
651
+ else {
652
+ setInspectorRevealRequest(null);
653
+ }
630
654
  selectionController.setSelectedItems(items);
631
655
  }, [
632
656
  canSelectItem,
633
657
  expandParentsForSelectionItems,
658
+ requestRevealSelectionItemInInspector,
634
659
  requestRevealSelectionItem,
635
660
  selectionController,
636
661
  timelineSelectionScope,
@@ -679,6 +704,7 @@ const TimelineSelectionProvider = ({ children }) => {
679
704
  }, [canSelectItem]);
680
705
  const clearSelection = (0, react_1.useCallback)(() => {
681
706
  selectionScope.current = null;
707
+ setInspectorRevealRequest(null);
682
708
  selectionController.clear();
683
709
  }, [selectionController]);
684
710
  const containsSelection = (0, react_1.useCallback)((nodePathInfo) => {
@@ -737,6 +763,7 @@ const TimelineSelectionProvider = ({ children }) => {
737
763
  }, [selectionController]);
738
764
  const value = (0, react_1.useMemo)(() => ({
739
765
  canSelect,
766
+ inspectorRevealRequest,
740
767
  revealRequest,
741
768
  selectedItems: availableSelectedItems,
742
769
  isSelected,
@@ -749,6 +776,7 @@ const TimelineSelectionProvider = ({ children }) => {
749
776
  clearSelection,
750
777
  }), [
751
778
  canSelect,
779
+ inspectorRevealRequest,
752
780
  revealRequest,
753
781
  availableSelectedItems,
754
782
  isSelected,
@@ -929,8 +957,7 @@ const useTimelineMarqueeSelection = () => {
929
957
  captureTarget: target,
930
958
  onMove: onPointerMove,
931
959
  onEnd: (reason, endEvent) => {
932
- if ((reason === 'pointerup' || reason === 'buttons-released') &&
933
- endEvent) {
960
+ if ((0, pointer_session_1.isPointerSessionRelease)(reason, endEvent)) {
934
961
  updateSelection(endEvent.clientX, endEvent.clientY);
935
962
  }
936
963
  cleanup();
@@ -960,7 +987,7 @@ const useTimelineMarqueeSelectableItem = (item, ref) => {
960
987
  }, [item, ref, registerMarqueeSelectableItem]);
961
988
  };
962
989
  exports.useTimelineMarqueeSelectableItem = useTimelineMarqueeSelectableItem;
963
- const useTimelineRowSelection = (nodePathInfo) => {
990
+ const useTimelineRowSelection = (nodePathInfo, revealInInspector = false) => {
964
991
  const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
965
992
  const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
966
993
  const selectionItem = (0, react_1.useMemo)(() => (0, exports.getTimelineSelectionFromNodePathInfo)(nodePathInfo), [nodePathInfo]);
@@ -969,8 +996,8 @@ const useTimelineRowSelection = (nodePathInfo) => {
969
996
  if (selectionItem === null) {
970
997
  return;
971
998
  }
972
- selectItem(selectionItem, interaction, selectableTimelineItemsRef.current);
973
- }, [selectItem, selectableTimelineItemsRef, selectionItem]);
999
+ selectItem(selectionItem, interaction, selectableTimelineItemsRef.current, { revealInInspector });
1000
+ }, [revealInInspector, selectItem, selectableTimelineItemsRef, selectionItem]);
974
1001
  return {
975
1002
  onSelect,
976
1003
  selectable: canSelect && selectionItem !== null,
@@ -263,7 +263,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
263
263
  ? Infinity
264
264
  : naturalMediaDuration;
265
265
  const effectiveMaxMediaDuration = s.loopDisplay ? null : maxMediaDuration;
266
- const { canOpenInEditor, canConfigureApps, codingAgentInfo, editorInfo, openInCodingAgent, openInEditor, originalLocation, } = (0, use_open_sequence_in_apps_1.useOpenSequenceInApps)(s);
266
+ const { canConfigureApps, canOpenInEditor, canOpenSource, codingAgentInfo, editorInfo, openInCodingAgent, openInEditor, openSource, originalLocation, } = (0, use_open_sequence_in_apps_1.useOpenSequenceInApps)(s);
267
267
  const validatedLocation = (0, react_1.useMemo)(() => {
268
268
  var _a;
269
269
  if (!originalLocation ||
@@ -321,7 +321,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
321
321
  }
322
322
  const action = (0, get_sequence_double_click_action_1.getSequenceDoubleClickAction)({
323
323
  button: e.button,
324
- canOpenInEditor,
324
+ canOpenSource,
325
325
  numberOfConnectedCompositions: connectedCompositions.length,
326
326
  sequenceWasDragged: dragAwareDoubleClick.consumePointerGestureWasDragged(),
327
327
  });
@@ -338,12 +338,12 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
338
338
  }));
339
339
  return;
340
340
  }
341
- openInEditor(null);
341
+ openSource();
342
342
  }, [
343
- canOpenInEditor,
343
+ canOpenSource,
344
344
  connectedCompositions,
345
345
  dragAwareDoubleClick,
346
- openInEditor,
346
+ openSource,
347
347
  s,
348
348
  selectComposition,
349
349
  sequenceFrameOffset,
@@ -354,7 +354,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
354
354
  }
355
355
  performSequenceDoubleClick(e);
356
356
  }, [dragAwareDoubleClick, performSequenceDoubleClick]);
357
- const canHandleSequenceDoubleClick = connectedCompositions.length === 1 || canOpenInEditor;
357
+ const canHandleSequenceDoubleClick = connectedCompositions.length === 1 || canOpenSource;
358
358
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
359
359
  const deleteDisabled = !previewInteractive || !s.controls || !canDeleteFromSource;
360
360
  const isProgrammaticallyDuplicated = ((_h = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) !== null && _h !== void 0 ? _h : 1) > 1;
@@ -204,7 +204,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
204
204
  const sequenceReorderWrapperRef = (0, react_1.useRef)(null);
205
205
  const stopSequencePointerSession = (0, react_1.useRef)(null);
206
206
  const suppressNextClick = (0, react_1.useRef)(false);
207
- const { canOpenInEditor, canConfigureApps, codingAgentInfo, editorInfo, openInCodingAgent, openInEditor, originalLocation, } = (0, use_open_sequence_in_apps_1.useOpenSequenceInApps)(sequence);
207
+ const { canConfigureApps, canOpenInEditor, canOpenSource, codingAgentInfo, editorInfo, openInCodingAgent, openInEditor, openSource, originalLocation, } = (0, use_open_sequence_in_apps_1.useOpenSequenceInApps)(sequence);
208
208
  const validatedLocation = (0, react_1.useMemo)(() => {
209
209
  var _a;
210
210
  if (!originalLocation ||
@@ -477,10 +477,10 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
477
477
  updateDropTarget(currentClientY);
478
478
  },
479
479
  });
480
- stopSequencePointerSession.current = (0, pointer_session_1.startCapturedPointerSession)({
480
+ stopSequencePointerSession.current = (0, pointer_session_1.startDeferredCapturedPointerSession)({
481
481
  captureTarget: sourceElement,
482
482
  event: e.nativeEvent,
483
- onMove: (pointerEvent) => {
483
+ onMove: (pointerEvent, capturePointer) => {
484
484
  currentClientY = pointerEvent.clientY;
485
485
  if (!didDrag &&
486
486
  Math.hypot(pointerEvent.clientX - startX, pointerEvent.clientY - startY) < SEQUENCE_REORDER_POINTER_THRESHOLD) {
@@ -488,6 +488,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
488
488
  }
489
489
  if (!didDrag) {
490
490
  didDrag = true;
491
+ capturePointer();
491
492
  previousUserSelect = document.body.style.userSelect;
492
493
  previousWebkitUserSelect = document.body.style.webkitUserSelect;
493
494
  document.body.style.userSelect = 'none';
@@ -515,7 +516,8 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
515
516
  autoScroll.update({ clientX: startX, clientY: pointerEvent.clientY });
516
517
  },
517
518
  onEnd: (reason, pointerEvent) => {
518
- if (reason === 'pointerup' && pointerEvent && didDrag) {
519
+ const released = (0, pointer_session_1.isPointerSessionRelease)(reason, pointerEvent);
520
+ if (released && didDrag) {
519
521
  updateDropTarget(pointerEvent.clientY);
520
522
  }
521
523
  autoScroll.stop();
@@ -531,7 +533,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
531
533
  setTimeout(() => {
532
534
  suppressNextClick.current = false;
533
535
  }, 0);
534
- if (reason === 'pointerup' && pointerEvent && activeDrop) {
536
+ if (released && activeDrop) {
535
537
  activeDropTarget === null || activeDropTarget === void 0 ? void 0 : activeDropTarget.reorder(activeDrop);
536
538
  }
537
539
  },
@@ -646,7 +648,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
646
648
  }
647
649
  const action = (0, get_sequence_double_click_action_1.getSequenceDoubleClickAction)({
648
650
  button: e.button,
649
- canOpenInEditor,
651
+ canOpenSource,
650
652
  numberOfConnectedCompositions: connectedCompositions.length,
651
653
  // The track list row reorders via native drag-and-drop, which
652
654
  // already suppresses `dblclick` after a drag.
@@ -665,16 +667,16 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
665
667
  }));
666
668
  return;
667
669
  }
668
- openInEditor(null);
670
+ openSource();
669
671
  }, [
670
- canOpenInEditor,
672
+ canOpenSource,
671
673
  connectedCompositions,
672
- openInEditor,
674
+ openSource,
673
675
  selectComposition,
674
676
  sequence,
675
677
  sequenceFrameOffset,
676
678
  ]);
677
- const canHandleSequenceDoubleClick = connectedCompositions.length === 1 || canOpenInEditor;
679
+ const canHandleSequenceDoubleClick = connectedCompositions.length === 1 || canOpenSource;
678
680
  const canRenameSelectedSequence = canRenameThisSequence &&
679
681
  selected &&
680
682
  selectedItems.length === 1 &&
@@ -899,10 +899,7 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
899
899
  onMove,
900
900
  onEnd: (reason, endEvent) => {
901
901
  stopPointerSessionRef.current = null;
902
- if ((reason === 'pointerup' ||
903
- reason === 'buttons-released' ||
904
- (reason === 'lostpointercapture' && (endEvent === null || endEvent === void 0 ? void 0 : endEvent.buttons) === 0)) &&
905
- endEvent) {
902
+ if ((0, pointer_session_1.isPointerSessionRelease)(reason, endEvent)) {
906
903
  onUp(endEvent);
907
904
  }
908
905
  else if (endEvent) {
@@ -1122,10 +1119,7 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
1122
1119
  },
1123
1120
  onEnd: (reason, endEvent) => {
1124
1121
  stopPointerSessionRef.current = null;
1125
- finishDrag((reason === 'pointerup' ||
1126
- reason === 'buttons-released' ||
1127
- (reason === 'lostpointercapture' && (endEvent === null || endEvent === void 0 ? void 0 : endEvent.buttons) === 0)) &&
1128
- endEvent !== null);
1122
+ finishDrag((0, pointer_session_1.isPointerSessionRelease)(reason, endEvent));
1129
1123
  },
1130
1124
  });
1131
1125
  }, [
@@ -1325,10 +1319,7 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1325
1319
  onMove,
1326
1320
  onEnd: (reason, endEvent) => {
1327
1321
  stopPointerSessionRef.current = null;
1328
- if ((reason === 'pointerup' ||
1329
- reason === 'buttons-released' ||
1330
- (reason === 'lostpointercapture' && (endEvent === null || endEvent === void 0 ? void 0 : endEvent.buttons) === 0)) &&
1331
- endEvent) {
1322
+ if ((0, pointer_session_1.isPointerSessionRelease)(reason, endEvent)) {
1332
1323
  onUp(endEvent);
1333
1324
  }
1334
1325
  else if (endEvent) {
@@ -4,9 +4,9 @@ exports.TimelineTranslateField = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const InputDragger_1 = require("../NewComposition/InputDragger");
7
- const timeline_field_display_utils_1 = require("./timeline-field-display-utils");
8
7
  const timeline_field_utils_1 = require("./timeline-field-utils");
9
8
  const timeline_translate_utils_1 = require("./timeline-translate-utils");
9
+ const TimelineSchemaField_1 = require("./TimelineSchemaField");
10
10
  const Transform3DModeContext_1 = require("./Transform3DModeContext");
11
11
  const leftDraggerStyle = {
12
12
  paddingLeft: 0,
@@ -21,11 +21,15 @@ const containerStyle = {
21
21
  const translateDragSensitivity = 3;
22
22
  const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onDragValueChange, onDragEnd, }) => {
23
23
  var _a;
24
+ var _b, _c, _d, _e;
24
25
  const [dragX, setDragX] = (0, react_1.useState)(null);
25
26
  const [dragY, setDragY] = (0, react_1.useState)(null);
26
27
  const [dragZ, setDragZ] = (0, react_1.useState)(null);
27
28
  const transform3DMode = (0, react_1.useContext)(Transform3DModeContext_1.Transform3DModeContext);
28
- const [codeX, codeY, codeZ] = (0, react_1.useMemo)(() => (0, timeline_translate_utils_1.parseTranslate)(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px')), [effectiveValue]);
29
+ const parsedTranslate = (0, react_1.useMemo)(() => (0, timeline_translate_utils_1.parseTranslateWithUnits)(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px')), [effectiveValue]);
30
+ const codeX = (_b = parsedTranslate === null || parsedTranslate === void 0 ? void 0 : parsedTranslate[0].value) !== null && _b !== void 0 ? _b : 0;
31
+ const codeY = (_c = parsedTranslate === null || parsedTranslate === void 0 ? void 0 : parsedTranslate[1].value) !== null && _c !== void 0 ? _c : 0;
32
+ const codeZ = (_d = (_a = parsedTranslate === null || parsedTranslate === void 0 ? void 0 : parsedTranslate[2]) === null || _a === void 0 ? void 0 : _a.value) !== null && _d !== void 0 ? _d : null;
29
33
  const show3D = transform3DMode || (codeZ !== null && codeZ !== 0);
30
34
  const configuredStep = field.fieldSchema.type === 'translate' ? field.fieldSchema.step : undefined;
31
35
  const step = configuredStep !== null && configuredStep !== void 0 ? configuredStep : 1;
@@ -33,15 +37,21 @@ const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onD
33
37
  defaultDecimalPlaces: 1,
34
38
  step: configuredStep,
35
39
  }), [configuredStep]);
36
- const formatter = (0, react_1.useCallback)((v) => {
37
- return (0, timeline_field_display_utils_1.formatTimelineFieldValueForDisplay)({
38
- fieldSchema: field.fieldSchema,
39
- value: v,
40
- });
41
- }, [field.fieldSchema]);
40
+ const formatCoordinate = (0, react_1.useCallback)((v, unit) => {
41
+ return `${(0, timeline_field_utils_1.formatTimelineNumber)({
42
+ decimalPlaces,
43
+ fixed: false,
44
+ value: (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(v)),
45
+ })}${unit}`;
46
+ }, [decimalPlaces]);
42
47
  const serialize = (0, react_1.useCallback)((x, y, z = dragZ !== null && dragZ !== void 0 ? dragZ : codeZ) => {
43
- return (0, timeline_translate_utils_1.serializeTranslate)([x, y, z], decimalPlaces);
44
- }, [codeZ, decimalPlaces, dragZ]);
48
+ var _a, _b;
49
+ return (0, timeline_translate_utils_1.serializeTranslateWithUnits)([
50
+ { value: x, unit: (_a = parsedTranslate === null || parsedTranslate === void 0 ? void 0 : parsedTranslate[0].unit) !== null && _a !== void 0 ? _a : 'px' },
51
+ { value: y, unit: (_b = parsedTranslate === null || parsedTranslate === void 0 ? void 0 : parsedTranslate[1].unit) !== null && _b !== void 0 ? _b : 'px' },
52
+ z === null ? null : { value: z, unit: 'px' },
53
+ ], decimalPlaces);
54
+ }, [codeZ, decimalPlaces, dragZ, parsedTranslate]);
45
55
  // --- X callbacks ---
46
56
  const onXChange = (0, react_1.useCallback)((newVal) => {
47
57
  setDragX(newVal);
@@ -135,9 +145,12 @@ const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onD
135
145
  }
136
146
  }
137
147
  }, [codeX, codeY, dragX, dragY, onSave, propStatus, serialize]);
148
+ if (parsedTranslate === null) {
149
+ return (jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "unsupported offset", formattedValue: false }));
150
+ }
138
151
  return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
139
- jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : codeX, buttonStyle: leftDraggerStyle, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset X" }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : codeY, buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset Y" }), show3D ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
140
- jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: (_a = dragZ !== null && dragZ !== void 0 ? dragZ : codeZ) !== null && _a !== void 0 ? _a : 0, buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onZChange, onValueChangeEnd: onZChangeEnd, onTextChange: onZTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset Z" })
152
+ jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : codeX, buttonStyle: leftDraggerStyle, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: (value) => formatCoordinate(value, parsedTranslate[0].unit), rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset X" }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : codeY, buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: (value) => formatCoordinate(value, parsedTranslate[1].unit), rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset Y" }), show3D ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
153
+ jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: (_e = dragZ !== null && dragZ !== void 0 ? dragZ : codeZ) !== null && _e !== void 0 ? _e : 0, buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onZChange, onValueChangeEnd: onZChangeEnd, onTextChange: onZTextChange, min: -Infinity, max: Infinity, step: step, formatter: (value) => formatCoordinate(value, 'px'), rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset Z" })
141
154
  ] })) : null] }));
142
155
  };
143
156
  exports.TimelineTranslateField = TimelineTranslateField;
@@ -124,7 +124,7 @@ const TimelineZoomControlsInner = ({ sliderMaxWidth }) => {
124
124
  return null;
125
125
  }
126
126
  return (jsx_runtime_1.jsxs("div", { style: container, children: [
127
- jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Zoom out timeline", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { onClick: onMinusClicked, style: buttonStyle, title: "", "aria-label": "Zoom out timeline", type: "button", children: (color) => jsx_runtime_1.jsx(canvas_zoom_1.CanvasZoomOutIcon, { color: color }) }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineZoomSlider, { maxWidth: sliderMaxWidth, minZoom: minZoom, timelineViewportWidth: timelineViewportWidth }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Zoom in timeline", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { onClick: onPlusClicked, style: buttonStyle, title: "", "aria-label": "Zoom in timeline", type: "button", children: (color) => jsx_runtime_1.jsx(canvas_zoom_1.CanvasZoomIcon, { color: color }) }) })
127
+ jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Zoom out", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { onClick: onMinusClicked, style: buttonStyle, title: "", "aria-label": "Zoom out timeline", type: "button", children: (color) => jsx_runtime_1.jsx(canvas_zoom_1.CanvasZoomOutIcon, { color: color }) }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineZoomSlider, { maxWidth: sliderMaxWidth, minZoom: minZoom, timelineViewportWidth: timelineViewportWidth }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Zoom in", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { onClick: onPlusClicked, style: buttonStyle, title: "", "aria-label": "Zoom in timeline", type: "button", children: (color) => jsx_runtime_1.jsx(canvas_zoom_1.CanvasZoomIcon, { color: color }) }) })
128
128
  ] }));
129
129
  };
130
130
  exports.TimelineZoomControls = react_1.default.memo(TimelineZoomControlsInner);
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSequenceContextMenuItems = exports.getMultiSequenceContextMenuItems = void 0;
4
4
  const no_react_1 = require("remotion/no-react");
5
5
  const format_file_location_1 = require("../../helpers/format-file-location");
6
+ const get_git_menu_item_1 = require("../../helpers/get-git-menu-item");
6
7
  const get_open_in_menu_items_1 = require("../get-open-in-menu-items");
7
8
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
8
9
  const actions_1 = require("../RenderQueue/actions");
@@ -68,6 +69,11 @@ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDis
68
69
  const defaultEditorId = (0, use_default_editor_info_1.getPreferredEditorId)(editorInfo);
69
70
  const defaultEditor = installedEditors.find((editor) => editor.id === defaultEditorId);
70
71
  const editorName = (_e = defaultEditor === null || defaultEditor === void 0 ? void 0 : defaultEditor.nameWithType) !== null && _e !== void 0 ? _e : null;
72
+ const defaultOpenInTarget = (0, get_git_menu_item_1.getDefaultOpenInTarget)({ canOpenInEditor });
73
+ const gitSourceName = window.remotion_gitSource
74
+ ? (0, get_git_menu_item_1.getGitSourceName)(window.remotion_gitSource)
75
+ : null;
76
+ const defaultOpenInName = defaultOpenInTarget === 'editor' ? editorName : gitSourceName;
71
77
  const defaultCodingAgent = codingAgentInfo === null || codingAgentInfo === void 0 ? void 0 : codingAgentInfo.installedCodingAgents.find((codingAgent) => codingAgent.id === codingAgentInfo.defaultCodingAgent);
72
78
  const contextForAgents = (0, format_file_location_1.formatContextForAgents)({
73
79
  location: originalLocation,
@@ -103,18 +109,28 @@ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDis
103
109
  })
104
110
  : [];
105
111
  const items = [
106
- editorName
112
+ defaultOpenInTarget && defaultOpenInName
107
113
  ? {
108
114
  type: 'item',
109
- id: 'open-in-editor',
115
+ id: defaultOpenInTarget === 'editor'
116
+ ? 'open-in-editor'
117
+ : 'open-in-git-source',
110
118
  keyHint: null,
111
- label: `Open in ${editorName}`,
119
+ label: `Open in ${defaultOpenInName}`,
112
120
  leftItem: null,
113
- disabled: !canOpenInEditor || !originalLocation,
114
- onClick: () => openInEditor(null),
121
+ disabled: !originalLocation,
122
+ onClick: () => {
123
+ if (defaultOpenInTarget === 'editor') {
124
+ openInEditor(null);
125
+ return;
126
+ }
127
+ (0, get_git_menu_item_1.openGitSource)({ folder: false, location: originalLocation });
128
+ },
115
129
  quickSwitcherLabel: null,
116
130
  subMenu: null,
117
- value: 'open-in-editor',
131
+ value: defaultOpenInTarget === 'editor'
132
+ ? 'open-in-editor'
133
+ : 'open-in-git-source',
118
134
  }
119
135
  : null,
120
136
  defaultCodingAgent
@@ -153,8 +153,10 @@ const formatTranslateTimelineFieldValueForDisplay = ({ fieldSchema, value, }) =>
153
153
  if (numericValue !== null) {
154
154
  return formatTranslateCoordinateForDisplay(numericValue, decimalPlaces);
155
155
  }
156
- const translate = (0, timeline_translate_utils_1.parseTranslate)(String(value !== null && value !== void 0 ? value : '0px 0px'));
157
- return (0, timeline_translate_utils_1.serializeTranslate)(translate, decimalPlaces);
156
+ const translate = (0, timeline_translate_utils_1.parseTranslateWithUnits)(String(value !== null && value !== void 0 ? value : '0px 0px'));
157
+ return translate === null
158
+ ? null
159
+ : (0, timeline_translate_utils_1.serializeTranslateWithUnits)(translate, decimalPlaces);
158
160
  };
159
161
  const formatTransformOriginAxisValueForDisplay = ({ decimalPlaces, unit, value, }) => {
160
162
  return `${(0, timeline_field_utils_1.formatTimelineNumber)({
@@ -1,3 +1,20 @@
1
1
  export type ParsedTranslate = readonly [number, number, number | null];
2
+ export type TranslateUnit = 'px' | '%';
3
+ export type ParsedTranslateWithUnits = readonly [
4
+ {
5
+ readonly value: number;
6
+ readonly unit: TranslateUnit;
7
+ },
8
+ {
9
+ readonly value: number;
10
+ readonly unit: TranslateUnit;
11
+ },
12
+ {
13
+ readonly value: number;
14
+ readonly unit: 'px';
15
+ } | null
16
+ ];
17
+ export declare const parseTranslateWithUnits: (value: string) => ParsedTranslateWithUnits | null;
2
18
  export declare const parseTranslate: (value: string) => ParsedTranslate;
3
19
  export declare const serializeTranslate: ([x, y, z]: ParsedTranslate, decimalPlaces?: number) => string;
20
+ export declare const serializeTranslateWithUnits: ([x, y, z]: ParsedTranslateWithUnits, decimalPlaces?: number) => string;
@@ -1,20 +1,53 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.serializeTranslate = exports.parseTranslate = void 0;
3
+ exports.serializeTranslateWithUnits = exports.serializeTranslate = exports.parseTranslate = exports.parseTranslateWithUnits = void 0;
4
4
  const timeline_field_utils_1 = require("./timeline-field-utils");
5
- const PIXEL_PATTERN = /^(-?\d+(?:\.\d+)?)px(?:\s+(-?\d+(?:\.\d+)?)px)?(?:\s+(-?\d+(?:\.\d+)?)px)?$/;
5
+ const TRANSLATE_PATTERN = /^(-?\d+(?:\.\d+)?)(px|%)?(?:\s+(-?\d+(?:\.\d+)?)(px|%)?)?(?:\s+(-?\d+(?:\.\d+)?)(px)?)?$/i;
6
6
  const translateDecimalPlaces = 1;
7
- const parseTranslate = (value) => {
8
- const m = value.match(PIXEL_PATTERN);
9
- if (!m) {
10
- return [0, 0, null];
7
+ const parseTranslateWithUnits = (value) => {
8
+ const match = value.match(TRANSLATE_PATTERN);
9
+ if (!match) {
10
+ return null;
11
+ }
12
+ const x = (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(match[1]));
13
+ const y = match[3] === undefined ? 0 : (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(match[3]));
14
+ const z = match[5] === undefined ? null : (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(match[5]));
15
+ if ((match[2] === undefined && x !== 0) ||
16
+ (match[3] !== undefined && match[4] === undefined && y !== 0) ||
17
+ (match[5] !== undefined && match[6] === undefined && z !== 0)) {
18
+ return null;
11
19
  }
12
20
  return [
13
- (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(m[1])),
14
- m[2] !== undefined ? (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(m[2])) : 0,
15
- m[3] !== undefined ? (0, timeline_field_utils_1.normalizeTimelineNumber)(Number(m[3])) : null,
21
+ {
22
+ value: x,
23
+ unit: match[2] === undefined
24
+ ? 'px'
25
+ : match[2].toLowerCase(),
26
+ },
27
+ {
28
+ value: y,
29
+ unit: match[4] === undefined
30
+ ? 'px'
31
+ : match[4].toLowerCase(),
32
+ },
33
+ z === null
34
+ ? z
35
+ : {
36
+ value: z,
37
+ unit: 'px',
38
+ },
16
39
  ];
17
40
  };
41
+ exports.parseTranslateWithUnits = parseTranslateWithUnits;
42
+ const parseTranslate = (value) => {
43
+ var _a;
44
+ var _b;
45
+ const parsed = (0, exports.parseTranslateWithUnits)(value);
46
+ if (parsed === null || parsed[0].unit !== 'px' || parsed[1].unit !== 'px') {
47
+ return [0, 0, null];
48
+ }
49
+ return [parsed[0].value, parsed[1].value, (_b = (_a = parsed[2]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null];
50
+ };
18
51
  exports.parseTranslate = parseTranslate;
19
52
  const formatTranslateCoordinate = (value, decimalPlaces) => {
20
53
  const normalized = (0, timeline_field_utils_1.normalizeTimelineNumber)(value);
@@ -22,9 +55,17 @@ const formatTranslateCoordinate = (value, decimalPlaces) => {
22
55
  return String(Object.is(rounded, -0) ? 0 : rounded);
23
56
  };
24
57
  const serializeTranslate = ([x, y, z], decimalPlaces = translateDecimalPlaces) => {
25
- const xy = `${formatTranslateCoordinate(x, decimalPlaces)}px ${formatTranslateCoordinate(y, decimalPlaces)}px`;
58
+ return (0, exports.serializeTranslateWithUnits)([
59
+ { value: x, unit: 'px' },
60
+ { value: y, unit: 'px' },
61
+ z === null ? null : { value: z, unit: 'px' },
62
+ ], decimalPlaces);
63
+ };
64
+ exports.serializeTranslate = serializeTranslate;
65
+ const serializeTranslateWithUnits = ([x, y, z], decimalPlaces = translateDecimalPlaces) => {
66
+ const xy = `${formatTranslateCoordinate(x.value, decimalPlaces)}${x.unit} ${formatTranslateCoordinate(y.value, decimalPlaces)}${y.unit}`;
26
67
  return z === null
27
68
  ? xy
28
- : `${xy} ${formatTranslateCoordinate(z, decimalPlaces)}px`;
69
+ : `${xy} ${formatTranslateCoordinate(z.value, decimalPlaces)}${z.unit}`;
29
70
  };
30
- exports.serializeTranslate = serializeTranslate;
71
+ exports.serializeTranslateWithUnits = serializeTranslateWithUnits;
@@ -1,11 +1,13 @@
1
1
  import type { EditorPickerId } from '@remotion/studio-shared';
2
2
  import type { TSequence } from 'remotion';
3
3
  export declare const useOpenSequenceInApps: (sequence: TSequence) => {
4
+ canOpenSource: boolean;
4
5
  canOpenInEditor: boolean;
5
6
  canConfigureApps: boolean;
6
7
  codingAgentInfo: import("@remotion/studio-shared").GetDefaultCodingAgentInfoResponse | null;
7
8
  editorInfo: import("@remotion/studio-shared").GetDefaultEditorInfoResponse | null;
8
9
  openInCodingAgent: (codingAgentId: "claude-code" | "codex" | "copilot" | "cursor", codingAgentName: string, contextForAgents: string | null) => Promise<void>;
9
10
  openInEditor: (editorId: EditorPickerId | null) => Promise<void>;
11
+ openSource: () => void;
10
12
  originalLocation: import("remotion").ResolvedStackLocation | null;
11
13
  };
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useOpenSequenceInApps = void 0;
4
4
  const react_1 = require("react");
5
5
  const client_id_1 = require("../../helpers/client-id");
6
+ const get_git_menu_item_1 = require("../../helpers/get-git-menu-item");
6
7
  const open_in_editor_1 = require("../../helpers/open-in-editor");
7
8
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
8
9
  const use_default_editor_info_1 = require("../use-default-editor-info");
@@ -16,6 +17,8 @@ const useOpenSequenceInApps = (sequence) => {
16
17
  const { canConfigureApps, canOpenInEditor: editorAvailable, defaultEditorId, editorInfo, } = (0, use_default_editor_info_1.useEditorOpening)(previewConnected);
17
18
  const codingAgentInfo = (0, use_default_editor_info_1.useDefaultCodingAgentInfo)(canConfigureApps);
18
19
  const canOpenInEditor = (0, react_1.useMemo)(() => Boolean(editorAvailable && originalLocation), [editorAvailable, originalLocation]);
20
+ const defaultOpenInTarget = (0, get_git_menu_item_1.getDefaultOpenInTarget)({ canOpenInEditor });
21
+ const canOpenSource = defaultOpenInTarget !== null && originalLocation !== null;
19
22
  const openInEditor = (0, react_1.useCallback)(async (editorId) => {
20
23
  const resolvedEditorId = editorId !== null && editorId !== void 0 ? editorId : defaultEditorId;
21
24
  if (!canOpenInEditor || !originalLocation || !resolvedEditorId) {
@@ -28,6 +31,18 @@ const useOpenSequenceInApps = (sequence) => {
28
31
  (0, NotificationCenter_1.showNotification)(err.message, 2000);
29
32
  }
30
33
  }, [canOpenInEditor, defaultEditorId, originalLocation]);
34
+ const openSource = (0, react_1.useCallback)(() => {
35
+ if (!originalLocation) {
36
+ return;
37
+ }
38
+ if (defaultOpenInTarget === 'editor') {
39
+ openInEditor(null);
40
+ return;
41
+ }
42
+ if (defaultOpenInTarget === 'git-source') {
43
+ (0, get_git_menu_item_1.openGitSource)({ folder: false, location: originalLocation });
44
+ }
45
+ }, [defaultOpenInTarget, openInEditor, originalLocation]);
31
46
  const openInCodingAgent = (0, react_1.useCallback)(async (codingAgentId, codingAgentName, contextForAgents) => {
32
47
  try {
33
48
  const response = await (0, open_in_editor_1.openInCodingAgent)(codingAgentId, contextForAgents);
@@ -40,12 +55,14 @@ const useOpenSequenceInApps = (sequence) => {
40
55
  }
41
56
  }, []);
42
57
  return {
58
+ canOpenSource,
43
59
  canOpenInEditor,
44
60
  canConfigureApps,
45
61
  codingAgentInfo,
46
62
  editorInfo,
47
63
  openInCodingAgent,
48
64
  openInEditor,
65
+ openSource,
49
66
  originalLocation,
50
67
  };
51
68
  };