@waveform-playlist/browser 11.0.0 → 11.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +11 -20
- package/dist/index.d.ts +11 -20
- package/dist/index.js +449 -397
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +327 -275
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -122,7 +122,7 @@ __export(index_exports, {
|
|
|
122
122
|
effectDefinitions: () => effectDefinitions,
|
|
123
123
|
getEffectDefinition: () => getEffectDefinition,
|
|
124
124
|
getEffectsByCategory: () => getEffectsByCategory,
|
|
125
|
-
getShortcutLabel: () => getShortcutLabel,
|
|
125
|
+
getShortcutLabel: () => import_core3.getShortcutLabel,
|
|
126
126
|
getWaveformDataMetadata: () => getWaveformDataMetadata,
|
|
127
127
|
loadPeaksFromWaveformData: () => loadPeaksFromWaveformData,
|
|
128
128
|
loadWaveformData: () => loadWaveformData,
|
|
@@ -161,7 +161,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
161
161
|
var Tone2 = __toESM(require("tone"));
|
|
162
162
|
|
|
163
163
|
// src/WaveformPlaylistContext.tsx
|
|
164
|
-
var
|
|
164
|
+
var import_react24 = require("react");
|
|
165
165
|
var import_styled_components = require("styled-components");
|
|
166
166
|
var import_playout5 = require("@waveform-playlist/playout");
|
|
167
167
|
var import_engine3 = require("@waveform-playlist/engine");
|
|
@@ -542,12 +542,52 @@ function useSelectedTrack({ engineRef }) {
|
|
|
542
542
|
};
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
-
// src/hooks/
|
|
545
|
+
// src/hooks/useUndoState.ts
|
|
546
546
|
var import_react7 = require("react");
|
|
547
|
+
function useUndoState({ engineRef }) {
|
|
548
|
+
const [canUndo, setCanUndo] = (0, import_react7.useState)(false);
|
|
549
|
+
const [canRedo, setCanRedo] = (0, import_react7.useState)(false);
|
|
550
|
+
const canUndoRef = (0, import_react7.useRef)(false);
|
|
551
|
+
const canRedoRef = (0, import_react7.useRef)(false);
|
|
552
|
+
const undo = (0, import_react7.useCallback)(() => {
|
|
553
|
+
if (!engineRef.current) {
|
|
554
|
+
console.warn("[waveform-playlist] undo: engine not ready, call ignored");
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
engineRef.current.undo();
|
|
558
|
+
}, [engineRef]);
|
|
559
|
+
const redo = (0, import_react7.useCallback)(() => {
|
|
560
|
+
if (!engineRef.current) {
|
|
561
|
+
console.warn("[waveform-playlist] redo: engine not ready, call ignored");
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
engineRef.current.redo();
|
|
565
|
+
}, [engineRef]);
|
|
566
|
+
const onEngineState = (0, import_react7.useCallback)((state) => {
|
|
567
|
+
if (state.canUndo !== canUndoRef.current) {
|
|
568
|
+
canUndoRef.current = state.canUndo;
|
|
569
|
+
setCanUndo(state.canUndo);
|
|
570
|
+
}
|
|
571
|
+
if (state.canRedo !== canRedoRef.current) {
|
|
572
|
+
canRedoRef.current = state.canRedo;
|
|
573
|
+
setCanRedo(state.canRedo);
|
|
574
|
+
}
|
|
575
|
+
}, []);
|
|
576
|
+
return {
|
|
577
|
+
canUndo,
|
|
578
|
+
canRedo,
|
|
579
|
+
undo,
|
|
580
|
+
redo,
|
|
581
|
+
onEngineState
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// src/hooks/useAudioEffects.ts
|
|
586
|
+
var import_react8 = require("react");
|
|
547
587
|
var import_tone = require("tone");
|
|
548
588
|
var useMasterAnalyser = (fftSize = 256) => {
|
|
549
|
-
const analyserRef = (0,
|
|
550
|
-
const masterEffects = (0,
|
|
589
|
+
const analyserRef = (0, import_react8.useRef)(null);
|
|
590
|
+
const masterEffects = (0, import_react8.useCallback)(
|
|
551
591
|
(masterGainNode, destination, _isOffline) => {
|
|
552
592
|
const analyserNode = new import_tone.Analyser("fft", fftSize);
|
|
553
593
|
masterGainNode.connect(analyserNode);
|
|
@@ -564,7 +604,7 @@ var useMasterAnalyser = (fftSize = 256) => {
|
|
|
564
604
|
};
|
|
565
605
|
|
|
566
606
|
// src/hooks/useAudioTracks.ts
|
|
567
|
-
var
|
|
607
|
+
var import_react9 = require("react");
|
|
568
608
|
var import_core = require("@waveform-playlist/core");
|
|
569
609
|
var Tone = __toESM(require("tone"));
|
|
570
610
|
function buildTrackFromConfig(config, index, audioBuffer, stableIds, contextSampleRate = 48e3) {
|
|
@@ -622,14 +662,14 @@ function buildTrackFromConfig(config, index, audioBuffer, stableIds, contextSamp
|
|
|
622
662
|
function useAudioTracks(configs, options = {}) {
|
|
623
663
|
const { immediate = false, progressive = false } = options;
|
|
624
664
|
const isImmediate = immediate || progressive;
|
|
625
|
-
const [loading, setLoading] = (0,
|
|
626
|
-
const [error, setError] = (0,
|
|
627
|
-
const [loadedCount, setLoadedCount] = (0,
|
|
665
|
+
const [loading, setLoading] = (0, import_react9.useState)(true);
|
|
666
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
667
|
+
const [loadedCount, setLoadedCount] = (0, import_react9.useState)(0);
|
|
628
668
|
const totalCount = configs.length;
|
|
629
|
-
const [loadedBuffers, setLoadedBuffers] = (0,
|
|
630
|
-
const stableIdsRef = (0,
|
|
631
|
-
const contextSampleRateRef = (0,
|
|
632
|
-
const derivedTracks = (0,
|
|
669
|
+
const [loadedBuffers, setLoadedBuffers] = (0, import_react9.useState)(/* @__PURE__ */ new Map());
|
|
670
|
+
const stableIdsRef = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
671
|
+
const contextSampleRateRef = (0, import_react9.useRef)(48e3);
|
|
672
|
+
const derivedTracks = (0, import_react9.useMemo)(() => {
|
|
633
673
|
if (!isImmediate) return null;
|
|
634
674
|
const result = [];
|
|
635
675
|
for (let i = 0; i < configs.length; i++) {
|
|
@@ -644,13 +684,13 @@ function useAudioTracks(configs, options = {}) {
|
|
|
644
684
|
}
|
|
645
685
|
return result;
|
|
646
686
|
}, [isImmediate, configs, loadedBuffers]);
|
|
647
|
-
const [tracks, setTracks] = (0,
|
|
648
|
-
const prevDerivedRef = (0,
|
|
687
|
+
const [tracks, setTracks] = (0, import_react9.useState)(derivedTracks != null ? derivedTracks : []);
|
|
688
|
+
const prevDerivedRef = (0, import_react9.useRef)(derivedTracks);
|
|
649
689
|
if (derivedTracks !== prevDerivedRef.current) {
|
|
650
690
|
prevDerivedRef.current = derivedTracks;
|
|
651
691
|
if (derivedTracks) setTracks(derivedTracks);
|
|
652
692
|
}
|
|
653
|
-
(0,
|
|
693
|
+
(0, import_react9.useEffect)(() => {
|
|
654
694
|
if (configs.length === 0) {
|
|
655
695
|
setTracks([]);
|
|
656
696
|
setLoading(false);
|
|
@@ -758,7 +798,7 @@ function useAudioTracks(configs, options = {}) {
|
|
|
758
798
|
}
|
|
759
799
|
|
|
760
800
|
// src/hooks/useClipDragHandlers.ts
|
|
761
|
-
var
|
|
801
|
+
var import_react10 = __toESM(require("react"));
|
|
762
802
|
|
|
763
803
|
// src/utils/boundaryTrim.ts
|
|
764
804
|
var import_engine = require("@waveform-playlist/engine");
|
|
@@ -812,17 +852,24 @@ function useClipDragHandlers({
|
|
|
812
852
|
snapSamplePosition
|
|
813
853
|
}) {
|
|
814
854
|
const { sampleRate } = usePlaylistData();
|
|
815
|
-
const snapSamplePositionRef =
|
|
855
|
+
const snapSamplePositionRef = import_react10.default.useRef(snapSamplePosition);
|
|
816
856
|
snapSamplePositionRef.current = snapSamplePosition;
|
|
817
|
-
const originalClipStateRef =
|
|
818
|
-
const lastBoundaryDeltaRef =
|
|
819
|
-
const onDragStart =
|
|
857
|
+
const originalClipStateRef = import_react10.default.useRef(null);
|
|
858
|
+
const lastBoundaryDeltaRef = import_react10.default.useRef(0);
|
|
859
|
+
const onDragStart = import_react10.default.useCallback(
|
|
820
860
|
(event) => {
|
|
821
861
|
var _a;
|
|
822
862
|
const data = (_a = event.operation.source) == null ? void 0 : _a.data;
|
|
823
863
|
if (!data) return;
|
|
824
864
|
if (!data.boundary) {
|
|
825
865
|
originalClipStateRef.current = null;
|
|
866
|
+
if (engineRef.current) {
|
|
867
|
+
engineRef.current.beginTransaction();
|
|
868
|
+
} else {
|
|
869
|
+
console.warn(
|
|
870
|
+
"[waveform-playlist] onDragStart: engine not ready, move will not be grouped for undo"
|
|
871
|
+
);
|
|
872
|
+
}
|
|
826
873
|
return;
|
|
827
874
|
}
|
|
828
875
|
const track = tracks[data.trackIndex];
|
|
@@ -834,11 +881,18 @@ function useClipDragHandlers({
|
|
|
834
881
|
startSample: clip.startSample
|
|
835
882
|
};
|
|
836
883
|
isDraggingRef.current = true;
|
|
884
|
+
if (engineRef.current) {
|
|
885
|
+
engineRef.current.beginTransaction();
|
|
886
|
+
} else {
|
|
887
|
+
console.warn(
|
|
888
|
+
"[waveform-playlist] onDragStart: engine not ready, trim will not be grouped for undo"
|
|
889
|
+
);
|
|
890
|
+
}
|
|
837
891
|
}
|
|
838
892
|
},
|
|
839
|
-
[tracks, isDraggingRef]
|
|
893
|
+
[tracks, isDraggingRef, engineRef]
|
|
840
894
|
);
|
|
841
|
-
const onDragMove =
|
|
895
|
+
const onDragMove = import_react10.default.useCallback(
|
|
842
896
|
(event) => {
|
|
843
897
|
var _a, _b, _c;
|
|
844
898
|
const data = (_a = event.operation.source) == null ? void 0 : _a.data;
|
|
@@ -900,9 +954,9 @@ function useClipDragHandlers({
|
|
|
900
954
|
},
|
|
901
955
|
[tracks, onTracksChange, samplesPerPixel, sampleRate]
|
|
902
956
|
);
|
|
903
|
-
const onDragEnd =
|
|
957
|
+
const onDragEnd = import_react10.default.useCallback(
|
|
904
958
|
(event) => {
|
|
905
|
-
var _a, _b, _c;
|
|
959
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
906
960
|
if (event.canceled) {
|
|
907
961
|
if (originalClipStateRef.current) {
|
|
908
962
|
const cancelData = (_a = event.operation.source) == null ? void 0 : _a.data;
|
|
@@ -927,23 +981,30 @@ function useClipDragHandlers({
|
|
|
927
981
|
isDraggingRef.current = false;
|
|
928
982
|
originalClipStateRef.current = null;
|
|
929
983
|
lastBoundaryDeltaRef.current = 0;
|
|
984
|
+
(_b = engineRef.current) == null ? void 0 : _b.abortTransaction();
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
const data = (_c = event.operation.source) == null ? void 0 : _c.data;
|
|
988
|
+
if (!data) {
|
|
989
|
+
isDraggingRef.current = false;
|
|
990
|
+
(_d = engineRef.current) == null ? void 0 : _d.abortTransaction();
|
|
930
991
|
return;
|
|
931
992
|
}
|
|
932
|
-
const data = (_b = event.operation.source) == null ? void 0 : _b.data;
|
|
933
|
-
if (!data) return;
|
|
934
993
|
const { trackIndex, clipId, boundary } = data;
|
|
935
994
|
const sampleDelta = boundary ? lastBoundaryDeltaRef.current : event.operation.transform.x * samplesPerPixel;
|
|
936
|
-
const trackId = (
|
|
995
|
+
const trackId = (_e = tracks[trackIndex]) == null ? void 0 : _e.id;
|
|
937
996
|
if (boundary) {
|
|
938
997
|
isDraggingRef.current = false;
|
|
939
998
|
if (!trackId) {
|
|
940
999
|
console.warn(
|
|
941
1000
|
`[waveform-playlist] onDragEnd: track at index ${trackIndex} not found \u2014 trim not synced to adapter`
|
|
942
1001
|
);
|
|
1002
|
+
(_f = engineRef.current) == null ? void 0 : _f.abortTransaction();
|
|
943
1003
|
} else if (!engineRef.current) {
|
|
944
1004
|
console.warn("[waveform-playlist] engineRef is null \u2014 trim not synced to adapter");
|
|
945
1005
|
} else {
|
|
946
1006
|
engineRef.current.trimClip(trackId, clipId, boundary, Math.floor(sampleDelta));
|
|
1007
|
+
engineRef.current.commitTransaction();
|
|
947
1008
|
}
|
|
948
1009
|
originalClipStateRef.current = null;
|
|
949
1010
|
lastBoundaryDeltaRef.current = 0;
|
|
@@ -953,10 +1014,12 @@ function useClipDragHandlers({
|
|
|
953
1014
|
console.warn(
|
|
954
1015
|
`[waveform-playlist] onDragEnd: track at index ${trackIndex} not found \u2014 move not synced to adapter`
|
|
955
1016
|
);
|
|
1017
|
+
(_g = engineRef.current) == null ? void 0 : _g.abortTransaction();
|
|
956
1018
|
} else if (!engineRef.current) {
|
|
957
1019
|
console.warn("[waveform-playlist] engineRef is null \u2014 move not synced to adapter");
|
|
958
1020
|
} else {
|
|
959
1021
|
engineRef.current.moveClip(trackId, clipId, Math.floor(sampleDelta));
|
|
1022
|
+
engineRef.current.commitTransaction();
|
|
960
1023
|
}
|
|
961
1024
|
},
|
|
962
1025
|
[tracks, onTracksChange, samplesPerPixel, engineRef, isDraggingRef]
|
|
@@ -969,7 +1032,7 @@ function useClipDragHandlers({
|
|
|
969
1032
|
}
|
|
970
1033
|
|
|
971
1034
|
// src/hooks/useAnnotationDragHandlers.ts
|
|
972
|
-
var
|
|
1035
|
+
var import_react11 = __toESM(require("react"));
|
|
973
1036
|
var import_playout = require("@waveform-playlist/playout");
|
|
974
1037
|
var LINK_THRESHOLD = 0.01;
|
|
975
1038
|
function useAnnotationDragHandlers({
|
|
@@ -980,8 +1043,8 @@ function useAnnotationDragHandlers({
|
|
|
980
1043
|
duration,
|
|
981
1044
|
linkEndpoints
|
|
982
1045
|
}) {
|
|
983
|
-
const originalAnnotationStateRef =
|
|
984
|
-
const onDragStart =
|
|
1046
|
+
const originalAnnotationStateRef = import_react11.default.useRef(null);
|
|
1047
|
+
const onDragStart = import_react11.default.useCallback(
|
|
985
1048
|
(event) => {
|
|
986
1049
|
var _a;
|
|
987
1050
|
const data = (_a = event.operation.source) == null ? void 0 : _a.data;
|
|
@@ -1000,7 +1063,7 @@ function useAnnotationDragHandlers({
|
|
|
1000
1063
|
},
|
|
1001
1064
|
[annotations]
|
|
1002
1065
|
);
|
|
1003
|
-
const onDragMove =
|
|
1066
|
+
const onDragMove = import_react11.default.useCallback(
|
|
1004
1067
|
(event) => {
|
|
1005
1068
|
var _a, _b, _c;
|
|
1006
1069
|
if (!originalAnnotationStateRef.current) {
|
|
@@ -1026,7 +1089,7 @@ function useAnnotationDragHandlers({
|
|
|
1026
1089
|
},
|
|
1027
1090
|
[annotations, onAnnotationsChange, samplesPerPixel, sampleRate, duration, linkEndpoints]
|
|
1028
1091
|
);
|
|
1029
|
-
const onDragEnd =
|
|
1092
|
+
const onDragEnd = import_react11.default.useCallback(
|
|
1030
1093
|
(event) => {
|
|
1031
1094
|
if (event.canceled && originalAnnotationStateRef.current) {
|
|
1032
1095
|
const { annotationIndex, start, end } = originalAnnotationStateRef.current;
|
|
@@ -1134,7 +1197,7 @@ function updateAnnotationBoundaries({
|
|
|
1134
1197
|
}
|
|
1135
1198
|
|
|
1136
1199
|
// src/hooks/useDragSensors.ts
|
|
1137
|
-
var
|
|
1200
|
+
var import_react12 = require("react");
|
|
1138
1201
|
var import_dom = require("@dnd-kit/dom");
|
|
1139
1202
|
function useDragSensors(options = {}) {
|
|
1140
1203
|
const {
|
|
@@ -1143,7 +1206,7 @@ function useDragSensors(options = {}) {
|
|
|
1143
1206
|
touchTolerance = 5,
|
|
1144
1207
|
mouseDistance = 1
|
|
1145
1208
|
} = options;
|
|
1146
|
-
return (0,
|
|
1209
|
+
return (0, import_react12.useMemo)(() => {
|
|
1147
1210
|
if (touchOptimized) {
|
|
1148
1211
|
return [
|
|
1149
1212
|
import_dom.PointerSensor.configure({
|
|
@@ -1172,14 +1235,14 @@ function useDragSensors(options = {}) {
|
|
|
1172
1235
|
}
|
|
1173
1236
|
|
|
1174
1237
|
// src/hooks/useClipSplitting.ts
|
|
1175
|
-
var
|
|
1238
|
+
var import_react13 = require("react");
|
|
1176
1239
|
var import_engine2 = require("@waveform-playlist/engine");
|
|
1177
1240
|
var useClipSplitting = (options) => {
|
|
1178
1241
|
const { tracks, engineRef } = options;
|
|
1179
1242
|
const { sampleRate } = usePlaylistData();
|
|
1180
1243
|
const { currentTimeRef } = usePlaybackAnimation();
|
|
1181
1244
|
const { selectedTrackId } = usePlaylistState();
|
|
1182
|
-
const splitClipAt = (0,
|
|
1245
|
+
const splitClipAt = (0, import_react13.useCallback)(
|
|
1183
1246
|
(trackIndex, clipIndex, splitTime) => {
|
|
1184
1247
|
const { samplesPerPixel } = options;
|
|
1185
1248
|
const track = tracks[trackIndex];
|
|
@@ -1203,7 +1266,7 @@ var useClipSplitting = (options) => {
|
|
|
1203
1266
|
},
|
|
1204
1267
|
[tracks, options, engineRef, sampleRate]
|
|
1205
1268
|
);
|
|
1206
|
-
const splitClipAtPlayhead = (0,
|
|
1269
|
+
const splitClipAtPlayhead = (0, import_react13.useCallback)(() => {
|
|
1207
1270
|
var _a;
|
|
1208
1271
|
if (!selectedTrackId) {
|
|
1209
1272
|
console.warn("[waveform-playlist] No track selected \u2014 click a clip to select a track first");
|
|
@@ -1234,36 +1297,16 @@ var useClipSplitting = (options) => {
|
|
|
1234
1297
|
};
|
|
1235
1298
|
|
|
1236
1299
|
// src/hooks/useKeyboardShortcuts.ts
|
|
1237
|
-
var
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
if (event.repeat) return;
|
|
1241
|
-
const target = event.target;
|
|
1242
|
-
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) {
|
|
1243
|
-
return;
|
|
1244
|
-
}
|
|
1245
|
-
const matchingShortcut = shortcuts.find((shortcut) => {
|
|
1246
|
-
const keyMatch = event.key.toLowerCase() === shortcut.key.toLowerCase() || event.key === shortcut.key;
|
|
1247
|
-
const ctrlMatch = shortcut.ctrlKey === void 0 || event.ctrlKey === shortcut.ctrlKey;
|
|
1248
|
-
const shiftMatch = shortcut.shiftKey === void 0 || event.shiftKey === shortcut.shiftKey;
|
|
1249
|
-
const metaMatch = shortcut.metaKey === void 0 || event.metaKey === shortcut.metaKey;
|
|
1250
|
-
const altMatch = shortcut.altKey === void 0 || event.altKey === shortcut.altKey;
|
|
1251
|
-
return keyMatch && ctrlMatch && shiftMatch && metaMatch && altMatch;
|
|
1252
|
-
});
|
|
1253
|
-
if (matchingShortcut) {
|
|
1254
|
-
if (matchingShortcut.preventDefault !== false) {
|
|
1255
|
-
event.preventDefault();
|
|
1256
|
-
}
|
|
1257
|
-
matchingShortcut.action();
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1300
|
+
var import_react14 = require("react");
|
|
1301
|
+
var import_core2 = require("@waveform-playlist/core");
|
|
1302
|
+
var import_core3 = require("@waveform-playlist/core");
|
|
1260
1303
|
var useKeyboardShortcuts = (options) => {
|
|
1261
1304
|
const { shortcuts, enabled = true } = options;
|
|
1262
|
-
const handleKeyDown = (0,
|
|
1263
|
-
(event) => handleKeyboardEvent(event, shortcuts, enabled),
|
|
1305
|
+
const handleKeyDown = (0, import_react14.useCallback)(
|
|
1306
|
+
(event) => (0, import_core2.handleKeyboardEvent)(event, shortcuts, enabled),
|
|
1264
1307
|
[shortcuts, enabled]
|
|
1265
1308
|
);
|
|
1266
|
-
(0,
|
|
1309
|
+
(0, import_react14.useEffect)(() => {
|
|
1267
1310
|
if (!enabled) return;
|
|
1268
1311
|
window.addEventListener("keydown", handleKeyDown);
|
|
1269
1312
|
return () => {
|
|
@@ -1271,42 +1314,24 @@ var useKeyboardShortcuts = (options) => {
|
|
|
1271
1314
|
};
|
|
1272
1315
|
}, [handleKeyDown, enabled]);
|
|
1273
1316
|
};
|
|
1274
|
-
var getShortcutLabel = (shortcut) => {
|
|
1275
|
-
const parts = [];
|
|
1276
|
-
const isMac = typeof navigator !== "undefined" && navigator.platform.includes("Mac");
|
|
1277
|
-
if (shortcut.metaKey) {
|
|
1278
|
-
parts.push(isMac ? "Cmd" : "Ctrl");
|
|
1279
|
-
}
|
|
1280
|
-
if (shortcut.ctrlKey && !shortcut.metaKey) {
|
|
1281
|
-
parts.push("Ctrl");
|
|
1282
|
-
}
|
|
1283
|
-
if (shortcut.altKey) {
|
|
1284
|
-
parts.push(isMac ? "Option" : "Alt");
|
|
1285
|
-
}
|
|
1286
|
-
if (shortcut.shiftKey) {
|
|
1287
|
-
parts.push("Shift");
|
|
1288
|
-
}
|
|
1289
|
-
parts.push(shortcut.key.toUpperCase());
|
|
1290
|
-
return parts.join("+");
|
|
1291
|
-
};
|
|
1292
1317
|
|
|
1293
1318
|
// src/hooks/usePlaybackShortcuts.ts
|
|
1294
|
-
var
|
|
1319
|
+
var import_react15 = require("react");
|
|
1295
1320
|
var usePlaybackShortcuts = (options = {}) => {
|
|
1296
1321
|
const { enabled = true, additionalShortcuts = [], shortcuts: overrideShortcuts } = options;
|
|
1297
1322
|
const { isPlaying } = usePlaybackAnimation();
|
|
1298
1323
|
const { setCurrentTime, play, pause, stop } = usePlaylistControls();
|
|
1299
|
-
const togglePlayPause = (0,
|
|
1324
|
+
const togglePlayPause = (0, import_react15.useCallback)(() => {
|
|
1300
1325
|
if (isPlaying) {
|
|
1301
1326
|
pause();
|
|
1302
1327
|
} else {
|
|
1303
1328
|
play();
|
|
1304
1329
|
}
|
|
1305
1330
|
}, [isPlaying, play, pause]);
|
|
1306
|
-
const stopPlayback = (0,
|
|
1331
|
+
const stopPlayback = (0, import_react15.useCallback)(() => {
|
|
1307
1332
|
stop();
|
|
1308
1333
|
}, [stop]);
|
|
1309
|
-
const rewindToStart = (0,
|
|
1334
|
+
const rewindToStart = (0, import_react15.useCallback)(() => {
|
|
1310
1335
|
setCurrentTime(0);
|
|
1311
1336
|
if (isPlaying) {
|
|
1312
1337
|
play(0);
|
|
@@ -1346,7 +1371,7 @@ var usePlaybackShortcuts = (options = {}) => {
|
|
|
1346
1371
|
};
|
|
1347
1372
|
|
|
1348
1373
|
// src/hooks/useAnnotationKeyboardControls.ts
|
|
1349
|
-
var
|
|
1374
|
+
var import_react16 = require("react");
|
|
1350
1375
|
var LINK_THRESHOLD2 = 0.01;
|
|
1351
1376
|
var TIME_DELTA = 0.01;
|
|
1352
1377
|
function useAnnotationKeyboardControls({
|
|
@@ -1362,11 +1387,11 @@ function useAnnotationKeyboardControls({
|
|
|
1362
1387
|
onPlay
|
|
1363
1388
|
}) {
|
|
1364
1389
|
const { samplesPerPixel, sampleRate } = usePlaylistData();
|
|
1365
|
-
const activeIndex = (0,
|
|
1390
|
+
const activeIndex = (0, import_react16.useMemo)(() => {
|
|
1366
1391
|
if (!activeAnnotationId) return -1;
|
|
1367
1392
|
return annotations.findIndex((a) => a.id === activeAnnotationId);
|
|
1368
1393
|
}, [annotations, activeAnnotationId]);
|
|
1369
|
-
const scrollToAnnotation = (0,
|
|
1394
|
+
const scrollToAnnotation = (0, import_react16.useCallback)(
|
|
1370
1395
|
(annotationId) => {
|
|
1371
1396
|
if (!(scrollContainerRef == null ? void 0 : scrollContainerRef.current) || !samplesPerPixel || !sampleRate) return;
|
|
1372
1397
|
const annotation = annotations.find((a) => a.id === annotationId);
|
|
@@ -1389,12 +1414,12 @@ function useAnnotationKeyboardControls({
|
|
|
1389
1414
|
},
|
|
1390
1415
|
[annotations, scrollContainerRef, samplesPerPixel, sampleRate]
|
|
1391
1416
|
);
|
|
1392
|
-
(0,
|
|
1417
|
+
(0, import_react16.useEffect)(() => {
|
|
1393
1418
|
if (activeAnnotationId && (scrollContainerRef == null ? void 0 : scrollContainerRef.current) && samplesPerPixel && sampleRate) {
|
|
1394
1419
|
scrollToAnnotation(activeAnnotationId);
|
|
1395
1420
|
}
|
|
1396
1421
|
}, [activeAnnotationId, scrollToAnnotation, scrollContainerRef, samplesPerPixel, sampleRate]);
|
|
1397
|
-
const moveStartBoundary = (0,
|
|
1422
|
+
const moveStartBoundary = (0, import_react16.useCallback)(
|
|
1398
1423
|
(delta) => {
|
|
1399
1424
|
if (activeIndex < 0) return;
|
|
1400
1425
|
const annotation = annotations[activeIndex];
|
|
@@ -1423,7 +1448,7 @@ function useAnnotationKeyboardControls({
|
|
|
1423
1448
|
},
|
|
1424
1449
|
[annotations, activeIndex, linkEndpoints, onAnnotationsChange]
|
|
1425
1450
|
);
|
|
1426
|
-
const moveEndBoundary = (0,
|
|
1451
|
+
const moveEndBoundary = (0, import_react16.useCallback)(
|
|
1427
1452
|
(delta) => {
|
|
1428
1453
|
if (activeIndex < 0) return;
|
|
1429
1454
|
const annotation = annotations[activeIndex];
|
|
@@ -1483,7 +1508,7 @@ function useAnnotationKeyboardControls({
|
|
|
1483
1508
|
},
|
|
1484
1509
|
[annotations, activeIndex, duration, linkEndpoints, onAnnotationsChange]
|
|
1485
1510
|
);
|
|
1486
|
-
const selectPrevious = (0,
|
|
1511
|
+
const selectPrevious = (0, import_react16.useCallback)(() => {
|
|
1487
1512
|
if (!onActiveAnnotationChange || annotations.length === 0) return;
|
|
1488
1513
|
if (activeIndex <= 0) {
|
|
1489
1514
|
onActiveAnnotationChange(annotations[annotations.length - 1].id);
|
|
@@ -1491,7 +1516,7 @@ function useAnnotationKeyboardControls({
|
|
|
1491
1516
|
onActiveAnnotationChange(annotations[activeIndex - 1].id);
|
|
1492
1517
|
}
|
|
1493
1518
|
}, [annotations, activeIndex, onActiveAnnotationChange]);
|
|
1494
|
-
const selectNext = (0,
|
|
1519
|
+
const selectNext = (0, import_react16.useCallback)(() => {
|
|
1495
1520
|
if (!onActiveAnnotationChange || annotations.length === 0) return;
|
|
1496
1521
|
if (activeIndex < 0 || activeIndex >= annotations.length - 1) {
|
|
1497
1522
|
onActiveAnnotationChange(annotations[0].id);
|
|
@@ -1499,25 +1524,25 @@ function useAnnotationKeyboardControls({
|
|
|
1499
1524
|
onActiveAnnotationChange(annotations[activeIndex + 1].id);
|
|
1500
1525
|
}
|
|
1501
1526
|
}, [annotations, activeIndex, onActiveAnnotationChange]);
|
|
1502
|
-
const selectFirst = (0,
|
|
1527
|
+
const selectFirst = (0, import_react16.useCallback)(() => {
|
|
1503
1528
|
if (!onActiveAnnotationChange || annotations.length === 0) return;
|
|
1504
1529
|
onActiveAnnotationChange(annotations[0].id);
|
|
1505
1530
|
}, [annotations, onActiveAnnotationChange]);
|
|
1506
|
-
const selectLast = (0,
|
|
1531
|
+
const selectLast = (0, import_react16.useCallback)(() => {
|
|
1507
1532
|
if (!onActiveAnnotationChange || annotations.length === 0) return;
|
|
1508
1533
|
onActiveAnnotationChange(annotations[annotations.length - 1].id);
|
|
1509
1534
|
}, [annotations, onActiveAnnotationChange]);
|
|
1510
|
-
const clearSelection = (0,
|
|
1535
|
+
const clearSelection = (0, import_react16.useCallback)(() => {
|
|
1511
1536
|
if (!onActiveAnnotationChange) return;
|
|
1512
1537
|
onActiveAnnotationChange(null);
|
|
1513
1538
|
}, [onActiveAnnotationChange]);
|
|
1514
|
-
const playActiveAnnotation = (0,
|
|
1539
|
+
const playActiveAnnotation = (0, import_react16.useCallback)(() => {
|
|
1515
1540
|
if (activeIndex < 0 || !onPlay) return;
|
|
1516
1541
|
const annotation = annotations[activeIndex];
|
|
1517
1542
|
const playDuration = !continuousPlay ? annotation.end - annotation.start : void 0;
|
|
1518
1543
|
onPlay(annotation.start, playDuration);
|
|
1519
1544
|
}, [annotations, activeIndex, continuousPlay, onPlay]);
|
|
1520
|
-
const activeAnnotationShortcuts = (0,
|
|
1545
|
+
const activeAnnotationShortcuts = (0, import_react16.useMemo)(
|
|
1521
1546
|
() => [
|
|
1522
1547
|
{
|
|
1523
1548
|
key: "[",
|
|
@@ -1554,7 +1579,7 @@ function useAnnotationKeyboardControls({
|
|
|
1554
1579
|
],
|
|
1555
1580
|
[moveStartBoundary, moveEndBoundary, playActiveAnnotation]
|
|
1556
1581
|
);
|
|
1557
|
-
const navigationShortcuts = (0,
|
|
1582
|
+
const navigationShortcuts = (0, import_react16.useMemo)(
|
|
1558
1583
|
() => [
|
|
1559
1584
|
{
|
|
1560
1585
|
key: "ArrowUp",
|
|
@@ -1623,7 +1648,7 @@ function useAnnotationKeyboardControls({
|
|
|
1623
1648
|
}
|
|
1624
1649
|
|
|
1625
1650
|
// src/hooks/useDynamicEffects.ts
|
|
1626
|
-
var
|
|
1651
|
+
var import_react17 = require("react");
|
|
1627
1652
|
|
|
1628
1653
|
// src/effects/effectDefinitions.ts
|
|
1629
1654
|
var effectDefinitions = [
|
|
@@ -2298,13 +2323,13 @@ function createEffectChain(effects) {
|
|
|
2298
2323
|
// src/hooks/useDynamicEffects.ts
|
|
2299
2324
|
var import_tone3 = require("tone");
|
|
2300
2325
|
function useDynamicEffects(fftSize = 256) {
|
|
2301
|
-
const [activeEffects, setActiveEffects] = (0,
|
|
2302
|
-
const activeEffectsRef = (0,
|
|
2326
|
+
const [activeEffects, setActiveEffects] = (0, import_react17.useState)([]);
|
|
2327
|
+
const activeEffectsRef = (0, import_react17.useRef)(activeEffects);
|
|
2303
2328
|
activeEffectsRef.current = activeEffects;
|
|
2304
|
-
const effectInstancesRef = (0,
|
|
2305
|
-
const analyserRef = (0,
|
|
2306
|
-
const graphNodesRef = (0,
|
|
2307
|
-
const rebuildChain = (0,
|
|
2329
|
+
const effectInstancesRef = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
|
|
2330
|
+
const analyserRef = (0, import_react17.useRef)(null);
|
|
2331
|
+
const graphNodesRef = (0, import_react17.useRef)(null);
|
|
2332
|
+
const rebuildChain = (0, import_react17.useCallback)((effects) => {
|
|
2308
2333
|
const nodes = graphNodesRef.current;
|
|
2309
2334
|
if (!nodes) return;
|
|
2310
2335
|
const { masterGainNode, destination, analyserNode } = nodes;
|
|
@@ -2332,7 +2357,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2332
2357
|
analyserNode.connect(destination);
|
|
2333
2358
|
}
|
|
2334
2359
|
}, []);
|
|
2335
|
-
const addEffect = (0,
|
|
2360
|
+
const addEffect = (0, import_react17.useCallback)((effectId) => {
|
|
2336
2361
|
const definition = getEffectDefinition(effectId);
|
|
2337
2362
|
if (!definition) {
|
|
2338
2363
|
console.error(`Unknown effect: ${effectId}`);
|
|
@@ -2353,7 +2378,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2353
2378
|
};
|
|
2354
2379
|
setActiveEffects((prev) => [...prev, newActiveEffect]);
|
|
2355
2380
|
}, []);
|
|
2356
|
-
const removeEffect = (0,
|
|
2381
|
+
const removeEffect = (0, import_react17.useCallback)((instanceId) => {
|
|
2357
2382
|
const instance = effectInstancesRef.current.get(instanceId);
|
|
2358
2383
|
if (instance) {
|
|
2359
2384
|
instance.dispose();
|
|
@@ -2361,7 +2386,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2361
2386
|
}
|
|
2362
2387
|
setActiveEffects((prev) => prev.filter((e) => e.instanceId !== instanceId));
|
|
2363
2388
|
}, []);
|
|
2364
|
-
const updateParameter = (0,
|
|
2389
|
+
const updateParameter = (0, import_react17.useCallback)(
|
|
2365
2390
|
(instanceId, paramName, value) => {
|
|
2366
2391
|
const instance = effectInstancesRef.current.get(instanceId);
|
|
2367
2392
|
if (instance) {
|
|
@@ -2375,7 +2400,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2375
2400
|
},
|
|
2376
2401
|
[]
|
|
2377
2402
|
);
|
|
2378
|
-
const toggleBypass = (0,
|
|
2403
|
+
const toggleBypass = (0, import_react17.useCallback)((instanceId) => {
|
|
2379
2404
|
var _a;
|
|
2380
2405
|
const effect = activeEffectsRef.current.find((e) => e.instanceId === instanceId);
|
|
2381
2406
|
if (!effect) return;
|
|
@@ -2389,7 +2414,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2389
2414
|
(prev) => prev.map((e) => e.instanceId === instanceId ? __spreadProps(__spreadValues({}, e), { bypassed: newBypassed }) : e)
|
|
2390
2415
|
);
|
|
2391
2416
|
}, []);
|
|
2392
|
-
const reorderEffects = (0,
|
|
2417
|
+
const reorderEffects = (0, import_react17.useCallback)((fromIndex, toIndex) => {
|
|
2393
2418
|
setActiveEffects((prev) => {
|
|
2394
2419
|
const newEffects = [...prev];
|
|
2395
2420
|
const [removed] = newEffects.splice(fromIndex, 1);
|
|
@@ -2397,15 +2422,15 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2397
2422
|
return newEffects;
|
|
2398
2423
|
});
|
|
2399
2424
|
}, []);
|
|
2400
|
-
const clearAllEffects = (0,
|
|
2425
|
+
const clearAllEffects = (0, import_react17.useCallback)(() => {
|
|
2401
2426
|
effectInstancesRef.current.forEach((inst) => inst.dispose());
|
|
2402
2427
|
effectInstancesRef.current.clear();
|
|
2403
2428
|
setActiveEffects([]);
|
|
2404
2429
|
}, []);
|
|
2405
|
-
(0,
|
|
2430
|
+
(0, import_react17.useEffect)(() => {
|
|
2406
2431
|
rebuildChain(activeEffects);
|
|
2407
2432
|
}, [activeEffects, rebuildChain]);
|
|
2408
|
-
const masterEffects = (0,
|
|
2433
|
+
const masterEffects = (0, import_react17.useCallback)(
|
|
2409
2434
|
(masterGainNode, destination, _isOffline) => {
|
|
2410
2435
|
const analyserNode = new import_tone3.Analyser("fft", fftSize);
|
|
2411
2436
|
analyserRef.current = analyserNode;
|
|
@@ -2437,14 +2462,14 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2437
2462
|
[fftSize]
|
|
2438
2463
|
// Only fftSize - reads effects from ref
|
|
2439
2464
|
);
|
|
2440
|
-
(0,
|
|
2465
|
+
(0, import_react17.useEffect)(() => {
|
|
2441
2466
|
const effectInstances = effectInstancesRef.current;
|
|
2442
2467
|
return () => {
|
|
2443
2468
|
effectInstances.forEach((inst) => inst.dispose());
|
|
2444
2469
|
effectInstances.clear();
|
|
2445
2470
|
};
|
|
2446
2471
|
}, []);
|
|
2447
|
-
const createOfflineEffectsFunction = (0,
|
|
2472
|
+
const createOfflineEffectsFunction = (0, import_react17.useCallback)(() => {
|
|
2448
2473
|
const nonBypassedEffects = activeEffects.filter((e) => !e.bypassed);
|
|
2449
2474
|
if (nonBypassedEffects.length === 0) {
|
|
2450
2475
|
return void 0;
|
|
@@ -2486,14 +2511,14 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2486
2511
|
}
|
|
2487
2512
|
|
|
2488
2513
|
// src/hooks/useTrackDynamicEffects.ts
|
|
2489
|
-
var
|
|
2514
|
+
var import_react18 = require("react");
|
|
2490
2515
|
function useTrackDynamicEffects() {
|
|
2491
|
-
const [trackEffectsState, setTrackEffectsState] = (0,
|
|
2516
|
+
const [trackEffectsState, setTrackEffectsState] = (0, import_react18.useState)(
|
|
2492
2517
|
/* @__PURE__ */ new Map()
|
|
2493
2518
|
);
|
|
2494
|
-
const trackEffectInstancesRef = (0,
|
|
2495
|
-
const trackGraphNodesRef = (0,
|
|
2496
|
-
const rebuildTrackChain = (0,
|
|
2519
|
+
const trackEffectInstancesRef = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
2520
|
+
const trackGraphNodesRef = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
2521
|
+
const rebuildTrackChain = (0, import_react18.useCallback)((trackId, trackEffects) => {
|
|
2497
2522
|
const nodes = trackGraphNodesRef.current.get(trackId);
|
|
2498
2523
|
if (!nodes) return;
|
|
2499
2524
|
const { graphEnd, masterGainNode } = nodes;
|
|
@@ -2523,7 +2548,7 @@ function useTrackDynamicEffects() {
|
|
|
2523
2548
|
currentNode.connect(masterGainNode);
|
|
2524
2549
|
}
|
|
2525
2550
|
}, []);
|
|
2526
|
-
const addEffectToTrack = (0,
|
|
2551
|
+
const addEffectToTrack = (0, import_react18.useCallback)((trackId, effectId) => {
|
|
2527
2552
|
const definition = getEffectDefinition(effectId);
|
|
2528
2553
|
if (!definition) {
|
|
2529
2554
|
console.error(`Unknown effect: ${effectId}`);
|
|
@@ -2552,7 +2577,7 @@ function useTrackDynamicEffects() {
|
|
|
2552
2577
|
return newState;
|
|
2553
2578
|
});
|
|
2554
2579
|
}, []);
|
|
2555
|
-
const removeEffectFromTrack = (0,
|
|
2580
|
+
const removeEffectFromTrack = (0, import_react18.useCallback)((trackId, instanceId) => {
|
|
2556
2581
|
const instancesMap = trackEffectInstancesRef.current.get(trackId);
|
|
2557
2582
|
const instance = instancesMap == null ? void 0 : instancesMap.get(instanceId);
|
|
2558
2583
|
if (instance) {
|
|
@@ -2569,7 +2594,7 @@ function useTrackDynamicEffects() {
|
|
|
2569
2594
|
return newState;
|
|
2570
2595
|
});
|
|
2571
2596
|
}, []);
|
|
2572
|
-
const updateTrackEffectParameter = (0,
|
|
2597
|
+
const updateTrackEffectParameter = (0, import_react18.useCallback)(
|
|
2573
2598
|
(trackId, instanceId, paramName, value) => {
|
|
2574
2599
|
const instancesMap = trackEffectInstancesRef.current.get(trackId);
|
|
2575
2600
|
const instance = instancesMap == null ? void 0 : instancesMap.get(instanceId);
|
|
@@ -2590,7 +2615,7 @@ function useTrackDynamicEffects() {
|
|
|
2590
2615
|
},
|
|
2591
2616
|
[]
|
|
2592
2617
|
);
|
|
2593
|
-
const toggleBypass = (0,
|
|
2618
|
+
const toggleBypass = (0, import_react18.useCallback)((trackId, instanceId) => {
|
|
2594
2619
|
var _a;
|
|
2595
2620
|
const trackEffects = trackEffectsStateRef.current.get(trackId) || [];
|
|
2596
2621
|
const effect = trackEffects.find((e) => e.instanceId === instanceId);
|
|
@@ -2612,7 +2637,7 @@ function useTrackDynamicEffects() {
|
|
|
2612
2637
|
return newState;
|
|
2613
2638
|
});
|
|
2614
2639
|
}, []);
|
|
2615
|
-
const clearTrackEffects = (0,
|
|
2640
|
+
const clearTrackEffects = (0, import_react18.useCallback)((trackId) => {
|
|
2616
2641
|
const instancesMap = trackEffectInstancesRef.current.get(trackId);
|
|
2617
2642
|
if (instancesMap) {
|
|
2618
2643
|
instancesMap.forEach((inst) => inst.dispose());
|
|
@@ -2624,9 +2649,9 @@ function useTrackDynamicEffects() {
|
|
|
2624
2649
|
return newState;
|
|
2625
2650
|
});
|
|
2626
2651
|
}, []);
|
|
2627
|
-
const trackEffectsStateRef = (0,
|
|
2652
|
+
const trackEffectsStateRef = (0, import_react18.useRef)(trackEffectsState);
|
|
2628
2653
|
trackEffectsStateRef.current = trackEffectsState;
|
|
2629
|
-
const getTrackEffectsFunction = (0,
|
|
2654
|
+
const getTrackEffectsFunction = (0, import_react18.useCallback)(
|
|
2630
2655
|
(trackId) => {
|
|
2631
2656
|
return (graphEnd, masterGainNode, _isOffline) => {
|
|
2632
2657
|
trackGraphNodesRef.current.set(trackId, {
|
|
@@ -2654,12 +2679,12 @@ function useTrackDynamicEffects() {
|
|
|
2654
2679
|
[]
|
|
2655
2680
|
// No dependencies - stable function that reads from refs
|
|
2656
2681
|
);
|
|
2657
|
-
(0,
|
|
2682
|
+
(0, import_react18.useEffect)(() => {
|
|
2658
2683
|
trackEffectsState.forEach((effects, trackId) => {
|
|
2659
2684
|
rebuildTrackChain(trackId, effects);
|
|
2660
2685
|
});
|
|
2661
2686
|
}, [trackEffectsState, rebuildTrackChain]);
|
|
2662
|
-
(0,
|
|
2687
|
+
(0, import_react18.useEffect)(() => {
|
|
2663
2688
|
const trackEffectInstances = trackEffectInstancesRef.current;
|
|
2664
2689
|
return () => {
|
|
2665
2690
|
trackEffectInstances.forEach((instancesMap) => {
|
|
@@ -2669,7 +2694,7 @@ function useTrackDynamicEffects() {
|
|
|
2669
2694
|
trackEffectInstances.clear();
|
|
2670
2695
|
};
|
|
2671
2696
|
}, []);
|
|
2672
|
-
const createOfflineTrackEffectsFunction = (0,
|
|
2697
|
+
const createOfflineTrackEffectsFunction = (0, import_react18.useCallback)(
|
|
2673
2698
|
(trackId) => {
|
|
2674
2699
|
const trackEffects = trackEffectsState.get(trackId) || [];
|
|
2675
2700
|
const nonBypassedEffects = trackEffects.filter((e) => !e.bypassed);
|
|
@@ -2713,7 +2738,7 @@ function useTrackDynamicEffects() {
|
|
|
2713
2738
|
}
|
|
2714
2739
|
|
|
2715
2740
|
// src/hooks/useExportWav.ts
|
|
2716
|
-
var
|
|
2741
|
+
var import_react19 = require("react");
|
|
2717
2742
|
var import_playout2 = require("@waveform-playlist/playout");
|
|
2718
2743
|
|
|
2719
2744
|
// src/utils/wavEncoder.ts
|
|
@@ -2787,10 +2812,10 @@ function downloadBlob(blob, filename) {
|
|
|
2787
2812
|
|
|
2788
2813
|
// src/hooks/useExportWav.ts
|
|
2789
2814
|
function useExportWav() {
|
|
2790
|
-
const [isExporting, setIsExporting] = (0,
|
|
2791
|
-
const [progress, setProgress] = (0,
|
|
2792
|
-
const [error, setError] = (0,
|
|
2793
|
-
const exportWav = (0,
|
|
2815
|
+
const [isExporting, setIsExporting] = (0, import_react19.useState)(false);
|
|
2816
|
+
const [progress, setProgress] = (0, import_react19.useState)(0);
|
|
2817
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
2818
|
+
const exportWav = (0, import_react19.useCallback)(
|
|
2794
2819
|
(_0, _1, ..._2) => __async(null, [_0, _1, ..._2], function* (tracks, trackStates, options = {}) {
|
|
2795
2820
|
const {
|
|
2796
2821
|
filename = "export",
|
|
@@ -3102,23 +3127,23 @@ function generateFadeCurve(startValue, endValue, numPoints, curveType) {
|
|
|
3102
3127
|
}
|
|
3103
3128
|
|
|
3104
3129
|
// src/hooks/useAnimationFrameLoop.ts
|
|
3105
|
-
var
|
|
3130
|
+
var import_react20 = require("react");
|
|
3106
3131
|
var useAnimationFrameLoop = () => {
|
|
3107
|
-
const animationFrameRef = (0,
|
|
3108
|
-
const stopAnimationFrameLoop = (0,
|
|
3132
|
+
const animationFrameRef = (0, import_react20.useRef)(null);
|
|
3133
|
+
const stopAnimationFrameLoop = (0, import_react20.useCallback)(() => {
|
|
3109
3134
|
if (animationFrameRef.current !== null) {
|
|
3110
3135
|
cancelAnimationFrame(animationFrameRef.current);
|
|
3111
3136
|
animationFrameRef.current = null;
|
|
3112
3137
|
}
|
|
3113
3138
|
}, []);
|
|
3114
|
-
const startAnimationFrameLoop = (0,
|
|
3139
|
+
const startAnimationFrameLoop = (0, import_react20.useCallback)(
|
|
3115
3140
|
(callback) => {
|
|
3116
3141
|
stopAnimationFrameLoop();
|
|
3117
3142
|
animationFrameRef.current = requestAnimationFrame(callback);
|
|
3118
3143
|
},
|
|
3119
3144
|
[stopAnimationFrameLoop]
|
|
3120
3145
|
);
|
|
3121
|
-
(0,
|
|
3146
|
+
(0, import_react20.useEffect)(() => {
|
|
3122
3147
|
return () => {
|
|
3123
3148
|
stopAnimationFrameLoop();
|
|
3124
3149
|
};
|
|
@@ -3131,7 +3156,7 @@ var useAnimationFrameLoop = () => {
|
|
|
3131
3156
|
};
|
|
3132
3157
|
|
|
3133
3158
|
// src/hooks/useWaveformDataCache.ts
|
|
3134
|
-
var
|
|
3159
|
+
var import_react21 = require("react");
|
|
3135
3160
|
|
|
3136
3161
|
// src/workers/peaksWorker.ts
|
|
3137
3162
|
var import_waveform_data2 = __toESM(require("waveform-data"));
|
|
@@ -3363,20 +3388,20 @@ function createPeaksWorker() {
|
|
|
3363
3388
|
|
|
3364
3389
|
// src/hooks/useWaveformDataCache.ts
|
|
3365
3390
|
function useWaveformDataCache(tracks, baseScale) {
|
|
3366
|
-
const [cache, setCache] = (0,
|
|
3367
|
-
const [isGenerating, setIsGenerating] = (0,
|
|
3368
|
-
const workerRef = (0,
|
|
3369
|
-
const generatedByBufferRef = (0,
|
|
3370
|
-
const inflightByBufferRef = (0,
|
|
3371
|
-
const subscribersByBufferRef = (0,
|
|
3372
|
-
const pendingCountRef = (0,
|
|
3373
|
-
const getWorker = (0,
|
|
3391
|
+
const [cache, setCache] = (0, import_react21.useState)(() => /* @__PURE__ */ new Map());
|
|
3392
|
+
const [isGenerating, setIsGenerating] = (0, import_react21.useState)(false);
|
|
3393
|
+
const workerRef = (0, import_react21.useRef)(null);
|
|
3394
|
+
const generatedByBufferRef = (0, import_react21.useRef)(/* @__PURE__ */ new WeakMap());
|
|
3395
|
+
const inflightByBufferRef = (0, import_react21.useRef)(/* @__PURE__ */ new WeakMap());
|
|
3396
|
+
const subscribersByBufferRef = (0, import_react21.useRef)(/* @__PURE__ */ new WeakMap());
|
|
3397
|
+
const pendingCountRef = (0, import_react21.useRef)(0);
|
|
3398
|
+
const getWorker = (0, import_react21.useCallback)(() => {
|
|
3374
3399
|
if (!workerRef.current) {
|
|
3375
3400
|
workerRef.current = createPeaksWorker();
|
|
3376
3401
|
}
|
|
3377
3402
|
return workerRef.current;
|
|
3378
3403
|
}, []);
|
|
3379
|
-
(0,
|
|
3404
|
+
(0, import_react21.useEffect)(() => {
|
|
3380
3405
|
let cancelled = false;
|
|
3381
3406
|
const generatedByBuffer = generatedByBufferRef.current;
|
|
3382
3407
|
const inflightByBuffer = inflightByBufferRef.current;
|
|
@@ -3481,7 +3506,7 @@ function useWaveformDataCache(tracks, baseScale) {
|
|
|
3481
3506
|
setIsGenerating(false);
|
|
3482
3507
|
};
|
|
3483
3508
|
}, [tracks, baseScale, getWorker]);
|
|
3484
|
-
(0,
|
|
3509
|
+
(0, import_react21.useEffect)(() => {
|
|
3485
3510
|
return () => {
|
|
3486
3511
|
var _a;
|
|
3487
3512
|
(_a = workerRef.current) == null ? void 0 : _a.terminate();
|
|
@@ -3492,8 +3517,8 @@ function useWaveformDataCache(tracks, baseScale) {
|
|
|
3492
3517
|
}
|
|
3493
3518
|
|
|
3494
3519
|
// src/hooks/useDynamicTracks.ts
|
|
3495
|
-
var
|
|
3496
|
-
var
|
|
3520
|
+
var import_react22 = require("react");
|
|
3521
|
+
var import_core4 = require("@waveform-playlist/core");
|
|
3497
3522
|
var import_playout3 = require("@waveform-playlist/playout");
|
|
3498
3523
|
function getSourceName(source) {
|
|
3499
3524
|
var _a, _b, _c, _d, _e;
|
|
@@ -3527,13 +3552,13 @@ function decodeSource(source, audioContext, signal) {
|
|
|
3527
3552
|
});
|
|
3528
3553
|
}
|
|
3529
3554
|
function useDynamicTracks() {
|
|
3530
|
-
const [tracks, setTracks] = (0,
|
|
3531
|
-
const [loadingCount, setLoadingCount] = (0,
|
|
3532
|
-
const [errors, setErrors] = (0,
|
|
3533
|
-
const cancelledRef = (0,
|
|
3534
|
-
const loadingIdsRef = (0,
|
|
3535
|
-
const abortControllersRef = (0,
|
|
3536
|
-
(0,
|
|
3555
|
+
const [tracks, setTracks] = (0, import_react22.useState)([]);
|
|
3556
|
+
const [loadingCount, setLoadingCount] = (0, import_react22.useState)(0);
|
|
3557
|
+
const [errors, setErrors] = (0, import_react22.useState)([]);
|
|
3558
|
+
const cancelledRef = (0, import_react22.useRef)(false);
|
|
3559
|
+
const loadingIdsRef = (0, import_react22.useRef)(/* @__PURE__ */ new Set());
|
|
3560
|
+
const abortControllersRef = (0, import_react22.useRef)(/* @__PURE__ */ new Map());
|
|
3561
|
+
(0, import_react22.useEffect)(() => {
|
|
3537
3562
|
const controllers = abortControllersRef.current;
|
|
3538
3563
|
return () => {
|
|
3539
3564
|
cancelledRef.current = true;
|
|
@@ -3543,11 +3568,11 @@ function useDynamicTracks() {
|
|
|
3543
3568
|
controllers.clear();
|
|
3544
3569
|
};
|
|
3545
3570
|
}, []);
|
|
3546
|
-
const addTracks = (0,
|
|
3571
|
+
const addTracks = (0, import_react22.useCallback)((sources) => {
|
|
3547
3572
|
if (sources.length === 0) return;
|
|
3548
3573
|
const audioContext = (0, import_playout3.getGlobalAudioContext)();
|
|
3549
3574
|
const placeholders = sources.map((source) => ({
|
|
3550
|
-
track: (0,
|
|
3575
|
+
track: (0, import_core4.createTrack)({ name: `${getSourceName(source)} (loading...)`, clips: [] }),
|
|
3551
3576
|
source
|
|
3552
3577
|
}));
|
|
3553
3578
|
setTracks((prev) => [...prev, ...placeholders.map((p) => p.track)]);
|
|
@@ -3559,7 +3584,7 @@ function useDynamicTracks() {
|
|
|
3559
3584
|
(() => __async(null, null, function* () {
|
|
3560
3585
|
try {
|
|
3561
3586
|
const { audioBuffer, name } = yield decodeSource(source, audioContext, controller.signal);
|
|
3562
|
-
const clip = (0,
|
|
3587
|
+
const clip = (0, import_core4.createClipFromSeconds)({
|
|
3563
3588
|
audioBuffer,
|
|
3564
3589
|
startTime: 0,
|
|
3565
3590
|
duration: audioBuffer.duration,
|
|
@@ -3593,7 +3618,7 @@ function useDynamicTracks() {
|
|
|
3593
3618
|
}))();
|
|
3594
3619
|
}
|
|
3595
3620
|
}, []);
|
|
3596
|
-
const removeTrack = (0,
|
|
3621
|
+
const removeTrack = (0, import_react22.useCallback)((trackId) => {
|
|
3597
3622
|
setTracks((prev) => prev.filter((t) => t.id !== trackId));
|
|
3598
3623
|
const controller = abortControllersRef.current.get(trackId);
|
|
3599
3624
|
if (controller) {
|
|
@@ -3615,24 +3640,24 @@ function useDynamicTracks() {
|
|
|
3615
3640
|
}
|
|
3616
3641
|
|
|
3617
3642
|
// src/hooks/useOutputMeter.ts
|
|
3618
|
-
var
|
|
3643
|
+
var import_react23 = require("react");
|
|
3619
3644
|
var import_playout4 = require("@waveform-playlist/playout");
|
|
3620
|
-
var
|
|
3645
|
+
var import_core5 = require("@waveform-playlist/core");
|
|
3621
3646
|
var import_worklets = require("@waveform-playlist/worklets");
|
|
3622
3647
|
var PEAK_DECAY = 0.98;
|
|
3623
3648
|
function useOutputMeter(options = {}) {
|
|
3624
3649
|
const { channelCount = 2, updateRate = 60, isPlaying = false } = options;
|
|
3625
|
-
const [levels, setLevels] = (0,
|
|
3626
|
-
const [peakLevels, setPeakLevels] = (0,
|
|
3627
|
-
const [rmsLevels, setRmsLevels] = (0,
|
|
3628
|
-
const workletNodeRef = (0,
|
|
3629
|
-
const smoothedPeakRef = (0,
|
|
3630
|
-
const [meterError, setMeterError] = (0,
|
|
3631
|
-
const resetPeak = (0,
|
|
3650
|
+
const [levels, setLevels] = (0, import_react23.useState)(() => new Array(channelCount).fill(0));
|
|
3651
|
+
const [peakLevels, setPeakLevels] = (0, import_react23.useState)(() => new Array(channelCount).fill(0));
|
|
3652
|
+
const [rmsLevels, setRmsLevels] = (0, import_react23.useState)(() => new Array(channelCount).fill(0));
|
|
3653
|
+
const workletNodeRef = (0, import_react23.useRef)(null);
|
|
3654
|
+
const smoothedPeakRef = (0, import_react23.useRef)(new Array(channelCount).fill(0));
|
|
3655
|
+
const [meterError, setMeterError] = (0, import_react23.useState)(null);
|
|
3656
|
+
const resetPeak = (0, import_react23.useCallback)(
|
|
3632
3657
|
() => setPeakLevels(new Array(channelCount).fill(0)),
|
|
3633
3658
|
[channelCount]
|
|
3634
3659
|
);
|
|
3635
|
-
(0,
|
|
3660
|
+
(0, import_react23.useEffect)(() => {
|
|
3636
3661
|
if (!isPlaying) {
|
|
3637
3662
|
const zeros = new Array(channelCount).fill(0);
|
|
3638
3663
|
smoothedPeakRef.current = new Array(channelCount).fill(0);
|
|
@@ -3641,7 +3666,7 @@ function useOutputMeter(options = {}) {
|
|
|
3641
3666
|
setPeakLevels(zeros);
|
|
3642
3667
|
}
|
|
3643
3668
|
}, [isPlaying, channelCount]);
|
|
3644
|
-
(0,
|
|
3669
|
+
(0, import_react23.useEffect)(() => {
|
|
3645
3670
|
let isMounted = true;
|
|
3646
3671
|
const setup = () => __async(null, null, function* () {
|
|
3647
3672
|
const context = (0, import_playout4.getGlobalContext)();
|
|
@@ -3672,8 +3697,8 @@ function useOutputMeter(options = {}) {
|
|
|
3672
3697
|
const rmsValues = [];
|
|
3673
3698
|
for (let ch = 0; ch < peak.length; ch++) {
|
|
3674
3699
|
smoothed[ch] = Math.max(peak[ch], ((_a = smoothed[ch]) != null ? _a : 0) * PEAK_DECAY);
|
|
3675
|
-
peakValues.push((0,
|
|
3676
|
-
rmsValues.push((0,
|
|
3700
|
+
peakValues.push((0, import_core5.gainToNormalized)(smoothed[ch]));
|
|
3701
|
+
rmsValues.push((0, import_core5.gainToNormalized)(rms[ch]));
|
|
3677
3702
|
}
|
|
3678
3703
|
setLevels(peakValues);
|
|
3679
3704
|
setRmsLevels(rmsValues);
|
|
@@ -3713,10 +3738,10 @@ function useOutputMeter(options = {}) {
|
|
|
3713
3738
|
|
|
3714
3739
|
// src/WaveformPlaylistContext.tsx
|
|
3715
3740
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
3716
|
-
var PlaybackAnimationContext = (0,
|
|
3717
|
-
var PlaylistStateContext = (0,
|
|
3718
|
-
var PlaylistControlsContext = (0,
|
|
3719
|
-
var PlaylistDataContext = (0,
|
|
3741
|
+
var PlaybackAnimationContext = (0, import_react24.createContext)(null);
|
|
3742
|
+
var PlaylistStateContext = (0, import_react24.createContext)(null);
|
|
3743
|
+
var PlaylistControlsContext = (0, import_react24.createContext)(null);
|
|
3744
|
+
var PlaylistDataContext = (0, import_react24.createContext)(null);
|
|
3720
3745
|
var WaveformPlaylistProvider = ({
|
|
3721
3746
|
tracks,
|
|
3722
3747
|
timescale = false,
|
|
@@ -3743,14 +3768,14 @@ var WaveformPlaylistProvider = ({
|
|
|
3743
3768
|
}) => {
|
|
3744
3769
|
var _a, _b, _c, _d;
|
|
3745
3770
|
const progressBarWidth = progressBarWidthProp != null ? progressBarWidthProp : barWidth + barGap;
|
|
3746
|
-
const indefinitePlaybackRef = (0,
|
|
3771
|
+
const indefinitePlaybackRef = (0, import_react24.useRef)(indefinitePlayback);
|
|
3747
3772
|
indefinitePlaybackRef.current = indefinitePlayback;
|
|
3748
|
-
const stableZoomLevels = (0,
|
|
3773
|
+
const stableZoomLevels = (0, import_react24.useMemo)(
|
|
3749
3774
|
() => zoomLevels,
|
|
3750
3775
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3751
3776
|
[zoomLevels == null ? void 0 : zoomLevels.join(",")]
|
|
3752
3777
|
);
|
|
3753
|
-
const annotations = (0,
|
|
3778
|
+
const annotations = (0, import_react24.useMemo)(() => {
|
|
3754
3779
|
if (!(annotationList == null ? void 0 : annotationList.annotations)) return [];
|
|
3755
3780
|
if (process.env.NODE_ENV !== "production" && annotationList.annotations.length > 0) {
|
|
3756
3781
|
const first = annotationList.annotations[0];
|
|
@@ -3763,46 +3788,46 @@ var WaveformPlaylistProvider = ({
|
|
|
3763
3788
|
}
|
|
3764
3789
|
return annotationList.annotations;
|
|
3765
3790
|
}, [annotationList == null ? void 0 : annotationList.annotations]);
|
|
3766
|
-
const annotationsRef = (0,
|
|
3791
|
+
const annotationsRef = (0, import_react24.useRef)(annotations);
|
|
3767
3792
|
annotationsRef.current = annotations;
|
|
3768
|
-
const [activeAnnotationId, setActiveAnnotationIdState] = (0,
|
|
3769
|
-
const [isPlaying, setIsPlaying] = (0,
|
|
3770
|
-
const [currentTime, setCurrentTime] = (0,
|
|
3771
|
-
const [duration, setDuration] = (0,
|
|
3772
|
-
const [audioBuffers, setAudioBuffers] = (0,
|
|
3773
|
-
const [peaksDataArray, setPeaksDataArray] = (0,
|
|
3774
|
-
const [trackStates, setTrackStates] = (0,
|
|
3775
|
-
const [isAutomaticScroll, setIsAutomaticScroll] = (0,
|
|
3776
|
-
const [continuousPlay, setContinuousPlayState] = (0,
|
|
3793
|
+
const [activeAnnotationId, setActiveAnnotationIdState] = (0, import_react24.useState)(null);
|
|
3794
|
+
const [isPlaying, setIsPlaying] = (0, import_react24.useState)(false);
|
|
3795
|
+
const [currentTime, setCurrentTime] = (0, import_react24.useState)(0);
|
|
3796
|
+
const [duration, setDuration] = (0, import_react24.useState)(0);
|
|
3797
|
+
const [audioBuffers, setAudioBuffers] = (0, import_react24.useState)([]);
|
|
3798
|
+
const [peaksDataArray, setPeaksDataArray] = (0, import_react24.useState)([]);
|
|
3799
|
+
const [trackStates, setTrackStates] = (0, import_react24.useState)([]);
|
|
3800
|
+
const [isAutomaticScroll, setIsAutomaticScroll] = (0, import_react24.useState)(automaticScroll);
|
|
3801
|
+
const [continuousPlay, setContinuousPlayState] = (0, import_react24.useState)(
|
|
3777
3802
|
(_a = annotationList == null ? void 0 : annotationList.isContinuousPlay) != null ? _a : false
|
|
3778
3803
|
);
|
|
3779
|
-
const [linkEndpoints, setLinkEndpoints] = (0,
|
|
3780
|
-
const [annotationsEditable, setAnnotationsEditable] = (0,
|
|
3781
|
-
const [isReady, setIsReady] = (0,
|
|
3782
|
-
const engineRef = (0,
|
|
3783
|
-
const audioInitializedRef = (0,
|
|
3784
|
-
const isPlayingRef = (0,
|
|
3804
|
+
const [linkEndpoints, setLinkEndpoints] = (0, import_react24.useState)((_b = annotationList == null ? void 0 : annotationList.linkEndpoints) != null ? _b : false);
|
|
3805
|
+
const [annotationsEditable, setAnnotationsEditable] = (0, import_react24.useState)((_c = annotationList == null ? void 0 : annotationList.editable) != null ? _c : false);
|
|
3806
|
+
const [isReady, setIsReady] = (0, import_react24.useState)(false);
|
|
3807
|
+
const engineRef = (0, import_react24.useRef)(null);
|
|
3808
|
+
const audioInitializedRef = (0, import_react24.useRef)(false);
|
|
3809
|
+
const isPlayingRef = (0, import_react24.useRef)(false);
|
|
3785
3810
|
isPlayingRef.current = isPlaying;
|
|
3786
|
-
const playStartPositionRef = (0,
|
|
3787
|
-
const currentTimeRef = (0,
|
|
3788
|
-
const tracksRef = (0,
|
|
3789
|
-
const soundFontCacheRef = (0,
|
|
3811
|
+
const playStartPositionRef = (0, import_react24.useRef)(0);
|
|
3812
|
+
const currentTimeRef = (0, import_react24.useRef)(0);
|
|
3813
|
+
const tracksRef = (0, import_react24.useRef)(tracks);
|
|
3814
|
+
const soundFontCacheRef = (0, import_react24.useRef)(soundFontCache);
|
|
3790
3815
|
soundFontCacheRef.current = soundFontCache;
|
|
3791
|
-
const trackStatesRef = (0,
|
|
3792
|
-
const playbackStartTimeRef = (0,
|
|
3793
|
-
const audioStartPositionRef = (0,
|
|
3794
|
-
const playbackEndTimeRef = (0,
|
|
3795
|
-
const scrollContainerRef = (0,
|
|
3796
|
-
const isAutomaticScrollRef = (0,
|
|
3797
|
-
const continuousPlayRef = (0,
|
|
3798
|
-
const activeAnnotationIdRef = (0,
|
|
3799
|
-
const engineTracksRef = (0,
|
|
3800
|
-
const lastTracksVersionRef = (0,
|
|
3801
|
-
const skipEngineDisposeRef = (0,
|
|
3802
|
-
const isDraggingRef = (0,
|
|
3803
|
-
const prevTracksRef = (0,
|
|
3804
|
-
const samplesPerPixelRef = (0,
|
|
3805
|
-
const sampleRateRef = (0,
|
|
3816
|
+
const trackStatesRef = (0, import_react24.useRef)(trackStates);
|
|
3817
|
+
const playbackStartTimeRef = (0, import_react24.useRef)(0);
|
|
3818
|
+
const audioStartPositionRef = (0, import_react24.useRef)(0);
|
|
3819
|
+
const playbackEndTimeRef = (0, import_react24.useRef)(null);
|
|
3820
|
+
const scrollContainerRef = (0, import_react24.useRef)(null);
|
|
3821
|
+
const isAutomaticScrollRef = (0, import_react24.useRef)(false);
|
|
3822
|
+
const continuousPlayRef = (0, import_react24.useRef)((_d = annotationList == null ? void 0 : annotationList.isContinuousPlay) != null ? _d : false);
|
|
3823
|
+
const activeAnnotationIdRef = (0, import_react24.useRef)(null);
|
|
3824
|
+
const engineTracksRef = (0, import_react24.useRef)(null);
|
|
3825
|
+
const lastTracksVersionRef = (0, import_react24.useRef)(0);
|
|
3826
|
+
const skipEngineDisposeRef = (0, import_react24.useRef)(false);
|
|
3827
|
+
const isDraggingRef = (0, import_react24.useRef)(false);
|
|
3828
|
+
const prevTracksRef = (0, import_react24.useRef)([]);
|
|
3829
|
+
const samplesPerPixelRef = (0, import_react24.useRef)(initialSamplesPerPixel);
|
|
3830
|
+
const sampleRateRef = (0, import_react24.useRef)(
|
|
3806
3831
|
typeof AudioContext !== "undefined" ? (0, import_playout5.getGlobalAudioContext)().sampleRate : 48e3
|
|
3807
3832
|
);
|
|
3808
3833
|
const { timeFormat, setTimeFormat, formatTime: formatTime2 } = useTimeFormat();
|
|
@@ -3841,21 +3866,28 @@ var WaveformPlaylistProvider = ({
|
|
|
3841
3866
|
onEngineState: onSelectedTrackEngineState,
|
|
3842
3867
|
selectedTrackIdRef
|
|
3843
3868
|
} = useSelectedTrack({ engineRef });
|
|
3869
|
+
const {
|
|
3870
|
+
canUndo,
|
|
3871
|
+
canRedo,
|
|
3872
|
+
undo,
|
|
3873
|
+
redo,
|
|
3874
|
+
onEngineState: onUndoEngineState
|
|
3875
|
+
} = useUndoState({ engineRef });
|
|
3844
3876
|
const { animationFrameRef, startAnimationFrameLoop, stopAnimationFrameLoop } = useAnimationFrameLoop();
|
|
3845
|
-
const baseScale = (0,
|
|
3877
|
+
const baseScale = (0, import_react24.useMemo)(
|
|
3846
3878
|
() => Math.min(...stableZoomLevels != null ? stableZoomLevels : [256, 512, 1024, 2048, 4096, 8192]),
|
|
3847
3879
|
[stableZoomLevels]
|
|
3848
3880
|
);
|
|
3849
3881
|
const { cache: waveformDataCache } = useWaveformDataCache(tracks, baseScale);
|
|
3850
|
-
const setContinuousPlay = (0,
|
|
3882
|
+
const setContinuousPlay = (0, import_react24.useCallback)((value) => {
|
|
3851
3883
|
continuousPlayRef.current = value;
|
|
3852
3884
|
setContinuousPlayState(value);
|
|
3853
3885
|
}, []);
|
|
3854
|
-
const setActiveAnnotationId = (0,
|
|
3886
|
+
const setActiveAnnotationId = (0, import_react24.useCallback)((value) => {
|
|
3855
3887
|
activeAnnotationIdRef.current = value;
|
|
3856
3888
|
setActiveAnnotationIdState(value);
|
|
3857
3889
|
}, []);
|
|
3858
|
-
const setLoopRegionFromSelection = (0,
|
|
3890
|
+
const setLoopRegionFromSelection = (0, import_react24.useCallback)(() => {
|
|
3859
3891
|
var _a2, _b2;
|
|
3860
3892
|
const start = (_a2 = selectionStartRef.current) != null ? _a2 : 0;
|
|
3861
3893
|
const end = (_b2 = selectionEndRef.current) != null ? _b2 : 0;
|
|
@@ -3863,10 +3895,10 @@ var WaveformPlaylistProvider = ({
|
|
|
3863
3895
|
setLoopRegion(start, end);
|
|
3864
3896
|
}
|
|
3865
3897
|
}, [setLoopRegion, selectionStartRef, selectionEndRef]);
|
|
3866
|
-
(0,
|
|
3898
|
+
(0, import_react24.useEffect)(() => {
|
|
3867
3899
|
isAutomaticScrollRef.current = isAutomaticScroll;
|
|
3868
3900
|
}, [isAutomaticScroll]);
|
|
3869
|
-
(0,
|
|
3901
|
+
(0, import_react24.useEffect)(() => {
|
|
3870
3902
|
trackStatesRef.current = trackStates;
|
|
3871
3903
|
}, [trackStates]);
|
|
3872
3904
|
tracksRef.current = tracks;
|
|
@@ -3877,7 +3909,7 @@ var WaveformPlaylistProvider = ({
|
|
|
3877
3909
|
return current === pt;
|
|
3878
3910
|
});
|
|
3879
3911
|
skipEngineDisposeRef.current = isEngineTracks || isDraggingRef.current || isIncrementalAdd;
|
|
3880
|
-
(0,
|
|
3912
|
+
(0, import_react24.useEffect)(() => {
|
|
3881
3913
|
if (!scrollContainerRef.current || duration === 0) return;
|
|
3882
3914
|
const container = scrollContainerRef.current;
|
|
3883
3915
|
const oldSamplesPerPixel = samplesPerPixelRef.current;
|
|
@@ -3893,8 +3925,8 @@ var WaveformPlaylistProvider = ({
|
|
|
3893
3925
|
container.scrollLeft = newScrollLeft;
|
|
3894
3926
|
samplesPerPixelRef.current = newSamplesPerPixel;
|
|
3895
3927
|
}, [samplesPerPixel, duration]);
|
|
3896
|
-
const pendingResumeRef = (0,
|
|
3897
|
-
(0,
|
|
3928
|
+
const pendingResumeRef = (0, import_react24.useRef)(null);
|
|
3929
|
+
(0, import_react24.useEffect)(() => {
|
|
3898
3930
|
var _a2, _b2, _c2, _d2;
|
|
3899
3931
|
if (isEngineTracks || isDraggingRef.current) {
|
|
3900
3932
|
if (isEngineTracks) {
|
|
@@ -4069,6 +4101,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4069
4101
|
onSelectedTrackEngineState(state);
|
|
4070
4102
|
onZoomEngineState(state);
|
|
4071
4103
|
onVolumeEngineState(state);
|
|
4104
|
+
onUndoEngineState(state);
|
|
4072
4105
|
if (!suppressTracksMirroring && state.tracksVersion !== lastTracksVersionRef.current) {
|
|
4073
4106
|
lastTracksVersionRef.current = state.tracksVersion;
|
|
4074
4107
|
engineTracksRef.current = state.tracks;
|
|
@@ -4126,6 +4159,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4126
4159
|
onSelectedTrackEngineState,
|
|
4127
4160
|
onZoomEngineState,
|
|
4128
4161
|
onVolumeEngineState,
|
|
4162
|
+
onUndoEngineState,
|
|
4129
4163
|
onTracksChange,
|
|
4130
4164
|
masterVolumeRef,
|
|
4131
4165
|
selectionStartRef,
|
|
@@ -4137,7 +4171,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4137
4171
|
soundFontCache,
|
|
4138
4172
|
deferEngineRebuild
|
|
4139
4173
|
]);
|
|
4140
|
-
(0,
|
|
4174
|
+
(0, import_react24.useEffect)(() => {
|
|
4141
4175
|
if (tracks.length === 0) return;
|
|
4142
4176
|
const allTrackPeaks = tracks.map((track) => {
|
|
4143
4177
|
const clipPeaks = track.clips.map((clip) => {
|
|
@@ -4203,8 +4237,8 @@ var WaveformPlaylistProvider = ({
|
|
|
4203
4237
|
});
|
|
4204
4238
|
setPeaksDataArray(allTrackPeaks);
|
|
4205
4239
|
}, [tracks, samplesPerPixel, mono, waveformDataCache, deferEngineRebuild]);
|
|
4206
|
-
const getPlaybackTimeFallbackWarnedRef = (0,
|
|
4207
|
-
const getPlaybackTime = (0,
|
|
4240
|
+
const getPlaybackTimeFallbackWarnedRef = (0, import_react24.useRef)(false);
|
|
4241
|
+
const getPlaybackTime = (0, import_react24.useCallback)(() => {
|
|
4208
4242
|
var _a2, _b2;
|
|
4209
4243
|
if (engineRef.current) {
|
|
4210
4244
|
return engineRef.current.getCurrentTime();
|
|
@@ -4218,7 +4252,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4218
4252
|
const elapsed = (0, import_tone4.getContext)().currentTime - ((_a2 = playbackStartTimeRef.current) != null ? _a2 : 0);
|
|
4219
4253
|
return ((_b2 = audioStartPositionRef.current) != null ? _b2 : 0) + elapsed;
|
|
4220
4254
|
}, []);
|
|
4221
|
-
const startAnimationLoop = (0,
|
|
4255
|
+
const startAnimationLoop = (0, import_react24.useCallback)(() => {
|
|
4222
4256
|
const updateTime = () => {
|
|
4223
4257
|
const time = getPlaybackTime();
|
|
4224
4258
|
currentTimeRef.current = time;
|
|
@@ -4287,7 +4321,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4287
4321
|
startAnimationFrameLoop(updateTime);
|
|
4288
4322
|
}, [duration, setActiveAnnotationId, startAnimationFrameLoop, getPlaybackTime]);
|
|
4289
4323
|
const stopAnimationLoop = stopAnimationFrameLoop;
|
|
4290
|
-
(0,
|
|
4324
|
+
(0, import_react24.useEffect)(() => {
|
|
4291
4325
|
const reschedulePlayback = () => __async(null, null, function* () {
|
|
4292
4326
|
if (isPlaying && animationFrameRef.current && engineRef.current) {
|
|
4293
4327
|
if (continuousPlay) {
|
|
@@ -4312,7 +4346,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4312
4346
|
stopAnimationLoop();
|
|
4313
4347
|
});
|
|
4314
4348
|
}, [continuousPlay, isPlaying, startAnimationLoop, stopAnimationLoop, animationFrameRef]);
|
|
4315
|
-
(0,
|
|
4349
|
+
(0, import_react24.useEffect)(() => {
|
|
4316
4350
|
const resumePlayback = () => __async(null, null, function* () {
|
|
4317
4351
|
if (pendingResumeRef.current && engineRef.current) {
|
|
4318
4352
|
const { position } = pendingResumeRef.current;
|
|
@@ -4336,7 +4370,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4336
4370
|
stopAnimationLoop();
|
|
4337
4371
|
});
|
|
4338
4372
|
}, [tracks, startAnimationLoop, stopAnimationLoop]);
|
|
4339
|
-
const play = (0,
|
|
4373
|
+
const play = (0, import_react24.useCallback)(
|
|
4340
4374
|
(startTime, playDuration) => __async(null, null, function* () {
|
|
4341
4375
|
if (!engineRef.current) return;
|
|
4342
4376
|
const actualStartTime = startTime != null ? startTime : currentTimeRef.current;
|
|
@@ -4367,7 +4401,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4367
4401
|
}),
|
|
4368
4402
|
[startAnimationLoop, stopAnimationLoop]
|
|
4369
4403
|
);
|
|
4370
|
-
const pause = (0,
|
|
4404
|
+
const pause = (0, import_react24.useCallback)(() => {
|
|
4371
4405
|
if (!engineRef.current) return;
|
|
4372
4406
|
const pauseTime = getPlaybackTime();
|
|
4373
4407
|
engineRef.current.pause();
|
|
@@ -4376,7 +4410,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4376
4410
|
currentTimeRef.current = pauseTime;
|
|
4377
4411
|
setCurrentTime(pauseTime);
|
|
4378
4412
|
}, [stopAnimationLoop, getPlaybackTime]);
|
|
4379
|
-
const stop = (0,
|
|
4413
|
+
const stop = (0, import_react24.useCallback)(() => {
|
|
4380
4414
|
if (!engineRef.current) return;
|
|
4381
4415
|
engineRef.current.stop();
|
|
4382
4416
|
setIsPlaying(false);
|
|
@@ -4385,7 +4419,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4385
4419
|
setCurrentTime(playStartPositionRef.current);
|
|
4386
4420
|
setActiveAnnotationId(null);
|
|
4387
4421
|
}, [stopAnimationLoop, setActiveAnnotationId]);
|
|
4388
|
-
const seekTo = (0,
|
|
4422
|
+
const seekTo = (0, import_react24.useCallback)(
|
|
4389
4423
|
(time) => {
|
|
4390
4424
|
const clampedTime = Math.max(0, Math.min(time, duration));
|
|
4391
4425
|
currentTimeRef.current = clampedTime;
|
|
@@ -4396,7 +4430,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4396
4430
|
},
|
|
4397
4431
|
[duration, isPlaying, play]
|
|
4398
4432
|
);
|
|
4399
|
-
const setTrackMute = (0,
|
|
4433
|
+
const setTrackMute = (0, import_react24.useCallback)(
|
|
4400
4434
|
(trackIndex, muted) => {
|
|
4401
4435
|
var _a2;
|
|
4402
4436
|
const trackId = (_a2 = tracksRef.current[trackIndex]) == null ? void 0 : _a2.id;
|
|
@@ -4410,7 +4444,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4410
4444
|
},
|
|
4411
4445
|
[trackStates]
|
|
4412
4446
|
);
|
|
4413
|
-
const setTrackSolo = (0,
|
|
4447
|
+
const setTrackSolo = (0, import_react24.useCallback)(
|
|
4414
4448
|
(trackIndex, soloed) => {
|
|
4415
4449
|
var _a2;
|
|
4416
4450
|
const trackId = (_a2 = tracksRef.current[trackIndex]) == null ? void 0 : _a2.id;
|
|
@@ -4424,7 +4458,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4424
4458
|
},
|
|
4425
4459
|
[trackStates]
|
|
4426
4460
|
);
|
|
4427
|
-
const setTrackVolume = (0,
|
|
4461
|
+
const setTrackVolume = (0, import_react24.useCallback)(
|
|
4428
4462
|
(trackIndex, volume2) => {
|
|
4429
4463
|
var _a2;
|
|
4430
4464
|
const trackId = (_a2 = tracksRef.current[trackIndex]) == null ? void 0 : _a2.id;
|
|
@@ -4438,7 +4472,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4438
4472
|
},
|
|
4439
4473
|
[trackStates]
|
|
4440
4474
|
);
|
|
4441
|
-
const setTrackPan = (0,
|
|
4475
|
+
const setTrackPan = (0, import_react24.useCallback)(
|
|
4442
4476
|
(trackIndex, pan) => {
|
|
4443
4477
|
var _a2;
|
|
4444
4478
|
const trackId = (_a2 = tracksRef.current[trackIndex]) == null ? void 0 : _a2.id;
|
|
@@ -4452,7 +4486,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4452
4486
|
},
|
|
4453
4487
|
[trackStates]
|
|
4454
4488
|
);
|
|
4455
|
-
const setSelection = (0,
|
|
4489
|
+
const setSelection = (0, import_react24.useCallback)(
|
|
4456
4490
|
(start, end) => {
|
|
4457
4491
|
setSelectionEngine(start, end);
|
|
4458
4492
|
currentTimeRef.current = start;
|
|
@@ -4465,12 +4499,12 @@ var WaveformPlaylistProvider = ({
|
|
|
4465
4499
|
},
|
|
4466
4500
|
[isPlaying, setSelectionEngine]
|
|
4467
4501
|
);
|
|
4468
|
-
const setScrollContainer = (0,
|
|
4502
|
+
const setScrollContainer = (0, import_react24.useCallback)((element) => {
|
|
4469
4503
|
scrollContainerRef.current = element;
|
|
4470
4504
|
}, []);
|
|
4471
|
-
const onAnnotationsChangeRef = (0,
|
|
4505
|
+
const onAnnotationsChangeRef = (0, import_react24.useRef)(onAnnotationsChange);
|
|
4472
4506
|
onAnnotationsChangeRef.current = onAnnotationsChange;
|
|
4473
|
-
const setAnnotations = (0,
|
|
4507
|
+
const setAnnotations = (0, import_react24.useCallback)(
|
|
4474
4508
|
(action) => {
|
|
4475
4509
|
const updated = typeof action === "function" ? action(annotationsRef.current) : action;
|
|
4476
4510
|
if (!onAnnotationsChangeRef.current) {
|
|
@@ -4488,7 +4522,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4488
4522
|
const sampleRate = sampleRateRef.current;
|
|
4489
4523
|
const timeScaleHeight = timescale ? 30 : 0;
|
|
4490
4524
|
const minimumPlaylistHeight = tracks.length * waveHeight + timeScaleHeight;
|
|
4491
|
-
const animationValue = (0,
|
|
4525
|
+
const animationValue = (0, import_react24.useMemo)(
|
|
4492
4526
|
() => ({
|
|
4493
4527
|
isPlaying,
|
|
4494
4528
|
currentTime,
|
|
@@ -4506,7 +4540,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4506
4540
|
getPlaybackTime
|
|
4507
4541
|
]
|
|
4508
4542
|
);
|
|
4509
|
-
const stateValue = (0,
|
|
4543
|
+
const stateValue = (0, import_react24.useMemo)(
|
|
4510
4544
|
() => ({
|
|
4511
4545
|
continuousPlay,
|
|
4512
4546
|
linkEndpoints,
|
|
@@ -4520,7 +4554,9 @@ var WaveformPlaylistProvider = ({
|
|
|
4520
4554
|
selectedTrackId,
|
|
4521
4555
|
loopStart,
|
|
4522
4556
|
loopEnd,
|
|
4523
|
-
indefinitePlayback
|
|
4557
|
+
indefinitePlayback,
|
|
4558
|
+
canUndo,
|
|
4559
|
+
canRedo
|
|
4524
4560
|
}),
|
|
4525
4561
|
[
|
|
4526
4562
|
continuousPlay,
|
|
@@ -4535,20 +4571,22 @@ var WaveformPlaylistProvider = ({
|
|
|
4535
4571
|
selectedTrackId,
|
|
4536
4572
|
loopStart,
|
|
4537
4573
|
loopEnd,
|
|
4538
|
-
indefinitePlayback
|
|
4574
|
+
indefinitePlayback,
|
|
4575
|
+
canUndo,
|
|
4576
|
+
canRedo
|
|
4539
4577
|
]
|
|
4540
4578
|
);
|
|
4541
|
-
const setCurrentTimeControl = (0,
|
|
4579
|
+
const setCurrentTimeControl = (0, import_react24.useCallback)(
|
|
4542
4580
|
(time) => {
|
|
4543
4581
|
currentTimeRef.current = time;
|
|
4544
4582
|
setCurrentTime(time);
|
|
4545
4583
|
},
|
|
4546
4584
|
[currentTimeRef]
|
|
4547
4585
|
);
|
|
4548
|
-
const setAutomaticScrollControl = (0,
|
|
4586
|
+
const setAutomaticScrollControl = (0, import_react24.useCallback)((enabled) => {
|
|
4549
4587
|
setIsAutomaticScroll(enabled);
|
|
4550
4588
|
}, []);
|
|
4551
|
-
const controlsValue = (0,
|
|
4589
|
+
const controlsValue = (0, import_react24.useMemo)(
|
|
4552
4590
|
() => ({
|
|
4553
4591
|
// Playback controls
|
|
4554
4592
|
play,
|
|
@@ -4586,7 +4624,10 @@ var WaveformPlaylistProvider = ({
|
|
|
4586
4624
|
setLoopEnabled,
|
|
4587
4625
|
setLoopRegion,
|
|
4588
4626
|
setLoopRegionFromSelection,
|
|
4589
|
-
clearLoopRegion
|
|
4627
|
+
clearLoopRegion,
|
|
4628
|
+
// Undo/redo
|
|
4629
|
+
undo,
|
|
4630
|
+
redo
|
|
4590
4631
|
}),
|
|
4591
4632
|
[
|
|
4592
4633
|
play,
|
|
@@ -4616,10 +4657,12 @@ var WaveformPlaylistProvider = ({
|
|
|
4616
4657
|
setLoopEnabled,
|
|
4617
4658
|
setLoopRegion,
|
|
4618
4659
|
setLoopRegionFromSelection,
|
|
4619
|
-
clearLoopRegion
|
|
4660
|
+
clearLoopRegion,
|
|
4661
|
+
undo,
|
|
4662
|
+
redo
|
|
4620
4663
|
]
|
|
4621
4664
|
);
|
|
4622
|
-
const dataValue = (0,
|
|
4665
|
+
const dataValue = (0, import_react24.useMemo)(
|
|
4623
4666
|
() => ({
|
|
4624
4667
|
duration,
|
|
4625
4668
|
audioBuffers,
|
|
@@ -4675,28 +4718,28 @@ var WaveformPlaylistProvider = ({
|
|
|
4675
4718
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_styled_components.ThemeProvider, { theme: mergedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlaybackAnimationContext.Provider, { value: animationValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlaylistStateContext.Provider, { value: stateValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlaylistControlsContext.Provider, { value: controlsValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlaylistDataContext.Provider, { value: dataValue, children }) }) }) }) });
|
|
4676
4719
|
};
|
|
4677
4720
|
var usePlaybackAnimation = () => {
|
|
4678
|
-
const context = (0,
|
|
4721
|
+
const context = (0, import_react24.useContext)(PlaybackAnimationContext);
|
|
4679
4722
|
if (!context) {
|
|
4680
4723
|
throw new Error("usePlaybackAnimation must be used within WaveformPlaylistProvider");
|
|
4681
4724
|
}
|
|
4682
4725
|
return context;
|
|
4683
4726
|
};
|
|
4684
4727
|
var usePlaylistState = () => {
|
|
4685
|
-
const context = (0,
|
|
4728
|
+
const context = (0, import_react24.useContext)(PlaylistStateContext);
|
|
4686
4729
|
if (!context) {
|
|
4687
4730
|
throw new Error("usePlaylistState must be used within WaveformPlaylistProvider");
|
|
4688
4731
|
}
|
|
4689
4732
|
return context;
|
|
4690
4733
|
};
|
|
4691
4734
|
var usePlaylistControls = () => {
|
|
4692
|
-
const context = (0,
|
|
4735
|
+
const context = (0, import_react24.useContext)(PlaylistControlsContext);
|
|
4693
4736
|
if (!context) {
|
|
4694
4737
|
throw new Error("usePlaylistControls must be used within WaveformPlaylistProvider");
|
|
4695
4738
|
}
|
|
4696
4739
|
return context;
|
|
4697
4740
|
};
|
|
4698
4741
|
var usePlaylistData = () => {
|
|
4699
|
-
const context = (0,
|
|
4742
|
+
const context = (0, import_react24.useContext)(PlaylistDataContext);
|
|
4700
4743
|
if (!context) {
|
|
4701
4744
|
throw new Error("usePlaylistData must be used within WaveformPlaylistProvider");
|
|
4702
4745
|
}
|
|
@@ -4704,15 +4747,15 @@ var usePlaylistData = () => {
|
|
|
4704
4747
|
};
|
|
4705
4748
|
|
|
4706
4749
|
// src/MediaElementPlaylistContext.tsx
|
|
4707
|
-
var
|
|
4750
|
+
var import_react25 = require("react");
|
|
4708
4751
|
var import_styled_components2 = require("styled-components");
|
|
4709
4752
|
var import_media_element_playout = require("@waveform-playlist/media-element-playout");
|
|
4710
4753
|
var import_ui_components3 = require("@waveform-playlist/ui-components");
|
|
4711
4754
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
4712
|
-
var MediaElementAnimationContext = (0,
|
|
4713
|
-
var MediaElementStateContext = (0,
|
|
4714
|
-
var MediaElementControlsContext = (0,
|
|
4715
|
-
var MediaElementDataContext = (0,
|
|
4755
|
+
var MediaElementAnimationContext = (0, import_react25.createContext)(null);
|
|
4756
|
+
var MediaElementStateContext = (0, import_react25.createContext)(null);
|
|
4757
|
+
var MediaElementControlsContext = (0, import_react25.createContext)(null);
|
|
4758
|
+
var MediaElementDataContext = (0, import_react25.createContext)(null);
|
|
4716
4759
|
var MediaElementPlaylistProvider = ({
|
|
4717
4760
|
track,
|
|
4718
4761
|
samplesPerPixel: initialSamplesPerPixel = 1024,
|
|
@@ -4734,12 +4777,12 @@ var MediaElementPlaylistProvider = ({
|
|
|
4734
4777
|
}) => {
|
|
4735
4778
|
var _a;
|
|
4736
4779
|
const progressBarWidth = progressBarWidthProp != null ? progressBarWidthProp : barWidth + barGap;
|
|
4737
|
-
const [isPlaying, setIsPlaying] = (0,
|
|
4738
|
-
const [currentTime, setCurrentTime] = (0,
|
|
4739
|
-
const [duration, setDuration] = (0,
|
|
4740
|
-
const [peaksDataArray, setPeaksDataArray] = (0,
|
|
4741
|
-
const [playbackRate, setPlaybackRateState] = (0,
|
|
4742
|
-
const annotations = (0,
|
|
4780
|
+
const [isPlaying, setIsPlaying] = (0, import_react25.useState)(false);
|
|
4781
|
+
const [currentTime, setCurrentTime] = (0, import_react25.useState)(0);
|
|
4782
|
+
const [duration, setDuration] = (0, import_react25.useState)(0);
|
|
4783
|
+
const [peaksDataArray, setPeaksDataArray] = (0, import_react25.useState)([]);
|
|
4784
|
+
const [playbackRate, setPlaybackRateState] = (0, import_react25.useState)(initialPlaybackRate);
|
|
4785
|
+
const annotations = (0, import_react25.useMemo)(() => {
|
|
4743
4786
|
if (!(annotationList == null ? void 0 : annotationList.annotations)) return [];
|
|
4744
4787
|
if (process.env.NODE_ENV !== "production" && annotationList.annotations.length > 0) {
|
|
4745
4788
|
const first = annotationList.annotations[0];
|
|
@@ -4752,41 +4795,41 @@ var MediaElementPlaylistProvider = ({
|
|
|
4752
4795
|
}
|
|
4753
4796
|
return annotationList.annotations;
|
|
4754
4797
|
}, [annotationList == null ? void 0 : annotationList.annotations]);
|
|
4755
|
-
const annotationsRef = (0,
|
|
4798
|
+
const annotationsRef = (0, import_react25.useRef)(annotations);
|
|
4756
4799
|
annotationsRef.current = annotations;
|
|
4757
|
-
const [activeAnnotationId, setActiveAnnotationIdState] = (0,
|
|
4758
|
-
const [continuousPlay, setContinuousPlayState] = (0,
|
|
4800
|
+
const [activeAnnotationId, setActiveAnnotationIdState] = (0, import_react25.useState)(null);
|
|
4801
|
+
const [continuousPlay, setContinuousPlayState] = (0, import_react25.useState)(
|
|
4759
4802
|
(_a = annotationList == null ? void 0 : annotationList.isContinuousPlay) != null ? _a : false
|
|
4760
4803
|
);
|
|
4761
|
-
const [samplesPerPixel] = (0,
|
|
4762
|
-
const [isAutomaticScroll, setIsAutomaticScroll] = (0,
|
|
4763
|
-
const playoutRef = (0,
|
|
4764
|
-
const currentTimeRef = (0,
|
|
4765
|
-
const continuousPlayRef = (0,
|
|
4766
|
-
const activeAnnotationIdRef = (0,
|
|
4767
|
-
const scrollContainerRef = (0,
|
|
4768
|
-
const isAutomaticScrollRef = (0,
|
|
4769
|
-
const samplesPerPixelRef = (0,
|
|
4804
|
+
const [samplesPerPixel] = (0, import_react25.useState)(initialSamplesPerPixel);
|
|
4805
|
+
const [isAutomaticScroll, setIsAutomaticScroll] = (0, import_react25.useState)(automaticScroll);
|
|
4806
|
+
const playoutRef = (0, import_react25.useRef)(null);
|
|
4807
|
+
const currentTimeRef = (0, import_react25.useRef)(0);
|
|
4808
|
+
const continuousPlayRef = (0, import_react25.useRef)(continuousPlay);
|
|
4809
|
+
const activeAnnotationIdRef = (0, import_react25.useRef)(null);
|
|
4810
|
+
const scrollContainerRef = (0, import_react25.useRef)(null);
|
|
4811
|
+
const isAutomaticScrollRef = (0, import_react25.useRef)(automaticScroll);
|
|
4812
|
+
const samplesPerPixelRef = (0, import_react25.useRef)(initialSamplesPerPixel);
|
|
4770
4813
|
const { startAnimationFrameLoop, stopAnimationFrameLoop } = useAnimationFrameLoop();
|
|
4771
|
-
(0,
|
|
4814
|
+
(0, import_react25.useEffect)(() => {
|
|
4772
4815
|
continuousPlayRef.current = continuousPlay;
|
|
4773
4816
|
}, [continuousPlay]);
|
|
4774
|
-
(0,
|
|
4817
|
+
(0, import_react25.useEffect)(() => {
|
|
4775
4818
|
isAutomaticScrollRef.current = isAutomaticScroll;
|
|
4776
4819
|
}, [isAutomaticScroll]);
|
|
4777
|
-
const setActiveAnnotationId = (0,
|
|
4820
|
+
const setActiveAnnotationId = (0, import_react25.useCallback)((value) => {
|
|
4778
4821
|
activeAnnotationIdRef.current = value;
|
|
4779
4822
|
setActiveAnnotationIdState(value);
|
|
4780
4823
|
}, []);
|
|
4781
|
-
const setContinuousPlay = (0,
|
|
4824
|
+
const setContinuousPlay = (0, import_react25.useCallback)((value) => {
|
|
4782
4825
|
continuousPlayRef.current = value;
|
|
4783
4826
|
setContinuousPlayState(value);
|
|
4784
4827
|
}, []);
|
|
4785
|
-
const setScrollContainer = (0,
|
|
4828
|
+
const setScrollContainer = (0, import_react25.useCallback)((element) => {
|
|
4786
4829
|
scrollContainerRef.current = element;
|
|
4787
4830
|
}, []);
|
|
4788
4831
|
const sampleRate = track.waveformData.sample_rate;
|
|
4789
|
-
(0,
|
|
4832
|
+
(0, import_react25.useEffect)(() => {
|
|
4790
4833
|
var _a2, _b;
|
|
4791
4834
|
const playout = new import_media_element_playout.MediaElementPlayout({
|
|
4792
4835
|
playbackRate: initialPlaybackRate,
|
|
@@ -4833,7 +4876,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4833
4876
|
stopAnimationFrameLoop,
|
|
4834
4877
|
setActiveAnnotationId
|
|
4835
4878
|
]);
|
|
4836
|
-
(0,
|
|
4879
|
+
(0, import_react25.useEffect)(() => {
|
|
4837
4880
|
var _a2;
|
|
4838
4881
|
try {
|
|
4839
4882
|
const extractedPeaks = extractPeaksFromWaveformData(
|
|
@@ -4862,7 +4905,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4862
4905
|
console.warn("[waveform-playlist] Failed to extract peaks from waveform data:", err);
|
|
4863
4906
|
}
|
|
4864
4907
|
}, [track.waveformData, track.name, samplesPerPixel, sampleRate]);
|
|
4865
|
-
const startAnimationLoop = (0,
|
|
4908
|
+
const startAnimationLoop = (0, import_react25.useCallback)(() => {
|
|
4866
4909
|
const updateTime = () => {
|
|
4867
4910
|
var _a2, _b, _c;
|
|
4868
4911
|
const time = (_b = (_a2 = playoutRef.current) == null ? void 0 : _a2.getCurrentTime()) != null ? _b : 0;
|
|
@@ -4905,7 +4948,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4905
4948
|
startAnimationFrameLoop(updateTime);
|
|
4906
4949
|
}, [setActiveAnnotationId, sampleRate, startAnimationFrameLoop]);
|
|
4907
4950
|
const stopAnimationLoop = stopAnimationFrameLoop;
|
|
4908
|
-
const play = (0,
|
|
4951
|
+
const play = (0, import_react25.useCallback)(
|
|
4909
4952
|
(startTime) => {
|
|
4910
4953
|
if (!playoutRef.current) return;
|
|
4911
4954
|
const actualStartTime = startTime != null ? startTime : currentTimeRef.current;
|
|
@@ -4915,14 +4958,14 @@ var MediaElementPlaylistProvider = ({
|
|
|
4915
4958
|
},
|
|
4916
4959
|
[startAnimationLoop]
|
|
4917
4960
|
);
|
|
4918
|
-
const pause = (0,
|
|
4961
|
+
const pause = (0, import_react25.useCallback)(() => {
|
|
4919
4962
|
if (!playoutRef.current) return;
|
|
4920
4963
|
playoutRef.current.pause();
|
|
4921
4964
|
setIsPlaying(false);
|
|
4922
4965
|
stopAnimationLoop();
|
|
4923
4966
|
setCurrentTime(playoutRef.current.getCurrentTime());
|
|
4924
4967
|
}, [stopAnimationLoop]);
|
|
4925
|
-
const stop = (0,
|
|
4968
|
+
const stop = (0, import_react25.useCallback)(() => {
|
|
4926
4969
|
if (!playoutRef.current) return;
|
|
4927
4970
|
playoutRef.current.stop();
|
|
4928
4971
|
setIsPlaying(false);
|
|
@@ -4931,7 +4974,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4931
4974
|
setCurrentTime(0);
|
|
4932
4975
|
setActiveAnnotationId(null);
|
|
4933
4976
|
}, [stopAnimationLoop, setActiveAnnotationId]);
|
|
4934
|
-
const seekTo = (0,
|
|
4977
|
+
const seekTo = (0, import_react25.useCallback)(
|
|
4935
4978
|
(time) => {
|
|
4936
4979
|
const clampedTime = Math.max(0, Math.min(time, duration));
|
|
4937
4980
|
currentTimeRef.current = clampedTime;
|
|
@@ -4942,7 +4985,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4942
4985
|
},
|
|
4943
4986
|
[duration]
|
|
4944
4987
|
);
|
|
4945
|
-
const setPlaybackRate = (0,
|
|
4988
|
+
const setPlaybackRate = (0, import_react25.useCallback)((rate) => {
|
|
4946
4989
|
const clampedRate = Math.max(0.5, Math.min(2, rate));
|
|
4947
4990
|
setPlaybackRateState(clampedRate);
|
|
4948
4991
|
if (playoutRef.current) {
|
|
@@ -4950,7 +4993,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4950
4993
|
}
|
|
4951
4994
|
}, []);
|
|
4952
4995
|
const timeScaleHeight = timescale ? 30 : 0;
|
|
4953
|
-
const animationValue = (0,
|
|
4996
|
+
const animationValue = (0, import_react25.useMemo)(
|
|
4954
4997
|
() => ({
|
|
4955
4998
|
isPlaying,
|
|
4956
4999
|
currentTime,
|
|
@@ -4958,7 +5001,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4958
5001
|
}),
|
|
4959
5002
|
[isPlaying, currentTime]
|
|
4960
5003
|
);
|
|
4961
|
-
const stateValue = (0,
|
|
5004
|
+
const stateValue = (0, import_react25.useMemo)(
|
|
4962
5005
|
() => ({
|
|
4963
5006
|
continuousPlay,
|
|
4964
5007
|
annotations,
|
|
@@ -4968,9 +5011,9 @@ var MediaElementPlaylistProvider = ({
|
|
|
4968
5011
|
}),
|
|
4969
5012
|
[continuousPlay, annotations, activeAnnotationId, playbackRate, isAutomaticScroll]
|
|
4970
5013
|
);
|
|
4971
|
-
const onAnnotationsChangeRef = (0,
|
|
5014
|
+
const onAnnotationsChangeRef = (0, import_react25.useRef)(onAnnotationsChange);
|
|
4972
5015
|
onAnnotationsChangeRef.current = onAnnotationsChange;
|
|
4973
|
-
const setAnnotations = (0,
|
|
5016
|
+
const setAnnotations = (0, import_react25.useCallback)(
|
|
4974
5017
|
(action) => {
|
|
4975
5018
|
const updated = typeof action === "function" ? action(annotationsRef.current) : action;
|
|
4976
5019
|
if (!onAnnotationsChangeRef.current) {
|
|
@@ -4985,7 +5028,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4985
5028
|
},
|
|
4986
5029
|
[]
|
|
4987
5030
|
);
|
|
4988
|
-
const controlsValue = (0,
|
|
5031
|
+
const controlsValue = (0, import_react25.useMemo)(
|
|
4989
5032
|
() => ({
|
|
4990
5033
|
play,
|
|
4991
5034
|
pause,
|
|
@@ -5013,7 +5056,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
5013
5056
|
setScrollContainer
|
|
5014
5057
|
]
|
|
5015
5058
|
);
|
|
5016
|
-
const dataValue = (0,
|
|
5059
|
+
const dataValue = (0, import_react25.useMemo)(
|
|
5017
5060
|
() => ({
|
|
5018
5061
|
duration,
|
|
5019
5062
|
peaksDataArray,
|
|
@@ -5048,28 +5091,28 @@ var MediaElementPlaylistProvider = ({
|
|
|
5048
5091
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_styled_components2.ThemeProvider, { theme: mergedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MediaElementAnimationContext.Provider, { value: animationValue, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MediaElementStateContext.Provider, { value: stateValue, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MediaElementControlsContext.Provider, { value: controlsValue, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MediaElementDataContext.Provider, { value: dataValue, children }) }) }) }) });
|
|
5049
5092
|
};
|
|
5050
5093
|
var useMediaElementAnimation = () => {
|
|
5051
|
-
const context = (0,
|
|
5094
|
+
const context = (0, import_react25.useContext)(MediaElementAnimationContext);
|
|
5052
5095
|
if (!context) {
|
|
5053
5096
|
throw new Error("useMediaElementAnimation must be used within MediaElementPlaylistProvider");
|
|
5054
5097
|
}
|
|
5055
5098
|
return context;
|
|
5056
5099
|
};
|
|
5057
5100
|
var useMediaElementState = () => {
|
|
5058
|
-
const context = (0,
|
|
5101
|
+
const context = (0, import_react25.useContext)(MediaElementStateContext);
|
|
5059
5102
|
if (!context) {
|
|
5060
5103
|
throw new Error("useMediaElementState must be used within MediaElementPlaylistProvider");
|
|
5061
5104
|
}
|
|
5062
5105
|
return context;
|
|
5063
5106
|
};
|
|
5064
5107
|
var useMediaElementControls = () => {
|
|
5065
|
-
const context = (0,
|
|
5108
|
+
const context = (0, import_react25.useContext)(MediaElementControlsContext);
|
|
5066
5109
|
if (!context) {
|
|
5067
5110
|
throw new Error("useMediaElementControls must be used within MediaElementPlaylistProvider");
|
|
5068
5111
|
}
|
|
5069
5112
|
return context;
|
|
5070
5113
|
};
|
|
5071
5114
|
var useMediaElementData = () => {
|
|
5072
|
-
const context = (0,
|
|
5115
|
+
const context = (0, import_react25.useContext)(MediaElementDataContext);
|
|
5073
5116
|
if (!context) {
|
|
5074
5117
|
throw new Error("useMediaElementData must be used within MediaElementPlaylistProvider");
|
|
5075
5118
|
}
|
|
@@ -5077,7 +5120,7 @@ var useMediaElementData = () => {
|
|
|
5077
5120
|
};
|
|
5078
5121
|
|
|
5079
5122
|
// src/components/PlaybackControls.tsx
|
|
5080
|
-
var
|
|
5123
|
+
var import_react26 = require("react");
|
|
5081
5124
|
var import_ui_components4 = require("@waveform-playlist/ui-components");
|
|
5082
5125
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
5083
5126
|
var PlayButton = ({ className }) => {
|
|
@@ -5213,7 +5256,7 @@ var ClearAllButton = ({
|
|
|
5213
5256
|
className
|
|
5214
5257
|
}) => {
|
|
5215
5258
|
const { stop } = usePlaylistControls();
|
|
5216
|
-
const handleClick = (0,
|
|
5259
|
+
const handleClick = (0, import_react26.useCallback)(() => {
|
|
5217
5260
|
stop();
|
|
5218
5261
|
onClearAll();
|
|
5219
5262
|
}, [stop, onClearAll]);
|
|
@@ -5241,7 +5284,7 @@ var ZoomOutButton = ({
|
|
|
5241
5284
|
};
|
|
5242
5285
|
|
|
5243
5286
|
// src/components/ContextualControls.tsx
|
|
5244
|
-
var
|
|
5287
|
+
var import_react27 = require("react");
|
|
5245
5288
|
var import_ui_components6 = require("@waveform-playlist/ui-components");
|
|
5246
5289
|
var import_styled_components3 = __toESM(require("styled-components"));
|
|
5247
5290
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
@@ -5274,11 +5317,11 @@ var PositionDisplay = import_styled_components3.default.span`
|
|
|
5274
5317
|
`;
|
|
5275
5318
|
var AudioPosition = ({ className }) => {
|
|
5276
5319
|
var _a;
|
|
5277
|
-
const timeRef = (0,
|
|
5278
|
-
const animationFrameRef = (0,
|
|
5320
|
+
const timeRef = (0, import_react27.useRef)(null);
|
|
5321
|
+
const animationFrameRef = (0, import_react27.useRef)(null);
|
|
5279
5322
|
const { isPlaying, currentTimeRef, getPlaybackTime } = usePlaybackAnimation();
|
|
5280
5323
|
const { timeFormat: format } = usePlaylistData();
|
|
5281
|
-
(0,
|
|
5324
|
+
(0, import_react27.useEffect)(() => {
|
|
5282
5325
|
const updateTime = () => {
|
|
5283
5326
|
var _a2;
|
|
5284
5327
|
if (timeRef.current) {
|
|
@@ -5301,7 +5344,7 @@ var AudioPosition = ({ className }) => {
|
|
|
5301
5344
|
}
|
|
5302
5345
|
};
|
|
5303
5346
|
}, [isPlaying, format, currentTimeRef, getPlaybackTime]);
|
|
5304
|
-
(0,
|
|
5347
|
+
(0, import_react27.useEffect)(() => {
|
|
5305
5348
|
var _a2;
|
|
5306
5349
|
if (!isPlaying && timeRef.current) {
|
|
5307
5350
|
timeRef.current.textContent = (0, import_ui_components6.formatTime)((_a2 = currentTimeRef.current) != null ? _a2 : 0, format);
|
|
@@ -5336,11 +5379,11 @@ var AutomaticScrollCheckbox = ({ className }) => {
|
|
|
5336
5379
|
};
|
|
5337
5380
|
|
|
5338
5381
|
// src/AnnotationIntegrationContext.tsx
|
|
5339
|
-
var
|
|
5340
|
-
var AnnotationIntegrationContext = (0,
|
|
5382
|
+
var import_react28 = require("react");
|
|
5383
|
+
var AnnotationIntegrationContext = (0, import_react28.createContext)(null);
|
|
5341
5384
|
var AnnotationIntegrationProvider = AnnotationIntegrationContext.Provider;
|
|
5342
5385
|
function useAnnotationIntegration() {
|
|
5343
|
-
const context = (0,
|
|
5386
|
+
const context = (0, import_react28.useContext)(AnnotationIntegrationContext);
|
|
5344
5387
|
if (!context) {
|
|
5345
5388
|
throw new Error(
|
|
5346
5389
|
"useAnnotationIntegration must be used within <AnnotationProvider>. Install @waveform-playlist/annotations and wrap your app with <AnnotationProvider>. See: https://waveform-playlist.naomiaro.com/docs/guides/annotations"
|
|
@@ -5426,22 +5469,22 @@ var ExportWavButton = ({
|
|
|
5426
5469
|
};
|
|
5427
5470
|
|
|
5428
5471
|
// src/contexts/ClipInteractionContext.tsx
|
|
5429
|
-
var
|
|
5430
|
-
var ClipInteractionContext = (0,
|
|
5472
|
+
var import_react29 = require("react");
|
|
5473
|
+
var ClipInteractionContext = (0, import_react29.createContext)(false);
|
|
5431
5474
|
var ClipInteractionContextProvider = ClipInteractionContext.Provider;
|
|
5432
5475
|
function useClipInteractionEnabled() {
|
|
5433
|
-
return (0,
|
|
5476
|
+
return (0, import_react29.useContext)(ClipInteractionContext);
|
|
5434
5477
|
}
|
|
5435
5478
|
|
|
5436
5479
|
// src/components/PlaylistVisualization.tsx
|
|
5437
|
-
var
|
|
5480
|
+
var import_react33 = require("react");
|
|
5438
5481
|
var import_react_dom = require("react-dom");
|
|
5439
5482
|
var import_styled_components6 = __toESM(require("styled-components"));
|
|
5440
5483
|
var import_playout6 = require("@waveform-playlist/playout");
|
|
5441
5484
|
var import_ui_components9 = require("@waveform-playlist/ui-components");
|
|
5442
5485
|
|
|
5443
5486
|
// src/components/AnimatedPlayhead.tsx
|
|
5444
|
-
var
|
|
5487
|
+
var import_react30 = require("react");
|
|
5445
5488
|
var import_styled_components4 = __toESM(require("styled-components"));
|
|
5446
5489
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
5447
5490
|
var PlayheadLine = import_styled_components4.default.div.attrs((props) => ({
|
|
@@ -5459,11 +5502,11 @@ var PlayheadLine = import_styled_components4.default.div.attrs((props) => ({
|
|
|
5459
5502
|
will-change: transform;
|
|
5460
5503
|
`;
|
|
5461
5504
|
var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
5462
|
-
const playheadRef = (0,
|
|
5463
|
-
const animationFrameRef = (0,
|
|
5505
|
+
const playheadRef = (0, import_react30.useRef)(null);
|
|
5506
|
+
const animationFrameRef = (0, import_react30.useRef)(null);
|
|
5464
5507
|
const { isPlaying, currentTimeRef, getPlaybackTime } = usePlaybackAnimation();
|
|
5465
5508
|
const { samplesPerPixel, sampleRate, progressBarWidth } = usePlaylistData();
|
|
5466
|
-
(0,
|
|
5509
|
+
(0, import_react30.useEffect)(() => {
|
|
5467
5510
|
const updatePosition = () => {
|
|
5468
5511
|
var _a;
|
|
5469
5512
|
if (playheadRef.current) {
|
|
@@ -5487,7 +5530,7 @@ var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
|
5487
5530
|
}
|
|
5488
5531
|
};
|
|
5489
5532
|
}, [isPlaying, sampleRate, samplesPerPixel, currentTimeRef, getPlaybackTime]);
|
|
5490
|
-
(0,
|
|
5533
|
+
(0, import_react30.useEffect)(() => {
|
|
5491
5534
|
var _a;
|
|
5492
5535
|
if (!isPlaying && playheadRef.current) {
|
|
5493
5536
|
const time = (_a = currentTimeRef.current) != null ? _a : 0;
|
|
@@ -5499,9 +5542,9 @@ var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
|
5499
5542
|
};
|
|
5500
5543
|
|
|
5501
5544
|
// src/components/ChannelWithProgress.tsx
|
|
5502
|
-
var
|
|
5545
|
+
var import_react31 = require("react");
|
|
5503
5546
|
var import_styled_components5 = __toESM(require("styled-components"));
|
|
5504
|
-
var
|
|
5547
|
+
var import_core6 = require("@waveform-playlist/core");
|
|
5505
5548
|
var import_ui_components8 = require("@waveform-playlist/ui-components");
|
|
5506
5549
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
5507
5550
|
var ChannelWrapper = import_styled_components5.default.div`
|
|
@@ -5557,19 +5600,19 @@ var ChannelWithProgress = (_a) => {
|
|
|
5557
5600
|
"clipSampleRate",
|
|
5558
5601
|
"clipOffsetSeconds"
|
|
5559
5602
|
]);
|
|
5560
|
-
const progressRef = (0,
|
|
5561
|
-
const animationFrameRef = (0,
|
|
5603
|
+
const progressRef = (0, import_react31.useRef)(null);
|
|
5604
|
+
const animationFrameRef = (0, import_react31.useRef)(null);
|
|
5562
5605
|
const theme = (0, import_ui_components8.useTheme)();
|
|
5563
5606
|
const { waveHeight } = (0, import_ui_components8.usePlaylistInfo)();
|
|
5564
5607
|
const { isPlaying, currentTimeRef, getPlaybackTime } = usePlaybackAnimation();
|
|
5565
5608
|
const { samplesPerPixel, sampleRate } = usePlaylistData();
|
|
5566
5609
|
const progressColor = (theme == null ? void 0 : theme.waveProgressColor) || "rgba(0, 0, 0, 0.1)";
|
|
5567
|
-
const clipPixelWidth = (0,
|
|
5610
|
+
const clipPixelWidth = (0, import_core6.clipPixelWidth)(
|
|
5568
5611
|
clipStartSample,
|
|
5569
5612
|
clipDurationSamples,
|
|
5570
5613
|
samplesPerPixel
|
|
5571
5614
|
);
|
|
5572
|
-
(0,
|
|
5615
|
+
(0, import_react31.useEffect)(() => {
|
|
5573
5616
|
const updateProgress = () => {
|
|
5574
5617
|
var _a2;
|
|
5575
5618
|
if (progressRef.current) {
|
|
@@ -5611,7 +5654,7 @@ var ChannelWithProgress = (_a) => {
|
|
|
5611
5654
|
currentTimeRef,
|
|
5612
5655
|
getPlaybackTime
|
|
5613
5656
|
]);
|
|
5614
|
-
(0,
|
|
5657
|
+
(0, import_react31.useEffect)(() => {
|
|
5615
5658
|
var _a2;
|
|
5616
5659
|
if (!isPlaying && progressRef.current) {
|
|
5617
5660
|
const currentTime = (_a2 = currentTimeRef.current) != null ? _a2 : 0;
|
|
@@ -5696,11 +5739,11 @@ var ChannelWithProgress = (_a) => {
|
|
|
5696
5739
|
};
|
|
5697
5740
|
|
|
5698
5741
|
// src/SpectrogramIntegrationContext.tsx
|
|
5699
|
-
var
|
|
5700
|
-
var SpectrogramIntegrationContext = (0,
|
|
5742
|
+
var import_react32 = require("react");
|
|
5743
|
+
var SpectrogramIntegrationContext = (0, import_react32.createContext)(null);
|
|
5701
5744
|
var SpectrogramIntegrationProvider = SpectrogramIntegrationContext.Provider;
|
|
5702
5745
|
function useSpectrogramIntegration() {
|
|
5703
|
-
const context = (0,
|
|
5746
|
+
const context = (0, import_react32.useContext)(SpectrogramIntegrationContext);
|
|
5704
5747
|
if (!context) {
|
|
5705
5748
|
throw new Error(
|
|
5706
5749
|
"useSpectrogramIntegration must be used within <SpectrogramProvider>. Install @waveform-playlist/spectrogram and wrap your app with <SpectrogramProvider>."
|
|
@@ -5780,7 +5823,7 @@ var PlaylistVisualization = ({
|
|
|
5780
5823
|
isLoopEnabled,
|
|
5781
5824
|
indefinitePlayback
|
|
5782
5825
|
} = usePlaylistState();
|
|
5783
|
-
const annotationIntegration = (0,
|
|
5826
|
+
const annotationIntegration = (0, import_react33.useContext)(AnnotationIntegrationContext);
|
|
5784
5827
|
const {
|
|
5785
5828
|
setAnnotations: _setAnnotations,
|
|
5786
5829
|
setActiveAnnotationId,
|
|
@@ -5810,8 +5853,8 @@ var PlaylistVisualization = ({
|
|
|
5810
5853
|
isReady,
|
|
5811
5854
|
mono
|
|
5812
5855
|
} = usePlaylistData();
|
|
5813
|
-
const spectrogram = (0,
|
|
5814
|
-
const perTrackSpectrogramHelpers = (0,
|
|
5856
|
+
const spectrogram = (0, import_react33.useContext)(SpectrogramIntegrationContext);
|
|
5857
|
+
const perTrackSpectrogramHelpers = (0, import_react33.useMemo)(() => {
|
|
5815
5858
|
if (!spectrogram)
|
|
5816
5859
|
return /* @__PURE__ */ new Map();
|
|
5817
5860
|
const helpers = /* @__PURE__ */ new Map();
|
|
@@ -5830,7 +5873,7 @@ var PlaylistVisualization = ({
|
|
|
5830
5873
|
});
|
|
5831
5874
|
return helpers;
|
|
5832
5875
|
}, [tracks, spectrogram]);
|
|
5833
|
-
const workerCanvasApi = (0,
|
|
5876
|
+
const workerCanvasApi = (0, import_react33.useMemo)(() => {
|
|
5834
5877
|
if (!(spectrogram == null ? void 0 : spectrogram.spectrogramWorkerApi)) return void 0;
|
|
5835
5878
|
return {
|
|
5836
5879
|
registerCanvas: spectrogram.spectrogramWorkerApi.registerCanvas.bind(
|
|
@@ -5841,11 +5884,11 @@ var PlaylistVisualization = ({
|
|
|
5841
5884
|
)
|
|
5842
5885
|
};
|
|
5843
5886
|
}, [spectrogram == null ? void 0 : spectrogram.spectrogramWorkerApi]);
|
|
5844
|
-
const [settingsModalTrackId, setSettingsModalTrackId] = (0,
|
|
5845
|
-
const [isSelecting, setIsSelecting] = (0,
|
|
5846
|
-
const mouseDownTimeRef = (0,
|
|
5847
|
-
const scrollContainerRef = (0,
|
|
5848
|
-
const handleScrollContainerRef = (0,
|
|
5887
|
+
const [settingsModalTrackId, setSettingsModalTrackId] = (0, import_react33.useState)(null);
|
|
5888
|
+
const [isSelecting, setIsSelecting] = (0, import_react33.useState)(false);
|
|
5889
|
+
const mouseDownTimeRef = (0, import_react33.useRef)(0);
|
|
5890
|
+
const scrollContainerRef = (0, import_react33.useRef)(null);
|
|
5891
|
+
const handleScrollContainerRef = (0, import_react33.useCallback)(
|
|
5849
5892
|
(element) => {
|
|
5850
5893
|
scrollContainerRef.current = element;
|
|
5851
5894
|
setScrollContainer(element);
|
|
@@ -5883,7 +5926,7 @@ var PlaylistVisualization = ({
|
|
|
5883
5926
|
);
|
|
5884
5927
|
}
|
|
5885
5928
|
});
|
|
5886
|
-
const selectTrack = (0,
|
|
5929
|
+
const selectTrack = (0, import_react33.useCallback)(
|
|
5887
5930
|
(trackIndex) => {
|
|
5888
5931
|
if (trackIndex >= 0 && trackIndex < tracks.length) {
|
|
5889
5932
|
const track = tracks[trackIndex];
|
|
@@ -6324,7 +6367,7 @@ var PlaylistVisualization = ({
|
|
|
6324
6367
|
};
|
|
6325
6368
|
|
|
6326
6369
|
// src/components/PlaylistAnnotationList.tsx
|
|
6327
|
-
var
|
|
6370
|
+
var import_react34 = require("react");
|
|
6328
6371
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
6329
6372
|
var PlaylistAnnotationList = ({
|
|
6330
6373
|
height,
|
|
@@ -6339,7 +6382,7 @@ var PlaylistAnnotationList = ({
|
|
|
6339
6382
|
const integration = useAnnotationIntegration();
|
|
6340
6383
|
const { setAnnotations } = usePlaylistControls();
|
|
6341
6384
|
const resolvedConfig = annotationListConfig != null ? annotationListConfig : { linkEndpoints, continuousPlay };
|
|
6342
|
-
const handleAnnotationUpdate = (0,
|
|
6385
|
+
const handleAnnotationUpdate = (0, import_react34.useCallback)(
|
|
6343
6386
|
(updatedAnnotations) => {
|
|
6344
6387
|
setAnnotations(updatedAnnotations);
|
|
6345
6388
|
onAnnotationUpdate == null ? void 0 : onAnnotationUpdate(updatedAnnotations);
|
|
@@ -6423,8 +6466,8 @@ var Waveform = ({
|
|
|
6423
6466
|
};
|
|
6424
6467
|
|
|
6425
6468
|
// src/components/MediaElementPlaylist.tsx
|
|
6426
|
-
var
|
|
6427
|
-
var
|
|
6469
|
+
var import_react37 = require("react");
|
|
6470
|
+
var import_react38 = require("@dnd-kit/react");
|
|
6428
6471
|
var import_modifiers = require("@dnd-kit/abstract/modifiers");
|
|
6429
6472
|
var import_ui_components11 = require("@waveform-playlist/ui-components");
|
|
6430
6473
|
|
|
@@ -6448,7 +6491,7 @@ var noDropAnimationPlugins = (defaults) => {
|
|
|
6448
6491
|
};
|
|
6449
6492
|
|
|
6450
6493
|
// src/components/AnimatedMediaElementPlayhead.tsx
|
|
6451
|
-
var
|
|
6494
|
+
var import_react35 = require("react");
|
|
6452
6495
|
var import_styled_components7 = __toESM(require("styled-components"));
|
|
6453
6496
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
6454
6497
|
var PlayheadLine2 = import_styled_components7.default.div`
|
|
@@ -6465,11 +6508,11 @@ var PlayheadLine2 = import_styled_components7.default.div`
|
|
|
6465
6508
|
var AnimatedMediaElementPlayhead = ({
|
|
6466
6509
|
color = "#ff0000"
|
|
6467
6510
|
}) => {
|
|
6468
|
-
const playheadRef = (0,
|
|
6469
|
-
const animationFrameRef = (0,
|
|
6511
|
+
const playheadRef = (0, import_react35.useRef)(null);
|
|
6512
|
+
const animationFrameRef = (0, import_react35.useRef)(null);
|
|
6470
6513
|
const { isPlaying, currentTimeRef } = useMediaElementAnimation();
|
|
6471
6514
|
const { samplesPerPixel, sampleRate, progressBarWidth } = useMediaElementData();
|
|
6472
|
-
(0,
|
|
6515
|
+
(0, import_react35.useEffect)(() => {
|
|
6473
6516
|
const updatePosition = () => {
|
|
6474
6517
|
var _a;
|
|
6475
6518
|
if (playheadRef.current) {
|
|
@@ -6493,7 +6536,7 @@ var AnimatedMediaElementPlayhead = ({
|
|
|
6493
6536
|
}
|
|
6494
6537
|
};
|
|
6495
6538
|
}, [isPlaying, sampleRate, samplesPerPixel, currentTimeRef]);
|
|
6496
|
-
(0,
|
|
6539
|
+
(0, import_react35.useEffect)(() => {
|
|
6497
6540
|
var _a;
|
|
6498
6541
|
if (!isPlaying && playheadRef.current) {
|
|
6499
6542
|
const time = (_a = currentTimeRef.current) != null ? _a : 0;
|
|
@@ -6505,7 +6548,7 @@ var AnimatedMediaElementPlayhead = ({
|
|
|
6505
6548
|
};
|
|
6506
6549
|
|
|
6507
6550
|
// src/components/ChannelWithMediaElementProgress.tsx
|
|
6508
|
-
var
|
|
6551
|
+
var import_react36 = require("react");
|
|
6509
6552
|
var import_styled_components8 = __toESM(require("styled-components"));
|
|
6510
6553
|
var import_ui_components10 = require("@waveform-playlist/ui-components");
|
|
6511
6554
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
@@ -6545,14 +6588,14 @@ var ChannelWithMediaElementProgress = (_a) => {
|
|
|
6545
6588
|
"clipStartSample",
|
|
6546
6589
|
"clipDurationSamples"
|
|
6547
6590
|
]);
|
|
6548
|
-
const progressRef = (0,
|
|
6549
|
-
const animationFrameRef = (0,
|
|
6591
|
+
const progressRef = (0, import_react36.useRef)(null);
|
|
6592
|
+
const animationFrameRef = (0, import_react36.useRef)(null);
|
|
6550
6593
|
const theme = (0, import_ui_components10.useTheme)();
|
|
6551
6594
|
const { waveHeight } = (0, import_ui_components10.usePlaylistInfo)();
|
|
6552
6595
|
const { isPlaying, currentTimeRef } = useMediaElementAnimation();
|
|
6553
6596
|
const { samplesPerPixel, sampleRate } = useMediaElementData();
|
|
6554
6597
|
const progressColor = (theme == null ? void 0 : theme.waveProgressColor) || "rgba(0, 0, 0, 0.1)";
|
|
6555
|
-
(0,
|
|
6598
|
+
(0, import_react36.useEffect)(() => {
|
|
6556
6599
|
const updateProgress = () => {
|
|
6557
6600
|
var _a2;
|
|
6558
6601
|
if (progressRef.current) {
|
|
@@ -6594,7 +6637,7 @@ var ChannelWithMediaElementProgress = (_a) => {
|
|
|
6594
6637
|
smartChannelProps.length,
|
|
6595
6638
|
currentTimeRef
|
|
6596
6639
|
]);
|
|
6597
|
-
(0,
|
|
6640
|
+
(0, import_react36.useEffect)(() => {
|
|
6598
6641
|
var _a2;
|
|
6599
6642
|
if (!isPlaying && progressRef.current) {
|
|
6600
6643
|
const currentTime = (_a2 = currentTimeRef.current) != null ? _a2 : 0;
|
|
@@ -6673,7 +6716,7 @@ var MediaElementPlaylist = ({
|
|
|
6673
6716
|
const theme = (0, import_ui_components11.useTheme)();
|
|
6674
6717
|
const { isPlaying } = useMediaElementAnimation();
|
|
6675
6718
|
const { annotations, activeAnnotationId } = useMediaElementState();
|
|
6676
|
-
const annotationIntegration = (0,
|
|
6719
|
+
const annotationIntegration = (0, import_react37.useContext)(AnnotationIntegrationContext);
|
|
6677
6720
|
const { play, seekTo, setActiveAnnotationId, setAnnotations, setScrollContainer } = useMediaElementControls();
|
|
6678
6721
|
const {
|
|
6679
6722
|
duration,
|
|
@@ -6689,11 +6732,11 @@ var MediaElementPlaylist = ({
|
|
|
6689
6732
|
fadeIn,
|
|
6690
6733
|
fadeOut
|
|
6691
6734
|
} = useMediaElementData();
|
|
6692
|
-
const [selectionStart, setSelectionStart] = (0,
|
|
6693
|
-
const [selectionEnd, setSelectionEnd] = (0,
|
|
6694
|
-
const [isSelecting, setIsSelecting] = (0,
|
|
6695
|
-
const scrollContainerRef = (0,
|
|
6696
|
-
const handleScrollContainerRef = (0,
|
|
6735
|
+
const [selectionStart, setSelectionStart] = (0, import_react37.useState)(0);
|
|
6736
|
+
const [selectionEnd, setSelectionEnd] = (0, import_react37.useState)(0);
|
|
6737
|
+
const [isSelecting, setIsSelecting] = (0, import_react37.useState)(false);
|
|
6738
|
+
const scrollContainerRef = (0, import_react37.useRef)(null);
|
|
6739
|
+
const handleScrollContainerRef = (0, import_react37.useCallback)(
|
|
6697
6740
|
(el) => {
|
|
6698
6741
|
scrollContainerRef.current = el;
|
|
6699
6742
|
setScrollContainer(el);
|
|
@@ -6701,7 +6744,7 @@ var MediaElementPlaylist = ({
|
|
|
6701
6744
|
[setScrollContainer]
|
|
6702
6745
|
);
|
|
6703
6746
|
const tracksFullWidth = Math.floor(duration * sampleRate / samplesPerPixel);
|
|
6704
|
-
const handleAnnotationClick = (0,
|
|
6747
|
+
const handleAnnotationClick = (0, import_react37.useCallback)(
|
|
6705
6748
|
(annotation) => __async(null, null, function* () {
|
|
6706
6749
|
setActiveAnnotationId(annotation.id);
|
|
6707
6750
|
try {
|
|
@@ -6716,7 +6759,7 @@ var MediaElementPlaylist = ({
|
|
|
6716
6759
|
}),
|
|
6717
6760
|
[setActiveAnnotationId, play]
|
|
6718
6761
|
);
|
|
6719
|
-
const handleAnnotationUpdate = (0,
|
|
6762
|
+
const handleAnnotationUpdate = (0, import_react37.useCallback)(
|
|
6720
6763
|
(updatedAnnotations) => {
|
|
6721
6764
|
setAnnotations(updatedAnnotations);
|
|
6722
6765
|
onAnnotationUpdate == null ? void 0 : onAnnotationUpdate(updatedAnnotations);
|
|
@@ -6730,8 +6773,8 @@ var MediaElementPlaylist = ({
|
|
|
6730
6773
|
duration,
|
|
6731
6774
|
linkEndpoints: linkEndpointsProp
|
|
6732
6775
|
});
|
|
6733
|
-
const mouseDownTimeRef = (0,
|
|
6734
|
-
const handleMouseDown = (0,
|
|
6776
|
+
const mouseDownTimeRef = (0, import_react37.useRef)(0);
|
|
6777
|
+
const handleMouseDown = (0, import_react37.useCallback)(
|
|
6735
6778
|
(e) => {
|
|
6736
6779
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
6737
6780
|
const x = e.clientX - rect.left;
|
|
@@ -6743,7 +6786,7 @@ var MediaElementPlaylist = ({
|
|
|
6743
6786
|
},
|
|
6744
6787
|
[samplesPerPixel, sampleRate]
|
|
6745
6788
|
);
|
|
6746
|
-
const handleMouseMove = (0,
|
|
6789
|
+
const handleMouseMove = (0, import_react37.useCallback)(
|
|
6747
6790
|
(e) => {
|
|
6748
6791
|
if (!isSelecting) return;
|
|
6749
6792
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -6753,7 +6796,7 @@ var MediaElementPlaylist = ({
|
|
|
6753
6796
|
},
|
|
6754
6797
|
[isSelecting, samplesPerPixel, sampleRate]
|
|
6755
6798
|
);
|
|
6756
|
-
const handleMouseUp = (0,
|
|
6799
|
+
const handleMouseUp = (0, import_react37.useCallback)(
|
|
6757
6800
|
(e) => {
|
|
6758
6801
|
if (!isSelecting) return;
|
|
6759
6802
|
setIsSelecting(false);
|
|
@@ -6885,7 +6928,7 @@ var MediaElementPlaylist = ({
|
|
|
6885
6928
|
);
|
|
6886
6929
|
}),
|
|
6887
6930
|
annotations.length > 0 && annotationIntegration && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6888
|
-
|
|
6931
|
+
import_react38.DragDropProvider,
|
|
6889
6932
|
{
|
|
6890
6933
|
onDragStart,
|
|
6891
6934
|
onDragMove,
|
|
@@ -6939,7 +6982,7 @@ var MediaElementPlaylist = ({
|
|
|
6939
6982
|
};
|
|
6940
6983
|
|
|
6941
6984
|
// src/components/MediaElementAnnotationList.tsx
|
|
6942
|
-
var
|
|
6985
|
+
var import_react39 = require("react");
|
|
6943
6986
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
6944
6987
|
var MediaElementAnnotationList = ({
|
|
6945
6988
|
height,
|
|
@@ -6955,7 +6998,7 @@ var MediaElementAnnotationList = ({
|
|
|
6955
6998
|
const integration = useAnnotationIntegration();
|
|
6956
6999
|
const { setAnnotations } = useMediaElementControls();
|
|
6957
7000
|
const resolvedConfig = annotationListConfig != null ? annotationListConfig : { linkEndpoints: false, continuousPlay };
|
|
6958
|
-
const handleAnnotationUpdate = (0,
|
|
7001
|
+
const handleAnnotationUpdate = (0, import_react39.useCallback)(
|
|
6959
7002
|
(updatedAnnotations) => {
|
|
6960
7003
|
setAnnotations(updatedAnnotations);
|
|
6961
7004
|
onAnnotationUpdate == null ? void 0 : onAnnotationUpdate(updatedAnnotations);
|
|
@@ -7030,6 +7073,7 @@ var KeyboardShortcuts = ({
|
|
|
7030
7073
|
playback = false,
|
|
7031
7074
|
clipSplitting = false,
|
|
7032
7075
|
annotations = false,
|
|
7076
|
+
undo: undoEnabled = false,
|
|
7033
7077
|
additionalShortcuts = []
|
|
7034
7078
|
}) => {
|
|
7035
7079
|
const { tracks, samplesPerPixel, playoutRef, duration } = usePlaylistData();
|
|
@@ -7039,7 +7083,7 @@ var KeyboardShortcuts = ({
|
|
|
7039
7083
|
activeAnnotationId,
|
|
7040
7084
|
continuousPlay
|
|
7041
7085
|
} = usePlaylistState();
|
|
7042
|
-
const { setAnnotations, setActiveAnnotationId, scrollContainerRef, play } = usePlaylistControls();
|
|
7086
|
+
const { setAnnotations, setActiveAnnotationId, scrollContainerRef, play, undo, redo } = usePlaylistControls();
|
|
7043
7087
|
const { splitClipAtPlayhead } = useClipSplitting({
|
|
7044
7088
|
tracks,
|
|
7045
7089
|
samplesPerPixel,
|
|
@@ -7054,6 +7098,14 @@ var KeyboardShortcuts = ({
|
|
|
7054
7098
|
preventDefault: true
|
|
7055
7099
|
});
|
|
7056
7100
|
}
|
|
7101
|
+
if (undoEnabled) {
|
|
7102
|
+
allAdditional.push(
|
|
7103
|
+
{ key: "z", ctrlKey: true, shiftKey: false, action: undo, description: "Undo" },
|
|
7104
|
+
{ key: "z", metaKey: true, shiftKey: false, action: undo, description: "Undo" },
|
|
7105
|
+
{ key: "z", ctrlKey: true, shiftKey: true, action: redo, description: "Redo" },
|
|
7106
|
+
{ key: "z", metaKey: true, shiftKey: true, action: redo, description: "Redo" }
|
|
7107
|
+
);
|
|
7108
|
+
}
|
|
7057
7109
|
if (additionalShortcuts.length > 0) {
|
|
7058
7110
|
allAdditional.push(...additionalShortcuts);
|
|
7059
7111
|
}
|
|
@@ -7076,10 +7128,10 @@ var KeyboardShortcuts = ({
|
|
|
7076
7128
|
};
|
|
7077
7129
|
|
|
7078
7130
|
// src/components/ClipInteractionProvider.tsx
|
|
7079
|
-
var
|
|
7080
|
-
var
|
|
7131
|
+
var import_react40 = __toESM(require("react"));
|
|
7132
|
+
var import_react41 = require("@dnd-kit/react");
|
|
7081
7133
|
var import_modifiers2 = require("@dnd-kit/abstract/modifiers");
|
|
7082
|
-
var
|
|
7134
|
+
var import_core8 = require("@waveform-playlist/core");
|
|
7083
7135
|
var import_ui_components12 = require("@waveform-playlist/ui-components");
|
|
7084
7136
|
|
|
7085
7137
|
// src/modifiers/ClipCollisionModifier.ts
|
|
@@ -7108,7 +7160,7 @@ var ClipCollisionModifier = _ClipCollisionModifier;
|
|
|
7108
7160
|
|
|
7109
7161
|
// src/modifiers/SnapToGridModifier.ts
|
|
7110
7162
|
var import_abstract2 = require("@dnd-kit/abstract");
|
|
7111
|
-
var
|
|
7163
|
+
var import_core7 = require("@waveform-playlist/core");
|
|
7112
7164
|
var _SnapToGridModifier = class _SnapToGridModifier extends import_abstract2.Modifier {
|
|
7113
7165
|
apply(operation) {
|
|
7114
7166
|
const { transform, source } = operation;
|
|
@@ -7129,18 +7181,18 @@ var _SnapToGridModifier = class _SnapToGridModifier extends import_abstract2.Mod
|
|
|
7129
7181
|
}
|
|
7130
7182
|
const { snapTo, bpm, timeSignature, sampleRate } = this.options;
|
|
7131
7183
|
if (snapTo === "off") return transform;
|
|
7132
|
-
const gridTicks = snapTo === "bar" ? (0,
|
|
7184
|
+
const gridTicks = snapTo === "bar" ? (0, import_core7.ticksPerBar)(timeSignature) : (0, import_core7.ticksPerBeat)(timeSignature);
|
|
7133
7185
|
if (startSample !== void 0) {
|
|
7134
7186
|
const proposedSamples = startSample + transform.x * samplesPerPixel;
|
|
7135
|
-
const proposedTicks = (0,
|
|
7136
|
-
const snappedTicks2 = (0,
|
|
7137
|
-
const snappedSamples2 = (0,
|
|
7187
|
+
const proposedTicks = (0, import_core7.samplesToTicks)(proposedSamples, bpm, sampleRate);
|
|
7188
|
+
const snappedTicks2 = (0, import_core7.snapToGrid)(proposedTicks, gridTicks);
|
|
7189
|
+
const snappedSamples2 = (0, import_core7.ticksToSamples)(snappedTicks2, bpm, sampleRate);
|
|
7138
7190
|
return { x: (snappedSamples2 - startSample) / samplesPerPixel, y: 0 };
|
|
7139
7191
|
}
|
|
7140
7192
|
const deltaSamples = transform.x * samplesPerPixel;
|
|
7141
|
-
const deltaTicks = (0,
|
|
7142
|
-
const snappedTicks = (0,
|
|
7143
|
-
const snappedSamples = (0,
|
|
7193
|
+
const deltaTicks = (0, import_core7.samplesToTicks)(deltaSamples, bpm, sampleRate);
|
|
7194
|
+
const snappedTicks = (0, import_core7.snapToGrid)(deltaTicks, gridTicks);
|
|
7195
|
+
const snappedSamples = (0, import_core7.ticksToSamples)(snappedTicks, bpm, sampleRate);
|
|
7144
7196
|
return { x: snappedSamples / samplesPerPixel, y: 0 };
|
|
7145
7197
|
}
|
|
7146
7198
|
};
|
|
@@ -7161,21 +7213,21 @@ var ClipInteractionProvider = ({
|
|
|
7161
7213
|
const beatsAndBars = (0, import_ui_components12.useBeatsAndBars)();
|
|
7162
7214
|
const useBeatsSnap = snap && beatsAndBars != null && beatsAndBars.scaleMode === "beats" && beatsAndBars.snapTo !== "off";
|
|
7163
7215
|
const useTimescaleSnap = snap && !useBeatsSnap;
|
|
7164
|
-
(0,
|
|
7216
|
+
(0, import_react40.useEffect)(() => {
|
|
7165
7217
|
if (onTracksChange == null) {
|
|
7166
7218
|
console.warn(
|
|
7167
7219
|
"[waveform-playlist] ClipInteractionProvider: onTracksChange is not set on WaveformPlaylistProvider. Drag and trim edits will not be persisted."
|
|
7168
7220
|
);
|
|
7169
7221
|
}
|
|
7170
7222
|
}, [onTracksChange]);
|
|
7171
|
-
const snapSamplePosition = (0,
|
|
7223
|
+
const snapSamplePosition = (0, import_react40.useMemo)(() => {
|
|
7172
7224
|
if (useBeatsSnap && beatsAndBars) {
|
|
7173
7225
|
const { bpm, timeSignature, snapTo } = beatsAndBars;
|
|
7174
|
-
const gridTicks = snapTo === "bar" ? (0,
|
|
7226
|
+
const gridTicks = snapTo === "bar" ? (0, import_core8.ticksPerBar)(timeSignature) : (0, import_core8.ticksPerBeat)(timeSignature);
|
|
7175
7227
|
return (samplePos) => {
|
|
7176
|
-
const ticks = (0,
|
|
7177
|
-
const snapped = (0,
|
|
7178
|
-
return (0,
|
|
7228
|
+
const ticks = (0, import_core8.samplesToTicks)(samplePos, bpm, sampleRate);
|
|
7229
|
+
const snapped = (0, import_core8.snapToGrid)(ticks, gridTicks);
|
|
7230
|
+
return (0, import_core8.ticksToSamples)(snapped, bpm, sampleRate);
|
|
7179
7231
|
};
|
|
7180
7232
|
}
|
|
7181
7233
|
if (useTimescaleSnap) {
|
|
@@ -7197,7 +7249,7 @@ var ClipInteractionProvider = ({
|
|
|
7197
7249
|
isDraggingRef,
|
|
7198
7250
|
snapSamplePosition
|
|
7199
7251
|
});
|
|
7200
|
-
const onDragStart =
|
|
7252
|
+
const onDragStart = import_react40.default.useCallback(
|
|
7201
7253
|
(event) => {
|
|
7202
7254
|
var _a, _b, _c;
|
|
7203
7255
|
const trackIndex = (_c = (_b = (_a = event.operation) == null ? void 0 : _a.source) == null ? void 0 : _b.data) == null ? void 0 : _c.trackIndex;
|
|
@@ -7208,7 +7260,7 @@ var ClipInteractionProvider = ({
|
|
|
7208
7260
|
},
|
|
7209
7261
|
[handleDragStart, tracks, setSelectedTrackId]
|
|
7210
7262
|
);
|
|
7211
|
-
const modifiers = (0,
|
|
7263
|
+
const modifiers = (0, import_react40.useMemo)(() => {
|
|
7212
7264
|
const mods = [import_modifiers2.RestrictToHorizontalAxis];
|
|
7213
7265
|
if (useBeatsSnap && beatsAndBars) {
|
|
7214
7266
|
mods.push(
|
|
@@ -7234,7 +7286,7 @@ var ClipInteractionProvider = ({
|
|
|
7234
7286
|
return mods;
|
|
7235
7287
|
}, [useBeatsSnap, useTimescaleSnap, beatsAndBars, tracks, samplesPerPixel, sampleRate]);
|
|
7236
7288
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ClipInteractionContextProvider, { value: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7237
|
-
|
|
7289
|
+
import_react41.DragDropProvider,
|
|
7238
7290
|
{
|
|
7239
7291
|
sensors,
|
|
7240
7292
|
onDragStart,
|