@waveform-playlist/browser 11.0.1 → 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.mjs
CHANGED
|
@@ -57,10 +57,10 @@ import * as Tone2 from "tone";
|
|
|
57
57
|
import {
|
|
58
58
|
createContext,
|
|
59
59
|
useContext,
|
|
60
|
-
useState as
|
|
60
|
+
useState as useState15,
|
|
61
61
|
useEffect as useEffect10,
|
|
62
|
-
useRef as
|
|
63
|
-
useCallback as
|
|
62
|
+
useRef as useRef15,
|
|
63
|
+
useCallback as useCallback19,
|
|
64
64
|
useMemo as useMemo4
|
|
65
65
|
} from "react";
|
|
66
66
|
import { ThemeProvider } from "styled-components";
|
|
@@ -451,12 +451,52 @@ function useSelectedTrack({ engineRef }) {
|
|
|
451
451
|
};
|
|
452
452
|
}
|
|
453
453
|
|
|
454
|
+
// src/hooks/useUndoState.ts
|
|
455
|
+
import { useState as useState7, useCallback as useCallback6, useRef as useRef6 } from "react";
|
|
456
|
+
function useUndoState({ engineRef }) {
|
|
457
|
+
const [canUndo, setCanUndo] = useState7(false);
|
|
458
|
+
const [canRedo, setCanRedo] = useState7(false);
|
|
459
|
+
const canUndoRef = useRef6(false);
|
|
460
|
+
const canRedoRef = useRef6(false);
|
|
461
|
+
const undo = useCallback6(() => {
|
|
462
|
+
if (!engineRef.current) {
|
|
463
|
+
console.warn("[waveform-playlist] undo: engine not ready, call ignored");
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
engineRef.current.undo();
|
|
467
|
+
}, [engineRef]);
|
|
468
|
+
const redo = useCallback6(() => {
|
|
469
|
+
if (!engineRef.current) {
|
|
470
|
+
console.warn("[waveform-playlist] redo: engine not ready, call ignored");
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
engineRef.current.redo();
|
|
474
|
+
}, [engineRef]);
|
|
475
|
+
const onEngineState = useCallback6((state) => {
|
|
476
|
+
if (state.canUndo !== canUndoRef.current) {
|
|
477
|
+
canUndoRef.current = state.canUndo;
|
|
478
|
+
setCanUndo(state.canUndo);
|
|
479
|
+
}
|
|
480
|
+
if (state.canRedo !== canRedoRef.current) {
|
|
481
|
+
canRedoRef.current = state.canRedo;
|
|
482
|
+
setCanRedo(state.canRedo);
|
|
483
|
+
}
|
|
484
|
+
}, []);
|
|
485
|
+
return {
|
|
486
|
+
canUndo,
|
|
487
|
+
canRedo,
|
|
488
|
+
undo,
|
|
489
|
+
redo,
|
|
490
|
+
onEngineState
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
454
494
|
// src/hooks/useAudioEffects.ts
|
|
455
|
-
import { useRef as
|
|
495
|
+
import { useRef as useRef7, useCallback as useCallback7 } from "react";
|
|
456
496
|
import { Analyser } from "tone";
|
|
457
497
|
var useMasterAnalyser = (fftSize = 256) => {
|
|
458
|
-
const analyserRef =
|
|
459
|
-
const masterEffects =
|
|
498
|
+
const analyserRef = useRef7(null);
|
|
499
|
+
const masterEffects = useCallback7(
|
|
460
500
|
(masterGainNode, destination, _isOffline) => {
|
|
461
501
|
const analyserNode = new Analyser("fft", fftSize);
|
|
462
502
|
masterGainNode.connect(analyserNode);
|
|
@@ -473,7 +513,7 @@ var useMasterAnalyser = (fftSize = 256) => {
|
|
|
473
513
|
};
|
|
474
514
|
|
|
475
515
|
// src/hooks/useAudioTracks.ts
|
|
476
|
-
import { useState as
|
|
516
|
+
import { useState as useState8, useEffect, useRef as useRef8, useMemo } from "react";
|
|
477
517
|
import {
|
|
478
518
|
createTrack,
|
|
479
519
|
createClipFromSeconds
|
|
@@ -534,13 +574,13 @@ function buildTrackFromConfig(config, index, audioBuffer, stableIds, contextSamp
|
|
|
534
574
|
function useAudioTracks(configs, options = {}) {
|
|
535
575
|
const { immediate = false, progressive = false } = options;
|
|
536
576
|
const isImmediate = immediate || progressive;
|
|
537
|
-
const [loading, setLoading] =
|
|
538
|
-
const [error, setError] =
|
|
539
|
-
const [loadedCount, setLoadedCount] =
|
|
577
|
+
const [loading, setLoading] = useState8(true);
|
|
578
|
+
const [error, setError] = useState8(null);
|
|
579
|
+
const [loadedCount, setLoadedCount] = useState8(0);
|
|
540
580
|
const totalCount = configs.length;
|
|
541
|
-
const [loadedBuffers, setLoadedBuffers] =
|
|
542
|
-
const stableIdsRef =
|
|
543
|
-
const contextSampleRateRef =
|
|
581
|
+
const [loadedBuffers, setLoadedBuffers] = useState8(/* @__PURE__ */ new Map());
|
|
582
|
+
const stableIdsRef = useRef8(/* @__PURE__ */ new Map());
|
|
583
|
+
const contextSampleRateRef = useRef8(48e3);
|
|
544
584
|
const derivedTracks = useMemo(() => {
|
|
545
585
|
if (!isImmediate) return null;
|
|
546
586
|
const result = [];
|
|
@@ -556,8 +596,8 @@ function useAudioTracks(configs, options = {}) {
|
|
|
556
596
|
}
|
|
557
597
|
return result;
|
|
558
598
|
}, [isImmediate, configs, loadedBuffers]);
|
|
559
|
-
const [tracks, setTracks] =
|
|
560
|
-
const prevDerivedRef =
|
|
599
|
+
const [tracks, setTracks] = useState8(derivedTracks != null ? derivedTracks : []);
|
|
600
|
+
const prevDerivedRef = useRef8(derivedTracks);
|
|
561
601
|
if (derivedTracks !== prevDerivedRef.current) {
|
|
562
602
|
prevDerivedRef.current = derivedTracks;
|
|
563
603
|
if (derivedTracks) setTracks(derivedTracks);
|
|
@@ -735,6 +775,13 @@ function useClipDragHandlers({
|
|
|
735
775
|
if (!data) return;
|
|
736
776
|
if (!data.boundary) {
|
|
737
777
|
originalClipStateRef.current = null;
|
|
778
|
+
if (engineRef.current) {
|
|
779
|
+
engineRef.current.beginTransaction();
|
|
780
|
+
} else {
|
|
781
|
+
console.warn(
|
|
782
|
+
"[waveform-playlist] onDragStart: engine not ready, move will not be grouped for undo"
|
|
783
|
+
);
|
|
784
|
+
}
|
|
738
785
|
return;
|
|
739
786
|
}
|
|
740
787
|
const track = tracks[data.trackIndex];
|
|
@@ -746,9 +793,16 @@ function useClipDragHandlers({
|
|
|
746
793
|
startSample: clip.startSample
|
|
747
794
|
};
|
|
748
795
|
isDraggingRef.current = true;
|
|
796
|
+
if (engineRef.current) {
|
|
797
|
+
engineRef.current.beginTransaction();
|
|
798
|
+
} else {
|
|
799
|
+
console.warn(
|
|
800
|
+
"[waveform-playlist] onDragStart: engine not ready, trim will not be grouped for undo"
|
|
801
|
+
);
|
|
802
|
+
}
|
|
749
803
|
}
|
|
750
804
|
},
|
|
751
|
-
[tracks, isDraggingRef]
|
|
805
|
+
[tracks, isDraggingRef, engineRef]
|
|
752
806
|
);
|
|
753
807
|
const onDragMove = React.useCallback(
|
|
754
808
|
(event) => {
|
|
@@ -814,7 +868,7 @@ function useClipDragHandlers({
|
|
|
814
868
|
);
|
|
815
869
|
const onDragEnd = React.useCallback(
|
|
816
870
|
(event) => {
|
|
817
|
-
var _a, _b, _c;
|
|
871
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
818
872
|
if (event.canceled) {
|
|
819
873
|
if (originalClipStateRef.current) {
|
|
820
874
|
const cancelData = (_a = event.operation.source) == null ? void 0 : _a.data;
|
|
@@ -839,23 +893,30 @@ function useClipDragHandlers({
|
|
|
839
893
|
isDraggingRef.current = false;
|
|
840
894
|
originalClipStateRef.current = null;
|
|
841
895
|
lastBoundaryDeltaRef.current = 0;
|
|
896
|
+
(_b = engineRef.current) == null ? void 0 : _b.abortTransaction();
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
const data = (_c = event.operation.source) == null ? void 0 : _c.data;
|
|
900
|
+
if (!data) {
|
|
901
|
+
isDraggingRef.current = false;
|
|
902
|
+
(_d = engineRef.current) == null ? void 0 : _d.abortTransaction();
|
|
842
903
|
return;
|
|
843
904
|
}
|
|
844
|
-
const data = (_b = event.operation.source) == null ? void 0 : _b.data;
|
|
845
|
-
if (!data) return;
|
|
846
905
|
const { trackIndex, clipId, boundary } = data;
|
|
847
906
|
const sampleDelta = boundary ? lastBoundaryDeltaRef.current : event.operation.transform.x * samplesPerPixel;
|
|
848
|
-
const trackId = (
|
|
907
|
+
const trackId = (_e = tracks[trackIndex]) == null ? void 0 : _e.id;
|
|
849
908
|
if (boundary) {
|
|
850
909
|
isDraggingRef.current = false;
|
|
851
910
|
if (!trackId) {
|
|
852
911
|
console.warn(
|
|
853
912
|
`[waveform-playlist] onDragEnd: track at index ${trackIndex} not found \u2014 trim not synced to adapter`
|
|
854
913
|
);
|
|
914
|
+
(_f = engineRef.current) == null ? void 0 : _f.abortTransaction();
|
|
855
915
|
} else if (!engineRef.current) {
|
|
856
916
|
console.warn("[waveform-playlist] engineRef is null \u2014 trim not synced to adapter");
|
|
857
917
|
} else {
|
|
858
918
|
engineRef.current.trimClip(trackId, clipId, boundary, Math.floor(sampleDelta));
|
|
919
|
+
engineRef.current.commitTransaction();
|
|
859
920
|
}
|
|
860
921
|
originalClipStateRef.current = null;
|
|
861
922
|
lastBoundaryDeltaRef.current = 0;
|
|
@@ -865,10 +926,12 @@ function useClipDragHandlers({
|
|
|
865
926
|
console.warn(
|
|
866
927
|
`[waveform-playlist] onDragEnd: track at index ${trackIndex} not found \u2014 move not synced to adapter`
|
|
867
928
|
);
|
|
929
|
+
(_g = engineRef.current) == null ? void 0 : _g.abortTransaction();
|
|
868
930
|
} else if (!engineRef.current) {
|
|
869
931
|
console.warn("[waveform-playlist] engineRef is null \u2014 move not synced to adapter");
|
|
870
932
|
} else {
|
|
871
933
|
engineRef.current.moveClip(trackId, clipId, Math.floor(sampleDelta));
|
|
934
|
+
engineRef.current.commitTransaction();
|
|
872
935
|
}
|
|
873
936
|
},
|
|
874
937
|
[tracks, onTracksChange, samplesPerPixel, engineRef, isDraggingRef]
|
|
@@ -1084,14 +1147,14 @@ function useDragSensors(options = {}) {
|
|
|
1084
1147
|
}
|
|
1085
1148
|
|
|
1086
1149
|
// src/hooks/useClipSplitting.ts
|
|
1087
|
-
import { useCallback as
|
|
1150
|
+
import { useCallback as useCallback8 } from "react";
|
|
1088
1151
|
import { calculateSplitPoint, canSplitAt } from "@waveform-playlist/engine";
|
|
1089
1152
|
var useClipSplitting = (options) => {
|
|
1090
1153
|
const { tracks, engineRef } = options;
|
|
1091
1154
|
const { sampleRate } = usePlaylistData();
|
|
1092
1155
|
const { currentTimeRef } = usePlaybackAnimation();
|
|
1093
1156
|
const { selectedTrackId } = usePlaylistState();
|
|
1094
|
-
const splitClipAt =
|
|
1157
|
+
const splitClipAt = useCallback8(
|
|
1095
1158
|
(trackIndex, clipIndex, splitTime) => {
|
|
1096
1159
|
const { samplesPerPixel } = options;
|
|
1097
1160
|
const track = tracks[trackIndex];
|
|
@@ -1115,7 +1178,7 @@ var useClipSplitting = (options) => {
|
|
|
1115
1178
|
},
|
|
1116
1179
|
[tracks, options, engineRef, sampleRate]
|
|
1117
1180
|
);
|
|
1118
|
-
const splitClipAtPlayhead =
|
|
1181
|
+
const splitClipAtPlayhead = useCallback8(() => {
|
|
1119
1182
|
var _a;
|
|
1120
1183
|
if (!selectedTrackId) {
|
|
1121
1184
|
console.warn("[waveform-playlist] No track selected \u2014 click a clip to select a track first");
|
|
@@ -1146,32 +1209,12 @@ var useClipSplitting = (options) => {
|
|
|
1146
1209
|
};
|
|
1147
1210
|
|
|
1148
1211
|
// src/hooks/useKeyboardShortcuts.ts
|
|
1149
|
-
import { useEffect as useEffect2, useCallback as
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
if (event.repeat) return;
|
|
1153
|
-
const target = event.target;
|
|
1154
|
-
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) {
|
|
1155
|
-
return;
|
|
1156
|
-
}
|
|
1157
|
-
const matchingShortcut = shortcuts.find((shortcut) => {
|
|
1158
|
-
const keyMatch = event.key.toLowerCase() === shortcut.key.toLowerCase() || event.key === shortcut.key;
|
|
1159
|
-
const ctrlMatch = shortcut.ctrlKey === void 0 || event.ctrlKey === shortcut.ctrlKey;
|
|
1160
|
-
const shiftMatch = shortcut.shiftKey === void 0 || event.shiftKey === shortcut.shiftKey;
|
|
1161
|
-
const metaMatch = shortcut.metaKey === void 0 || event.metaKey === shortcut.metaKey;
|
|
1162
|
-
const altMatch = shortcut.altKey === void 0 || event.altKey === shortcut.altKey;
|
|
1163
|
-
return keyMatch && ctrlMatch && shiftMatch && metaMatch && altMatch;
|
|
1164
|
-
});
|
|
1165
|
-
if (matchingShortcut) {
|
|
1166
|
-
if (matchingShortcut.preventDefault !== false) {
|
|
1167
|
-
event.preventDefault();
|
|
1168
|
-
}
|
|
1169
|
-
matchingShortcut.action();
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1212
|
+
import { useEffect as useEffect2, useCallback as useCallback9 } from "react";
|
|
1213
|
+
import { handleKeyboardEvent } from "@waveform-playlist/core";
|
|
1214
|
+
import { handleKeyboardEvent as handleKeyboardEvent2, getShortcutLabel } from "@waveform-playlist/core";
|
|
1172
1215
|
var useKeyboardShortcuts = (options) => {
|
|
1173
1216
|
const { shortcuts, enabled = true } = options;
|
|
1174
|
-
const handleKeyDown =
|
|
1217
|
+
const handleKeyDown = useCallback9(
|
|
1175
1218
|
(event) => handleKeyboardEvent(event, shortcuts, enabled),
|
|
1176
1219
|
[shortcuts, enabled]
|
|
1177
1220
|
);
|
|
@@ -1183,42 +1226,24 @@ var useKeyboardShortcuts = (options) => {
|
|
|
1183
1226
|
};
|
|
1184
1227
|
}, [handleKeyDown, enabled]);
|
|
1185
1228
|
};
|
|
1186
|
-
var getShortcutLabel = (shortcut) => {
|
|
1187
|
-
const parts = [];
|
|
1188
|
-
const isMac = typeof navigator !== "undefined" && navigator.platform.includes("Mac");
|
|
1189
|
-
if (shortcut.metaKey) {
|
|
1190
|
-
parts.push(isMac ? "Cmd" : "Ctrl");
|
|
1191
|
-
}
|
|
1192
|
-
if (shortcut.ctrlKey && !shortcut.metaKey) {
|
|
1193
|
-
parts.push("Ctrl");
|
|
1194
|
-
}
|
|
1195
|
-
if (shortcut.altKey) {
|
|
1196
|
-
parts.push(isMac ? "Option" : "Alt");
|
|
1197
|
-
}
|
|
1198
|
-
if (shortcut.shiftKey) {
|
|
1199
|
-
parts.push("Shift");
|
|
1200
|
-
}
|
|
1201
|
-
parts.push(shortcut.key.toUpperCase());
|
|
1202
|
-
return parts.join("+");
|
|
1203
|
-
};
|
|
1204
1229
|
|
|
1205
1230
|
// src/hooks/usePlaybackShortcuts.ts
|
|
1206
|
-
import { useCallback as
|
|
1231
|
+
import { useCallback as useCallback10 } from "react";
|
|
1207
1232
|
var usePlaybackShortcuts = (options = {}) => {
|
|
1208
1233
|
const { enabled = true, additionalShortcuts = [], shortcuts: overrideShortcuts } = options;
|
|
1209
1234
|
const { isPlaying } = usePlaybackAnimation();
|
|
1210
1235
|
const { setCurrentTime, play, pause, stop } = usePlaylistControls();
|
|
1211
|
-
const togglePlayPause =
|
|
1236
|
+
const togglePlayPause = useCallback10(() => {
|
|
1212
1237
|
if (isPlaying) {
|
|
1213
1238
|
pause();
|
|
1214
1239
|
} else {
|
|
1215
1240
|
play();
|
|
1216
1241
|
}
|
|
1217
1242
|
}, [isPlaying, play, pause]);
|
|
1218
|
-
const stopPlayback =
|
|
1243
|
+
const stopPlayback = useCallback10(() => {
|
|
1219
1244
|
stop();
|
|
1220
1245
|
}, [stop]);
|
|
1221
|
-
const rewindToStart =
|
|
1246
|
+
const rewindToStart = useCallback10(() => {
|
|
1222
1247
|
setCurrentTime(0);
|
|
1223
1248
|
if (isPlaying) {
|
|
1224
1249
|
play(0);
|
|
@@ -1258,7 +1283,7 @@ var usePlaybackShortcuts = (options = {}) => {
|
|
|
1258
1283
|
};
|
|
1259
1284
|
|
|
1260
1285
|
// src/hooks/useAnnotationKeyboardControls.ts
|
|
1261
|
-
import { useCallback as
|
|
1286
|
+
import { useCallback as useCallback11, useMemo as useMemo3, useEffect as useEffect3 } from "react";
|
|
1262
1287
|
var LINK_THRESHOLD2 = 0.01;
|
|
1263
1288
|
var TIME_DELTA = 0.01;
|
|
1264
1289
|
function useAnnotationKeyboardControls({
|
|
@@ -1278,7 +1303,7 @@ function useAnnotationKeyboardControls({
|
|
|
1278
1303
|
if (!activeAnnotationId) return -1;
|
|
1279
1304
|
return annotations.findIndex((a) => a.id === activeAnnotationId);
|
|
1280
1305
|
}, [annotations, activeAnnotationId]);
|
|
1281
|
-
const scrollToAnnotation =
|
|
1306
|
+
const scrollToAnnotation = useCallback11(
|
|
1282
1307
|
(annotationId) => {
|
|
1283
1308
|
if (!(scrollContainerRef == null ? void 0 : scrollContainerRef.current) || !samplesPerPixel || !sampleRate) return;
|
|
1284
1309
|
const annotation = annotations.find((a) => a.id === annotationId);
|
|
@@ -1306,7 +1331,7 @@ function useAnnotationKeyboardControls({
|
|
|
1306
1331
|
scrollToAnnotation(activeAnnotationId);
|
|
1307
1332
|
}
|
|
1308
1333
|
}, [activeAnnotationId, scrollToAnnotation, scrollContainerRef, samplesPerPixel, sampleRate]);
|
|
1309
|
-
const moveStartBoundary =
|
|
1334
|
+
const moveStartBoundary = useCallback11(
|
|
1310
1335
|
(delta) => {
|
|
1311
1336
|
if (activeIndex < 0) return;
|
|
1312
1337
|
const annotation = annotations[activeIndex];
|
|
@@ -1335,7 +1360,7 @@ function useAnnotationKeyboardControls({
|
|
|
1335
1360
|
},
|
|
1336
1361
|
[annotations, activeIndex, linkEndpoints, onAnnotationsChange]
|
|
1337
1362
|
);
|
|
1338
|
-
const moveEndBoundary =
|
|
1363
|
+
const moveEndBoundary = useCallback11(
|
|
1339
1364
|
(delta) => {
|
|
1340
1365
|
if (activeIndex < 0) return;
|
|
1341
1366
|
const annotation = annotations[activeIndex];
|
|
@@ -1395,7 +1420,7 @@ function useAnnotationKeyboardControls({
|
|
|
1395
1420
|
},
|
|
1396
1421
|
[annotations, activeIndex, duration, linkEndpoints, onAnnotationsChange]
|
|
1397
1422
|
);
|
|
1398
|
-
const selectPrevious =
|
|
1423
|
+
const selectPrevious = useCallback11(() => {
|
|
1399
1424
|
if (!onActiveAnnotationChange || annotations.length === 0) return;
|
|
1400
1425
|
if (activeIndex <= 0) {
|
|
1401
1426
|
onActiveAnnotationChange(annotations[annotations.length - 1].id);
|
|
@@ -1403,7 +1428,7 @@ function useAnnotationKeyboardControls({
|
|
|
1403
1428
|
onActiveAnnotationChange(annotations[activeIndex - 1].id);
|
|
1404
1429
|
}
|
|
1405
1430
|
}, [annotations, activeIndex, onActiveAnnotationChange]);
|
|
1406
|
-
const selectNext =
|
|
1431
|
+
const selectNext = useCallback11(() => {
|
|
1407
1432
|
if (!onActiveAnnotationChange || annotations.length === 0) return;
|
|
1408
1433
|
if (activeIndex < 0 || activeIndex >= annotations.length - 1) {
|
|
1409
1434
|
onActiveAnnotationChange(annotations[0].id);
|
|
@@ -1411,19 +1436,19 @@ function useAnnotationKeyboardControls({
|
|
|
1411
1436
|
onActiveAnnotationChange(annotations[activeIndex + 1].id);
|
|
1412
1437
|
}
|
|
1413
1438
|
}, [annotations, activeIndex, onActiveAnnotationChange]);
|
|
1414
|
-
const selectFirst =
|
|
1439
|
+
const selectFirst = useCallback11(() => {
|
|
1415
1440
|
if (!onActiveAnnotationChange || annotations.length === 0) return;
|
|
1416
1441
|
onActiveAnnotationChange(annotations[0].id);
|
|
1417
1442
|
}, [annotations, onActiveAnnotationChange]);
|
|
1418
|
-
const selectLast =
|
|
1443
|
+
const selectLast = useCallback11(() => {
|
|
1419
1444
|
if (!onActiveAnnotationChange || annotations.length === 0) return;
|
|
1420
1445
|
onActiveAnnotationChange(annotations[annotations.length - 1].id);
|
|
1421
1446
|
}, [annotations, onActiveAnnotationChange]);
|
|
1422
|
-
const clearSelection =
|
|
1447
|
+
const clearSelection = useCallback11(() => {
|
|
1423
1448
|
if (!onActiveAnnotationChange) return;
|
|
1424
1449
|
onActiveAnnotationChange(null);
|
|
1425
1450
|
}, [onActiveAnnotationChange]);
|
|
1426
|
-
const playActiveAnnotation =
|
|
1451
|
+
const playActiveAnnotation = useCallback11(() => {
|
|
1427
1452
|
if (activeIndex < 0 || !onPlay) return;
|
|
1428
1453
|
const annotation = annotations[activeIndex];
|
|
1429
1454
|
const playDuration = !continuousPlay ? annotation.end - annotation.start : void 0;
|
|
@@ -1535,7 +1560,7 @@ function useAnnotationKeyboardControls({
|
|
|
1535
1560
|
}
|
|
1536
1561
|
|
|
1537
1562
|
// src/hooks/useDynamicEffects.ts
|
|
1538
|
-
import { useState as
|
|
1563
|
+
import { useState as useState9, useCallback as useCallback12, useRef as useRef9, useEffect as useEffect4 } from "react";
|
|
1539
1564
|
|
|
1540
1565
|
// src/effects/effectDefinitions.ts
|
|
1541
1566
|
var effectDefinitions = [
|
|
@@ -2231,13 +2256,13 @@ function createEffectChain(effects) {
|
|
|
2231
2256
|
// src/hooks/useDynamicEffects.ts
|
|
2232
2257
|
import { Analyser as Analyser2 } from "tone";
|
|
2233
2258
|
function useDynamicEffects(fftSize = 256) {
|
|
2234
|
-
const [activeEffects, setActiveEffects] =
|
|
2235
|
-
const activeEffectsRef =
|
|
2259
|
+
const [activeEffects, setActiveEffects] = useState9([]);
|
|
2260
|
+
const activeEffectsRef = useRef9(activeEffects);
|
|
2236
2261
|
activeEffectsRef.current = activeEffects;
|
|
2237
|
-
const effectInstancesRef =
|
|
2238
|
-
const analyserRef =
|
|
2239
|
-
const graphNodesRef =
|
|
2240
|
-
const rebuildChain =
|
|
2262
|
+
const effectInstancesRef = useRef9(/* @__PURE__ */ new Map());
|
|
2263
|
+
const analyserRef = useRef9(null);
|
|
2264
|
+
const graphNodesRef = useRef9(null);
|
|
2265
|
+
const rebuildChain = useCallback12((effects) => {
|
|
2241
2266
|
const nodes = graphNodesRef.current;
|
|
2242
2267
|
if (!nodes) return;
|
|
2243
2268
|
const { masterGainNode, destination, analyserNode } = nodes;
|
|
@@ -2265,7 +2290,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2265
2290
|
analyserNode.connect(destination);
|
|
2266
2291
|
}
|
|
2267
2292
|
}, []);
|
|
2268
|
-
const addEffect =
|
|
2293
|
+
const addEffect = useCallback12((effectId) => {
|
|
2269
2294
|
const definition = getEffectDefinition(effectId);
|
|
2270
2295
|
if (!definition) {
|
|
2271
2296
|
console.error(`Unknown effect: ${effectId}`);
|
|
@@ -2286,7 +2311,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2286
2311
|
};
|
|
2287
2312
|
setActiveEffects((prev) => [...prev, newActiveEffect]);
|
|
2288
2313
|
}, []);
|
|
2289
|
-
const removeEffect =
|
|
2314
|
+
const removeEffect = useCallback12((instanceId) => {
|
|
2290
2315
|
const instance = effectInstancesRef.current.get(instanceId);
|
|
2291
2316
|
if (instance) {
|
|
2292
2317
|
instance.dispose();
|
|
@@ -2294,7 +2319,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2294
2319
|
}
|
|
2295
2320
|
setActiveEffects((prev) => prev.filter((e) => e.instanceId !== instanceId));
|
|
2296
2321
|
}, []);
|
|
2297
|
-
const updateParameter =
|
|
2322
|
+
const updateParameter = useCallback12(
|
|
2298
2323
|
(instanceId, paramName, value) => {
|
|
2299
2324
|
const instance = effectInstancesRef.current.get(instanceId);
|
|
2300
2325
|
if (instance) {
|
|
@@ -2308,7 +2333,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2308
2333
|
},
|
|
2309
2334
|
[]
|
|
2310
2335
|
);
|
|
2311
|
-
const toggleBypass =
|
|
2336
|
+
const toggleBypass = useCallback12((instanceId) => {
|
|
2312
2337
|
var _a;
|
|
2313
2338
|
const effect = activeEffectsRef.current.find((e) => e.instanceId === instanceId);
|
|
2314
2339
|
if (!effect) return;
|
|
@@ -2322,7 +2347,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2322
2347
|
(prev) => prev.map((e) => e.instanceId === instanceId ? __spreadProps(__spreadValues({}, e), { bypassed: newBypassed }) : e)
|
|
2323
2348
|
);
|
|
2324
2349
|
}, []);
|
|
2325
|
-
const reorderEffects =
|
|
2350
|
+
const reorderEffects = useCallback12((fromIndex, toIndex) => {
|
|
2326
2351
|
setActiveEffects((prev) => {
|
|
2327
2352
|
const newEffects = [...prev];
|
|
2328
2353
|
const [removed] = newEffects.splice(fromIndex, 1);
|
|
@@ -2330,7 +2355,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2330
2355
|
return newEffects;
|
|
2331
2356
|
});
|
|
2332
2357
|
}, []);
|
|
2333
|
-
const clearAllEffects =
|
|
2358
|
+
const clearAllEffects = useCallback12(() => {
|
|
2334
2359
|
effectInstancesRef.current.forEach((inst) => inst.dispose());
|
|
2335
2360
|
effectInstancesRef.current.clear();
|
|
2336
2361
|
setActiveEffects([]);
|
|
@@ -2338,7 +2363,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2338
2363
|
useEffect4(() => {
|
|
2339
2364
|
rebuildChain(activeEffects);
|
|
2340
2365
|
}, [activeEffects, rebuildChain]);
|
|
2341
|
-
const masterEffects =
|
|
2366
|
+
const masterEffects = useCallback12(
|
|
2342
2367
|
(masterGainNode, destination, _isOffline) => {
|
|
2343
2368
|
const analyserNode = new Analyser2("fft", fftSize);
|
|
2344
2369
|
analyserRef.current = analyserNode;
|
|
@@ -2377,7 +2402,7 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2377
2402
|
effectInstances.clear();
|
|
2378
2403
|
};
|
|
2379
2404
|
}, []);
|
|
2380
|
-
const createOfflineEffectsFunction =
|
|
2405
|
+
const createOfflineEffectsFunction = useCallback12(() => {
|
|
2381
2406
|
const nonBypassedEffects = activeEffects.filter((e) => !e.bypassed);
|
|
2382
2407
|
if (nonBypassedEffects.length === 0) {
|
|
2383
2408
|
return void 0;
|
|
@@ -2419,14 +2444,14 @@ function useDynamicEffects(fftSize = 256) {
|
|
|
2419
2444
|
}
|
|
2420
2445
|
|
|
2421
2446
|
// src/hooks/useTrackDynamicEffects.ts
|
|
2422
|
-
import { useState as
|
|
2447
|
+
import { useState as useState10, useCallback as useCallback13, useRef as useRef10, useEffect as useEffect5 } from "react";
|
|
2423
2448
|
function useTrackDynamicEffects() {
|
|
2424
|
-
const [trackEffectsState, setTrackEffectsState] =
|
|
2449
|
+
const [trackEffectsState, setTrackEffectsState] = useState10(
|
|
2425
2450
|
/* @__PURE__ */ new Map()
|
|
2426
2451
|
);
|
|
2427
|
-
const trackEffectInstancesRef =
|
|
2428
|
-
const trackGraphNodesRef =
|
|
2429
|
-
const rebuildTrackChain =
|
|
2452
|
+
const trackEffectInstancesRef = useRef10(/* @__PURE__ */ new Map());
|
|
2453
|
+
const trackGraphNodesRef = useRef10(/* @__PURE__ */ new Map());
|
|
2454
|
+
const rebuildTrackChain = useCallback13((trackId, trackEffects) => {
|
|
2430
2455
|
const nodes = trackGraphNodesRef.current.get(trackId);
|
|
2431
2456
|
if (!nodes) return;
|
|
2432
2457
|
const { graphEnd, masterGainNode } = nodes;
|
|
@@ -2456,7 +2481,7 @@ function useTrackDynamicEffects() {
|
|
|
2456
2481
|
currentNode.connect(masterGainNode);
|
|
2457
2482
|
}
|
|
2458
2483
|
}, []);
|
|
2459
|
-
const addEffectToTrack =
|
|
2484
|
+
const addEffectToTrack = useCallback13((trackId, effectId) => {
|
|
2460
2485
|
const definition = getEffectDefinition(effectId);
|
|
2461
2486
|
if (!definition) {
|
|
2462
2487
|
console.error(`Unknown effect: ${effectId}`);
|
|
@@ -2485,7 +2510,7 @@ function useTrackDynamicEffects() {
|
|
|
2485
2510
|
return newState;
|
|
2486
2511
|
});
|
|
2487
2512
|
}, []);
|
|
2488
|
-
const removeEffectFromTrack =
|
|
2513
|
+
const removeEffectFromTrack = useCallback13((trackId, instanceId) => {
|
|
2489
2514
|
const instancesMap = trackEffectInstancesRef.current.get(trackId);
|
|
2490
2515
|
const instance = instancesMap == null ? void 0 : instancesMap.get(instanceId);
|
|
2491
2516
|
if (instance) {
|
|
@@ -2502,7 +2527,7 @@ function useTrackDynamicEffects() {
|
|
|
2502
2527
|
return newState;
|
|
2503
2528
|
});
|
|
2504
2529
|
}, []);
|
|
2505
|
-
const updateTrackEffectParameter =
|
|
2530
|
+
const updateTrackEffectParameter = useCallback13(
|
|
2506
2531
|
(trackId, instanceId, paramName, value) => {
|
|
2507
2532
|
const instancesMap = trackEffectInstancesRef.current.get(trackId);
|
|
2508
2533
|
const instance = instancesMap == null ? void 0 : instancesMap.get(instanceId);
|
|
@@ -2523,7 +2548,7 @@ function useTrackDynamicEffects() {
|
|
|
2523
2548
|
},
|
|
2524
2549
|
[]
|
|
2525
2550
|
);
|
|
2526
|
-
const toggleBypass =
|
|
2551
|
+
const toggleBypass = useCallback13((trackId, instanceId) => {
|
|
2527
2552
|
var _a;
|
|
2528
2553
|
const trackEffects = trackEffectsStateRef.current.get(trackId) || [];
|
|
2529
2554
|
const effect = trackEffects.find((e) => e.instanceId === instanceId);
|
|
@@ -2545,7 +2570,7 @@ function useTrackDynamicEffects() {
|
|
|
2545
2570
|
return newState;
|
|
2546
2571
|
});
|
|
2547
2572
|
}, []);
|
|
2548
|
-
const clearTrackEffects =
|
|
2573
|
+
const clearTrackEffects = useCallback13((trackId) => {
|
|
2549
2574
|
const instancesMap = trackEffectInstancesRef.current.get(trackId);
|
|
2550
2575
|
if (instancesMap) {
|
|
2551
2576
|
instancesMap.forEach((inst) => inst.dispose());
|
|
@@ -2557,9 +2582,9 @@ function useTrackDynamicEffects() {
|
|
|
2557
2582
|
return newState;
|
|
2558
2583
|
});
|
|
2559
2584
|
}, []);
|
|
2560
|
-
const trackEffectsStateRef =
|
|
2585
|
+
const trackEffectsStateRef = useRef10(trackEffectsState);
|
|
2561
2586
|
trackEffectsStateRef.current = trackEffectsState;
|
|
2562
|
-
const getTrackEffectsFunction =
|
|
2587
|
+
const getTrackEffectsFunction = useCallback13(
|
|
2563
2588
|
(trackId) => {
|
|
2564
2589
|
return (graphEnd, masterGainNode, _isOffline) => {
|
|
2565
2590
|
trackGraphNodesRef.current.set(trackId, {
|
|
@@ -2602,7 +2627,7 @@ function useTrackDynamicEffects() {
|
|
|
2602
2627
|
trackEffectInstances.clear();
|
|
2603
2628
|
};
|
|
2604
2629
|
}, []);
|
|
2605
|
-
const createOfflineTrackEffectsFunction =
|
|
2630
|
+
const createOfflineTrackEffectsFunction = useCallback13(
|
|
2606
2631
|
(trackId) => {
|
|
2607
2632
|
const trackEffects = trackEffectsState.get(trackId) || [];
|
|
2608
2633
|
const nonBypassedEffects = trackEffects.filter((e) => !e.bypassed);
|
|
@@ -2646,7 +2671,7 @@ function useTrackDynamicEffects() {
|
|
|
2646
2671
|
}
|
|
2647
2672
|
|
|
2648
2673
|
// src/hooks/useExportWav.ts
|
|
2649
|
-
import { useState as
|
|
2674
|
+
import { useState as useState11, useCallback as useCallback14 } from "react";
|
|
2650
2675
|
import {
|
|
2651
2676
|
getUnderlyingAudioParam,
|
|
2652
2677
|
getGlobalAudioContext as getGlobalAudioContext2
|
|
@@ -2723,10 +2748,10 @@ function downloadBlob(blob, filename) {
|
|
|
2723
2748
|
|
|
2724
2749
|
// src/hooks/useExportWav.ts
|
|
2725
2750
|
function useExportWav() {
|
|
2726
|
-
const [isExporting, setIsExporting] =
|
|
2727
|
-
const [progress, setProgress] =
|
|
2728
|
-
const [error, setError] =
|
|
2729
|
-
const exportWav =
|
|
2751
|
+
const [isExporting, setIsExporting] = useState11(false);
|
|
2752
|
+
const [progress, setProgress] = useState11(0);
|
|
2753
|
+
const [error, setError] = useState11(null);
|
|
2754
|
+
const exportWav = useCallback14(
|
|
2730
2755
|
(_0, _1, ..._2) => __async(null, [_0, _1, ..._2], function* (tracks, trackStates, options = {}) {
|
|
2731
2756
|
const {
|
|
2732
2757
|
filename = "export",
|
|
@@ -3038,16 +3063,16 @@ function generateFadeCurve(startValue, endValue, numPoints, curveType) {
|
|
|
3038
3063
|
}
|
|
3039
3064
|
|
|
3040
3065
|
// src/hooks/useAnimationFrameLoop.ts
|
|
3041
|
-
import { useCallback as
|
|
3066
|
+
import { useCallback as useCallback15, useEffect as useEffect6, useRef as useRef11 } from "react";
|
|
3042
3067
|
var useAnimationFrameLoop = () => {
|
|
3043
|
-
const animationFrameRef =
|
|
3044
|
-
const stopAnimationFrameLoop =
|
|
3068
|
+
const animationFrameRef = useRef11(null);
|
|
3069
|
+
const stopAnimationFrameLoop = useCallback15(() => {
|
|
3045
3070
|
if (animationFrameRef.current !== null) {
|
|
3046
3071
|
cancelAnimationFrame(animationFrameRef.current);
|
|
3047
3072
|
animationFrameRef.current = null;
|
|
3048
3073
|
}
|
|
3049
3074
|
}, []);
|
|
3050
|
-
const startAnimationFrameLoop =
|
|
3075
|
+
const startAnimationFrameLoop = useCallback15(
|
|
3051
3076
|
(callback) => {
|
|
3052
3077
|
stopAnimationFrameLoop();
|
|
3053
3078
|
animationFrameRef.current = requestAnimationFrame(callback);
|
|
@@ -3067,7 +3092,7 @@ var useAnimationFrameLoop = () => {
|
|
|
3067
3092
|
};
|
|
3068
3093
|
|
|
3069
3094
|
// src/hooks/useWaveformDataCache.ts
|
|
3070
|
-
import { useState as
|
|
3095
|
+
import { useState as useState12, useEffect as useEffect7, useRef as useRef12, useCallback as useCallback16 } from "react";
|
|
3071
3096
|
|
|
3072
3097
|
// src/workers/peaksWorker.ts
|
|
3073
3098
|
import WaveformData2 from "waveform-data";
|
|
@@ -3299,14 +3324,14 @@ function createPeaksWorker() {
|
|
|
3299
3324
|
|
|
3300
3325
|
// src/hooks/useWaveformDataCache.ts
|
|
3301
3326
|
function useWaveformDataCache(tracks, baseScale) {
|
|
3302
|
-
const [cache, setCache] =
|
|
3303
|
-
const [isGenerating, setIsGenerating] =
|
|
3304
|
-
const workerRef =
|
|
3305
|
-
const generatedByBufferRef =
|
|
3306
|
-
const inflightByBufferRef =
|
|
3307
|
-
const subscribersByBufferRef =
|
|
3308
|
-
const pendingCountRef =
|
|
3309
|
-
const getWorker =
|
|
3327
|
+
const [cache, setCache] = useState12(() => /* @__PURE__ */ new Map());
|
|
3328
|
+
const [isGenerating, setIsGenerating] = useState12(false);
|
|
3329
|
+
const workerRef = useRef12(null);
|
|
3330
|
+
const generatedByBufferRef = useRef12(/* @__PURE__ */ new WeakMap());
|
|
3331
|
+
const inflightByBufferRef = useRef12(/* @__PURE__ */ new WeakMap());
|
|
3332
|
+
const subscribersByBufferRef = useRef12(/* @__PURE__ */ new WeakMap());
|
|
3333
|
+
const pendingCountRef = useRef12(0);
|
|
3334
|
+
const getWorker = useCallback16(() => {
|
|
3310
3335
|
if (!workerRef.current) {
|
|
3311
3336
|
workerRef.current = createPeaksWorker();
|
|
3312
3337
|
}
|
|
@@ -3428,7 +3453,7 @@ function useWaveformDataCache(tracks, baseScale) {
|
|
|
3428
3453
|
}
|
|
3429
3454
|
|
|
3430
3455
|
// src/hooks/useDynamicTracks.ts
|
|
3431
|
-
import { useState as
|
|
3456
|
+
import { useState as useState13, useCallback as useCallback17, useRef as useRef13, useEffect as useEffect8 } from "react";
|
|
3432
3457
|
import { createTrack as createTrack2, createClipFromSeconds as createClipFromSeconds2 } from "@waveform-playlist/core";
|
|
3433
3458
|
import { getGlobalAudioContext as getGlobalAudioContext3 } from "@waveform-playlist/playout";
|
|
3434
3459
|
function getSourceName(source) {
|
|
@@ -3463,12 +3488,12 @@ function decodeSource(source, audioContext, signal) {
|
|
|
3463
3488
|
});
|
|
3464
3489
|
}
|
|
3465
3490
|
function useDynamicTracks() {
|
|
3466
|
-
const [tracks, setTracks] =
|
|
3467
|
-
const [loadingCount, setLoadingCount] =
|
|
3468
|
-
const [errors, setErrors] =
|
|
3469
|
-
const cancelledRef =
|
|
3470
|
-
const loadingIdsRef =
|
|
3471
|
-
const abortControllersRef =
|
|
3491
|
+
const [tracks, setTracks] = useState13([]);
|
|
3492
|
+
const [loadingCount, setLoadingCount] = useState13(0);
|
|
3493
|
+
const [errors, setErrors] = useState13([]);
|
|
3494
|
+
const cancelledRef = useRef13(false);
|
|
3495
|
+
const loadingIdsRef = useRef13(/* @__PURE__ */ new Set());
|
|
3496
|
+
const abortControllersRef = useRef13(/* @__PURE__ */ new Map());
|
|
3472
3497
|
useEffect8(() => {
|
|
3473
3498
|
const controllers = abortControllersRef.current;
|
|
3474
3499
|
return () => {
|
|
@@ -3479,7 +3504,7 @@ function useDynamicTracks() {
|
|
|
3479
3504
|
controllers.clear();
|
|
3480
3505
|
};
|
|
3481
3506
|
}, []);
|
|
3482
|
-
const addTracks =
|
|
3507
|
+
const addTracks = useCallback17((sources) => {
|
|
3483
3508
|
if (sources.length === 0) return;
|
|
3484
3509
|
const audioContext = getGlobalAudioContext3();
|
|
3485
3510
|
const placeholders = sources.map((source) => ({
|
|
@@ -3529,7 +3554,7 @@ function useDynamicTracks() {
|
|
|
3529
3554
|
}))();
|
|
3530
3555
|
}
|
|
3531
3556
|
}, []);
|
|
3532
|
-
const removeTrack =
|
|
3557
|
+
const removeTrack = useCallback17((trackId) => {
|
|
3533
3558
|
setTracks((prev) => prev.filter((t) => t.id !== trackId));
|
|
3534
3559
|
const controller = abortControllersRef.current.get(trackId);
|
|
3535
3560
|
if (controller) {
|
|
@@ -3551,20 +3576,20 @@ function useDynamicTracks() {
|
|
|
3551
3576
|
}
|
|
3552
3577
|
|
|
3553
3578
|
// src/hooks/useOutputMeter.ts
|
|
3554
|
-
import { useEffect as useEffect9, useState as
|
|
3579
|
+
import { useEffect as useEffect9, useState as useState14, useRef as useRef14, useCallback as useCallback18 } from "react";
|
|
3555
3580
|
import { getGlobalContext } from "@waveform-playlist/playout";
|
|
3556
3581
|
import { gainToNormalized } from "@waveform-playlist/core";
|
|
3557
3582
|
import { meterProcessorUrl } from "@waveform-playlist/worklets";
|
|
3558
3583
|
var PEAK_DECAY = 0.98;
|
|
3559
3584
|
function useOutputMeter(options = {}) {
|
|
3560
3585
|
const { channelCount = 2, updateRate = 60, isPlaying = false } = options;
|
|
3561
|
-
const [levels, setLevels] =
|
|
3562
|
-
const [peakLevels, setPeakLevels] =
|
|
3563
|
-
const [rmsLevels, setRmsLevels] =
|
|
3564
|
-
const workletNodeRef =
|
|
3565
|
-
const smoothedPeakRef =
|
|
3566
|
-
const [meterError, setMeterError] =
|
|
3567
|
-
const resetPeak =
|
|
3586
|
+
const [levels, setLevels] = useState14(() => new Array(channelCount).fill(0));
|
|
3587
|
+
const [peakLevels, setPeakLevels] = useState14(() => new Array(channelCount).fill(0));
|
|
3588
|
+
const [rmsLevels, setRmsLevels] = useState14(() => new Array(channelCount).fill(0));
|
|
3589
|
+
const workletNodeRef = useRef14(null);
|
|
3590
|
+
const smoothedPeakRef = useRef14(new Array(channelCount).fill(0));
|
|
3591
|
+
const [meterError, setMeterError] = useState14(null);
|
|
3592
|
+
const resetPeak = useCallback18(
|
|
3568
3593
|
() => setPeakLevels(new Array(channelCount).fill(0)),
|
|
3569
3594
|
[channelCount]
|
|
3570
3595
|
);
|
|
@@ -3679,7 +3704,7 @@ var WaveformPlaylistProvider = ({
|
|
|
3679
3704
|
}) => {
|
|
3680
3705
|
var _a, _b, _c, _d;
|
|
3681
3706
|
const progressBarWidth = progressBarWidthProp != null ? progressBarWidthProp : barWidth + barGap;
|
|
3682
|
-
const indefinitePlaybackRef =
|
|
3707
|
+
const indefinitePlaybackRef = useRef15(indefinitePlayback);
|
|
3683
3708
|
indefinitePlaybackRef.current = indefinitePlayback;
|
|
3684
3709
|
const stableZoomLevels = useMemo4(
|
|
3685
3710
|
() => zoomLevels,
|
|
@@ -3699,46 +3724,46 @@ var WaveformPlaylistProvider = ({
|
|
|
3699
3724
|
}
|
|
3700
3725
|
return annotationList.annotations;
|
|
3701
3726
|
}, [annotationList == null ? void 0 : annotationList.annotations]);
|
|
3702
|
-
const annotationsRef =
|
|
3727
|
+
const annotationsRef = useRef15(annotations);
|
|
3703
3728
|
annotationsRef.current = annotations;
|
|
3704
|
-
const [activeAnnotationId, setActiveAnnotationIdState] =
|
|
3705
|
-
const [isPlaying, setIsPlaying] =
|
|
3706
|
-
const [currentTime, setCurrentTime] =
|
|
3707
|
-
const [duration, setDuration] =
|
|
3708
|
-
const [audioBuffers, setAudioBuffers] =
|
|
3709
|
-
const [peaksDataArray, setPeaksDataArray] =
|
|
3710
|
-
const [trackStates, setTrackStates] =
|
|
3711
|
-
const [isAutomaticScroll, setIsAutomaticScroll] =
|
|
3712
|
-
const [continuousPlay, setContinuousPlayState] =
|
|
3729
|
+
const [activeAnnotationId, setActiveAnnotationIdState] = useState15(null);
|
|
3730
|
+
const [isPlaying, setIsPlaying] = useState15(false);
|
|
3731
|
+
const [currentTime, setCurrentTime] = useState15(0);
|
|
3732
|
+
const [duration, setDuration] = useState15(0);
|
|
3733
|
+
const [audioBuffers, setAudioBuffers] = useState15([]);
|
|
3734
|
+
const [peaksDataArray, setPeaksDataArray] = useState15([]);
|
|
3735
|
+
const [trackStates, setTrackStates] = useState15([]);
|
|
3736
|
+
const [isAutomaticScroll, setIsAutomaticScroll] = useState15(automaticScroll);
|
|
3737
|
+
const [continuousPlay, setContinuousPlayState] = useState15(
|
|
3713
3738
|
(_a = annotationList == null ? void 0 : annotationList.isContinuousPlay) != null ? _a : false
|
|
3714
3739
|
);
|
|
3715
|
-
const [linkEndpoints, setLinkEndpoints] =
|
|
3716
|
-
const [annotationsEditable, setAnnotationsEditable] =
|
|
3717
|
-
const [isReady, setIsReady] =
|
|
3718
|
-
const engineRef =
|
|
3719
|
-
const audioInitializedRef =
|
|
3720
|
-
const isPlayingRef =
|
|
3740
|
+
const [linkEndpoints, setLinkEndpoints] = useState15((_b = annotationList == null ? void 0 : annotationList.linkEndpoints) != null ? _b : false);
|
|
3741
|
+
const [annotationsEditable, setAnnotationsEditable] = useState15((_c = annotationList == null ? void 0 : annotationList.editable) != null ? _c : false);
|
|
3742
|
+
const [isReady, setIsReady] = useState15(false);
|
|
3743
|
+
const engineRef = useRef15(null);
|
|
3744
|
+
const audioInitializedRef = useRef15(false);
|
|
3745
|
+
const isPlayingRef = useRef15(false);
|
|
3721
3746
|
isPlayingRef.current = isPlaying;
|
|
3722
|
-
const playStartPositionRef =
|
|
3723
|
-
const currentTimeRef =
|
|
3724
|
-
const tracksRef =
|
|
3725
|
-
const soundFontCacheRef =
|
|
3747
|
+
const playStartPositionRef = useRef15(0);
|
|
3748
|
+
const currentTimeRef = useRef15(0);
|
|
3749
|
+
const tracksRef = useRef15(tracks);
|
|
3750
|
+
const soundFontCacheRef = useRef15(soundFontCache);
|
|
3726
3751
|
soundFontCacheRef.current = soundFontCache;
|
|
3727
|
-
const trackStatesRef =
|
|
3728
|
-
const playbackStartTimeRef =
|
|
3729
|
-
const audioStartPositionRef =
|
|
3730
|
-
const playbackEndTimeRef =
|
|
3731
|
-
const scrollContainerRef =
|
|
3732
|
-
const isAutomaticScrollRef =
|
|
3733
|
-
const continuousPlayRef =
|
|
3734
|
-
const activeAnnotationIdRef =
|
|
3735
|
-
const engineTracksRef =
|
|
3736
|
-
const lastTracksVersionRef =
|
|
3737
|
-
const skipEngineDisposeRef =
|
|
3738
|
-
const isDraggingRef =
|
|
3739
|
-
const prevTracksRef =
|
|
3740
|
-
const samplesPerPixelRef =
|
|
3741
|
-
const sampleRateRef =
|
|
3752
|
+
const trackStatesRef = useRef15(trackStates);
|
|
3753
|
+
const playbackStartTimeRef = useRef15(0);
|
|
3754
|
+
const audioStartPositionRef = useRef15(0);
|
|
3755
|
+
const playbackEndTimeRef = useRef15(null);
|
|
3756
|
+
const scrollContainerRef = useRef15(null);
|
|
3757
|
+
const isAutomaticScrollRef = useRef15(false);
|
|
3758
|
+
const continuousPlayRef = useRef15((_d = annotationList == null ? void 0 : annotationList.isContinuousPlay) != null ? _d : false);
|
|
3759
|
+
const activeAnnotationIdRef = useRef15(null);
|
|
3760
|
+
const engineTracksRef = useRef15(null);
|
|
3761
|
+
const lastTracksVersionRef = useRef15(0);
|
|
3762
|
+
const skipEngineDisposeRef = useRef15(false);
|
|
3763
|
+
const isDraggingRef = useRef15(false);
|
|
3764
|
+
const prevTracksRef = useRef15([]);
|
|
3765
|
+
const samplesPerPixelRef = useRef15(initialSamplesPerPixel);
|
|
3766
|
+
const sampleRateRef = useRef15(
|
|
3742
3767
|
typeof AudioContext !== "undefined" ? getGlobalAudioContext4().sampleRate : 48e3
|
|
3743
3768
|
);
|
|
3744
3769
|
const { timeFormat, setTimeFormat, formatTime: formatTime2 } = useTimeFormat();
|
|
@@ -3777,21 +3802,28 @@ var WaveformPlaylistProvider = ({
|
|
|
3777
3802
|
onEngineState: onSelectedTrackEngineState,
|
|
3778
3803
|
selectedTrackIdRef
|
|
3779
3804
|
} = useSelectedTrack({ engineRef });
|
|
3805
|
+
const {
|
|
3806
|
+
canUndo,
|
|
3807
|
+
canRedo,
|
|
3808
|
+
undo,
|
|
3809
|
+
redo,
|
|
3810
|
+
onEngineState: onUndoEngineState
|
|
3811
|
+
} = useUndoState({ engineRef });
|
|
3780
3812
|
const { animationFrameRef, startAnimationFrameLoop, stopAnimationFrameLoop } = useAnimationFrameLoop();
|
|
3781
3813
|
const baseScale = useMemo4(
|
|
3782
3814
|
() => Math.min(...stableZoomLevels != null ? stableZoomLevels : [256, 512, 1024, 2048, 4096, 8192]),
|
|
3783
3815
|
[stableZoomLevels]
|
|
3784
3816
|
);
|
|
3785
3817
|
const { cache: waveformDataCache } = useWaveformDataCache(tracks, baseScale);
|
|
3786
|
-
const setContinuousPlay =
|
|
3818
|
+
const setContinuousPlay = useCallback19((value) => {
|
|
3787
3819
|
continuousPlayRef.current = value;
|
|
3788
3820
|
setContinuousPlayState(value);
|
|
3789
3821
|
}, []);
|
|
3790
|
-
const setActiveAnnotationId =
|
|
3822
|
+
const setActiveAnnotationId = useCallback19((value) => {
|
|
3791
3823
|
activeAnnotationIdRef.current = value;
|
|
3792
3824
|
setActiveAnnotationIdState(value);
|
|
3793
3825
|
}, []);
|
|
3794
|
-
const setLoopRegionFromSelection =
|
|
3826
|
+
const setLoopRegionFromSelection = useCallback19(() => {
|
|
3795
3827
|
var _a2, _b2;
|
|
3796
3828
|
const start = (_a2 = selectionStartRef.current) != null ? _a2 : 0;
|
|
3797
3829
|
const end = (_b2 = selectionEndRef.current) != null ? _b2 : 0;
|
|
@@ -3829,7 +3861,7 @@ var WaveformPlaylistProvider = ({
|
|
|
3829
3861
|
container.scrollLeft = newScrollLeft;
|
|
3830
3862
|
samplesPerPixelRef.current = newSamplesPerPixel;
|
|
3831
3863
|
}, [samplesPerPixel, duration]);
|
|
3832
|
-
const pendingResumeRef =
|
|
3864
|
+
const pendingResumeRef = useRef15(null);
|
|
3833
3865
|
useEffect10(() => {
|
|
3834
3866
|
var _a2, _b2, _c2, _d2;
|
|
3835
3867
|
if (isEngineTracks || isDraggingRef.current) {
|
|
@@ -4005,6 +4037,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4005
4037
|
onSelectedTrackEngineState(state);
|
|
4006
4038
|
onZoomEngineState(state);
|
|
4007
4039
|
onVolumeEngineState(state);
|
|
4040
|
+
onUndoEngineState(state);
|
|
4008
4041
|
if (!suppressTracksMirroring && state.tracksVersion !== lastTracksVersionRef.current) {
|
|
4009
4042
|
lastTracksVersionRef.current = state.tracksVersion;
|
|
4010
4043
|
engineTracksRef.current = state.tracks;
|
|
@@ -4062,6 +4095,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4062
4095
|
onSelectedTrackEngineState,
|
|
4063
4096
|
onZoomEngineState,
|
|
4064
4097
|
onVolumeEngineState,
|
|
4098
|
+
onUndoEngineState,
|
|
4065
4099
|
onTracksChange,
|
|
4066
4100
|
masterVolumeRef,
|
|
4067
4101
|
selectionStartRef,
|
|
@@ -4139,8 +4173,8 @@ var WaveformPlaylistProvider = ({
|
|
|
4139
4173
|
});
|
|
4140
4174
|
setPeaksDataArray(allTrackPeaks);
|
|
4141
4175
|
}, [tracks, samplesPerPixel, mono, waveformDataCache, deferEngineRebuild]);
|
|
4142
|
-
const getPlaybackTimeFallbackWarnedRef =
|
|
4143
|
-
const getPlaybackTime =
|
|
4176
|
+
const getPlaybackTimeFallbackWarnedRef = useRef15(false);
|
|
4177
|
+
const getPlaybackTime = useCallback19(() => {
|
|
4144
4178
|
var _a2, _b2;
|
|
4145
4179
|
if (engineRef.current) {
|
|
4146
4180
|
return engineRef.current.getCurrentTime();
|
|
@@ -4154,7 +4188,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4154
4188
|
const elapsed = getContext2().currentTime - ((_a2 = playbackStartTimeRef.current) != null ? _a2 : 0);
|
|
4155
4189
|
return ((_b2 = audioStartPositionRef.current) != null ? _b2 : 0) + elapsed;
|
|
4156
4190
|
}, []);
|
|
4157
|
-
const startAnimationLoop =
|
|
4191
|
+
const startAnimationLoop = useCallback19(() => {
|
|
4158
4192
|
const updateTime = () => {
|
|
4159
4193
|
const time = getPlaybackTime();
|
|
4160
4194
|
currentTimeRef.current = time;
|
|
@@ -4272,7 +4306,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4272
4306
|
stopAnimationLoop();
|
|
4273
4307
|
});
|
|
4274
4308
|
}, [tracks, startAnimationLoop, stopAnimationLoop]);
|
|
4275
|
-
const play =
|
|
4309
|
+
const play = useCallback19(
|
|
4276
4310
|
(startTime, playDuration) => __async(null, null, function* () {
|
|
4277
4311
|
if (!engineRef.current) return;
|
|
4278
4312
|
const actualStartTime = startTime != null ? startTime : currentTimeRef.current;
|
|
@@ -4303,7 +4337,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4303
4337
|
}),
|
|
4304
4338
|
[startAnimationLoop, stopAnimationLoop]
|
|
4305
4339
|
);
|
|
4306
|
-
const pause =
|
|
4340
|
+
const pause = useCallback19(() => {
|
|
4307
4341
|
if (!engineRef.current) return;
|
|
4308
4342
|
const pauseTime = getPlaybackTime();
|
|
4309
4343
|
engineRef.current.pause();
|
|
@@ -4312,7 +4346,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4312
4346
|
currentTimeRef.current = pauseTime;
|
|
4313
4347
|
setCurrentTime(pauseTime);
|
|
4314
4348
|
}, [stopAnimationLoop, getPlaybackTime]);
|
|
4315
|
-
const stop =
|
|
4349
|
+
const stop = useCallback19(() => {
|
|
4316
4350
|
if (!engineRef.current) return;
|
|
4317
4351
|
engineRef.current.stop();
|
|
4318
4352
|
setIsPlaying(false);
|
|
@@ -4321,7 +4355,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4321
4355
|
setCurrentTime(playStartPositionRef.current);
|
|
4322
4356
|
setActiveAnnotationId(null);
|
|
4323
4357
|
}, [stopAnimationLoop, setActiveAnnotationId]);
|
|
4324
|
-
const seekTo =
|
|
4358
|
+
const seekTo = useCallback19(
|
|
4325
4359
|
(time) => {
|
|
4326
4360
|
const clampedTime = Math.max(0, Math.min(time, duration));
|
|
4327
4361
|
currentTimeRef.current = clampedTime;
|
|
@@ -4332,7 +4366,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4332
4366
|
},
|
|
4333
4367
|
[duration, isPlaying, play]
|
|
4334
4368
|
);
|
|
4335
|
-
const setTrackMute =
|
|
4369
|
+
const setTrackMute = useCallback19(
|
|
4336
4370
|
(trackIndex, muted) => {
|
|
4337
4371
|
var _a2;
|
|
4338
4372
|
const trackId = (_a2 = tracksRef.current[trackIndex]) == null ? void 0 : _a2.id;
|
|
@@ -4346,7 +4380,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4346
4380
|
},
|
|
4347
4381
|
[trackStates]
|
|
4348
4382
|
);
|
|
4349
|
-
const setTrackSolo =
|
|
4383
|
+
const setTrackSolo = useCallback19(
|
|
4350
4384
|
(trackIndex, soloed) => {
|
|
4351
4385
|
var _a2;
|
|
4352
4386
|
const trackId = (_a2 = tracksRef.current[trackIndex]) == null ? void 0 : _a2.id;
|
|
@@ -4360,7 +4394,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4360
4394
|
},
|
|
4361
4395
|
[trackStates]
|
|
4362
4396
|
);
|
|
4363
|
-
const setTrackVolume =
|
|
4397
|
+
const setTrackVolume = useCallback19(
|
|
4364
4398
|
(trackIndex, volume2) => {
|
|
4365
4399
|
var _a2;
|
|
4366
4400
|
const trackId = (_a2 = tracksRef.current[trackIndex]) == null ? void 0 : _a2.id;
|
|
@@ -4374,7 +4408,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4374
4408
|
},
|
|
4375
4409
|
[trackStates]
|
|
4376
4410
|
);
|
|
4377
|
-
const setTrackPan =
|
|
4411
|
+
const setTrackPan = useCallback19(
|
|
4378
4412
|
(trackIndex, pan) => {
|
|
4379
4413
|
var _a2;
|
|
4380
4414
|
const trackId = (_a2 = tracksRef.current[trackIndex]) == null ? void 0 : _a2.id;
|
|
@@ -4388,7 +4422,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4388
4422
|
},
|
|
4389
4423
|
[trackStates]
|
|
4390
4424
|
);
|
|
4391
|
-
const setSelection =
|
|
4425
|
+
const setSelection = useCallback19(
|
|
4392
4426
|
(start, end) => {
|
|
4393
4427
|
setSelectionEngine(start, end);
|
|
4394
4428
|
currentTimeRef.current = start;
|
|
@@ -4401,12 +4435,12 @@ var WaveformPlaylistProvider = ({
|
|
|
4401
4435
|
},
|
|
4402
4436
|
[isPlaying, setSelectionEngine]
|
|
4403
4437
|
);
|
|
4404
|
-
const setScrollContainer =
|
|
4438
|
+
const setScrollContainer = useCallback19((element) => {
|
|
4405
4439
|
scrollContainerRef.current = element;
|
|
4406
4440
|
}, []);
|
|
4407
|
-
const onAnnotationsChangeRef =
|
|
4441
|
+
const onAnnotationsChangeRef = useRef15(onAnnotationsChange);
|
|
4408
4442
|
onAnnotationsChangeRef.current = onAnnotationsChange;
|
|
4409
|
-
const setAnnotations =
|
|
4443
|
+
const setAnnotations = useCallback19(
|
|
4410
4444
|
(action) => {
|
|
4411
4445
|
const updated = typeof action === "function" ? action(annotationsRef.current) : action;
|
|
4412
4446
|
if (!onAnnotationsChangeRef.current) {
|
|
@@ -4456,7 +4490,9 @@ var WaveformPlaylistProvider = ({
|
|
|
4456
4490
|
selectedTrackId,
|
|
4457
4491
|
loopStart,
|
|
4458
4492
|
loopEnd,
|
|
4459
|
-
indefinitePlayback
|
|
4493
|
+
indefinitePlayback,
|
|
4494
|
+
canUndo,
|
|
4495
|
+
canRedo
|
|
4460
4496
|
}),
|
|
4461
4497
|
[
|
|
4462
4498
|
continuousPlay,
|
|
@@ -4471,17 +4507,19 @@ var WaveformPlaylistProvider = ({
|
|
|
4471
4507
|
selectedTrackId,
|
|
4472
4508
|
loopStart,
|
|
4473
4509
|
loopEnd,
|
|
4474
|
-
indefinitePlayback
|
|
4510
|
+
indefinitePlayback,
|
|
4511
|
+
canUndo,
|
|
4512
|
+
canRedo
|
|
4475
4513
|
]
|
|
4476
4514
|
);
|
|
4477
|
-
const setCurrentTimeControl =
|
|
4515
|
+
const setCurrentTimeControl = useCallback19(
|
|
4478
4516
|
(time) => {
|
|
4479
4517
|
currentTimeRef.current = time;
|
|
4480
4518
|
setCurrentTime(time);
|
|
4481
4519
|
},
|
|
4482
4520
|
[currentTimeRef]
|
|
4483
4521
|
);
|
|
4484
|
-
const setAutomaticScrollControl =
|
|
4522
|
+
const setAutomaticScrollControl = useCallback19((enabled) => {
|
|
4485
4523
|
setIsAutomaticScroll(enabled);
|
|
4486
4524
|
}, []);
|
|
4487
4525
|
const controlsValue = useMemo4(
|
|
@@ -4522,7 +4560,10 @@ var WaveformPlaylistProvider = ({
|
|
|
4522
4560
|
setLoopEnabled,
|
|
4523
4561
|
setLoopRegion,
|
|
4524
4562
|
setLoopRegionFromSelection,
|
|
4525
|
-
clearLoopRegion
|
|
4563
|
+
clearLoopRegion,
|
|
4564
|
+
// Undo/redo
|
|
4565
|
+
undo,
|
|
4566
|
+
redo
|
|
4526
4567
|
}),
|
|
4527
4568
|
[
|
|
4528
4569
|
play,
|
|
@@ -4552,7 +4593,9 @@ var WaveformPlaylistProvider = ({
|
|
|
4552
4593
|
setLoopEnabled,
|
|
4553
4594
|
setLoopRegion,
|
|
4554
4595
|
setLoopRegionFromSelection,
|
|
4555
|
-
clearLoopRegion
|
|
4596
|
+
clearLoopRegion,
|
|
4597
|
+
undo,
|
|
4598
|
+
redo
|
|
4556
4599
|
]
|
|
4557
4600
|
);
|
|
4558
4601
|
const dataValue = useMemo4(
|
|
@@ -4643,10 +4686,10 @@ var usePlaylistData = () => {
|
|
|
4643
4686
|
import {
|
|
4644
4687
|
createContext as createContext2,
|
|
4645
4688
|
useContext as useContext2,
|
|
4646
|
-
useState as
|
|
4689
|
+
useState as useState16,
|
|
4647
4690
|
useEffect as useEffect11,
|
|
4648
|
-
useRef as
|
|
4649
|
-
useCallback as
|
|
4691
|
+
useRef as useRef16,
|
|
4692
|
+
useCallback as useCallback20,
|
|
4650
4693
|
useMemo as useMemo5
|
|
4651
4694
|
} from "react";
|
|
4652
4695
|
import { ThemeProvider as ThemeProvider2 } from "styled-components";
|
|
@@ -4678,11 +4721,11 @@ var MediaElementPlaylistProvider = ({
|
|
|
4678
4721
|
}) => {
|
|
4679
4722
|
var _a;
|
|
4680
4723
|
const progressBarWidth = progressBarWidthProp != null ? progressBarWidthProp : barWidth + barGap;
|
|
4681
|
-
const [isPlaying, setIsPlaying] =
|
|
4682
|
-
const [currentTime, setCurrentTime] =
|
|
4683
|
-
const [duration, setDuration] =
|
|
4684
|
-
const [peaksDataArray, setPeaksDataArray] =
|
|
4685
|
-
const [playbackRate, setPlaybackRateState] =
|
|
4724
|
+
const [isPlaying, setIsPlaying] = useState16(false);
|
|
4725
|
+
const [currentTime, setCurrentTime] = useState16(0);
|
|
4726
|
+
const [duration, setDuration] = useState16(0);
|
|
4727
|
+
const [peaksDataArray, setPeaksDataArray] = useState16([]);
|
|
4728
|
+
const [playbackRate, setPlaybackRateState] = useState16(initialPlaybackRate);
|
|
4686
4729
|
const annotations = useMemo5(() => {
|
|
4687
4730
|
if (!(annotationList == null ? void 0 : annotationList.annotations)) return [];
|
|
4688
4731
|
if (process.env.NODE_ENV !== "production" && annotationList.annotations.length > 0) {
|
|
@@ -4696,21 +4739,21 @@ var MediaElementPlaylistProvider = ({
|
|
|
4696
4739
|
}
|
|
4697
4740
|
return annotationList.annotations;
|
|
4698
4741
|
}, [annotationList == null ? void 0 : annotationList.annotations]);
|
|
4699
|
-
const annotationsRef =
|
|
4742
|
+
const annotationsRef = useRef16(annotations);
|
|
4700
4743
|
annotationsRef.current = annotations;
|
|
4701
|
-
const [activeAnnotationId, setActiveAnnotationIdState] =
|
|
4702
|
-
const [continuousPlay, setContinuousPlayState] =
|
|
4744
|
+
const [activeAnnotationId, setActiveAnnotationIdState] = useState16(null);
|
|
4745
|
+
const [continuousPlay, setContinuousPlayState] = useState16(
|
|
4703
4746
|
(_a = annotationList == null ? void 0 : annotationList.isContinuousPlay) != null ? _a : false
|
|
4704
4747
|
);
|
|
4705
|
-
const [samplesPerPixel] =
|
|
4706
|
-
const [isAutomaticScroll, setIsAutomaticScroll] =
|
|
4707
|
-
const playoutRef =
|
|
4708
|
-
const currentTimeRef =
|
|
4709
|
-
const continuousPlayRef =
|
|
4710
|
-
const activeAnnotationIdRef =
|
|
4711
|
-
const scrollContainerRef =
|
|
4712
|
-
const isAutomaticScrollRef =
|
|
4713
|
-
const samplesPerPixelRef =
|
|
4748
|
+
const [samplesPerPixel] = useState16(initialSamplesPerPixel);
|
|
4749
|
+
const [isAutomaticScroll, setIsAutomaticScroll] = useState16(automaticScroll);
|
|
4750
|
+
const playoutRef = useRef16(null);
|
|
4751
|
+
const currentTimeRef = useRef16(0);
|
|
4752
|
+
const continuousPlayRef = useRef16(continuousPlay);
|
|
4753
|
+
const activeAnnotationIdRef = useRef16(null);
|
|
4754
|
+
const scrollContainerRef = useRef16(null);
|
|
4755
|
+
const isAutomaticScrollRef = useRef16(automaticScroll);
|
|
4756
|
+
const samplesPerPixelRef = useRef16(initialSamplesPerPixel);
|
|
4714
4757
|
const { startAnimationFrameLoop, stopAnimationFrameLoop } = useAnimationFrameLoop();
|
|
4715
4758
|
useEffect11(() => {
|
|
4716
4759
|
continuousPlayRef.current = continuousPlay;
|
|
@@ -4718,15 +4761,15 @@ var MediaElementPlaylistProvider = ({
|
|
|
4718
4761
|
useEffect11(() => {
|
|
4719
4762
|
isAutomaticScrollRef.current = isAutomaticScroll;
|
|
4720
4763
|
}, [isAutomaticScroll]);
|
|
4721
|
-
const setActiveAnnotationId =
|
|
4764
|
+
const setActiveAnnotationId = useCallback20((value) => {
|
|
4722
4765
|
activeAnnotationIdRef.current = value;
|
|
4723
4766
|
setActiveAnnotationIdState(value);
|
|
4724
4767
|
}, []);
|
|
4725
|
-
const setContinuousPlay =
|
|
4768
|
+
const setContinuousPlay = useCallback20((value) => {
|
|
4726
4769
|
continuousPlayRef.current = value;
|
|
4727
4770
|
setContinuousPlayState(value);
|
|
4728
4771
|
}, []);
|
|
4729
|
-
const setScrollContainer =
|
|
4772
|
+
const setScrollContainer = useCallback20((element) => {
|
|
4730
4773
|
scrollContainerRef.current = element;
|
|
4731
4774
|
}, []);
|
|
4732
4775
|
const sampleRate = track.waveformData.sample_rate;
|
|
@@ -4806,7 +4849,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4806
4849
|
console.warn("[waveform-playlist] Failed to extract peaks from waveform data:", err);
|
|
4807
4850
|
}
|
|
4808
4851
|
}, [track.waveformData, track.name, samplesPerPixel, sampleRate]);
|
|
4809
|
-
const startAnimationLoop =
|
|
4852
|
+
const startAnimationLoop = useCallback20(() => {
|
|
4810
4853
|
const updateTime = () => {
|
|
4811
4854
|
var _a2, _b, _c;
|
|
4812
4855
|
const time = (_b = (_a2 = playoutRef.current) == null ? void 0 : _a2.getCurrentTime()) != null ? _b : 0;
|
|
@@ -4849,7 +4892,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4849
4892
|
startAnimationFrameLoop(updateTime);
|
|
4850
4893
|
}, [setActiveAnnotationId, sampleRate, startAnimationFrameLoop]);
|
|
4851
4894
|
const stopAnimationLoop = stopAnimationFrameLoop;
|
|
4852
|
-
const play =
|
|
4895
|
+
const play = useCallback20(
|
|
4853
4896
|
(startTime) => {
|
|
4854
4897
|
if (!playoutRef.current) return;
|
|
4855
4898
|
const actualStartTime = startTime != null ? startTime : currentTimeRef.current;
|
|
@@ -4859,14 +4902,14 @@ var MediaElementPlaylistProvider = ({
|
|
|
4859
4902
|
},
|
|
4860
4903
|
[startAnimationLoop]
|
|
4861
4904
|
);
|
|
4862
|
-
const pause =
|
|
4905
|
+
const pause = useCallback20(() => {
|
|
4863
4906
|
if (!playoutRef.current) return;
|
|
4864
4907
|
playoutRef.current.pause();
|
|
4865
4908
|
setIsPlaying(false);
|
|
4866
4909
|
stopAnimationLoop();
|
|
4867
4910
|
setCurrentTime(playoutRef.current.getCurrentTime());
|
|
4868
4911
|
}, [stopAnimationLoop]);
|
|
4869
|
-
const stop =
|
|
4912
|
+
const stop = useCallback20(() => {
|
|
4870
4913
|
if (!playoutRef.current) return;
|
|
4871
4914
|
playoutRef.current.stop();
|
|
4872
4915
|
setIsPlaying(false);
|
|
@@ -4875,7 +4918,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4875
4918
|
setCurrentTime(0);
|
|
4876
4919
|
setActiveAnnotationId(null);
|
|
4877
4920
|
}, [stopAnimationLoop, setActiveAnnotationId]);
|
|
4878
|
-
const seekTo =
|
|
4921
|
+
const seekTo = useCallback20(
|
|
4879
4922
|
(time) => {
|
|
4880
4923
|
const clampedTime = Math.max(0, Math.min(time, duration));
|
|
4881
4924
|
currentTimeRef.current = clampedTime;
|
|
@@ -4886,7 +4929,7 @@ var MediaElementPlaylistProvider = ({
|
|
|
4886
4929
|
},
|
|
4887
4930
|
[duration]
|
|
4888
4931
|
);
|
|
4889
|
-
const setPlaybackRate =
|
|
4932
|
+
const setPlaybackRate = useCallback20((rate) => {
|
|
4890
4933
|
const clampedRate = Math.max(0.5, Math.min(2, rate));
|
|
4891
4934
|
setPlaybackRateState(clampedRate);
|
|
4892
4935
|
if (playoutRef.current) {
|
|
@@ -4912,9 +4955,9 @@ var MediaElementPlaylistProvider = ({
|
|
|
4912
4955
|
}),
|
|
4913
4956
|
[continuousPlay, annotations, activeAnnotationId, playbackRate, isAutomaticScroll]
|
|
4914
4957
|
);
|
|
4915
|
-
const onAnnotationsChangeRef =
|
|
4958
|
+
const onAnnotationsChangeRef = useRef16(onAnnotationsChange);
|
|
4916
4959
|
onAnnotationsChangeRef.current = onAnnotationsChange;
|
|
4917
|
-
const setAnnotations =
|
|
4960
|
+
const setAnnotations = useCallback20(
|
|
4918
4961
|
(action) => {
|
|
4919
4962
|
const updated = typeof action === "function" ? action(annotationsRef.current) : action;
|
|
4920
4963
|
if (!onAnnotationsChangeRef.current) {
|
|
@@ -5021,7 +5064,7 @@ var useMediaElementData = () => {
|
|
|
5021
5064
|
};
|
|
5022
5065
|
|
|
5023
5066
|
// src/components/PlaybackControls.tsx
|
|
5024
|
-
import { useCallback as
|
|
5067
|
+
import { useCallback as useCallback21 } from "react";
|
|
5025
5068
|
import { BaseControlButton } from "@waveform-playlist/ui-components";
|
|
5026
5069
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
5027
5070
|
var PlayButton = ({ className }) => {
|
|
@@ -5157,7 +5200,7 @@ var ClearAllButton = ({
|
|
|
5157
5200
|
className
|
|
5158
5201
|
}) => {
|
|
5159
5202
|
const { stop } = usePlaylistControls();
|
|
5160
|
-
const handleClick =
|
|
5203
|
+
const handleClick = useCallback21(() => {
|
|
5161
5204
|
stop();
|
|
5162
5205
|
onClearAll();
|
|
5163
5206
|
}, [stop, onClearAll]);
|
|
@@ -5185,7 +5228,7 @@ var ZoomOutButton = ({
|
|
|
5185
5228
|
};
|
|
5186
5229
|
|
|
5187
5230
|
// src/components/ContextualControls.tsx
|
|
5188
|
-
import { useRef as
|
|
5231
|
+
import { useRef as useRef17, useEffect as useEffect12 } from "react";
|
|
5189
5232
|
import {
|
|
5190
5233
|
MasterVolumeControl as BaseMasterVolumeControl,
|
|
5191
5234
|
TimeFormatSelect as BaseTimeFormatSelect,
|
|
@@ -5224,8 +5267,8 @@ var PositionDisplay = styled.span`
|
|
|
5224
5267
|
`;
|
|
5225
5268
|
var AudioPosition = ({ className }) => {
|
|
5226
5269
|
var _a;
|
|
5227
|
-
const timeRef =
|
|
5228
|
-
const animationFrameRef =
|
|
5270
|
+
const timeRef = useRef17(null);
|
|
5271
|
+
const animationFrameRef = useRef17(null);
|
|
5229
5272
|
const { isPlaying, currentTimeRef, getPlaybackTime } = usePlaybackAnimation();
|
|
5230
5273
|
const { timeFormat: format } = usePlaylistData();
|
|
5231
5274
|
useEffect12(() => {
|
|
@@ -5384,7 +5427,7 @@ function useClipInteractionEnabled() {
|
|
|
5384
5427
|
}
|
|
5385
5428
|
|
|
5386
5429
|
// src/components/PlaylistVisualization.tsx
|
|
5387
|
-
import { useContext as useContext6, useRef as
|
|
5430
|
+
import { useContext as useContext6, useRef as useRef20, useState as useState17, useMemo as useMemo6, useCallback as useCallback22 } from "react";
|
|
5388
5431
|
import { createPortal } from "react-dom";
|
|
5389
5432
|
import styled4 from "styled-components";
|
|
5390
5433
|
import { getGlobalContext as getGlobalContext2 } from "@waveform-playlist/playout";
|
|
@@ -5414,7 +5457,7 @@ import {
|
|
|
5414
5457
|
} from "@waveform-playlist/ui-components";
|
|
5415
5458
|
|
|
5416
5459
|
// src/components/AnimatedPlayhead.tsx
|
|
5417
|
-
import { useRef as
|
|
5460
|
+
import { useRef as useRef18, useEffect as useEffect13 } from "react";
|
|
5418
5461
|
import styled2 from "styled-components";
|
|
5419
5462
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
5420
5463
|
var PlayheadLine = styled2.div.attrs((props) => ({
|
|
@@ -5432,8 +5475,8 @@ var PlayheadLine = styled2.div.attrs((props) => ({
|
|
|
5432
5475
|
will-change: transform;
|
|
5433
5476
|
`;
|
|
5434
5477
|
var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
5435
|
-
const playheadRef =
|
|
5436
|
-
const animationFrameRef =
|
|
5478
|
+
const playheadRef = useRef18(null);
|
|
5479
|
+
const animationFrameRef = useRef18(null);
|
|
5437
5480
|
const { isPlaying, currentTimeRef, getPlaybackTime } = usePlaybackAnimation();
|
|
5438
5481
|
const { samplesPerPixel, sampleRate, progressBarWidth } = usePlaylistData();
|
|
5439
5482
|
useEffect13(() => {
|
|
@@ -5472,7 +5515,7 @@ var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
|
5472
5515
|
};
|
|
5473
5516
|
|
|
5474
5517
|
// src/components/ChannelWithProgress.tsx
|
|
5475
|
-
import { useRef as
|
|
5518
|
+
import { useRef as useRef19, useEffect as useEffect14 } from "react";
|
|
5476
5519
|
import styled3 from "styled-components";
|
|
5477
5520
|
import {
|
|
5478
5521
|
clipPixelWidth as computeClipPixelWidth
|
|
@@ -5537,8 +5580,8 @@ var ChannelWithProgress = (_a) => {
|
|
|
5537
5580
|
"clipSampleRate",
|
|
5538
5581
|
"clipOffsetSeconds"
|
|
5539
5582
|
]);
|
|
5540
|
-
const progressRef =
|
|
5541
|
-
const animationFrameRef =
|
|
5583
|
+
const progressRef = useRef19(null);
|
|
5584
|
+
const animationFrameRef = useRef19(null);
|
|
5542
5585
|
const theme = useTheme();
|
|
5543
5586
|
const { waveHeight } = usePlaylistInfo();
|
|
5544
5587
|
const { isPlaying, currentTimeRef, getPlaybackTime } = usePlaybackAnimation();
|
|
@@ -5821,11 +5864,11 @@ var PlaylistVisualization = ({
|
|
|
5821
5864
|
)
|
|
5822
5865
|
};
|
|
5823
5866
|
}, [spectrogram == null ? void 0 : spectrogram.spectrogramWorkerApi]);
|
|
5824
|
-
const [settingsModalTrackId, setSettingsModalTrackId] =
|
|
5825
|
-
const [isSelecting, setIsSelecting] =
|
|
5826
|
-
const mouseDownTimeRef =
|
|
5827
|
-
const scrollContainerRef =
|
|
5828
|
-
const handleScrollContainerRef =
|
|
5867
|
+
const [settingsModalTrackId, setSettingsModalTrackId] = useState17(null);
|
|
5868
|
+
const [isSelecting, setIsSelecting] = useState17(false);
|
|
5869
|
+
const mouseDownTimeRef = useRef20(0);
|
|
5870
|
+
const scrollContainerRef = useRef20(null);
|
|
5871
|
+
const handleScrollContainerRef = useCallback22(
|
|
5829
5872
|
(element) => {
|
|
5830
5873
|
scrollContainerRef.current = element;
|
|
5831
5874
|
setScrollContainer(element);
|
|
@@ -5863,7 +5906,7 @@ var PlaylistVisualization = ({
|
|
|
5863
5906
|
);
|
|
5864
5907
|
}
|
|
5865
5908
|
});
|
|
5866
|
-
const selectTrack =
|
|
5909
|
+
const selectTrack = useCallback22(
|
|
5867
5910
|
(trackIndex) => {
|
|
5868
5911
|
if (trackIndex >= 0 && trackIndex < tracks.length) {
|
|
5869
5912
|
const track = tracks[trackIndex];
|
|
@@ -6304,7 +6347,7 @@ var PlaylistVisualization = ({
|
|
|
6304
6347
|
};
|
|
6305
6348
|
|
|
6306
6349
|
// src/components/PlaylistAnnotationList.tsx
|
|
6307
|
-
import { useCallback as
|
|
6350
|
+
import { useCallback as useCallback23 } from "react";
|
|
6308
6351
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
6309
6352
|
var PlaylistAnnotationList = ({
|
|
6310
6353
|
height,
|
|
@@ -6319,7 +6362,7 @@ var PlaylistAnnotationList = ({
|
|
|
6319
6362
|
const integration = useAnnotationIntegration();
|
|
6320
6363
|
const { setAnnotations } = usePlaylistControls();
|
|
6321
6364
|
const resolvedConfig = annotationListConfig != null ? annotationListConfig : { linkEndpoints, continuousPlay };
|
|
6322
|
-
const handleAnnotationUpdate =
|
|
6365
|
+
const handleAnnotationUpdate = useCallback23(
|
|
6323
6366
|
(updatedAnnotations) => {
|
|
6324
6367
|
setAnnotations(updatedAnnotations);
|
|
6325
6368
|
onAnnotationUpdate == null ? void 0 : onAnnotationUpdate(updatedAnnotations);
|
|
@@ -6403,7 +6446,7 @@ var Waveform = ({
|
|
|
6403
6446
|
};
|
|
6404
6447
|
|
|
6405
6448
|
// src/components/MediaElementPlaylist.tsx
|
|
6406
|
-
import { useContext as useContext7, useRef as
|
|
6449
|
+
import { useContext as useContext7, useRef as useRef23, useState as useState18, useCallback as useCallback24 } from "react";
|
|
6407
6450
|
import { DragDropProvider } from "@dnd-kit/react";
|
|
6408
6451
|
import { RestrictToHorizontalAxis } from "@dnd-kit/abstract/modifiers";
|
|
6409
6452
|
import {
|
|
@@ -6439,7 +6482,7 @@ var noDropAnimationPlugins = (defaults) => {
|
|
|
6439
6482
|
};
|
|
6440
6483
|
|
|
6441
6484
|
// src/components/AnimatedMediaElementPlayhead.tsx
|
|
6442
|
-
import { useRef as
|
|
6485
|
+
import { useRef as useRef21, useEffect as useEffect15 } from "react";
|
|
6443
6486
|
import styled5 from "styled-components";
|
|
6444
6487
|
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
6445
6488
|
var PlayheadLine2 = styled5.div`
|
|
@@ -6456,8 +6499,8 @@ var PlayheadLine2 = styled5.div`
|
|
|
6456
6499
|
var AnimatedMediaElementPlayhead = ({
|
|
6457
6500
|
color = "#ff0000"
|
|
6458
6501
|
}) => {
|
|
6459
|
-
const playheadRef =
|
|
6460
|
-
const animationFrameRef =
|
|
6502
|
+
const playheadRef = useRef21(null);
|
|
6503
|
+
const animationFrameRef = useRef21(null);
|
|
6461
6504
|
const { isPlaying, currentTimeRef } = useMediaElementAnimation();
|
|
6462
6505
|
const { samplesPerPixel, sampleRate, progressBarWidth } = useMediaElementData();
|
|
6463
6506
|
useEffect15(() => {
|
|
@@ -6496,7 +6539,7 @@ var AnimatedMediaElementPlayhead = ({
|
|
|
6496
6539
|
};
|
|
6497
6540
|
|
|
6498
6541
|
// src/components/ChannelWithMediaElementProgress.tsx
|
|
6499
|
-
import { useRef as
|
|
6542
|
+
import { useRef as useRef22, useEffect as useEffect16 } from "react";
|
|
6500
6543
|
import styled6 from "styled-components";
|
|
6501
6544
|
import {
|
|
6502
6545
|
SmartChannel as SmartChannel2,
|
|
@@ -6541,8 +6584,8 @@ var ChannelWithMediaElementProgress = (_a) => {
|
|
|
6541
6584
|
"clipStartSample",
|
|
6542
6585
|
"clipDurationSamples"
|
|
6543
6586
|
]);
|
|
6544
|
-
const progressRef =
|
|
6545
|
-
const animationFrameRef =
|
|
6587
|
+
const progressRef = useRef22(null);
|
|
6588
|
+
const animationFrameRef = useRef22(null);
|
|
6546
6589
|
const theme = useTheme3();
|
|
6547
6590
|
const { waveHeight } = usePlaylistInfo2();
|
|
6548
6591
|
const { isPlaying, currentTimeRef } = useMediaElementAnimation();
|
|
@@ -6685,11 +6728,11 @@ var MediaElementPlaylist = ({
|
|
|
6685
6728
|
fadeIn,
|
|
6686
6729
|
fadeOut
|
|
6687
6730
|
} = useMediaElementData();
|
|
6688
|
-
const [selectionStart, setSelectionStart] =
|
|
6689
|
-
const [selectionEnd, setSelectionEnd] =
|
|
6690
|
-
const [isSelecting, setIsSelecting] =
|
|
6691
|
-
const scrollContainerRef =
|
|
6692
|
-
const handleScrollContainerRef =
|
|
6731
|
+
const [selectionStart, setSelectionStart] = useState18(0);
|
|
6732
|
+
const [selectionEnd, setSelectionEnd] = useState18(0);
|
|
6733
|
+
const [isSelecting, setIsSelecting] = useState18(false);
|
|
6734
|
+
const scrollContainerRef = useRef23(null);
|
|
6735
|
+
const handleScrollContainerRef = useCallback24(
|
|
6693
6736
|
(el) => {
|
|
6694
6737
|
scrollContainerRef.current = el;
|
|
6695
6738
|
setScrollContainer(el);
|
|
@@ -6697,7 +6740,7 @@ var MediaElementPlaylist = ({
|
|
|
6697
6740
|
[setScrollContainer]
|
|
6698
6741
|
);
|
|
6699
6742
|
const tracksFullWidth = Math.floor(duration * sampleRate / samplesPerPixel);
|
|
6700
|
-
const handleAnnotationClick =
|
|
6743
|
+
const handleAnnotationClick = useCallback24(
|
|
6701
6744
|
(annotation) => __async(null, null, function* () {
|
|
6702
6745
|
setActiveAnnotationId(annotation.id);
|
|
6703
6746
|
try {
|
|
@@ -6712,7 +6755,7 @@ var MediaElementPlaylist = ({
|
|
|
6712
6755
|
}),
|
|
6713
6756
|
[setActiveAnnotationId, play]
|
|
6714
6757
|
);
|
|
6715
|
-
const handleAnnotationUpdate =
|
|
6758
|
+
const handleAnnotationUpdate = useCallback24(
|
|
6716
6759
|
(updatedAnnotations) => {
|
|
6717
6760
|
setAnnotations(updatedAnnotations);
|
|
6718
6761
|
onAnnotationUpdate == null ? void 0 : onAnnotationUpdate(updatedAnnotations);
|
|
@@ -6726,8 +6769,8 @@ var MediaElementPlaylist = ({
|
|
|
6726
6769
|
duration,
|
|
6727
6770
|
linkEndpoints: linkEndpointsProp
|
|
6728
6771
|
});
|
|
6729
|
-
const mouseDownTimeRef =
|
|
6730
|
-
const handleMouseDown =
|
|
6772
|
+
const mouseDownTimeRef = useRef23(0);
|
|
6773
|
+
const handleMouseDown = useCallback24(
|
|
6731
6774
|
(e) => {
|
|
6732
6775
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
6733
6776
|
const x = e.clientX - rect.left;
|
|
@@ -6739,7 +6782,7 @@ var MediaElementPlaylist = ({
|
|
|
6739
6782
|
},
|
|
6740
6783
|
[samplesPerPixel, sampleRate]
|
|
6741
6784
|
);
|
|
6742
|
-
const handleMouseMove =
|
|
6785
|
+
const handleMouseMove = useCallback24(
|
|
6743
6786
|
(e) => {
|
|
6744
6787
|
if (!isSelecting) return;
|
|
6745
6788
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -6749,7 +6792,7 @@ var MediaElementPlaylist = ({
|
|
|
6749
6792
|
},
|
|
6750
6793
|
[isSelecting, samplesPerPixel, sampleRate]
|
|
6751
6794
|
);
|
|
6752
|
-
const handleMouseUp =
|
|
6795
|
+
const handleMouseUp = useCallback24(
|
|
6753
6796
|
(e) => {
|
|
6754
6797
|
if (!isSelecting) return;
|
|
6755
6798
|
setIsSelecting(false);
|
|
@@ -6935,7 +6978,7 @@ var MediaElementPlaylist = ({
|
|
|
6935
6978
|
};
|
|
6936
6979
|
|
|
6937
6980
|
// src/components/MediaElementAnnotationList.tsx
|
|
6938
|
-
import { useCallback as
|
|
6981
|
+
import { useCallback as useCallback25 } from "react";
|
|
6939
6982
|
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
6940
6983
|
var MediaElementAnnotationList = ({
|
|
6941
6984
|
height,
|
|
@@ -6951,7 +6994,7 @@ var MediaElementAnnotationList = ({
|
|
|
6951
6994
|
const integration = useAnnotationIntegration();
|
|
6952
6995
|
const { setAnnotations } = useMediaElementControls();
|
|
6953
6996
|
const resolvedConfig = annotationListConfig != null ? annotationListConfig : { linkEndpoints: false, continuousPlay };
|
|
6954
|
-
const handleAnnotationUpdate =
|
|
6997
|
+
const handleAnnotationUpdate = useCallback25(
|
|
6955
6998
|
(updatedAnnotations) => {
|
|
6956
6999
|
setAnnotations(updatedAnnotations);
|
|
6957
7000
|
onAnnotationUpdate == null ? void 0 : onAnnotationUpdate(updatedAnnotations);
|
|
@@ -7026,6 +7069,7 @@ var KeyboardShortcuts = ({
|
|
|
7026
7069
|
playback = false,
|
|
7027
7070
|
clipSplitting = false,
|
|
7028
7071
|
annotations = false,
|
|
7072
|
+
undo: undoEnabled = false,
|
|
7029
7073
|
additionalShortcuts = []
|
|
7030
7074
|
}) => {
|
|
7031
7075
|
const { tracks, samplesPerPixel, playoutRef, duration } = usePlaylistData();
|
|
@@ -7035,7 +7079,7 @@ var KeyboardShortcuts = ({
|
|
|
7035
7079
|
activeAnnotationId,
|
|
7036
7080
|
continuousPlay
|
|
7037
7081
|
} = usePlaylistState();
|
|
7038
|
-
const { setAnnotations, setActiveAnnotationId, scrollContainerRef, play } = usePlaylistControls();
|
|
7082
|
+
const { setAnnotations, setActiveAnnotationId, scrollContainerRef, play, undo, redo } = usePlaylistControls();
|
|
7039
7083
|
const { splitClipAtPlayhead } = useClipSplitting({
|
|
7040
7084
|
tracks,
|
|
7041
7085
|
samplesPerPixel,
|
|
@@ -7050,6 +7094,14 @@ var KeyboardShortcuts = ({
|
|
|
7050
7094
|
preventDefault: true
|
|
7051
7095
|
});
|
|
7052
7096
|
}
|
|
7097
|
+
if (undoEnabled) {
|
|
7098
|
+
allAdditional.push(
|
|
7099
|
+
{ key: "z", ctrlKey: true, shiftKey: false, action: undo, description: "Undo" },
|
|
7100
|
+
{ key: "z", metaKey: true, shiftKey: false, action: undo, description: "Undo" },
|
|
7101
|
+
{ key: "z", ctrlKey: true, shiftKey: true, action: redo, description: "Redo" },
|
|
7102
|
+
{ key: "z", metaKey: true, shiftKey: true, action: redo, description: "Redo" }
|
|
7103
|
+
);
|
|
7104
|
+
}
|
|
7053
7105
|
if (additionalShortcuts.length > 0) {
|
|
7054
7106
|
allAdditional.push(...additionalShortcuts);
|
|
7055
7107
|
}
|