@waveform-playlist/ui-components 7.1.0 → 7.1.2
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 +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +201 -250
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +113 -161
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -60,7 +60,6 @@ __export(index_exports, {
|
|
|
60
60
|
InlineLabel: () => InlineLabel,
|
|
61
61
|
LoopRegion: () => LoopRegion,
|
|
62
62
|
LoopRegionMarkers: () => LoopRegionMarkers,
|
|
63
|
-
MAX_CANVAS_WIDTH: () => MAX_CANVAS_WIDTH,
|
|
64
63
|
MasterVolumeControl: () => MasterVolumeControl,
|
|
65
64
|
Playhead: () => Playhead,
|
|
66
65
|
PlayheadWithMarker: () => PlayheadWithMarker,
|
|
@@ -109,6 +108,7 @@ __export(index_exports, {
|
|
|
109
108
|
useScrollViewportSelector: () => useScrollViewportSelector,
|
|
110
109
|
useTheme: () => useTheme2,
|
|
111
110
|
useTrackControls: () => useTrackControls,
|
|
111
|
+
useVisibleChunkIndices: () => useVisibleChunkIndices,
|
|
112
112
|
waveformColorToCss: () => waveformColorToCss
|
|
113
113
|
});
|
|
114
114
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -442,7 +442,7 @@ var AutomaticScrollCheckbox = ({
|
|
|
442
442
|
};
|
|
443
443
|
|
|
444
444
|
// src/components/Channel.tsx
|
|
445
|
-
var
|
|
445
|
+
var import_react3 = require("react");
|
|
446
446
|
var import_styled_components9 = __toESM(require("styled-components"));
|
|
447
447
|
|
|
448
448
|
// src/wfpl-theme.ts
|
|
@@ -695,11 +695,52 @@ function useScrollViewportSelector(selector) {
|
|
|
695
695
|
() => selector(null)
|
|
696
696
|
);
|
|
697
697
|
}
|
|
698
|
+
function useVisibleChunkIndices(totalWidth, chunkWidth) {
|
|
699
|
+
const visibleChunkKey = useScrollViewportSelector((viewport) => {
|
|
700
|
+
const totalChunks = Math.ceil(totalWidth / chunkWidth);
|
|
701
|
+
const indices = [];
|
|
702
|
+
for (let i = 0; i < totalChunks; i++) {
|
|
703
|
+
const chunkLeft = i * chunkWidth;
|
|
704
|
+
const thisChunkWidth = Math.min(totalWidth - chunkLeft, chunkWidth);
|
|
705
|
+
if (viewport) {
|
|
706
|
+
const chunkEnd = chunkLeft + thisChunkWidth;
|
|
707
|
+
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
indices.push(i);
|
|
712
|
+
}
|
|
713
|
+
return indices.join(",");
|
|
714
|
+
});
|
|
715
|
+
return (0, import_react.useMemo)(
|
|
716
|
+
() => visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [],
|
|
717
|
+
[visibleChunkKey]
|
|
718
|
+
);
|
|
719
|
+
}
|
|
698
720
|
|
|
699
|
-
// src/
|
|
700
|
-
var
|
|
721
|
+
// src/hooks/useChunkedCanvasRefs.ts
|
|
722
|
+
var import_react2 = require("react");
|
|
723
|
+
function useChunkedCanvasRefs() {
|
|
724
|
+
const canvasMapRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
725
|
+
const canvasRef = (0, import_react2.useCallback)((canvas) => {
|
|
726
|
+
if (canvas !== null) {
|
|
727
|
+
const idx = parseInt(canvas.dataset.index, 10);
|
|
728
|
+
canvasMapRef.current.set(idx, canvas);
|
|
729
|
+
}
|
|
730
|
+
}, []);
|
|
731
|
+
(0, import_react2.useEffect)(() => {
|
|
732
|
+
const map = canvasMapRef.current;
|
|
733
|
+
for (const [idx, canvas] of map.entries()) {
|
|
734
|
+
if (!canvas.isConnected) {
|
|
735
|
+
map.delete(idx);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
});
|
|
739
|
+
return { canvasRef, canvasMapRef };
|
|
740
|
+
}
|
|
701
741
|
|
|
702
742
|
// src/components/Channel.tsx
|
|
743
|
+
var import_core = require("@waveform-playlist/core");
|
|
703
744
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
704
745
|
function createCanvasFillStyle(ctx, color, width, height) {
|
|
705
746
|
if (!isWaveformGradient(color)) {
|
|
@@ -760,49 +801,12 @@ var Channel = (props) => {
|
|
|
760
801
|
transparentBackground = false,
|
|
761
802
|
drawMode = "inverted"
|
|
762
803
|
} = props;
|
|
763
|
-
const
|
|
764
|
-
const
|
|
765
|
-
|
|
766
|
-
const indices = [];
|
|
767
|
-
for (let i = 0; i < totalChunks; i++) {
|
|
768
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
769
|
-
const chunkWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
770
|
-
if (viewport) {
|
|
771
|
-
const chunkEnd = chunkLeft + chunkWidth;
|
|
772
|
-
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
773
|
-
continue;
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
indices.push(i);
|
|
777
|
-
}
|
|
778
|
-
return indices.join(",");
|
|
779
|
-
});
|
|
780
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
781
|
-
const canvasRef = (0, import_react2.useCallback)(
|
|
782
|
-
(canvas) => {
|
|
783
|
-
if (canvas !== null) {
|
|
784
|
-
const index2 = parseInt(canvas.dataset.index, 10);
|
|
785
|
-
canvasesRef.current[index2] = canvas;
|
|
786
|
-
}
|
|
787
|
-
},
|
|
788
|
-
[]
|
|
789
|
-
);
|
|
790
|
-
(0, import_react2.useEffect)(() => {
|
|
791
|
-
const canvases = canvasesRef.current;
|
|
792
|
-
for (let i = canvases.length - 1; i >= 0; i--) {
|
|
793
|
-
if (canvases[i] && !canvases[i].isConnected) {
|
|
794
|
-
delete canvases[i];
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
});
|
|
798
|
-
(0, import_react2.useLayoutEffect)(() => {
|
|
799
|
-
const canvases = canvasesRef.current;
|
|
804
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
805
|
+
const visibleChunkIndices = useVisibleChunkIndices(length, import_core.MAX_CANVAS_WIDTH);
|
|
806
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
800
807
|
const step = barWidth + barGap;
|
|
801
|
-
for (
|
|
802
|
-
const
|
|
803
|
-
if (!canvas) continue;
|
|
804
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
805
|
-
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
|
|
808
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
809
|
+
const globalPixelOffset = canvasIdx * import_core.MAX_CANVAS_WIDTH;
|
|
806
810
|
const ctx = canvas.getContext("2d");
|
|
807
811
|
const h2 = Math.floor(waveHeight / 2);
|
|
808
812
|
const maxValue = 2 ** (bits - 1);
|
|
@@ -847,6 +851,7 @@ var Channel = (props) => {
|
|
|
847
851
|
}
|
|
848
852
|
}
|
|
849
853
|
}, [
|
|
854
|
+
canvasMapRef,
|
|
850
855
|
data,
|
|
851
856
|
bits,
|
|
852
857
|
waveHeight,
|
|
@@ -857,11 +862,11 @@ var Channel = (props) => {
|
|
|
857
862
|
barWidth,
|
|
858
863
|
barGap,
|
|
859
864
|
drawMode,
|
|
860
|
-
|
|
865
|
+
visibleChunkIndices
|
|
861
866
|
]);
|
|
862
867
|
const waveforms = visibleChunkIndices.map((i) => {
|
|
863
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
864
|
-
const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
868
|
+
const chunkLeft = i * import_core.MAX_CANVAS_WIDTH;
|
|
869
|
+
const currentWidth = Math.min(length - chunkLeft, import_core.MAX_CANVAS_WIDTH);
|
|
865
870
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
866
871
|
Waveform,
|
|
867
872
|
{
|
|
@@ -892,7 +897,7 @@ var Channel = (props) => {
|
|
|
892
897
|
};
|
|
893
898
|
|
|
894
899
|
// src/components/ErrorBoundary.tsx
|
|
895
|
-
var
|
|
900
|
+
var import_react4 = __toESM(require("react"));
|
|
896
901
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
897
902
|
var errorContainerStyle = {
|
|
898
903
|
padding: "16px",
|
|
@@ -907,7 +912,7 @@ var errorContainerStyle = {
|
|
|
907
912
|
alignItems: "center",
|
|
908
913
|
justifyContent: "center"
|
|
909
914
|
};
|
|
910
|
-
var PlaylistErrorBoundary = class extends
|
|
915
|
+
var PlaylistErrorBoundary = class extends import_react4.default.Component {
|
|
911
916
|
constructor(props) {
|
|
912
917
|
super(props);
|
|
913
918
|
this.state = { hasError: false, error: null };
|
|
@@ -931,7 +936,7 @@ var PlaylistErrorBoundary = class extends import_react3.default.Component {
|
|
|
931
936
|
|
|
932
937
|
// src/components/Clip.tsx
|
|
933
938
|
var import_styled_components13 = __toESM(require("styled-components"));
|
|
934
|
-
var
|
|
939
|
+
var import_core2 = require("@dnd-kit/core");
|
|
935
940
|
var import_utilities = require("@dnd-kit/utilities");
|
|
936
941
|
|
|
937
942
|
// src/components/ClipHeader.tsx
|
|
@@ -1020,7 +1025,7 @@ var ClipHeader = ({
|
|
|
1020
1025
|
};
|
|
1021
1026
|
|
|
1022
1027
|
// src/components/ClipBoundary.tsx
|
|
1023
|
-
var
|
|
1028
|
+
var import_react5 = __toESM(require("react"));
|
|
1024
1029
|
var import_styled_components11 = __toESM(require("styled-components"));
|
|
1025
1030
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1026
1031
|
var CLIP_BOUNDARY_WIDTH = 8;
|
|
@@ -1062,7 +1067,7 @@ var ClipBoundary = ({
|
|
|
1062
1067
|
dragHandleProps,
|
|
1063
1068
|
touchOptimized = false
|
|
1064
1069
|
}) => {
|
|
1065
|
-
const [isHovered, setIsHovered] =
|
|
1070
|
+
const [isHovered, setIsHovered] = import_react5.default.useState(false);
|
|
1066
1071
|
if (!dragHandleProps) {
|
|
1067
1072
|
return null;
|
|
1068
1073
|
}
|
|
@@ -1207,7 +1212,7 @@ var Clip = ({
|
|
|
1207
1212
|
const width = endPixel - left;
|
|
1208
1213
|
const enableDrag = showHeader && !disableHeaderDrag && !isOverlay;
|
|
1209
1214
|
const draggableId = `clip-${trackIndex}-${clipIndex}`;
|
|
1210
|
-
const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, isDragging } = (0,
|
|
1215
|
+
const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, isDragging } = (0, import_core2.useDraggable)({
|
|
1211
1216
|
id: draggableId,
|
|
1212
1217
|
data: { clipId, trackIndex, clipIndex },
|
|
1213
1218
|
disabled: !enableDrag
|
|
@@ -1218,7 +1223,7 @@ var Clip = ({
|
|
|
1218
1223
|
listeners: leftBoundaryListeners,
|
|
1219
1224
|
setActivatorNodeRef: setLeftBoundaryActivatorRef,
|
|
1220
1225
|
isDragging: isLeftBoundaryDragging
|
|
1221
|
-
} = (0,
|
|
1226
|
+
} = (0, import_core2.useDraggable)({
|
|
1222
1227
|
id: leftBoundaryId,
|
|
1223
1228
|
data: { clipId, trackIndex, clipIndex, boundary: "left" },
|
|
1224
1229
|
disabled: !enableDrag
|
|
@@ -1229,7 +1234,7 @@ var Clip = ({
|
|
|
1229
1234
|
listeners: rightBoundaryListeners,
|
|
1230
1235
|
setActivatorNodeRef: setRightBoundaryActivatorRef,
|
|
1231
1236
|
isDragging: isRightBoundaryDragging
|
|
1232
|
-
} = (0,
|
|
1237
|
+
} = (0, import_core2.useDraggable)({
|
|
1233
1238
|
id: rightBoundaryId,
|
|
1234
1239
|
data: { clipId, trackIndex, clipIndex, boundary: "right" },
|
|
1235
1240
|
disabled: !enableDrag
|
|
@@ -1365,7 +1370,7 @@ var MasterVolumeControl = ({
|
|
|
1365
1370
|
};
|
|
1366
1371
|
|
|
1367
1372
|
// src/components/Playhead.tsx
|
|
1368
|
-
var
|
|
1373
|
+
var import_react6 = require("react");
|
|
1369
1374
|
var import_styled_components15 = __toESM(require("styled-components"));
|
|
1370
1375
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1371
1376
|
var PlayheadLine = import_styled_components15.default.div.attrs((props) => ({
|
|
@@ -1424,9 +1429,9 @@ var PlayheadWithMarker = ({
|
|
|
1424
1429
|
controlsOffset,
|
|
1425
1430
|
getAudioContextTime
|
|
1426
1431
|
}) => {
|
|
1427
|
-
const containerRef = (0,
|
|
1428
|
-
const animationFrameRef = (0,
|
|
1429
|
-
(0,
|
|
1432
|
+
const containerRef = (0, import_react6.useRef)(null);
|
|
1433
|
+
const animationFrameRef = (0, import_react6.useRef)(null);
|
|
1434
|
+
(0, import_react6.useEffect)(() => {
|
|
1430
1435
|
const updatePosition = () => {
|
|
1431
1436
|
if (containerRef.current) {
|
|
1432
1437
|
let time;
|
|
@@ -1455,7 +1460,7 @@ var PlayheadWithMarker = ({
|
|
|
1455
1460
|
}
|
|
1456
1461
|
};
|
|
1457
1462
|
}, [isPlaying, sampleRate, samplesPerPixel, controlsOffset, currentTimeRef, playbackStartTimeRef, audioStartPositionRef, getAudioContextTime]);
|
|
1458
|
-
(0,
|
|
1463
|
+
(0, import_react6.useEffect)(() => {
|
|
1459
1464
|
if (!isPlaying && containerRef.current) {
|
|
1460
1465
|
const time = currentTimeRef.current ?? 0;
|
|
1461
1466
|
const pos = time * sampleRate / samplesPerPixel + controlsOffset;
|
|
@@ -1470,7 +1475,7 @@ var PlayheadWithMarker = ({
|
|
|
1470
1475
|
|
|
1471
1476
|
// src/components/Playlist.tsx
|
|
1472
1477
|
var import_styled_components16 = __toESM(require("styled-components"));
|
|
1473
|
-
var
|
|
1478
|
+
var import_react7 = require("react");
|
|
1474
1479
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1475
1480
|
var Wrapper2 = import_styled_components16.default.div`
|
|
1476
1481
|
overflow-y: hidden;
|
|
@@ -1525,8 +1530,8 @@ var Playlist = ({
|
|
|
1525
1530
|
isSelecting,
|
|
1526
1531
|
"data-playlist-state": playlistState
|
|
1527
1532
|
}) => {
|
|
1528
|
-
const wrapperRef = (0,
|
|
1529
|
-
const handleRef = (0,
|
|
1533
|
+
const wrapperRef = (0, import_react7.useRef)(null);
|
|
1534
|
+
const handleRef = (0, import_react7.useCallback)((el) => {
|
|
1530
1535
|
wrapperRef.current = el;
|
|
1531
1536
|
scrollContainerRef?.(el);
|
|
1532
1537
|
}, [scrollContainerRef]);
|
|
@@ -1587,7 +1592,7 @@ var Selection = ({
|
|
|
1587
1592
|
};
|
|
1588
1593
|
|
|
1589
1594
|
// src/components/LoopRegion.tsx
|
|
1590
|
-
var
|
|
1595
|
+
var import_react8 = require("react");
|
|
1591
1596
|
var import_styled_components18 = __toESM(require("styled-components"));
|
|
1592
1597
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1593
1598
|
var LoopRegionOverlayDiv = import_styled_components18.default.div.attrs((props) => ({
|
|
@@ -1738,12 +1743,12 @@ var LoopRegionMarkers = ({
|
|
|
1738
1743
|
minPosition = 0,
|
|
1739
1744
|
maxPosition = Infinity
|
|
1740
1745
|
}) => {
|
|
1741
|
-
const [draggingMarker, setDraggingMarker] = (0,
|
|
1742
|
-
const dragStartX = (0,
|
|
1743
|
-
const dragStartPosition = (0,
|
|
1744
|
-
const dragStartEnd = (0,
|
|
1746
|
+
const [draggingMarker, setDraggingMarker] = (0, import_react8.useState)(null);
|
|
1747
|
+
const dragStartX = (0, import_react8.useRef)(0);
|
|
1748
|
+
const dragStartPosition = (0, import_react8.useRef)(0);
|
|
1749
|
+
const dragStartEnd = (0, import_react8.useRef)(0);
|
|
1745
1750
|
const width = Math.max(0, endPosition - startPosition);
|
|
1746
|
-
const handleMarkerMouseDown = (0,
|
|
1751
|
+
const handleMarkerMouseDown = (0, import_react8.useCallback)((e, marker) => {
|
|
1747
1752
|
e.preventDefault();
|
|
1748
1753
|
e.stopPropagation();
|
|
1749
1754
|
setDraggingMarker(marker);
|
|
@@ -1768,7 +1773,7 @@ var LoopRegionMarkers = ({
|
|
|
1768
1773
|
document.addEventListener("mousemove", handleMouseMove);
|
|
1769
1774
|
document.addEventListener("mouseup", handleMouseUp);
|
|
1770
1775
|
}, [startPosition, endPosition, minPosition, maxPosition, onLoopStartChange, onLoopEndChange]);
|
|
1771
|
-
const handleRegionMouseDown = (0,
|
|
1776
|
+
const handleRegionMouseDown = (0, import_react8.useCallback)((e) => {
|
|
1772
1777
|
e.preventDefault();
|
|
1773
1778
|
e.stopPropagation();
|
|
1774
1779
|
setDraggingMarker("region");
|
|
@@ -1859,11 +1864,11 @@ var TimescaleLoopRegion = ({
|
|
|
1859
1864
|
maxPosition = Infinity,
|
|
1860
1865
|
controlsOffset = 0
|
|
1861
1866
|
}) => {
|
|
1862
|
-
const [, setIsCreating] = (0,
|
|
1863
|
-
const createStartX = (0,
|
|
1864
|
-
const containerRef = (0,
|
|
1867
|
+
const [, setIsCreating] = (0, import_react8.useState)(false);
|
|
1868
|
+
const createStartX = (0, import_react8.useRef)(0);
|
|
1869
|
+
const containerRef = (0, import_react8.useRef)(null);
|
|
1865
1870
|
const hasLoopRegion = endPosition > startPosition;
|
|
1866
|
-
const handleBackgroundMouseDown = (0,
|
|
1871
|
+
const handleBackgroundMouseDown = (0, import_react8.useCallback)((e) => {
|
|
1867
1872
|
const target = e.target;
|
|
1868
1873
|
if (target.closest("[data-loop-marker-handle]") || target.closest("[data-loop-region-timescale]")) {
|
|
1869
1874
|
return;
|
|
@@ -1917,10 +1922,10 @@ var TimescaleLoopRegion = ({
|
|
|
1917
1922
|
};
|
|
1918
1923
|
|
|
1919
1924
|
// src/components/SelectionTimeInputs.tsx
|
|
1920
|
-
var
|
|
1925
|
+
var import_react10 = require("react");
|
|
1921
1926
|
|
|
1922
1927
|
// src/components/TimeInput.tsx
|
|
1923
|
-
var
|
|
1928
|
+
var import_react9 = require("react");
|
|
1924
1929
|
|
|
1925
1930
|
// src/utils/timeFormat.ts
|
|
1926
1931
|
function clockFormat(seconds, decimals) {
|
|
@@ -1980,8 +1985,8 @@ var TimeInput = ({
|
|
|
1980
1985
|
onChange,
|
|
1981
1986
|
readOnly = false
|
|
1982
1987
|
}) => {
|
|
1983
|
-
const [displayValue, setDisplayValue] = (0,
|
|
1984
|
-
(0,
|
|
1988
|
+
const [displayValue, setDisplayValue] = (0, import_react9.useState)("");
|
|
1989
|
+
(0, import_react9.useEffect)(() => {
|
|
1985
1990
|
const formatted = formatTime(value, format);
|
|
1986
1991
|
setDisplayValue(formatted);
|
|
1987
1992
|
}, [value, format, id]);
|
|
@@ -2027,8 +2032,8 @@ var SelectionTimeInputs = ({
|
|
|
2027
2032
|
onSelectionChange,
|
|
2028
2033
|
className
|
|
2029
2034
|
}) => {
|
|
2030
|
-
const [timeFormat, setTimeFormat] = (0,
|
|
2031
|
-
(0,
|
|
2035
|
+
const [timeFormat, setTimeFormat] = (0, import_react10.useState)("hh:mm:ss.uuu");
|
|
2036
|
+
(0, import_react10.useEffect)(() => {
|
|
2032
2037
|
const timeFormatSelect = document.querySelector(".time-format");
|
|
2033
2038
|
const handleFormatChange = () => {
|
|
2034
2039
|
if (timeFormatSelect) {
|
|
@@ -2080,14 +2085,14 @@ var SelectionTimeInputs = ({
|
|
|
2080
2085
|
};
|
|
2081
2086
|
|
|
2082
2087
|
// src/contexts/DevicePixelRatio.tsx
|
|
2083
|
-
var
|
|
2088
|
+
var import_react11 = require("react");
|
|
2084
2089
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2085
2090
|
function getScale() {
|
|
2086
2091
|
return window.devicePixelRatio;
|
|
2087
2092
|
}
|
|
2088
|
-
var DevicePixelRatioContext = (0,
|
|
2093
|
+
var DevicePixelRatioContext = (0, import_react11.createContext)(getScale());
|
|
2089
2094
|
var DevicePixelRatioProvider = ({ children }) => {
|
|
2090
|
-
const [scale, setScale] = (0,
|
|
2095
|
+
const [scale, setScale] = (0, import_react11.useState)(getScale());
|
|
2091
2096
|
matchMedia(`(resolution: ${getScale()}dppx)`).addEventListener(
|
|
2092
2097
|
"change",
|
|
2093
2098
|
() => {
|
|
@@ -2097,11 +2102,11 @@ var DevicePixelRatioProvider = ({ children }) => {
|
|
|
2097
2102
|
);
|
|
2098
2103
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DevicePixelRatioContext.Provider, { value: Math.ceil(scale), children });
|
|
2099
2104
|
};
|
|
2100
|
-
var useDevicePixelRatio = () => (0,
|
|
2105
|
+
var useDevicePixelRatio = () => (0, import_react11.useContext)(DevicePixelRatioContext);
|
|
2101
2106
|
|
|
2102
2107
|
// src/contexts/PlaylistInfo.tsx
|
|
2103
|
-
var
|
|
2104
|
-
var PlaylistInfoContext = (0,
|
|
2108
|
+
var import_react12 = require("react");
|
|
2109
|
+
var PlaylistInfoContext = (0, import_react12.createContext)({
|
|
2105
2110
|
sampleRate: 48e3,
|
|
2106
2111
|
samplesPerPixel: 1e3,
|
|
2107
2112
|
zoomLevels: [1e3, 1500, 2e3, 2500],
|
|
@@ -2115,21 +2120,21 @@ var PlaylistInfoContext = (0, import_react11.createContext)({
|
|
|
2115
2120
|
barWidth: 1,
|
|
2116
2121
|
barGap: 0
|
|
2117
2122
|
});
|
|
2118
|
-
var usePlaylistInfo = () => (0,
|
|
2123
|
+
var usePlaylistInfo = () => (0, import_react12.useContext)(PlaylistInfoContext);
|
|
2119
2124
|
|
|
2120
2125
|
// src/contexts/Theme.tsx
|
|
2121
|
-
var
|
|
2126
|
+
var import_react13 = require("react");
|
|
2122
2127
|
var import_styled_components19 = require("styled-components");
|
|
2123
|
-
var useTheme2 = () => (0,
|
|
2128
|
+
var useTheme2 = () => (0, import_react13.useContext)(import_styled_components19.ThemeContext);
|
|
2124
2129
|
|
|
2125
2130
|
// src/contexts/TrackControls.tsx
|
|
2126
|
-
var
|
|
2131
|
+
var import_react14 = require("react");
|
|
2127
2132
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2128
|
-
var TrackControlsContext = (0,
|
|
2129
|
-
var useTrackControls = () => (0,
|
|
2133
|
+
var TrackControlsContext = (0, import_react14.createContext)(/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react14.Fragment, {}));
|
|
2134
|
+
var useTrackControls = () => (0, import_react14.useContext)(TrackControlsContext);
|
|
2130
2135
|
|
|
2131
2136
|
// src/contexts/Playout.tsx
|
|
2132
|
-
var
|
|
2137
|
+
var import_react15 = require("react");
|
|
2133
2138
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2134
2139
|
var defaultProgress = 0;
|
|
2135
2140
|
var defaultIsPlaying = false;
|
|
@@ -2141,8 +2146,8 @@ var defaultPlayout = {
|
|
|
2141
2146
|
selectionStart: defaultSelectionStart,
|
|
2142
2147
|
selectionEnd: defaultSelectionEnd
|
|
2143
2148
|
};
|
|
2144
|
-
var PlayoutStatusContext = (0,
|
|
2145
|
-
var PlayoutStatusUpdateContext = (0,
|
|
2149
|
+
var PlayoutStatusContext = (0, import_react15.createContext)(defaultPlayout);
|
|
2150
|
+
var PlayoutStatusUpdateContext = (0, import_react15.createContext)({
|
|
2146
2151
|
setIsPlaying: () => {
|
|
2147
2152
|
},
|
|
2148
2153
|
setProgress: () => {
|
|
@@ -2151,22 +2156,23 @@ var PlayoutStatusUpdateContext = (0, import_react14.createContext)({
|
|
|
2151
2156
|
}
|
|
2152
2157
|
});
|
|
2153
2158
|
var PlayoutProvider = ({ children }) => {
|
|
2154
|
-
const [isPlaying, setIsPlaying] = (0,
|
|
2155
|
-
const [progress, setProgress] = (0,
|
|
2156
|
-
const [selectionStart, setSelectionStart] = (0,
|
|
2157
|
-
const [selectionEnd, setSelectionEnd] = (0,
|
|
2159
|
+
const [isPlaying, setIsPlaying] = (0, import_react15.useState)(defaultIsPlaying);
|
|
2160
|
+
const [progress, setProgress] = (0, import_react15.useState)(defaultProgress);
|
|
2161
|
+
const [selectionStart, setSelectionStart] = (0, import_react15.useState)(defaultSelectionStart);
|
|
2162
|
+
const [selectionEnd, setSelectionEnd] = (0, import_react15.useState)(defaultSelectionEnd);
|
|
2158
2163
|
const setSelection = (start, end) => {
|
|
2159
2164
|
setSelectionStart(start);
|
|
2160
2165
|
setSelectionEnd(end);
|
|
2161
2166
|
};
|
|
2162
2167
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PlayoutStatusUpdateContext.Provider, { value: { setIsPlaying, setProgress, setSelection }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PlayoutStatusContext.Provider, { value: { isPlaying, progress, selectionStart, selectionEnd }, children }) });
|
|
2163
2168
|
};
|
|
2164
|
-
var usePlayoutStatus = () => (0,
|
|
2165
|
-
var usePlayoutStatusUpdate = () => (0,
|
|
2169
|
+
var usePlayoutStatus = () => (0, import_react15.useContext)(PlayoutStatusContext);
|
|
2170
|
+
var usePlayoutStatusUpdate = () => (0, import_react15.useContext)(PlayoutStatusUpdateContext);
|
|
2166
2171
|
|
|
2167
2172
|
// src/components/SpectrogramChannel.tsx
|
|
2168
|
-
var
|
|
2173
|
+
var import_react16 = require("react");
|
|
2169
2174
|
var import_styled_components20 = __toESM(require("styled-components"));
|
|
2175
|
+
var import_core3 = require("@waveform-playlist/core");
|
|
2170
2176
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2171
2177
|
var LINEAR_FREQUENCY_SCALE = (f, minF, maxF) => (f - minF) / (maxF - minF);
|
|
2172
2178
|
var Wrapper3 = import_styled_components20.default.div.attrs((props) => ({
|
|
@@ -2220,60 +2226,51 @@ var SpectrogramChannel = ({
|
|
|
2220
2226
|
onCanvasesReady
|
|
2221
2227
|
}) => {
|
|
2222
2228
|
const channelIndex = channelIndexProp ?? index;
|
|
2223
|
-
const
|
|
2224
|
-
const registeredIdsRef = (0,
|
|
2225
|
-
const transferredCanvasesRef = (0,
|
|
2226
|
-
const workerApiRef = (0,
|
|
2227
|
-
const onCanvasesReadyRef = (0,
|
|
2229
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2230
|
+
const registeredIdsRef = (0, import_react16.useRef)([]);
|
|
2231
|
+
const transferredCanvasesRef = (0, import_react16.useRef)(/* @__PURE__ */ new WeakSet());
|
|
2232
|
+
const workerApiRef = (0, import_react16.useRef)(workerApi);
|
|
2233
|
+
const onCanvasesReadyRef = (0, import_react16.useRef)(onCanvasesReady);
|
|
2228
2234
|
const isWorkerMode = !!(workerApi && clipId);
|
|
2229
|
-
const
|
|
2230
|
-
const totalChunks = Math.ceil(length / MAX_CANVAS_WIDTH);
|
|
2231
|
-
const indices = [];
|
|
2232
|
-
for (let i = 0; i < totalChunks; i++) {
|
|
2233
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
2234
|
-
const chunkWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
2235
|
-
if (viewport) {
|
|
2236
|
-
const chunkEnd = chunkLeft + chunkWidth;
|
|
2237
|
-
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
2238
|
-
continue;
|
|
2239
|
-
}
|
|
2240
|
-
}
|
|
2241
|
-
indices.push(i);
|
|
2242
|
-
}
|
|
2243
|
-
return indices.join(",");
|
|
2244
|
-
});
|
|
2245
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
2246
|
-
const canvasRef = (0, import_react15.useCallback)(
|
|
2247
|
-
(canvas) => {
|
|
2248
|
-
if (canvas !== null) {
|
|
2249
|
-
const idx = parseInt(canvas.dataset.index, 10);
|
|
2250
|
-
canvasesRef.current[idx] = canvas;
|
|
2251
|
-
}
|
|
2252
|
-
},
|
|
2253
|
-
[]
|
|
2254
|
-
);
|
|
2235
|
+
const visibleChunkIndices = useVisibleChunkIndices(length, import_core3.MAX_CANVAS_WIDTH);
|
|
2255
2236
|
const lut = colorLUT ?? DEFAULT_COLOR_LUT;
|
|
2256
2237
|
const maxF = maxFrequency ?? (data ? data.sampleRate / 2 : 22050);
|
|
2257
2238
|
const scaleFn = frequencyScaleFn ?? LINEAR_FREQUENCY_SCALE;
|
|
2258
2239
|
const hasCustomFrequencyScale = Boolean(frequencyScaleFn);
|
|
2259
|
-
(0,
|
|
2240
|
+
(0, import_react16.useEffect)(() => {
|
|
2260
2241
|
workerApiRef.current = workerApi;
|
|
2261
2242
|
}, [workerApi]);
|
|
2262
|
-
(0,
|
|
2243
|
+
(0, import_react16.useEffect)(() => {
|
|
2263
2244
|
onCanvasesReadyRef.current = onCanvasesReady;
|
|
2264
2245
|
}, [onCanvasesReady]);
|
|
2265
|
-
(0,
|
|
2246
|
+
(0, import_react16.useEffect)(() => {
|
|
2266
2247
|
if (!isWorkerMode) return;
|
|
2267
2248
|
const currentWorkerApi = workerApiRef.current;
|
|
2268
2249
|
if (!currentWorkerApi || !clipId) return;
|
|
2269
|
-
const
|
|
2250
|
+
const previousCount = registeredIdsRef.current.length;
|
|
2251
|
+
const remaining = [];
|
|
2252
|
+
for (const id of registeredIdsRef.current) {
|
|
2253
|
+
const match = id.match(/chunk(\d+)$/);
|
|
2254
|
+
if (!match) {
|
|
2255
|
+
remaining.push(id);
|
|
2256
|
+
continue;
|
|
2257
|
+
}
|
|
2258
|
+
const chunkIdx = parseInt(match[1], 10);
|
|
2259
|
+
const canvas = canvasMapRef.current.get(chunkIdx);
|
|
2260
|
+
if (canvas && canvas.isConnected) {
|
|
2261
|
+
remaining.push(id);
|
|
2262
|
+
} else {
|
|
2263
|
+
try {
|
|
2264
|
+
currentWorkerApi.unregisterCanvas(id);
|
|
2265
|
+
} catch (err) {
|
|
2266
|
+
console.warn(`[spectrogram] unregisterCanvas failed for ${id}:`, err);
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
registeredIdsRef.current = remaining;
|
|
2270
2271
|
const newIds = [];
|
|
2271
|
-
const
|
|
2272
|
-
for (let i = 0; i < canvases2.length; i++) {
|
|
2273
|
-
const canvas = canvases2[i];
|
|
2274
|
-
if (!canvas) continue;
|
|
2272
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2275
2273
|
if (transferredCanvasesRef.current.has(canvas)) continue;
|
|
2276
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
2277
2274
|
const canvasId = `${clipId}-ch${channelIndex}-chunk${canvasIdx}`;
|
|
2278
2275
|
let offscreen;
|
|
2279
2276
|
try {
|
|
@@ -2286,7 +2283,6 @@ var SpectrogramChannel = ({
|
|
|
2286
2283
|
try {
|
|
2287
2284
|
currentWorkerApi.registerCanvas(canvasId, offscreen);
|
|
2288
2285
|
newIds.push(canvasId);
|
|
2289
|
-
newWidths.push(Math.min(length - canvasIdx * MAX_CANVAS_WIDTH, MAX_CANVAS_WIDTH));
|
|
2290
2286
|
} catch (err) {
|
|
2291
2287
|
console.warn(`[spectrogram] registerCanvas failed for ${canvasId}:`, err);
|
|
2292
2288
|
continue;
|
|
@@ -2294,35 +2290,23 @@ var SpectrogramChannel = ({
|
|
|
2294
2290
|
}
|
|
2295
2291
|
if (newIds.length > 0) {
|
|
2296
2292
|
registeredIdsRef.current = [...registeredIdsRef.current, ...newIds];
|
|
2297
|
-
onCanvasesReadyRef.current?.(newIds, newWidths);
|
|
2298
2293
|
}
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
if (!match) {
|
|
2308
|
-
remaining.push(id);
|
|
2309
|
-
continue;
|
|
2310
|
-
}
|
|
2311
|
-
const chunkIdx = parseInt(match[1], 10);
|
|
2312
|
-
const canvas = canvasesRef.current[chunkIdx];
|
|
2313
|
-
if (canvas && canvas.isConnected) {
|
|
2314
|
-
remaining.push(id);
|
|
2315
|
-
} else {
|
|
2316
|
-
try {
|
|
2317
|
-
currentWorkerApi.unregisterCanvas(id);
|
|
2318
|
-
} catch (err) {
|
|
2319
|
-
console.warn(`[spectrogram] unregisterCanvas failed for ${id}:`, err);
|
|
2294
|
+
const canvasSetChanged = newIds.length > 0 || remaining.length < previousCount;
|
|
2295
|
+
if (canvasSetChanged) {
|
|
2296
|
+
const allIds = registeredIdsRef.current;
|
|
2297
|
+
const allWidths = allIds.map((id) => {
|
|
2298
|
+
const match = id.match(/chunk(\d+)$/);
|
|
2299
|
+
if (!match) {
|
|
2300
|
+
console.warn(`[spectrogram] Unexpected canvas ID format: ${id}`);
|
|
2301
|
+
return import_core3.MAX_CANVAS_WIDTH;
|
|
2320
2302
|
}
|
|
2321
|
-
|
|
2303
|
+
const chunkIdx = parseInt(match[1], 10);
|
|
2304
|
+
return Math.min(length - chunkIdx * import_core3.MAX_CANVAS_WIDTH, import_core3.MAX_CANVAS_WIDTH);
|
|
2305
|
+
});
|
|
2306
|
+
onCanvasesReadyRef.current?.(allIds, allWidths);
|
|
2322
2307
|
}
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
(0, import_react15.useEffect)(() => {
|
|
2308
|
+
}, [canvasMapRef, isWorkerMode, clipId, channelIndex, length, visibleChunkIndices]);
|
|
2309
|
+
(0, import_react16.useEffect)(() => {
|
|
2326
2310
|
return () => {
|
|
2327
2311
|
const api = workerApiRef.current;
|
|
2328
2312
|
if (!api) return;
|
|
@@ -2336,17 +2320,13 @@ var SpectrogramChannel = ({
|
|
|
2336
2320
|
registeredIdsRef.current = [];
|
|
2337
2321
|
};
|
|
2338
2322
|
}, []);
|
|
2339
|
-
(0,
|
|
2323
|
+
(0, import_react16.useLayoutEffect)(() => {
|
|
2340
2324
|
if (isWorkerMode || !data) return;
|
|
2341
|
-
const canvases2 = canvasesRef.current;
|
|
2342
2325
|
const { frequencyBinCount, frameCount, hopSize, sampleRate, gainDb, rangeDb: rawRangeDb } = data;
|
|
2343
2326
|
const rangeDb = rawRangeDb === 0 ? 1 : rawRangeDb;
|
|
2344
2327
|
const binToFreq = (bin) => bin / frequencyBinCount * (sampleRate / 2);
|
|
2345
|
-
for (
|
|
2346
|
-
const
|
|
2347
|
-
if (!canvas) continue;
|
|
2348
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
2349
|
-
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
|
|
2328
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2329
|
+
const globalPixelOffset = canvasIdx * import_core3.MAX_CANVAS_WIDTH;
|
|
2350
2330
|
const ctx = canvas.getContext("2d");
|
|
2351
2331
|
if (!ctx) continue;
|
|
2352
2332
|
const canvasWidth = canvas.width / devicePixelRatio;
|
|
@@ -2406,10 +2386,10 @@ var SpectrogramChannel = ({
|
|
|
2406
2386
|
ctx.drawImage(tmpCanvas, 0, 0, canvas.width, canvas.height);
|
|
2407
2387
|
}
|
|
2408
2388
|
}
|
|
2409
|
-
}, [isWorkerMode, data, length, waveHeight, devicePixelRatio, samplesPerPixel, lut, minFrequency, maxF, scaleFn, hasCustomFrequencyScale,
|
|
2389
|
+
}, [canvasMapRef, isWorkerMode, data, length, waveHeight, devicePixelRatio, samplesPerPixel, lut, minFrequency, maxF, scaleFn, hasCustomFrequencyScale, visibleChunkIndices]);
|
|
2410
2390
|
const canvases = visibleChunkIndices.map((i) => {
|
|
2411
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
2412
|
-
const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
2391
|
+
const chunkLeft = i * import_core3.MAX_CANVAS_WIDTH;
|
|
2392
|
+
const currentWidth = Math.min(length - chunkLeft, import_core3.MAX_CANVAS_WIDTH);
|
|
2413
2393
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2414
2394
|
SpectrogramCanvas,
|
|
2415
2395
|
{
|
|
@@ -2528,7 +2508,7 @@ var SmartChannel = ({
|
|
|
2528
2508
|
};
|
|
2529
2509
|
|
|
2530
2510
|
// src/components/SpectrogramLabels.tsx
|
|
2531
|
-
var
|
|
2511
|
+
var import_react17 = require("react");
|
|
2532
2512
|
var import_styled_components21 = __toESM(require("styled-components"));
|
|
2533
2513
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2534
2514
|
var LABELS_WIDTH = 72;
|
|
@@ -2580,12 +2560,12 @@ var SpectrogramLabels = ({
|
|
|
2580
2560
|
renderMode = "spectrogram",
|
|
2581
2561
|
hasClipHeaders = false
|
|
2582
2562
|
}) => {
|
|
2583
|
-
const canvasRef = (0,
|
|
2563
|
+
const canvasRef = (0, import_react17.useRef)(null);
|
|
2584
2564
|
const devicePixelRatio = useDevicePixelRatio();
|
|
2585
2565
|
const spectrogramHeight = renderMode === "both" ? Math.floor(waveHeight / 2) : waveHeight;
|
|
2586
2566
|
const totalHeight = numChannels * waveHeight;
|
|
2587
2567
|
const clipHeaderOffset = hasClipHeaders ? 22 : 0;
|
|
2588
|
-
(0,
|
|
2568
|
+
(0, import_react17.useLayoutEffect)(() => {
|
|
2589
2569
|
const canvas = canvasRef.current;
|
|
2590
2570
|
if (!canvas) return;
|
|
2591
2571
|
const ctx = canvas.getContext("2d");
|
|
@@ -2628,10 +2608,10 @@ var SpectrogramLabels = ({
|
|
|
2628
2608
|
};
|
|
2629
2609
|
|
|
2630
2610
|
// src/components/SmartScale.tsx
|
|
2631
|
-
var
|
|
2611
|
+
var import_react19 = require("react");
|
|
2632
2612
|
|
|
2633
2613
|
// src/components/TimeScale.tsx
|
|
2634
|
-
var
|
|
2614
|
+
var import_react18 = __toESM(require("react"));
|
|
2635
2615
|
var import_styled_components22 = __toESM(require("styled-components"));
|
|
2636
2616
|
|
|
2637
2617
|
// src/utils/conversions.ts
|
|
@@ -2655,6 +2635,7 @@ function secondsToPixels(seconds, samplesPerPixel, sampleRate) {
|
|
|
2655
2635
|
}
|
|
2656
2636
|
|
|
2657
2637
|
// src/components/TimeScale.tsx
|
|
2638
|
+
var import_core4 = require("@waveform-playlist/core");
|
|
2658
2639
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2659
2640
|
function formatTime2(milliseconds) {
|
|
2660
2641
|
const seconds = Math.floor(milliseconds / 1e3);
|
|
@@ -2706,21 +2687,15 @@ var TimeScale = (props) => {
|
|
|
2706
2687
|
secondStep,
|
|
2707
2688
|
renderTimestamp
|
|
2708
2689
|
} = props;
|
|
2709
|
-
const
|
|
2690
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2710
2691
|
const {
|
|
2711
2692
|
sampleRate,
|
|
2712
2693
|
samplesPerPixel,
|
|
2713
2694
|
timeScaleHeight,
|
|
2714
2695
|
controls: { show: showControls, width: controlWidth }
|
|
2715
|
-
} = (0,
|
|
2696
|
+
} = (0, import_react18.useContext)(PlaylistInfoContext);
|
|
2716
2697
|
const devicePixelRatio = useDevicePixelRatio();
|
|
2717
|
-
const
|
|
2718
|
-
if (canvas !== null) {
|
|
2719
|
-
const idx = parseInt(canvas.dataset.index, 10);
|
|
2720
|
-
canvasRefsMap.current.set(idx, canvas);
|
|
2721
|
-
}
|
|
2722
|
-
}, []);
|
|
2723
|
-
const { widthX, canvasInfo, timeMarkersWithPositions } = (0, import_react17.useMemo)(() => {
|
|
2698
|
+
const { widthX, canvasInfo, timeMarkersWithPositions } = (0, import_react18.useMemo)(() => {
|
|
2724
2699
|
const nextCanvasInfo = /* @__PURE__ */ new Map();
|
|
2725
2700
|
const nextMarkers = [];
|
|
2726
2701
|
const nextWidthX = secondsToPixels(duration / 1e3, samplesPerPixel, sampleRate);
|
|
@@ -2731,7 +2706,7 @@ var TimeScale = (props) => {
|
|
|
2731
2706
|
if (counter % marker === 0) {
|
|
2732
2707
|
const timeMs = counter;
|
|
2733
2708
|
const timestamp = formatTime2(timeMs);
|
|
2734
|
-
const element = renderTimestamp ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2709
|
+
const element = renderTimestamp ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react18.default.Fragment, { children: renderTimestamp(timeMs, pix) }, `timestamp-${counter}`) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TimeStamp, { $left: pix, children: timestamp }, timestamp);
|
|
2735
2710
|
nextMarkers.push({ pix, element });
|
|
2736
2711
|
nextCanvasInfo.set(pix, timeScaleHeight);
|
|
2737
2712
|
} else if (counter % bigStep === 0) {
|
|
@@ -2747,26 +2722,10 @@ var TimeScale = (props) => {
|
|
|
2747
2722
|
timeMarkersWithPositions: nextMarkers
|
|
2748
2723
|
};
|
|
2749
2724
|
}, [duration, samplesPerPixel, sampleRate, marker, bigStep, secondStep, renderTimestamp, timeScaleHeight]);
|
|
2750
|
-
const
|
|
2751
|
-
const totalChunks = Math.ceil(widthX / MAX_CANVAS_WIDTH);
|
|
2752
|
-
const indices = [];
|
|
2753
|
-
for (let i = 0; i < totalChunks; i++) {
|
|
2754
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
2755
|
-
const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH);
|
|
2756
|
-
if (viewport) {
|
|
2757
|
-
const chunkEnd = chunkLeft + chunkWidth;
|
|
2758
|
-
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
2759
|
-
continue;
|
|
2760
|
-
}
|
|
2761
|
-
}
|
|
2762
|
-
indices.push(i);
|
|
2763
|
-
}
|
|
2764
|
-
return indices.join(",");
|
|
2765
|
-
});
|
|
2766
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
2725
|
+
const visibleChunkIndices = useVisibleChunkIndices(widthX, import_core4.MAX_CANVAS_WIDTH);
|
|
2767
2726
|
const visibleChunks = visibleChunkIndices.map((i) => {
|
|
2768
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
2769
|
-
const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH);
|
|
2727
|
+
const chunkLeft = i * import_core4.MAX_CANVAS_WIDTH;
|
|
2728
|
+
const chunkWidth = Math.min(widthX - chunkLeft, import_core4.MAX_CANVAS_WIDTH);
|
|
2770
2729
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2771
2730
|
TimeTickChunk,
|
|
2772
2731
|
{
|
|
@@ -2776,27 +2735,19 @@ var TimeScale = (props) => {
|
|
|
2776
2735
|
width: chunkWidth * devicePixelRatio,
|
|
2777
2736
|
height: timeScaleHeight * devicePixelRatio,
|
|
2778
2737
|
"data-index": i,
|
|
2779
|
-
ref:
|
|
2738
|
+
ref: canvasRef
|
|
2780
2739
|
},
|
|
2781
2740
|
`timescale-${i}`
|
|
2782
2741
|
);
|
|
2783
2742
|
});
|
|
2784
|
-
const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] * MAX_CANVAS_WIDTH : 0;
|
|
2785
|
-
const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) * MAX_CANVAS_WIDTH : Infinity;
|
|
2743
|
+
const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] * import_core4.MAX_CANVAS_WIDTH : 0;
|
|
2744
|
+
const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) * import_core4.MAX_CANVAS_WIDTH : Infinity;
|
|
2786
2745
|
const visibleMarkers = visibleChunkIndices.length > 0 ? timeMarkersWithPositions.filter(({ pix }) => pix >= firstChunkLeft && pix < lastChunkRight).map(({ element }) => element) : timeMarkersWithPositions.map(({ element }) => element);
|
|
2787
|
-
(0,
|
|
2788
|
-
const
|
|
2789
|
-
for (const [idx, canvas] of currentMap.entries()) {
|
|
2790
|
-
if (!canvas.isConnected) {
|
|
2791
|
-
currentMap.delete(idx);
|
|
2792
|
-
}
|
|
2793
|
-
}
|
|
2794
|
-
});
|
|
2795
|
-
(0, import_react17.useLayoutEffect)(() => {
|
|
2796
|
-
for (const [chunkIdx, canvas] of canvasRefsMap.current.entries()) {
|
|
2746
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
2747
|
+
for (const [chunkIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2797
2748
|
const ctx = canvas.getContext("2d");
|
|
2798
2749
|
if (!ctx) continue;
|
|
2799
|
-
const chunkLeft = chunkIdx * MAX_CANVAS_WIDTH;
|
|
2750
|
+
const chunkLeft = chunkIdx * import_core4.MAX_CANVAS_WIDTH;
|
|
2800
2751
|
const chunkWidth = canvas.width / devicePixelRatio;
|
|
2801
2752
|
ctx.resetTransform();
|
|
2802
2753
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
@@ -2810,7 +2761,7 @@ var TimeScale = (props) => {
|
|
|
2810
2761
|
ctx.fillRect(localX, scaleY, 1, scaleHeight);
|
|
2811
2762
|
}
|
|
2812
2763
|
}
|
|
2813
|
-
}, [duration, devicePixelRatio, timeColor, timeScaleHeight, canvasInfo,
|
|
2764
|
+
}, [canvasMapRef, duration, devicePixelRatio, timeColor, timeScaleHeight, canvasInfo, visibleChunkIndices]);
|
|
2814
2765
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2815
2766
|
PlaylistTimeScaleScroll,
|
|
2816
2767
|
{
|
|
@@ -2901,7 +2852,7 @@ function getScaleInfo(samplesPerPixel) {
|
|
|
2901
2852
|
return config;
|
|
2902
2853
|
}
|
|
2903
2854
|
var SmartScale = ({ renderTimestamp }) => {
|
|
2904
|
-
const { samplesPerPixel, duration } = (0,
|
|
2855
|
+
const { samplesPerPixel, duration } = (0, import_react19.useContext)(PlaylistInfoContext);
|
|
2905
2856
|
let config = getScaleInfo(samplesPerPixel);
|
|
2906
2857
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2907
2858
|
StyledTimeScale,
|
|
@@ -3136,7 +3087,7 @@ var ButtonGroup = import_styled_components26.default.div`
|
|
|
3136
3087
|
|
|
3137
3088
|
// src/components/TrackControls/CloseButton.tsx
|
|
3138
3089
|
var import_styled_components27 = __toESM(require("styled-components"));
|
|
3139
|
-
var
|
|
3090
|
+
var import_react20 = require("@phosphor-icons/react");
|
|
3140
3091
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3141
3092
|
var StyledCloseButton = import_styled_components27.default.button`
|
|
3142
3093
|
position: absolute;
|
|
@@ -3162,7 +3113,7 @@ var StyledCloseButton = import_styled_components27.default.button`
|
|
|
3162
3113
|
var CloseButton = ({
|
|
3163
3114
|
onClick,
|
|
3164
3115
|
title = "Remove track"
|
|
3165
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(StyledCloseButton, { onClick, title, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3116
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(StyledCloseButton, { onClick, title, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react20.X, { size: 12, weight: "bold" }) });
|
|
3166
3117
|
|
|
3167
3118
|
// src/components/TrackControls/Controls.tsx
|
|
3168
3119
|
var import_styled_components28 = __toESM(require("styled-components"));
|
|
@@ -3197,24 +3148,24 @@ var Header = import_styled_components29.default.header`
|
|
|
3197
3148
|
`;
|
|
3198
3149
|
|
|
3199
3150
|
// src/components/TrackControls/VolumeDownIcon.tsx
|
|
3200
|
-
var
|
|
3151
|
+
var import_react21 = require("@phosphor-icons/react");
|
|
3201
3152
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3202
|
-
var VolumeDownIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3153
|
+
var VolumeDownIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react21.SpeakerLowIcon, { weight: "light", ...props });
|
|
3203
3154
|
|
|
3204
3155
|
// src/components/TrackControls/VolumeUpIcon.tsx
|
|
3205
|
-
var
|
|
3156
|
+
var import_react22 = require("@phosphor-icons/react");
|
|
3206
3157
|
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
3207
|
-
var VolumeUpIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3158
|
+
var VolumeUpIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react22.SpeakerHighIcon, { weight: "light", ...props });
|
|
3208
3159
|
|
|
3209
3160
|
// src/components/TrackControls/TrashIcon.tsx
|
|
3210
|
-
var
|
|
3161
|
+
var import_react23 = require("@phosphor-icons/react");
|
|
3211
3162
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
3212
|
-
var TrashIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3163
|
+
var TrashIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react23.TrashIcon, { weight: "light", ...props });
|
|
3213
3164
|
|
|
3214
3165
|
// src/components/TrackControls/DotsIcon.tsx
|
|
3215
|
-
var
|
|
3166
|
+
var import_react24 = require("@phosphor-icons/react");
|
|
3216
3167
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
3217
|
-
var DotsIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
3168
|
+
var DotsIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react24.DotsThreeIcon, { weight: "bold", ...props });
|
|
3218
3169
|
|
|
3219
3170
|
// src/components/TrackControls/Slider.tsx
|
|
3220
3171
|
var import_styled_components30 = __toESM(require("styled-components"));
|
|
@@ -3282,7 +3233,7 @@ var SliderWrapper = import_styled_components31.default.label`
|
|
|
3282
3233
|
`;
|
|
3283
3234
|
|
|
3284
3235
|
// src/components/TrackMenu.tsx
|
|
3285
|
-
var
|
|
3236
|
+
var import_react25 = __toESM(require("react"));
|
|
3286
3237
|
var import_react_dom = require("react-dom");
|
|
3287
3238
|
var import_styled_components32 = __toESM(require("styled-components"));
|
|
3288
3239
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
@@ -3326,13 +3277,13 @@ var Divider = import_styled_components32.default.hr`
|
|
|
3326
3277
|
var TrackMenu = ({
|
|
3327
3278
|
items: itemsProp
|
|
3328
3279
|
}) => {
|
|
3329
|
-
const [open, setOpen] = (0,
|
|
3280
|
+
const [open, setOpen] = (0, import_react25.useState)(false);
|
|
3330
3281
|
const close = () => setOpen(false);
|
|
3331
3282
|
const items = typeof itemsProp === "function" ? itemsProp(close) : itemsProp;
|
|
3332
|
-
const [dropdownPos, setDropdownPos] = (0,
|
|
3333
|
-
const buttonRef = (0,
|
|
3334
|
-
const dropdownRef = (0,
|
|
3335
|
-
(0,
|
|
3283
|
+
const [dropdownPos, setDropdownPos] = (0, import_react25.useState)({ top: 0, left: 0 });
|
|
3284
|
+
const buttonRef = (0, import_react25.useRef)(null);
|
|
3285
|
+
const dropdownRef = (0, import_react25.useRef)(null);
|
|
3286
|
+
(0, import_react25.useEffect)(() => {
|
|
3336
3287
|
if (open && buttonRef.current) {
|
|
3337
3288
|
const rect = buttonRef.current.getBoundingClientRect();
|
|
3338
3289
|
setDropdownPos({
|
|
@@ -3341,7 +3292,7 @@ var TrackMenu = ({
|
|
|
3341
3292
|
});
|
|
3342
3293
|
}
|
|
3343
3294
|
}, [open]);
|
|
3344
|
-
(0,
|
|
3295
|
+
(0, import_react25.useEffect)(() => {
|
|
3345
3296
|
if (!open) return;
|
|
3346
3297
|
const handleClick = (e) => {
|
|
3347
3298
|
const target = e.target;
|
|
@@ -3375,7 +3326,7 @@ var TrackMenu = ({
|
|
|
3375
3326
|
$top: dropdownPos.top,
|
|
3376
3327
|
$left: dropdownPos.left,
|
|
3377
3328
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3378
|
-
children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
3329
|
+
children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react25.default.Fragment, { children: [
|
|
3379
3330
|
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Divider, {}),
|
|
3380
3331
|
item.content
|
|
3381
3332
|
] }, item.id))
|
|
@@ -3417,7 +3368,6 @@ var TrackMenu = ({
|
|
|
3417
3368
|
InlineLabel,
|
|
3418
3369
|
LoopRegion,
|
|
3419
3370
|
LoopRegionMarkers,
|
|
3420
|
-
MAX_CANVAS_WIDTH,
|
|
3421
3371
|
MasterVolumeControl,
|
|
3422
3372
|
Playhead,
|
|
3423
3373
|
PlayheadWithMarker,
|
|
@@ -3466,6 +3416,7 @@ var TrackMenu = ({
|
|
|
3466
3416
|
useScrollViewportSelector,
|
|
3467
3417
|
useTheme,
|
|
3468
3418
|
useTrackControls,
|
|
3419
|
+
useVisibleChunkIndices,
|
|
3469
3420
|
waveformColorToCss
|
|
3470
3421
|
});
|
|
3471
3422
|
//# sourceMappingURL=index.js.map
|