sense-react-timeline-editor 1.0.9 → 1.0.11

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.
@@ -4,6 +4,7 @@ import { TimelineRow } from '../../interface/action';
4
4
  import { CommonProp } from '../../interface/common_prop';
5
5
  import './edit_area.less';
6
6
  import { type UploadProps } from 'antd/es';
7
+ import { ITimelineEngine } from '@/engine/engine';
7
8
  export declare type EditAreaProps = CommonProp & {
8
9
  className?: string;
9
10
  isMulti?: boolean;
@@ -25,12 +26,13 @@ export declare type EditAreaProps = CommonProp & {
25
26
  allowCreateTrack?: boolean;
26
27
  /** time-editor-container的ref引用 */
27
28
  containerRef?: React.MutableRefObject<HTMLDivElement>;
29
+ engineRef?: React.MutableRefObject<ITimelineEngine>;
28
30
  };
29
31
  /** edit area ref数据 */
30
32
  export interface EditAreaState {
31
33
  domRef: React.MutableRefObject<HTMLDivElement>;
32
34
  }
33
- export declare const EditArea: React.ForwardRefExoticComponent<CommonProp & {
35
+ export declare const EditArea: React.MemoExoticComponent<React.ForwardRefExoticComponent<CommonProp & {
34
36
  className?: string;
35
37
  isMulti?: boolean;
36
38
  /** 距离左侧滚动距离 */
@@ -51,4 +53,5 @@ export declare const EditArea: React.ForwardRefExoticComponent<CommonProp & {
51
53
  allowCreateTrack?: boolean;
52
54
  /** time-editor-container的ref引用 */
53
55
  containerRef?: React.MutableRefObject<HTMLDivElement>;
54
- } & React.RefAttributes<EditAreaState>>;
56
+ engineRef?: React.MutableRefObject<ITimelineEngine>;
57
+ } & React.RefAttributes<EditAreaState>>>;
@@ -14,6 +14,7 @@ export interface UseRowDragOptions {
14
14
  setEditorData?: (data: TimelineRow[]) => void;
15
15
  allowCreateTrack?: boolean;
16
16
  rowHeight?: number;
17
+ onUpdateEditorData?: (editorData: TimelineRow, actions: TimelineAction[]) => void;
17
18
  }
18
19
  export interface MultiDragState {
19
20
  /** 是否正在多选拖拽 */
@@ -13,4 +13,7 @@ export declare const useRowSelection: (options: UseRowSelectionOptions) => {
13
13
  DragSelection: () => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
14
14
  selectedActionIds: string[];
15
15
  clearSelection: () => void;
16
+ onClickOutside: (target: HTMLElement) => void;
17
+ onCtrlClick: (actionId: string, event: MouseEvent) => void;
18
+ setSelectedActionIds: import("react").Dispatch<import("react").SetStateAction<Set<string>>>;
16
19
  };
@@ -1,4 +1,5 @@
1
1
  /// <reference types="react" />
2
+ import { TimelineAction } from "@/interface/action";
2
3
  declare type EventData = {
3
4
  lastLeft: number;
4
5
  left: number;
@@ -11,7 +12,10 @@ declare type EventData = {
11
12
  };
12
13
  export declare type RndDragStartCallback = () => void;
13
14
  export declare type RndDragCallback = (data: EventData, scrollDelta?: number) => boolean | void;
14
- export declare type RndDragEndCallback = (data: Pick<EventData, 'left' | 'width' | 'top' | 'height'>) => void;
15
+ export declare type RndDragEndCallback = (data: Pick<EventData, 'left' | 'width' | 'top' | 'height'> & {
16
+ isMultiDrag?: boolean;
17
+ fn?: (item: TimelineAction) => void;
18
+ }) => void;
15
19
  export declare type Direction = "left" | "right";
16
20
  export declare type RndResizeStartCallback = (dir: Direction) => void;
17
21
  export declare type RndResizeCallback = (dir: Direction, data: EventData) => boolean | void;
@@ -74,4 +74,13 @@ export interface EventTypes {
74
74
  ended: {
75
75
  engine: TimelineEngine;
76
76
  };
77
+ /**
78
+ * 鼠标点击事件
79
+ * @type {{ target: HTMLElement, engine: TimelineEngine }}
80
+ * @memberof EventTypes
81
+ */
82
+ mousedown: {
83
+ target: HTMLElement;
84
+ evt: MouseEvent;
85
+ };
77
86
  }
package/dist/index.esm.js CHANGED
@@ -400,7 +400,8 @@ var Events = /*#__PURE__*/_createClass(function Events() {
400
400
  setActiveActionIds: [],
401
401
  play: [],
402
402
  paused: [],
403
- ended: []
403
+ ended: [],
404
+ mousedown: []
404
405
  }, handlers);
405
406
  });
406
407
 
@@ -2099,7 +2100,7 @@ var DragLines = function DragLines(_ref) {
2099
2100
  }));
2100
2101
  };
2101
2102
 
2102
- var css_248z$2 = ".timeline-editor .ant-upload-wrapper .ant-upload-drag {\n border: none !important;\n background: none !important;\n}\n.timeline-editor:hover .timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n height: 4px;\n}\n.timeline-editor-edit-area {\n flex: 1 1 auto;\n margin-top: 10px;\n overflow: hidden;\n position: relative;\n}\n.timeline-editor-edit-area.no-flex {\n flex: 0 0 auto;\n}\n.timeline-editor-edit-area.overflow-hidden {\n overflow: hidden;\n}\n.timeline-editor-edit-area.overflow-hidden .ReactVirtualized__Grid {\n overflow: hidden !important;\n height: initial !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid {\n outline: none !important;\n overflow: overlay !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n width: 0;\n height: 0;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-track {\n background-color: transparent !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-thumb {\n background: #666;\n border-radius: 16px;\n}\n.timeline-editor-selection-box {\n position: fixed;\n border: 2px solid #1890ff;\n background-color: rgba(24, 144, 255, 0.1);\n pointer-events: none;\n z-index: 9999;\n box-shadow: 0 0 8px rgba(24, 144, 255, 0.3);\n}\n";
2103
+ var css_248z$2 = ".timeline-editor .ant-upload-wrapper .ant-upload-drag {\n border: none !important;\n background: none !important;\n}\n.timeline-editor:hover .timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n height: 4px;\n}\n.timeline-editor-edit-area {\n flex: 1 1 auto;\n margin-top: 10px;\n overflow: hidden;\n position: relative;\n}\n.timeline-editor-edit-area.no-flex {\n flex: 0 0 auto;\n}\n.timeline-editor-edit-area.overflow-hidden {\n overflow: hidden;\n}\n.timeline-editor-edit-area.overflow-hidden .ReactVirtualized__Grid {\n overflow: hidden !important;\n height: initial !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid {\n outline: none !important;\n overflow: overlay !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n width: 0;\n height: 0;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-track {\n background-color: transparent !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-thumb {\n background: #666;\n border-radius: 16px;\n}\n.timeline-editor-selection-box {\n position: fixed;\n border: 2px solid #1890ff;\n background-color: rgba(24, 144, 255, 0.1);\n pointer-events: none;\n z-index: 9999;\n box-shadow: 0 0 8px rgba(24, 144, 255, 0.3);\n left: -100px;\n}\n";
2103
2104
  styleInject(css_248z$2);
2104
2105
 
2105
2106
  var css_248z$3 = ".timeline-editor-action {\n position: absolute;\n left: 0;\n top: 0;\n background-color: #c6cbd2;\n display: flex;\n align-items: center;\n}\n.timeline-editor-action .timeline-editor-action-left-stretch,\n.timeline-editor-action .timeline-editor-action-right-stretch {\n position: absolute;\n}\n.timeline-editor-action .timeline-editor-action-left-stretch {\n left: -3px;\n}\n.timeline-editor-action .timeline-editor-action-right-stretch {\n right: -3px;\n transform: rotate(180deg);\n}\n";
@@ -2142,7 +2143,9 @@ var EditAction = function EditAction(_ref) {
2142
2143
  _ref$allowCreateTrack = _ref.allowCreateTrack,
2143
2144
  allowCreateTrack = _ref$allowCreateTrack === void 0 ? true : _ref$allowCreateTrack,
2144
2145
  setDropPreview = _ref.setDropPreview,
2145
- containerRef = _ref.containerRef;
2146
+ containerRef = _ref.containerRef,
2147
+ selectedActionIds = _ref.selectedActionIds;
2148
+ console.log('action: selectedActionIds = ', selectedActionIds);
2146
2149
  var rowRnd = useRef();
2147
2150
  var isDragWhenClick = useRef(false);
2148
2151
  var originalPosition = useRef({
@@ -2311,7 +2314,9 @@ var EditAction = function EditAction(_ref) {
2311
2314
  var left = _ref3.left,
2312
2315
  width = _ref3.width,
2313
2316
  top = _ref3.top,
2314
- height = _ref3.height;
2317
+ height = _ref3.height,
2318
+ isMultiDrag = _ref3.isMultiDrag,
2319
+ fnCallback = _ref3.fn;
2315
2320
  console.log('handleDragEnd: ', left, width, top, height);
2316
2321
  // 清理预览指示器
2317
2322
  if (setDropPreview) {
@@ -2627,6 +2632,7 @@ var EditAction = function EditAction(_ref) {
2627
2632
  if (targetRowItem.id !== row.id) {
2628
2633
  up = top > 0 ? 1 : -1;
2629
2634
  }
2635
+ fnCallback === null || fnCallback === void 0 ? void 0 : fnCallback(actionItem);
2630
2636
  // 执行回调
2631
2637
  if (onActionMoveEnd) onActionMoveEnd({
2632
2638
  action: actionItem,
@@ -2638,9 +2644,10 @@ var EditAction = function EditAction(_ref) {
2638
2644
  width: width,
2639
2645
  top: top,
2640
2646
  height: height,
2641
- up: up
2647
+ up: up,
2648
+ isMultiDrag: (selectedActionIds === null || selectedActionIds === void 0 ? void 0 : selectedActionIds.length) > 1 || isMultiDrag
2642
2649
  });
2643
- }, [action, allowCreateTrack, editorData, id, onActionMoveEnd, parserTimeToTransform, parserTransformToTime, row, scale, scaleWidth, setDropPreview, setEditorData, startLeft]);
2650
+ }, [action, allowCreateTrack, editorData, id, onActionMoveEnd, parserTimeToTransform, parserTransformToTime, row, scale, scaleWidth, setDropPreview, setEditorData, startLeft, selectedActionIds]);
2644
2651
  // 防抖版本的 handleDragEnd
2645
2652
  var _useDebounceFn = useDebounceFn(handleDragEndBase, {
2646
2653
  wait: 300
@@ -2746,14 +2753,16 @@ var EditAction = function EditAction(_ref) {
2746
2753
  width = _ref6.width,
2747
2754
  top = _ref6.top,
2748
2755
  height = _ref6.height,
2749
- id = _ref6.id;
2750
- console.log('handleActionMoveEnd: ', left, width, top, height, id);
2756
+ id = _ref6.id,
2757
+ fn = _ref6.fn;
2758
+ console.log('handleActionMoveEnd: ', left, width, top, height, id, fn);
2751
2759
  if (id === action.id) {
2752
2760
  handleDragEnd({
2753
2761
  left: left,
2754
2762
  width: width,
2755
2763
  top: top,
2756
- height: height
2764
+ height: height,
2765
+ fn: fn
2757
2766
  });
2758
2767
  }
2759
2768
  };
@@ -2796,6 +2805,7 @@ var EditAction = function EditAction(_ref) {
2796
2805
  deltaScrollTop: handleDeltaScrollTop
2797
2806
  }, /*#__PURE__*/React.createElement("div", {
2798
2807
  "data-action-id": action.id,
2808
+ "data-action-disabled": action.is_disabled ? 1 : 0,
2799
2809
  onMouseDown: function onMouseDown() {
2800
2810
  isDragWhenClick.current = false;
2801
2811
  },
@@ -2817,6 +2827,19 @@ var EditAction = function EditAction(_ref) {
2817
2827
  time: time
2818
2828
  });
2819
2829
  }
2830
+ // 处理 Ctrl+ 点击选择
2831
+ if (e.ctrlKey || e.metaKey) {
2832
+ e.preventDefault();
2833
+ e.stopPropagation();
2834
+ var event = new CustomEvent('ctrl-click-action', {
2835
+ detail: {
2836
+ actionId: action.id,
2837
+ row: row,
2838
+ originalEvent: e.nativeEvent
2839
+ }
2840
+ });
2841
+ window.dispatchEvent(event);
2842
+ }
2820
2843
  },
2821
2844
  onDoubleClick: function onDoubleClick(e) {
2822
2845
  if (onDoubleClickAction) {
@@ -3070,6 +3093,7 @@ var useRowSelection = function useRowSelection(options) {
3070
3093
  // 检查框选区域是否与 action 相交
3071
3094
  row.actions.forEach(function (action) {
3072
3095
  var _containerRef$current3;
3096
+ if (action.is_disabled) return;
3073
3097
  var actionEl = (_containerRef$current3 = containerRef.current) === null || _containerRef$current3 === void 0 ? void 0 : _containerRef$current3.querySelector(".timeline-editor-action[data-action-id=\"".concat(action.id, "\"]"));
3074
3098
  if (actionEl) {
3075
3099
  var actionRect = actionEl.getBoundingClientRect();
@@ -3125,7 +3149,7 @@ var useRowSelection = function useRowSelection(options) {
3125
3149
  if (disabled) return false;
3126
3150
  // 不在 action 元素上启动框选
3127
3151
  var element = target;
3128
- if (((_element$closest = element.closest) === null || _element$closest === void 0 ? void 0 : _element$closest.call(element, '.timeline-editor-action')) || ((_element$closest2 = element.closest) === null || _element$closest2 === void 0 ? void 0 : _element$closest2.call(element, '.timeline-editor-edit-action')) || ((_element$closest3 = element.closest) === null || _element$closest3 === void 0 ? void 0 : _element$closest3.call(element, '[data-draggable="true"]')) || ((_element$closest4 = element.closest) === null || _element$closest4 === void 0 ? void 0 : _element$closest4.call(element, '.timeline-editor-edit-row.dragging'))) {
3152
+ if (((_element$closest = element.closest) === null || _element$closest === void 0 ? void 0 : _element$closest.call(element, '.timeline-editor-action[data-action-disabled="0"]')) || ((_element$closest2 = element.closest) === null || _element$closest2 === void 0 ? void 0 : _element$closest2.call(element, '.timeline-editor-edit-action')) || ((_element$closest3 = element.closest) === null || _element$closest3 === void 0 ? void 0 : _element$closest3.call(element, '[data-draggable="true"]')) || ((_element$closest4 = element.closest) === null || _element$closest4 === void 0 ? void 0 : _element$closest4.call(element, '.timeline-editor-edit-row.dragging'))) {
3129
3153
  return false;
3130
3154
  }
3131
3155
  return true;
@@ -3147,38 +3171,48 @@ var useRowSelection = function useRowSelection(options) {
3147
3171
  setSelectedActionIds(new Set());
3148
3172
  _onSelectionChange([]);
3149
3173
  }, [_onSelectionChange]);
3174
+ // 处理 Ctrl+ 点击选择
3175
+ var handleCtrlClick = useCallback(function (actionId, event) {
3176
+ if (disabled) return;
3177
+ var newSelectedActionIds = new Set(selectedActionIds);
3178
+ if (newSelectedActionIds.has(actionId)) {
3179
+ // 如果已选中,则取消选中
3180
+ newSelectedActionIds.delete(actionId);
3181
+ } else {
3182
+ // 如果未选中,则添加选中
3183
+ newSelectedActionIds.add(actionId);
3184
+ }
3185
+ setSelectedActionIds(newSelectedActionIds);
3186
+ _onSelectionChange(Array.from(newSelectedActionIds));
3187
+ }, [disabled, selectedActionIds, _onSelectionChange]);
3150
3188
  // 点击空白区域取消选择
3151
- useEffect(function () {
3189
+ var handleClickOutside = useCallback(function (target) {
3152
3190
  if (disabled) return;
3153
- var handleClickOutside = function handleClickOutside(e) {
3154
- var target = e.target;
3155
- // 如果点击的不是选中的 action 或框选框,清除选择
3156
- if (!target.closest('.timeline-editor-selection-box') && !target.closest('.timeline-editor-action') && !target.closest('[data-draggable="true"]')) {
3157
- clearSelection();
3158
- }
3159
- };
3160
- document.addEventListener('mousedown', handleClickOutside);
3161
- return function () {
3162
- document.removeEventListener('mousedown', handleClickOutside);
3163
- };
3191
+ // 如果点击的不是选中的 action 或框选框,清除选择
3192
+ if (!target.closest('.timeline-editor-selection-box') && !target.closest('.timeline-editor-action') && !target.closest('[data-draggable="true"]') && !target.closest('.voice-studio-right-config-panel') && !target.closest('.voice-studio-main-content-panel')) {
3193
+ clearSelection();
3194
+ }
3164
3195
  }, [disabled, clearSelection]);
3165
3196
  // 监听 Escape 键取消选择
3166
- useEffect(function () {
3197
+ var handleKeyDown = useCallback(function (e) {
3167
3198
  if (disabled) return;
3168
- var handleKeyDown = function handleKeyDown(e) {
3169
- if (e.key === 'Escape' && selectedActionIds.size > 0) {
3170
- clearSelection();
3171
- }
3172
- };
3199
+ if (e.key === 'Escape' && selectedActionIds.size > 0) {
3200
+ clearSelection();
3201
+ }
3202
+ }, [disabled, selectedActionIds.size, clearSelection]);
3203
+ useEffect(function () {
3173
3204
  document.addEventListener('keydown', handleKeyDown);
3174
3205
  return function () {
3175
3206
  document.removeEventListener('keydown', handleKeyDown);
3176
3207
  };
3177
- }, [disabled, selectedActionIds.size, clearSelection]);
3208
+ }, [handleKeyDown]);
3178
3209
  return {
3179
3210
  DragSelection: DragSelection,
3180
3211
  selectedActionIds: Array.from(selectedActionIds),
3181
- clearSelection: clearSelection
3212
+ clearSelection: clearSelection,
3213
+ onClickOutside: handleClickOutside,
3214
+ onCtrlClick: handleCtrlClick,
3215
+ setSelectedActionIds: setSelectedActionIds
3182
3216
  };
3183
3217
  };
3184
3218
 
@@ -3192,7 +3226,8 @@ var useRowDrag = function useRowDrag(options) {
3192
3226
  scaleWidth = _options$scaleWidth === void 0 ? 160 : _options$scaleWidth,
3193
3227
  _options$startLeft = options.startLeft,
3194
3228
  startLeft = _options$startLeft === void 0 ? 20 : _options$startLeft,
3195
- setEditorData = options.setEditorData;
3229
+ setEditorData = options.setEditorData,
3230
+ onUpdateEditorData = options.onUpdateEditorData;
3196
3231
  // 多选拖拽状态
3197
3232
  var multiDragState = React.useRef({
3198
3233
  isMultiDrag: false,
@@ -3500,8 +3535,9 @@ var useRowDrag = function useRowDrag(options) {
3500
3535
  }).start;
3501
3536
  var deltaTime = currentStart - start;
3502
3537
  console.log('Multi-drag ended, deltaTime:', deltaTime);
3538
+ var updatedData = [];
3503
3539
  // 更新所有选中的 actions 的最终位置
3504
- var updatedData = editorData.map(function (r) {
3540
+ editorData.map(function (r) {
3505
3541
  return _objectSpread2(_objectSpread2({}, r), {}, {
3506
3542
  actions: r.actions.map(function (a) {
3507
3543
  if (selectedActionIds.includes(a.id) && primaryActionId !== a.id) {
@@ -3532,7 +3568,13 @@ var useRowDrag = function useRowDrag(options) {
3532
3568
  width: _width,
3533
3569
  top: top,
3534
3570
  height: height,
3535
- id: a.id
3571
+ id: a.id,
3572
+ fn: function fn(item) {
3573
+ updatedData.push(item);
3574
+ if (updatedData.length === selectedActionIds.length) {
3575
+ onUpdateEditorData === null || onUpdateEditorData === void 0 ? void 0 : onUpdateEditorData(r, updatedData);
3576
+ }
3577
+ }
3536
3578
  }
3537
3579
  }));
3538
3580
  }, 0);
@@ -3541,6 +3583,9 @@ var useRowDrag = function useRowDrag(options) {
3541
3583
  end: newEnd
3542
3584
  });
3543
3585
  }
3586
+ if (a.id === primaryActionId) {
3587
+ updatedData.push(a);
3588
+ }
3544
3589
  return a;
3545
3590
  })
3546
3591
  });
@@ -3611,7 +3656,7 @@ var getAudioDuration = function getAudioDuration(url) {
3611
3656
  });
3612
3657
  });
3613
3658
  };
3614
- var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3659
+ var EditAreaO = /*#__PURE__*/React.forwardRef(function (props, ref) {
3615
3660
  var className = props.className,
3616
3661
  _props$isMulti = props.isMulti,
3617
3662
  isMulti = _props$isMulti === void 0 ? false : _props$isMulti,
@@ -3642,7 +3687,8 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3642
3687
  setEditorData = props.setEditorData,
3643
3688
  _props$allowCreateTra = props.allowCreateTrack,
3644
3689
  allowCreateTrack = _props$allowCreateTra === void 0 ? true : _props$allowCreateTra,
3645
- containerRef = props.containerRef;
3690
+ containerRef = props.containerRef,
3691
+ engineRef = props.engineRef;
3646
3692
  // 支持mp3\wav格式上传
3647
3693
  var onBeforeUpload = function onBeforeUpload(file) {
3648
3694
  if (file.type !== 'audio/mp3' && file.type !== 'audio/wav') {
@@ -3677,7 +3723,8 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3677
3723
  flexible: true,
3678
3724
  url: info.file.response.url,
3679
3725
  start: currentMouseTime,
3680
- end: currentMouseTime + duration
3726
+ end: currentMouseTime + duration,
3727
+ isUpload: true
3681
3728
  };
3682
3729
  onUpdateEditorData === null || onUpdateEditorData === void 0 ? void 0 : onUpdateEditorData(row, [newAction]);
3683
3730
  case 3:
@@ -3714,30 +3761,34 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3714
3761
  dragIndicator = _useState6[0],
3715
3762
  setDragIndicator = _useState6[1];
3716
3763
  // 框选功能
3764
+ var handleSelectionChange = useCallback(function (selectedActionIds) {
3765
+ // 更新 editorData 中每个 action 的选中状态
3766
+ var updatedData = editorData.map(function (row) {
3767
+ return _objectSpread2(_objectSpread2({}, row), {}, {
3768
+ actions: row.actions.map(function (action) {
3769
+ return _objectSpread2(_objectSpread2({}, action), {}, {
3770
+ selected: selectedActionIds.includes(action.id)
3771
+ });
3772
+ })
3773
+ });
3774
+ });
3775
+ setEditorData(updatedData);
3776
+ onMutiSelectChange === null || onMutiSelectChange === void 0 ? void 0 : onMutiSelectChange(selectedActionIds);
3777
+ }, [editorData, setEditorData, onMutiSelectChange]);
3717
3778
  var _useRowSelection = useRowSelection({
3718
3779
  editorData: editorData,
3719
3780
  rowHeight: _rowHeight,
3720
3781
  scrollTop: scrollTop,
3721
3782
  scrollLeft: scrollLeft,
3722
- onSelectionChange: function onSelectionChange(selectedActionIds) {
3723
- // 更新 editorData 中每个 action 的选中状态
3724
- var updatedData = editorData.map(function (row) {
3725
- return _objectSpread2(_objectSpread2({}, row), {}, {
3726
- actions: row.actions.map(function (action) {
3727
- return _objectSpread2(_objectSpread2({}, action), {}, {
3728
- selected: selectedActionIds.includes(action.id)
3729
- });
3730
- })
3731
- });
3732
- });
3733
- setEditorData(updatedData);
3734
- onMutiSelectChange === null || onMutiSelectChange === void 0 ? void 0 : onMutiSelectChange(selectedActionIds);
3735
- },
3783
+ onSelectionChange: handleSelectionChange,
3736
3784
  disabled: false,
3737
3785
  containerRef: editAreaRef
3738
3786
  }),
3739
3787
  DragSelection = _useRowSelection.DragSelection,
3740
- selectedActionIds = _useRowSelection.selectedActionIds;
3788
+ selectedActionIds = _useRowSelection.selectedActionIds,
3789
+ onClickOutside = _useRowSelection.onClickOutside,
3790
+ onCtrlClick = _useRowSelection.onCtrlClick,
3791
+ setSelectedActionIds = _useRowSelection.setSelectedActionIds;
3741
3792
  var _useRowDrag = useRowDrag({
3742
3793
  selectedActionIds: selectedActionIds,
3743
3794
  editorData: editorData,
@@ -3747,7 +3798,8 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3747
3798
  startLeft: startLeft,
3748
3799
  setEditorData: setEditorData,
3749
3800
  allowCreateTrack: allowCreateTrack,
3750
- rowHeight: _rowHeight
3801
+ rowHeight: _rowHeight,
3802
+ onUpdateEditorData: onUpdateEditorData
3751
3803
  }),
3752
3804
  onDragStart = _useRowDrag.onDragStart,
3753
3805
  onDragMove = _useRowDrag.onDragMove,
@@ -3832,6 +3884,45 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3832
3884
  });
3833
3885
  }
3834
3886
  };
3887
+ useEffect(function () {
3888
+ if (!(engineRef === null || engineRef === void 0 ? void 0 : engineRef.current)) return;
3889
+ engineRef.current.on('mousedown', function (data) {
3890
+ console.log('mousedown', data);
3891
+ onClickOutside(data.target);
3892
+ });
3893
+ return function () {
3894
+ var _engineRef$current;
3895
+ engineRef === null || engineRef === void 0 ? void 0 : (_engineRef$current = engineRef.current) === null || _engineRef$current === void 0 ? void 0 : _engineRef$current.off('mousedown');
3896
+ };
3897
+ }, [engineRef, onClickOutside]);
3898
+ // 监听 Ctrl+ 点击事件
3899
+ useEffect(function () {
3900
+ var handleCtrlClickAction = function handleCtrlClickAction(e) {
3901
+ var _e$detail = e.detail,
3902
+ actionId = _e$detail.actionId,
3903
+ row = _e$detail.row;
3904
+ console.log('ctrl-click-action', row, ', editorData = ', editorData);
3905
+ setSelectedActionIds(function (ids) {
3906
+ var newIds = new Set();
3907
+ ids.forEach(function (id) {
3908
+ editorData.forEach(function (item) {
3909
+ item.actions.forEach(function (action) {
3910
+ if (item.type === row.type && action.id === id) {
3911
+ newIds.add(id);
3912
+ }
3913
+ });
3914
+ });
3915
+ });
3916
+ newIds.add(actionId);
3917
+ handleSelectionChange(Array.from(newIds));
3918
+ return new Set(newIds);
3919
+ });
3920
+ };
3921
+ window.addEventListener('ctrl-click-action', handleCtrlClickAction);
3922
+ return function () {
3923
+ window.removeEventListener('ctrl-click-action', handleCtrlClickAction);
3924
+ };
3925
+ }, [onCtrlClick, editorData, handleSelectionChange]);
3835
3926
  /** 获取每个cell渲染内容 */
3836
3927
  var cellRenderer = function cellRenderer(_ref2) {
3837
3928
  var rowIndex = _ref2.rowIndex,
@@ -3901,10 +3992,14 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3901
3992
  height: data.height || 0,
3902
3993
  up: data.up || 0
3903
3994
  });
3904
- return _onActionMoveEnd && _onActionMoveEnd(data);
3995
+ if (!data.isMultiDrag) {
3996
+ return _onActionMoveEnd && _onActionMoveEnd(data);
3997
+ }
3998
+ return;
3905
3999
  }
3906
4000
  }));
3907
4001
  if (!!row && (canUpload || (row === null || row === void 0 ? void 0 : row.canUpload))) {
4002
+ var _row$actions;
3908
4003
  return /*#__PURE__*/React.createElement(Upload, {
3909
4004
  ref: uploadRef,
3910
4005
  key: key + 'upload',
@@ -3917,7 +4012,9 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3917
4012
  beforeUpload: onBeforeUpload,
3918
4013
  onChange: handleUploadChange(row),
3919
4014
  showUploadList: false,
3920
- openFileDialogOnClick: false,
4015
+ openFileDialogOnClick: ((_row$actions = row.actions) === null || _row$actions === void 0 ? void 0 : _row$actions.filter(function (item) {
4016
+ return item.effectId === 'effect2';
4017
+ }).length) > 0,
3921
4018
  customRequest: customRequest,
3922
4019
  onDrop: handleDrop,
3923
4020
  type: "drag"
@@ -3958,7 +4055,7 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
3958
4055
  var totalHeight = 0;
3959
4056
  // 高度列表
3960
4057
  var heights = editorData.map(function (row) {
3961
- var itemHeight = row.rowHeight || _rowHeight;
4058
+ var itemHeight = (row.rowHeight || _rowHeight) + 2;
3962
4059
  totalHeight += itemHeight;
3963
4060
  return itemHeight;
3964
4061
  });
@@ -4042,6 +4139,7 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
4042
4139
  });
4043
4140
  }());
4044
4141
  });
4142
+ var EditArea = /*#__PURE__*/React.memo(EditAreaO);
4045
4143
 
4046
4144
  var css_248z$5 = ".timeline-editor {\n height: 600px;\n width: 600px;\n min-height: 32px;\n position: relative;\n font-size: 12px;\n font-family: \"PingFang SC\";\n background-color: #191b1d;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.timeline-editor.light {\n background-color: #fff;\n}\n";
4047
4145
  styleInject(css_248z$5);
@@ -4171,6 +4269,7 @@ var Timeline = /*#__PURE__*/React.forwardRef(function (props, ref) {
4171
4269
  var areaRef = useRef();
4172
4270
  var scrollSync = useRef();
4173
4271
  var containerRef = useRef();
4272
+ console.log(' Timeline mounted = ', areaRef);
4174
4273
  // 编辑器数据
4175
4274
  var _useState = useState(data),
4176
4275
  _useState2 = _slicedToArray(_useState, 2),
@@ -4290,6 +4389,19 @@ var Timeline = /*#__PURE__*/React.forwardRef(function (props, ref) {
4290
4389
  engineRef.current.on('play', handlePlay);
4291
4390
  engineRef.current.on('paused', handlePaused);
4292
4391
  }, []);
4392
+ useEffect(function () {
4393
+ var handleClickOutside = function handleClickOutside(e) {
4394
+ var target = e.target;
4395
+ engineRef.current.trigger('mousedown', {
4396
+ target: target,
4397
+ evt: e
4398
+ });
4399
+ };
4400
+ document.addEventListener('mousedown', handleClickOutside);
4401
+ return function () {
4402
+ document.removeEventListener('mousedown', handleClickOutside);
4403
+ };
4404
+ }, []);
4293
4405
  // ref 数据
4294
4406
  useImperativeHandle(ref, function () {
4295
4407
  return {
@@ -4375,6 +4487,7 @@ var Timeline = /*#__PURE__*/React.forwardRef(function (props, ref) {
4375
4487
  setScaleCount: handleSetScaleCount,
4376
4488
  scrollTop: scrollTop,
4377
4489
  scrollLeft: scrollLeft,
4490
+ engineRef: engineRef,
4378
4491
  setEditorData: handleEditorDataChange,
4379
4492
  deltaScrollLeft: autoScroll && handleDeltaScrollLeft,
4380
4493
  allowCreateTrack: allowCreateTrack,
@@ -4385,10 +4498,7 @@ var Timeline = /*#__PURE__*/React.forwardRef(function (props, ref) {
4385
4498
  }
4386
4499
  }))) : null, areaCount > 1 ? /*#__PURE__*/React.createElement("div", {
4387
4500
  id: 'time-editor-container',
4388
- ref: containerRef,
4389
- style: {
4390
- overflow: 'auto'
4391
- }
4501
+ ref: containerRef
4392
4502
  }, Object.keys(groupedData).map(function (key, index) {
4393
4503
  var handleGroupDataChange = function handleGroupDataChange(updatedData) {
4394
4504
  var mergedData = editorData.filter(function (item) {
@@ -4427,6 +4537,7 @@ var Timeline = /*#__PURE__*/React.forwardRef(function (props, ref) {
4427
4537
  allowCreateTrack: allowCreateTrack,
4428
4538
  containerRef: containerRef,
4429
4539
  onMutiSelectChange: props === null || props === void 0 ? void 0 : props.onMutiSelectChange,
4540
+ engineRef: engineRef,
4430
4541
  onScroll: function onScroll(params) {
4431
4542
  _onScroll(params);
4432
4543
  onScrollVertical && onScrollVertical(params);
package/dist/index.js CHANGED
@@ -409,7 +409,8 @@ var Events = /*#__PURE__*/_createClass(function Events() {
409
409
  setActiveActionIds: [],
410
410
  play: [],
411
411
  paused: [],
412
- ended: []
412
+ ended: [],
413
+ mousedown: []
413
414
  }, handlers);
414
415
  });
415
416
 
@@ -2108,7 +2109,7 @@ var DragLines = function DragLines(_ref) {
2108
2109
  }));
2109
2110
  };
2110
2111
 
2111
- var css_248z$2 = ".timeline-editor .ant-upload-wrapper .ant-upload-drag {\n border: none !important;\n background: none !important;\n}\n.timeline-editor:hover .timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n height: 4px;\n}\n.timeline-editor-edit-area {\n flex: 1 1 auto;\n margin-top: 10px;\n overflow: hidden;\n position: relative;\n}\n.timeline-editor-edit-area.no-flex {\n flex: 0 0 auto;\n}\n.timeline-editor-edit-area.overflow-hidden {\n overflow: hidden;\n}\n.timeline-editor-edit-area.overflow-hidden .ReactVirtualized__Grid {\n overflow: hidden !important;\n height: initial !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid {\n outline: none !important;\n overflow: overlay !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n width: 0;\n height: 0;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-track {\n background-color: transparent !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-thumb {\n background: #666;\n border-radius: 16px;\n}\n.timeline-editor-selection-box {\n position: fixed;\n border: 2px solid #1890ff;\n background-color: rgba(24, 144, 255, 0.1);\n pointer-events: none;\n z-index: 9999;\n box-shadow: 0 0 8px rgba(24, 144, 255, 0.3);\n}\n";
2112
+ var css_248z$2 = ".timeline-editor .ant-upload-wrapper .ant-upload-drag {\n border: none !important;\n background: none !important;\n}\n.timeline-editor:hover .timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n height: 4px;\n}\n.timeline-editor-edit-area {\n flex: 1 1 auto;\n margin-top: 10px;\n overflow: hidden;\n position: relative;\n}\n.timeline-editor-edit-area.no-flex {\n flex: 0 0 auto;\n}\n.timeline-editor-edit-area.overflow-hidden {\n overflow: hidden;\n}\n.timeline-editor-edit-area.overflow-hidden .ReactVirtualized__Grid {\n overflow: hidden !important;\n height: initial !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid {\n outline: none !important;\n overflow: overlay !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n width: 0;\n height: 0;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-track {\n background-color: transparent !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-thumb {\n background: #666;\n border-radius: 16px;\n}\n.timeline-editor-selection-box {\n position: fixed;\n border: 2px solid #1890ff;\n background-color: rgba(24, 144, 255, 0.1);\n pointer-events: none;\n z-index: 9999;\n box-shadow: 0 0 8px rgba(24, 144, 255, 0.3);\n left: -100px;\n}\n";
2112
2113
  styleInject(css_248z$2);
2113
2114
 
2114
2115
  var css_248z$3 = ".timeline-editor-action {\n position: absolute;\n left: 0;\n top: 0;\n background-color: #c6cbd2;\n display: flex;\n align-items: center;\n}\n.timeline-editor-action .timeline-editor-action-left-stretch,\n.timeline-editor-action .timeline-editor-action-right-stretch {\n position: absolute;\n}\n.timeline-editor-action .timeline-editor-action-left-stretch {\n left: -3px;\n}\n.timeline-editor-action .timeline-editor-action-right-stretch {\n right: -3px;\n transform: rotate(180deg);\n}\n";
@@ -2151,7 +2152,9 @@ var EditAction = function EditAction(_ref) {
2151
2152
  _ref$allowCreateTrack = _ref.allowCreateTrack,
2152
2153
  allowCreateTrack = _ref$allowCreateTrack === void 0 ? true : _ref$allowCreateTrack,
2153
2154
  setDropPreview = _ref.setDropPreview,
2154
- containerRef = _ref.containerRef;
2155
+ containerRef = _ref.containerRef,
2156
+ selectedActionIds = _ref.selectedActionIds;
2157
+ console.log('action: selectedActionIds = ', selectedActionIds);
2155
2158
  var rowRnd = React.useRef();
2156
2159
  var isDragWhenClick = React.useRef(false);
2157
2160
  var originalPosition = React.useRef({
@@ -2320,7 +2323,9 @@ var EditAction = function EditAction(_ref) {
2320
2323
  var left = _ref3.left,
2321
2324
  width = _ref3.width,
2322
2325
  top = _ref3.top,
2323
- height = _ref3.height;
2326
+ height = _ref3.height,
2327
+ isMultiDrag = _ref3.isMultiDrag,
2328
+ fnCallback = _ref3.fn;
2324
2329
  console.log('handleDragEnd: ', left, width, top, height);
2325
2330
  // 清理预览指示器
2326
2331
  if (setDropPreview) {
@@ -2636,6 +2641,7 @@ var EditAction = function EditAction(_ref) {
2636
2641
  if (targetRowItem.id !== row.id) {
2637
2642
  up = top > 0 ? 1 : -1;
2638
2643
  }
2644
+ fnCallback === null || fnCallback === void 0 ? void 0 : fnCallback(actionItem);
2639
2645
  // 执行回调
2640
2646
  if (onActionMoveEnd) onActionMoveEnd({
2641
2647
  action: actionItem,
@@ -2647,9 +2653,10 @@ var EditAction = function EditAction(_ref) {
2647
2653
  width: width,
2648
2654
  top: top,
2649
2655
  height: height,
2650
- up: up
2656
+ up: up,
2657
+ isMultiDrag: (selectedActionIds === null || selectedActionIds === void 0 ? void 0 : selectedActionIds.length) > 1 || isMultiDrag
2651
2658
  });
2652
- }, [action, allowCreateTrack, editorData, id, onActionMoveEnd, parserTimeToTransform, parserTransformToTime, row, scale, scaleWidth, setDropPreview, setEditorData, startLeft]);
2659
+ }, [action, allowCreateTrack, editorData, id, onActionMoveEnd, parserTimeToTransform, parserTransformToTime, row, scale, scaleWidth, setDropPreview, setEditorData, startLeft, selectedActionIds]);
2653
2660
  // 防抖版本的 handleDragEnd
2654
2661
  var _useDebounceFn = ahooks.useDebounceFn(handleDragEndBase, {
2655
2662
  wait: 300
@@ -2755,14 +2762,16 @@ var EditAction = function EditAction(_ref) {
2755
2762
  width = _ref6.width,
2756
2763
  top = _ref6.top,
2757
2764
  height = _ref6.height,
2758
- id = _ref6.id;
2759
- console.log('handleActionMoveEnd: ', left, width, top, height, id);
2765
+ id = _ref6.id,
2766
+ fn = _ref6.fn;
2767
+ console.log('handleActionMoveEnd: ', left, width, top, height, id, fn);
2760
2768
  if (id === action.id) {
2761
2769
  handleDragEnd({
2762
2770
  left: left,
2763
2771
  width: width,
2764
2772
  top: top,
2765
- height: height
2773
+ height: height,
2774
+ fn: fn
2766
2775
  });
2767
2776
  }
2768
2777
  };
@@ -2805,6 +2814,7 @@ var EditAction = function EditAction(_ref) {
2805
2814
  deltaScrollTop: handleDeltaScrollTop
2806
2815
  }, /*#__PURE__*/React__default['default'].createElement("div", {
2807
2816
  "data-action-id": action.id,
2817
+ "data-action-disabled": action.is_disabled ? 1 : 0,
2808
2818
  onMouseDown: function onMouseDown() {
2809
2819
  isDragWhenClick.current = false;
2810
2820
  },
@@ -2826,6 +2836,19 @@ var EditAction = function EditAction(_ref) {
2826
2836
  time: time
2827
2837
  });
2828
2838
  }
2839
+ // 处理 Ctrl+ 点击选择
2840
+ if (e.ctrlKey || e.metaKey) {
2841
+ e.preventDefault();
2842
+ e.stopPropagation();
2843
+ var event = new CustomEvent('ctrl-click-action', {
2844
+ detail: {
2845
+ actionId: action.id,
2846
+ row: row,
2847
+ originalEvent: e.nativeEvent
2848
+ }
2849
+ });
2850
+ window.dispatchEvent(event);
2851
+ }
2829
2852
  },
2830
2853
  onDoubleClick: function onDoubleClick(e) {
2831
2854
  if (onDoubleClickAction) {
@@ -3079,6 +3102,7 @@ var useRowSelection = function useRowSelection(options) {
3079
3102
  // 检查框选区域是否与 action 相交
3080
3103
  row.actions.forEach(function (action) {
3081
3104
  var _containerRef$current3;
3105
+ if (action.is_disabled) return;
3082
3106
  var actionEl = (_containerRef$current3 = containerRef.current) === null || _containerRef$current3 === void 0 ? void 0 : _containerRef$current3.querySelector(".timeline-editor-action[data-action-id=\"".concat(action.id, "\"]"));
3083
3107
  if (actionEl) {
3084
3108
  var actionRect = actionEl.getBoundingClientRect();
@@ -3134,7 +3158,7 @@ var useRowSelection = function useRowSelection(options) {
3134
3158
  if (disabled) return false;
3135
3159
  // 不在 action 元素上启动框选
3136
3160
  var element = target;
3137
- if (((_element$closest = element.closest) === null || _element$closest === void 0 ? void 0 : _element$closest.call(element, '.timeline-editor-action')) || ((_element$closest2 = element.closest) === null || _element$closest2 === void 0 ? void 0 : _element$closest2.call(element, '.timeline-editor-edit-action')) || ((_element$closest3 = element.closest) === null || _element$closest3 === void 0 ? void 0 : _element$closest3.call(element, '[data-draggable="true"]')) || ((_element$closest4 = element.closest) === null || _element$closest4 === void 0 ? void 0 : _element$closest4.call(element, '.timeline-editor-edit-row.dragging'))) {
3161
+ if (((_element$closest = element.closest) === null || _element$closest === void 0 ? void 0 : _element$closest.call(element, '.timeline-editor-action[data-action-disabled="0"]')) || ((_element$closest2 = element.closest) === null || _element$closest2 === void 0 ? void 0 : _element$closest2.call(element, '.timeline-editor-edit-action')) || ((_element$closest3 = element.closest) === null || _element$closest3 === void 0 ? void 0 : _element$closest3.call(element, '[data-draggable="true"]')) || ((_element$closest4 = element.closest) === null || _element$closest4 === void 0 ? void 0 : _element$closest4.call(element, '.timeline-editor-edit-row.dragging'))) {
3138
3162
  return false;
3139
3163
  }
3140
3164
  return true;
@@ -3156,38 +3180,48 @@ var useRowSelection = function useRowSelection(options) {
3156
3180
  setSelectedActionIds(new Set());
3157
3181
  _onSelectionChange([]);
3158
3182
  }, [_onSelectionChange]);
3183
+ // 处理 Ctrl+ 点击选择
3184
+ var handleCtrlClick = React.useCallback(function (actionId, event) {
3185
+ if (disabled) return;
3186
+ var newSelectedActionIds = new Set(selectedActionIds);
3187
+ if (newSelectedActionIds.has(actionId)) {
3188
+ // 如果已选中,则取消选中
3189
+ newSelectedActionIds.delete(actionId);
3190
+ } else {
3191
+ // 如果未选中,则添加选中
3192
+ newSelectedActionIds.add(actionId);
3193
+ }
3194
+ setSelectedActionIds(newSelectedActionIds);
3195
+ _onSelectionChange(Array.from(newSelectedActionIds));
3196
+ }, [disabled, selectedActionIds, _onSelectionChange]);
3159
3197
  // 点击空白区域取消选择
3160
- React.useEffect(function () {
3198
+ var handleClickOutside = React.useCallback(function (target) {
3161
3199
  if (disabled) return;
3162
- var handleClickOutside = function handleClickOutside(e) {
3163
- var target = e.target;
3164
- // 如果点击的不是选中的 action 或框选框,清除选择
3165
- if (!target.closest('.timeline-editor-selection-box') && !target.closest('.timeline-editor-action') && !target.closest('[data-draggable="true"]')) {
3166
- clearSelection();
3167
- }
3168
- };
3169
- document.addEventListener('mousedown', handleClickOutside);
3170
- return function () {
3171
- document.removeEventListener('mousedown', handleClickOutside);
3172
- };
3200
+ // 如果点击的不是选中的 action 或框选框,清除选择
3201
+ if (!target.closest('.timeline-editor-selection-box') && !target.closest('.timeline-editor-action') && !target.closest('[data-draggable="true"]') && !target.closest('.voice-studio-right-config-panel') && !target.closest('.voice-studio-main-content-panel')) {
3202
+ clearSelection();
3203
+ }
3173
3204
  }, [disabled, clearSelection]);
3174
3205
  // 监听 Escape 键取消选择
3175
- React.useEffect(function () {
3206
+ var handleKeyDown = React.useCallback(function (e) {
3176
3207
  if (disabled) return;
3177
- var handleKeyDown = function handleKeyDown(e) {
3178
- if (e.key === 'Escape' && selectedActionIds.size > 0) {
3179
- clearSelection();
3180
- }
3181
- };
3208
+ if (e.key === 'Escape' && selectedActionIds.size > 0) {
3209
+ clearSelection();
3210
+ }
3211
+ }, [disabled, selectedActionIds.size, clearSelection]);
3212
+ React.useEffect(function () {
3182
3213
  document.addEventListener('keydown', handleKeyDown);
3183
3214
  return function () {
3184
3215
  document.removeEventListener('keydown', handleKeyDown);
3185
3216
  };
3186
- }, [disabled, selectedActionIds.size, clearSelection]);
3217
+ }, [handleKeyDown]);
3187
3218
  return {
3188
3219
  DragSelection: DragSelection,
3189
3220
  selectedActionIds: Array.from(selectedActionIds),
3190
- clearSelection: clearSelection
3221
+ clearSelection: clearSelection,
3222
+ onClickOutside: handleClickOutside,
3223
+ onCtrlClick: handleCtrlClick,
3224
+ setSelectedActionIds: setSelectedActionIds
3191
3225
  };
3192
3226
  };
3193
3227
 
@@ -3201,7 +3235,8 @@ var useRowDrag = function useRowDrag(options) {
3201
3235
  scaleWidth = _options$scaleWidth === void 0 ? 160 : _options$scaleWidth,
3202
3236
  _options$startLeft = options.startLeft,
3203
3237
  startLeft = _options$startLeft === void 0 ? 20 : _options$startLeft,
3204
- setEditorData = options.setEditorData;
3238
+ setEditorData = options.setEditorData,
3239
+ onUpdateEditorData = options.onUpdateEditorData;
3205
3240
  // 多选拖拽状态
3206
3241
  var multiDragState = React__default['default'].useRef({
3207
3242
  isMultiDrag: false,
@@ -3509,8 +3544,9 @@ var useRowDrag = function useRowDrag(options) {
3509
3544
  }).start;
3510
3545
  var deltaTime = currentStart - start;
3511
3546
  console.log('Multi-drag ended, deltaTime:', deltaTime);
3547
+ var updatedData = [];
3512
3548
  // 更新所有选中的 actions 的最终位置
3513
- var updatedData = editorData.map(function (r) {
3549
+ editorData.map(function (r) {
3514
3550
  return _objectSpread2(_objectSpread2({}, r), {}, {
3515
3551
  actions: r.actions.map(function (a) {
3516
3552
  if (selectedActionIds.includes(a.id) && primaryActionId !== a.id) {
@@ -3541,7 +3577,13 @@ var useRowDrag = function useRowDrag(options) {
3541
3577
  width: _width,
3542
3578
  top: top,
3543
3579
  height: height,
3544
- id: a.id
3580
+ id: a.id,
3581
+ fn: function fn(item) {
3582
+ updatedData.push(item);
3583
+ if (updatedData.length === selectedActionIds.length) {
3584
+ onUpdateEditorData === null || onUpdateEditorData === void 0 ? void 0 : onUpdateEditorData(r, updatedData);
3585
+ }
3586
+ }
3545
3587
  }
3546
3588
  }));
3547
3589
  }, 0);
@@ -3550,6 +3592,9 @@ var useRowDrag = function useRowDrag(options) {
3550
3592
  end: newEnd
3551
3593
  });
3552
3594
  }
3595
+ if (a.id === primaryActionId) {
3596
+ updatedData.push(a);
3597
+ }
3553
3598
  return a;
3554
3599
  })
3555
3600
  });
@@ -3620,7 +3665,7 @@ var getAudioDuration = function getAudioDuration(url) {
3620
3665
  });
3621
3666
  });
3622
3667
  };
3623
- var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props, ref) {
3668
+ var EditAreaO = /*#__PURE__*/React__default['default'].forwardRef(function (props, ref) {
3624
3669
  var className = props.className,
3625
3670
  _props$isMulti = props.isMulti,
3626
3671
  isMulti = _props$isMulti === void 0 ? false : _props$isMulti,
@@ -3651,7 +3696,8 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
3651
3696
  setEditorData = props.setEditorData,
3652
3697
  _props$allowCreateTra = props.allowCreateTrack,
3653
3698
  allowCreateTrack = _props$allowCreateTra === void 0 ? true : _props$allowCreateTra,
3654
- containerRef = props.containerRef;
3699
+ containerRef = props.containerRef,
3700
+ engineRef = props.engineRef;
3655
3701
  // 支持mp3\wav格式上传
3656
3702
  var onBeforeUpload = function onBeforeUpload(file) {
3657
3703
  if (file.type !== 'audio/mp3' && file.type !== 'audio/wav') {
@@ -3686,7 +3732,8 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
3686
3732
  flexible: true,
3687
3733
  url: info.file.response.url,
3688
3734
  start: currentMouseTime,
3689
- end: currentMouseTime + duration
3735
+ end: currentMouseTime + duration,
3736
+ isUpload: true
3690
3737
  };
3691
3738
  onUpdateEditorData === null || onUpdateEditorData === void 0 ? void 0 : onUpdateEditorData(row, [newAction]);
3692
3739
  case 3:
@@ -3723,30 +3770,34 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
3723
3770
  dragIndicator = _useState6[0],
3724
3771
  setDragIndicator = _useState6[1];
3725
3772
  // 框选功能
3773
+ var handleSelectionChange = React.useCallback(function (selectedActionIds) {
3774
+ // 更新 editorData 中每个 action 的选中状态
3775
+ var updatedData = editorData.map(function (row) {
3776
+ return _objectSpread2(_objectSpread2({}, row), {}, {
3777
+ actions: row.actions.map(function (action) {
3778
+ return _objectSpread2(_objectSpread2({}, action), {}, {
3779
+ selected: selectedActionIds.includes(action.id)
3780
+ });
3781
+ })
3782
+ });
3783
+ });
3784
+ setEditorData(updatedData);
3785
+ onMutiSelectChange === null || onMutiSelectChange === void 0 ? void 0 : onMutiSelectChange(selectedActionIds);
3786
+ }, [editorData, setEditorData, onMutiSelectChange]);
3726
3787
  var _useRowSelection = useRowSelection({
3727
3788
  editorData: editorData,
3728
3789
  rowHeight: _rowHeight,
3729
3790
  scrollTop: scrollTop,
3730
3791
  scrollLeft: scrollLeft,
3731
- onSelectionChange: function onSelectionChange(selectedActionIds) {
3732
- // 更新 editorData 中每个 action 的选中状态
3733
- var updatedData = editorData.map(function (row) {
3734
- return _objectSpread2(_objectSpread2({}, row), {}, {
3735
- actions: row.actions.map(function (action) {
3736
- return _objectSpread2(_objectSpread2({}, action), {}, {
3737
- selected: selectedActionIds.includes(action.id)
3738
- });
3739
- })
3740
- });
3741
- });
3742
- setEditorData(updatedData);
3743
- onMutiSelectChange === null || onMutiSelectChange === void 0 ? void 0 : onMutiSelectChange(selectedActionIds);
3744
- },
3792
+ onSelectionChange: handleSelectionChange,
3745
3793
  disabled: false,
3746
3794
  containerRef: editAreaRef
3747
3795
  }),
3748
3796
  DragSelection = _useRowSelection.DragSelection,
3749
- selectedActionIds = _useRowSelection.selectedActionIds;
3797
+ selectedActionIds = _useRowSelection.selectedActionIds,
3798
+ onClickOutside = _useRowSelection.onClickOutside,
3799
+ onCtrlClick = _useRowSelection.onCtrlClick,
3800
+ setSelectedActionIds = _useRowSelection.setSelectedActionIds;
3750
3801
  var _useRowDrag = useRowDrag({
3751
3802
  selectedActionIds: selectedActionIds,
3752
3803
  editorData: editorData,
@@ -3756,7 +3807,8 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
3756
3807
  startLeft: startLeft,
3757
3808
  setEditorData: setEditorData,
3758
3809
  allowCreateTrack: allowCreateTrack,
3759
- rowHeight: _rowHeight
3810
+ rowHeight: _rowHeight,
3811
+ onUpdateEditorData: onUpdateEditorData
3760
3812
  }),
3761
3813
  onDragStart = _useRowDrag.onDragStart,
3762
3814
  onDragMove = _useRowDrag.onDragMove,
@@ -3841,6 +3893,45 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
3841
3893
  });
3842
3894
  }
3843
3895
  };
3896
+ React.useEffect(function () {
3897
+ if (!(engineRef === null || engineRef === void 0 ? void 0 : engineRef.current)) return;
3898
+ engineRef.current.on('mousedown', function (data) {
3899
+ console.log('mousedown', data);
3900
+ onClickOutside(data.target);
3901
+ });
3902
+ return function () {
3903
+ var _engineRef$current;
3904
+ engineRef === null || engineRef === void 0 ? void 0 : (_engineRef$current = engineRef.current) === null || _engineRef$current === void 0 ? void 0 : _engineRef$current.off('mousedown');
3905
+ };
3906
+ }, [engineRef, onClickOutside]);
3907
+ // 监听 Ctrl+ 点击事件
3908
+ React.useEffect(function () {
3909
+ var handleCtrlClickAction = function handleCtrlClickAction(e) {
3910
+ var _e$detail = e.detail,
3911
+ actionId = _e$detail.actionId,
3912
+ row = _e$detail.row;
3913
+ console.log('ctrl-click-action', row, ', editorData = ', editorData);
3914
+ setSelectedActionIds(function (ids) {
3915
+ var newIds = new Set();
3916
+ ids.forEach(function (id) {
3917
+ editorData.forEach(function (item) {
3918
+ item.actions.forEach(function (action) {
3919
+ if (item.type === row.type && action.id === id) {
3920
+ newIds.add(id);
3921
+ }
3922
+ });
3923
+ });
3924
+ });
3925
+ newIds.add(actionId);
3926
+ handleSelectionChange(Array.from(newIds));
3927
+ return new Set(newIds);
3928
+ });
3929
+ };
3930
+ window.addEventListener('ctrl-click-action', handleCtrlClickAction);
3931
+ return function () {
3932
+ window.removeEventListener('ctrl-click-action', handleCtrlClickAction);
3933
+ };
3934
+ }, [onCtrlClick, editorData, handleSelectionChange]);
3844
3935
  /** 获取每个cell渲染内容 */
3845
3936
  var cellRenderer = function cellRenderer(_ref2) {
3846
3937
  var rowIndex = _ref2.rowIndex,
@@ -3910,10 +4001,14 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
3910
4001
  height: data.height || 0,
3911
4002
  up: data.up || 0
3912
4003
  });
3913
- return _onActionMoveEnd && _onActionMoveEnd(data);
4004
+ if (!data.isMultiDrag) {
4005
+ return _onActionMoveEnd && _onActionMoveEnd(data);
4006
+ }
4007
+ return;
3914
4008
  }
3915
4009
  }));
3916
4010
  if (!!row && (canUpload || (row === null || row === void 0 ? void 0 : row.canUpload))) {
4011
+ var _row$actions;
3917
4012
  return /*#__PURE__*/React__default['default'].createElement(es.Upload, {
3918
4013
  ref: uploadRef,
3919
4014
  key: key + 'upload',
@@ -3926,7 +4021,9 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
3926
4021
  beforeUpload: onBeforeUpload,
3927
4022
  onChange: handleUploadChange(row),
3928
4023
  showUploadList: false,
3929
- openFileDialogOnClick: false,
4024
+ openFileDialogOnClick: ((_row$actions = row.actions) === null || _row$actions === void 0 ? void 0 : _row$actions.filter(function (item) {
4025
+ return item.effectId === 'effect2';
4026
+ }).length) > 0,
3930
4027
  customRequest: customRequest,
3931
4028
  onDrop: handleDrop,
3932
4029
  type: "drag"
@@ -3967,7 +4064,7 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
3967
4064
  var totalHeight = 0;
3968
4065
  // 高度列表
3969
4066
  var heights = editorData.map(function (row) {
3970
- var itemHeight = row.rowHeight || _rowHeight;
4067
+ var itemHeight = (row.rowHeight || _rowHeight) + 2;
3971
4068
  totalHeight += itemHeight;
3972
4069
  return itemHeight;
3973
4070
  });
@@ -4051,6 +4148,7 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
4051
4148
  });
4052
4149
  }());
4053
4150
  });
4151
+ var EditArea = /*#__PURE__*/React__default['default'].memo(EditAreaO);
4054
4152
 
4055
4153
  var css_248z$5 = ".timeline-editor {\n height: 600px;\n width: 600px;\n min-height: 32px;\n position: relative;\n font-size: 12px;\n font-family: \"PingFang SC\";\n background-color: #191b1d;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.timeline-editor.light {\n background-color: #fff;\n}\n";
4056
4154
  styleInject(css_248z$5);
@@ -4180,6 +4278,7 @@ var Timeline = /*#__PURE__*/React__default['default'].forwardRef(function (props
4180
4278
  var areaRef = React.useRef();
4181
4279
  var scrollSync = React.useRef();
4182
4280
  var containerRef = React.useRef();
4281
+ console.log(' Timeline mounted = ', areaRef);
4183
4282
  // 编辑器数据
4184
4283
  var _useState = React.useState(data),
4185
4284
  _useState2 = _slicedToArray(_useState, 2),
@@ -4299,6 +4398,19 @@ var Timeline = /*#__PURE__*/React__default['default'].forwardRef(function (props
4299
4398
  engineRef.current.on('play', handlePlay);
4300
4399
  engineRef.current.on('paused', handlePaused);
4301
4400
  }, []);
4401
+ React.useEffect(function () {
4402
+ var handleClickOutside = function handleClickOutside(e) {
4403
+ var target = e.target;
4404
+ engineRef.current.trigger('mousedown', {
4405
+ target: target,
4406
+ evt: e
4407
+ });
4408
+ };
4409
+ document.addEventListener('mousedown', handleClickOutside);
4410
+ return function () {
4411
+ document.removeEventListener('mousedown', handleClickOutside);
4412
+ };
4413
+ }, []);
4302
4414
  // ref 数据
4303
4415
  React.useImperativeHandle(ref, function () {
4304
4416
  return {
@@ -4384,6 +4496,7 @@ var Timeline = /*#__PURE__*/React__default['default'].forwardRef(function (props
4384
4496
  setScaleCount: handleSetScaleCount,
4385
4497
  scrollTop: scrollTop,
4386
4498
  scrollLeft: scrollLeft,
4499
+ engineRef: engineRef,
4387
4500
  setEditorData: handleEditorDataChange,
4388
4501
  deltaScrollLeft: autoScroll && handleDeltaScrollLeft,
4389
4502
  allowCreateTrack: allowCreateTrack,
@@ -4394,10 +4507,7 @@ var Timeline = /*#__PURE__*/React__default['default'].forwardRef(function (props
4394
4507
  }
4395
4508
  }))) : null, areaCount > 1 ? /*#__PURE__*/React__default['default'].createElement("div", {
4396
4509
  id: 'time-editor-container',
4397
- ref: containerRef,
4398
- style: {
4399
- overflow: 'auto'
4400
- }
4510
+ ref: containerRef
4401
4511
  }, Object.keys(groupedData).map(function (key, index) {
4402
4512
  var handleGroupDataChange = function handleGroupDataChange(updatedData) {
4403
4513
  var mergedData = editorData.filter(function (item) {
@@ -4436,6 +4546,7 @@ var Timeline = /*#__PURE__*/React__default['default'].forwardRef(function (props
4436
4546
  allowCreateTrack: allowCreateTrack,
4437
4547
  containerRef: containerRef,
4438
4548
  onMutiSelectChange: props === null || props === void 0 ? void 0 : props.onMutiSelectChange,
4549
+ engineRef: engineRef,
4439
4550
  onScroll: function onScroll(params) {
4440
4551
  _onScroll(params);
4441
4552
  onScrollVertical && onScrollVertical(params);
@@ -26,6 +26,10 @@ export interface TimelineAction {
26
26
  maxEnd?: number;
27
27
  /** 动作的url */
28
28
  url?: string;
29
+ /** 动作是否被禁用 */
30
+ is_disabled?: boolean;
31
+ /** 动作是否为上传 */
32
+ isUpload?: boolean;
29
33
  }
30
34
  /**
31
35
  * 动作行基本参数
@@ -120,6 +120,7 @@ export interface EditData {
120
120
  top?: number;
121
121
  height?: number;
122
122
  up?: number;
123
+ isMultiDrag?: boolean;
123
124
  }) => void;
124
125
  /**
125
126
  * @description 开始改变大小回调
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sense-react-timeline-editor",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "author": "xzdarcy",
5
5
  "license": "MIT",
6
6
  "keywords": [