@waveform-playlist/ui-components 7.1.1 → 7.1.3
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 +33 -9
- package/dist/index.d.ts +33 -9
- package/dist/index.js +536 -522
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +469 -456
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -5
package/dist/index.mjs
CHANGED
|
@@ -8,10 +8,7 @@ var PositionDisplay = styled.span`
|
|
|
8
8
|
color: ${(props) => props.theme?.textColor || "#333"};
|
|
9
9
|
user-select: none;
|
|
10
10
|
`;
|
|
11
|
-
var AudioPosition = ({
|
|
12
|
-
formattedTime,
|
|
13
|
-
className
|
|
14
|
-
}) => {
|
|
11
|
+
var AudioPosition = ({ formattedTime, className }) => {
|
|
15
12
|
return /* @__PURE__ */ jsx(PositionDisplay, { className, "aria-label": "Audio position", children: formattedTime });
|
|
16
13
|
};
|
|
17
14
|
|
|
@@ -31,7 +28,9 @@ var BaseButton = styled2.button`
|
|
|
31
28
|
border-radius: ${(props) => props.theme.borderRadius};
|
|
32
29
|
cursor: pointer;
|
|
33
30
|
outline: none;
|
|
34
|
-
transition:
|
|
31
|
+
transition:
|
|
32
|
+
background-color 0.15s ease-in-out,
|
|
33
|
+
border-color 0.15s ease-in-out,
|
|
35
34
|
box-shadow 0.15s ease-in-out;
|
|
36
35
|
|
|
37
36
|
&:hover:not(:disabled) {
|
|
@@ -128,7 +127,9 @@ var BaseInput = styled5.input`
|
|
|
128
127
|
border: 1px solid ${(props) => props.theme.inputBorder};
|
|
129
128
|
border-radius: ${(props) => props.theme.borderRadius};
|
|
130
129
|
outline: none;
|
|
131
|
-
transition:
|
|
130
|
+
transition:
|
|
131
|
+
border-color 0.15s ease-in-out,
|
|
132
|
+
box-shadow 0.15s ease-in-out;
|
|
132
133
|
|
|
133
134
|
&::placeholder {
|
|
134
135
|
color: ${(props) => props.theme.inputPlaceholder};
|
|
@@ -196,7 +197,9 @@ var BaseSelect = styled7.select`
|
|
|
196
197
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
|
|
197
198
|
background-repeat: no-repeat;
|
|
198
199
|
background-position: right 0.75rem center;
|
|
199
|
-
transition:
|
|
200
|
+
transition:
|
|
201
|
+
border-color 0.15s ease-in-out,
|
|
202
|
+
box-shadow 0.15s ease-in-out;
|
|
200
203
|
|
|
201
204
|
&:focus {
|
|
202
205
|
border-color: ${(props) => props.theme.inputFocusBorder};
|
|
@@ -242,7 +245,9 @@ var BaseSlider = styled8.input.attrs({ type: "range" })`
|
|
|
242
245
|
border-radius: 50%;
|
|
243
246
|
cursor: pointer;
|
|
244
247
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
245
|
-
transition:
|
|
248
|
+
transition:
|
|
249
|
+
transform 0.15s ease,
|
|
250
|
+
box-shadow 0.15s ease;
|
|
246
251
|
}
|
|
247
252
|
|
|
248
253
|
&::-webkit-slider-thumb:hover {
|
|
@@ -259,7 +264,9 @@ var BaseSlider = styled8.input.attrs({ type: "range" })`
|
|
|
259
264
|
border-radius: 50%;
|
|
260
265
|
cursor: pointer;
|
|
261
266
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
262
|
-
transition:
|
|
267
|
+
transition:
|
|
268
|
+
transform 0.15s ease,
|
|
269
|
+
box-shadow 0.15s ease;
|
|
263
270
|
}
|
|
264
271
|
|
|
265
272
|
&::-moz-range-thumb:hover {
|
|
@@ -327,7 +334,7 @@ var AutomaticScrollCheckbox = ({
|
|
|
327
334
|
};
|
|
328
335
|
|
|
329
336
|
// src/components/Channel.tsx
|
|
330
|
-
import { useLayoutEffect
|
|
337
|
+
import { useLayoutEffect } from "react";
|
|
331
338
|
import styled9 from "styled-components";
|
|
332
339
|
|
|
333
340
|
// src/wfpl-theme.ts
|
|
@@ -493,6 +500,7 @@ import {
|
|
|
493
500
|
useContext,
|
|
494
501
|
useEffect,
|
|
495
502
|
useCallback,
|
|
503
|
+
useMemo,
|
|
496
504
|
useRef,
|
|
497
505
|
useSyncExternalStore
|
|
498
506
|
} from "react";
|
|
@@ -529,10 +537,7 @@ var ViewportStoreContext = createContext(null);
|
|
|
529
537
|
var EMPTY_SUBSCRIBE = () => () => {
|
|
530
538
|
};
|
|
531
539
|
var NULL_SNAPSHOT = () => null;
|
|
532
|
-
var ScrollViewportProvider = ({
|
|
533
|
-
containerRef,
|
|
534
|
-
children
|
|
535
|
-
}) => {
|
|
540
|
+
var ScrollViewportProvider = ({ containerRef, children }) => {
|
|
536
541
|
const storeRef = useRef(null);
|
|
537
542
|
if (storeRef.current === null) {
|
|
538
543
|
storeRef.current = new ViewportStore();
|
|
@@ -587,12 +592,64 @@ function useScrollViewportSelector(selector) {
|
|
|
587
592
|
() => selector(null)
|
|
588
593
|
);
|
|
589
594
|
}
|
|
595
|
+
function useVisibleChunkIndices(totalWidth, chunkWidth, originX = 0) {
|
|
596
|
+
const visibleChunkKey = useScrollViewportSelector((viewport) => {
|
|
597
|
+
const totalChunks = Math.ceil(totalWidth / chunkWidth);
|
|
598
|
+
const indices = [];
|
|
599
|
+
for (let i = 0; i < totalChunks; i++) {
|
|
600
|
+
const chunkLeft = i * chunkWidth;
|
|
601
|
+
const thisChunkWidth = Math.min(totalWidth - chunkLeft, chunkWidth);
|
|
602
|
+
if (viewport) {
|
|
603
|
+
const chunkLeftGlobal = originX + chunkLeft;
|
|
604
|
+
const chunkEndGlobal = chunkLeftGlobal + thisChunkWidth;
|
|
605
|
+
if (chunkEndGlobal <= viewport.visibleStart || chunkLeftGlobal >= viewport.visibleEnd) {
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
indices.push(i);
|
|
610
|
+
}
|
|
611
|
+
return indices.join(",");
|
|
612
|
+
});
|
|
613
|
+
return useMemo(
|
|
614
|
+
() => visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [],
|
|
615
|
+
[visibleChunkKey]
|
|
616
|
+
);
|
|
617
|
+
}
|
|
590
618
|
|
|
591
|
-
// src/
|
|
592
|
-
|
|
619
|
+
// src/contexts/ClipViewportOrigin.tsx
|
|
620
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
621
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
622
|
+
var ClipViewportOriginContext = createContext2(0);
|
|
623
|
+
var ClipViewportOriginProvider = ({
|
|
624
|
+
originX,
|
|
625
|
+
children
|
|
626
|
+
}) => /* @__PURE__ */ jsx4(ClipViewportOriginContext.Provider, { value: originX, children });
|
|
627
|
+
var useClipViewportOrigin = () => useContext2(ClipViewportOriginContext);
|
|
628
|
+
|
|
629
|
+
// src/hooks/useChunkedCanvasRefs.ts
|
|
630
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
631
|
+
function useChunkedCanvasRefs() {
|
|
632
|
+
const canvasMapRef = useRef2(/* @__PURE__ */ new Map());
|
|
633
|
+
const canvasRef = useCallback2((canvas) => {
|
|
634
|
+
if (canvas !== null) {
|
|
635
|
+
const idx = parseInt(canvas.dataset.index, 10);
|
|
636
|
+
canvasMapRef.current.set(idx, canvas);
|
|
637
|
+
}
|
|
638
|
+
}, []);
|
|
639
|
+
useEffect2(() => {
|
|
640
|
+
const map = canvasMapRef.current;
|
|
641
|
+
for (const [idx, canvas] of map.entries()) {
|
|
642
|
+
if (!canvas.isConnected) {
|
|
643
|
+
map.delete(idx);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
return { canvasRef, canvasMapRef };
|
|
648
|
+
}
|
|
593
649
|
|
|
594
650
|
// src/components/Channel.tsx
|
|
595
|
-
import {
|
|
651
|
+
import { MAX_CANVAS_WIDTH } from "@waveform-playlist/core";
|
|
652
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
596
653
|
function createCanvasFillStyle(ctx, color, width, height) {
|
|
597
654
|
if (!isWaveformGradient(color)) {
|
|
598
655
|
return color;
|
|
@@ -652,48 +709,12 @@ var Channel = (props) => {
|
|
|
652
709
|
transparentBackground = false,
|
|
653
710
|
drawMode = "inverted"
|
|
654
711
|
} = props;
|
|
655
|
-
const
|
|
656
|
-
const
|
|
657
|
-
|
|
658
|
-
const indices = [];
|
|
659
|
-
for (let i = 0; i < totalChunks; i++) {
|
|
660
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
661
|
-
const chunkWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
662
|
-
if (viewport) {
|
|
663
|
-
const chunkEnd = chunkLeft + chunkWidth;
|
|
664
|
-
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
indices.push(i);
|
|
669
|
-
}
|
|
670
|
-
return indices.join(",");
|
|
671
|
-
});
|
|
672
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
673
|
-
const canvasRef = useCallback2(
|
|
674
|
-
(canvas) => {
|
|
675
|
-
if (canvas !== null) {
|
|
676
|
-
const index2 = parseInt(canvas.dataset.index, 10);
|
|
677
|
-
canvasesRef.current[index2] = canvas;
|
|
678
|
-
}
|
|
679
|
-
},
|
|
680
|
-
[]
|
|
681
|
-
);
|
|
682
|
-
useEffect2(() => {
|
|
683
|
-
const canvases = canvasesRef.current;
|
|
684
|
-
for (let i = canvases.length - 1; i >= 0; i--) {
|
|
685
|
-
if (canvases[i] && !canvases[i].isConnected) {
|
|
686
|
-
delete canvases[i];
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
});
|
|
712
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
713
|
+
const clipOriginX = useClipViewportOrigin();
|
|
714
|
+
const visibleChunkIndices = useVisibleChunkIndices(length, MAX_CANVAS_WIDTH, clipOriginX);
|
|
690
715
|
useLayoutEffect(() => {
|
|
691
|
-
const canvases = canvasesRef.current;
|
|
692
716
|
const step = barWidth + barGap;
|
|
693
|
-
for (
|
|
694
|
-
const canvas = canvases[i];
|
|
695
|
-
if (!canvas) continue;
|
|
696
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
717
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
697
718
|
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
|
|
698
719
|
const ctx = canvas.getContext("2d");
|
|
699
720
|
const h2 = Math.floor(waveHeight / 2);
|
|
@@ -710,12 +731,7 @@ var Channel = (props) => {
|
|
|
710
731
|
} else {
|
|
711
732
|
fillColor = waveOutlineColor;
|
|
712
733
|
}
|
|
713
|
-
ctx.fillStyle = createCanvasFillStyle(
|
|
714
|
-
ctx,
|
|
715
|
-
fillColor,
|
|
716
|
-
canvasWidth,
|
|
717
|
-
waveHeight
|
|
718
|
-
);
|
|
734
|
+
ctx.fillStyle = createCanvasFillStyle(ctx, fillColor, canvasWidth, waveHeight);
|
|
719
735
|
const canvasStartGlobal = globalPixelOffset;
|
|
720
736
|
const canvasEndGlobal = globalPixelOffset + canvasWidth;
|
|
721
737
|
const firstBarGlobal = Math.floor((canvasStartGlobal - barWidth + step) / step) * step;
|
|
@@ -739,6 +755,7 @@ var Channel = (props) => {
|
|
|
739
755
|
}
|
|
740
756
|
}
|
|
741
757
|
}, [
|
|
758
|
+
canvasMapRef,
|
|
742
759
|
data,
|
|
743
760
|
bits,
|
|
744
761
|
waveHeight,
|
|
@@ -749,12 +766,12 @@ var Channel = (props) => {
|
|
|
749
766
|
barWidth,
|
|
750
767
|
barGap,
|
|
751
768
|
drawMode,
|
|
752
|
-
|
|
769
|
+
visibleChunkIndices
|
|
753
770
|
]);
|
|
754
771
|
const waveforms = visibleChunkIndices.map((i) => {
|
|
755
772
|
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
756
773
|
const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
757
|
-
return /* @__PURE__ */
|
|
774
|
+
return /* @__PURE__ */ jsx5(
|
|
758
775
|
Waveform,
|
|
759
776
|
{
|
|
760
777
|
$cssWidth: currentWidth,
|
|
@@ -770,7 +787,7 @@ var Channel = (props) => {
|
|
|
770
787
|
});
|
|
771
788
|
const bgColor = waveFillColor;
|
|
772
789
|
const backgroundCss = transparentBackground ? "transparent" : waveformColorToCss(bgColor);
|
|
773
|
-
return /* @__PURE__ */
|
|
790
|
+
return /* @__PURE__ */ jsx5(
|
|
774
791
|
Wrapper,
|
|
775
792
|
{
|
|
776
793
|
$index: index,
|
|
@@ -784,8 +801,8 @@ var Channel = (props) => {
|
|
|
784
801
|
};
|
|
785
802
|
|
|
786
803
|
// src/components/ErrorBoundary.tsx
|
|
787
|
-
import
|
|
788
|
-
import { jsx as
|
|
804
|
+
import React4 from "react";
|
|
805
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
789
806
|
var errorContainerStyle = {
|
|
790
807
|
padding: "16px",
|
|
791
808
|
background: "#1a1a2e",
|
|
@@ -799,7 +816,7 @@ var errorContainerStyle = {
|
|
|
799
816
|
alignItems: "center",
|
|
800
817
|
justifyContent: "center"
|
|
801
818
|
};
|
|
802
|
-
var PlaylistErrorBoundary = class extends
|
|
819
|
+
var PlaylistErrorBoundary = class extends React4.Component {
|
|
803
820
|
constructor(props) {
|
|
804
821
|
super(props);
|
|
805
822
|
this.state = { hasError: false, error: null };
|
|
@@ -815,7 +832,7 @@ var PlaylistErrorBoundary = class extends React3.Component {
|
|
|
815
832
|
if (this.props.fallback) {
|
|
816
833
|
return this.props.fallback;
|
|
817
834
|
}
|
|
818
|
-
return /* @__PURE__ */
|
|
835
|
+
return /* @__PURE__ */ jsx6("div", { style: errorContainerStyle, children: "Waveform playlist encountered an error. Check console for details." });
|
|
819
836
|
}
|
|
820
837
|
return this.props.children;
|
|
821
838
|
}
|
|
@@ -828,7 +845,7 @@ import { CSS } from "@dnd-kit/utilities";
|
|
|
828
845
|
|
|
829
846
|
// src/components/ClipHeader.tsx
|
|
830
847
|
import styled10 from "styled-components";
|
|
831
|
-
import { jsx as
|
|
848
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
832
849
|
var CLIP_HEADER_HEIGHT = 22;
|
|
833
850
|
var HeaderContainer = styled10.div`
|
|
834
851
|
position: relative;
|
|
@@ -868,15 +885,7 @@ var ClipHeaderPresentational = ({
|
|
|
868
885
|
trackName,
|
|
869
886
|
isSelected = false
|
|
870
887
|
}) => {
|
|
871
|
-
return /* @__PURE__ */
|
|
872
|
-
HeaderContainer,
|
|
873
|
-
{
|
|
874
|
-
$isDragging: false,
|
|
875
|
-
$interactive: false,
|
|
876
|
-
$isSelected: isSelected,
|
|
877
|
-
children: /* @__PURE__ */ jsx6(TrackName, { children: trackName })
|
|
878
|
-
}
|
|
879
|
-
);
|
|
888
|
+
return /* @__PURE__ */ jsx7(HeaderContainer, { $isDragging: false, $interactive: false, $isSelected: isSelected, children: /* @__PURE__ */ jsx7(TrackName, { children: trackName }) });
|
|
880
889
|
};
|
|
881
890
|
var ClipHeader = ({
|
|
882
891
|
clipId,
|
|
@@ -888,16 +897,10 @@ var ClipHeader = ({
|
|
|
888
897
|
dragHandleProps
|
|
889
898
|
}) => {
|
|
890
899
|
if (disableDrag || !dragHandleProps) {
|
|
891
|
-
return /* @__PURE__ */
|
|
892
|
-
ClipHeaderPresentational,
|
|
893
|
-
{
|
|
894
|
-
trackName,
|
|
895
|
-
isSelected
|
|
896
|
-
}
|
|
897
|
-
);
|
|
900
|
+
return /* @__PURE__ */ jsx7(ClipHeaderPresentational, { trackName, isSelected });
|
|
898
901
|
}
|
|
899
902
|
const { attributes, listeners, setActivatorNodeRef } = dragHandleProps;
|
|
900
|
-
return /* @__PURE__ */
|
|
903
|
+
return /* @__PURE__ */ jsx7(
|
|
901
904
|
HeaderContainer,
|
|
902
905
|
{
|
|
903
906
|
ref: setActivatorNodeRef,
|
|
@@ -906,15 +909,15 @@ var ClipHeader = ({
|
|
|
906
909
|
$isSelected: isSelected,
|
|
907
910
|
...listeners,
|
|
908
911
|
...attributes,
|
|
909
|
-
children: /* @__PURE__ */
|
|
912
|
+
children: /* @__PURE__ */ jsx7(TrackName, { children: trackName })
|
|
910
913
|
}
|
|
911
914
|
);
|
|
912
915
|
};
|
|
913
916
|
|
|
914
917
|
// src/components/ClipBoundary.tsx
|
|
915
|
-
import
|
|
918
|
+
import React5 from "react";
|
|
916
919
|
import styled11 from "styled-components";
|
|
917
|
-
import { jsx as
|
|
920
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
918
921
|
var CLIP_BOUNDARY_WIDTH = 8;
|
|
919
922
|
var CLIP_BOUNDARY_WIDTH_TOUCH = 24;
|
|
920
923
|
var BoundaryContainer = styled11.div`
|
|
@@ -954,12 +957,12 @@ var ClipBoundary = ({
|
|
|
954
957
|
dragHandleProps,
|
|
955
958
|
touchOptimized = false
|
|
956
959
|
}) => {
|
|
957
|
-
const [isHovered, setIsHovered] =
|
|
960
|
+
const [isHovered, setIsHovered] = React5.useState(false);
|
|
958
961
|
if (!dragHandleProps) {
|
|
959
962
|
return null;
|
|
960
963
|
}
|
|
961
964
|
const { attributes, listeners, setActivatorNodeRef, isDragging } = dragHandleProps;
|
|
962
|
-
return /* @__PURE__ */
|
|
965
|
+
return /* @__PURE__ */ jsx8(
|
|
963
966
|
BoundaryContainer,
|
|
964
967
|
{
|
|
965
968
|
ref: setActivatorNodeRef,
|
|
@@ -979,7 +982,7 @@ var ClipBoundary = ({
|
|
|
979
982
|
|
|
980
983
|
// src/components/FadeOverlay.tsx
|
|
981
984
|
import styled12, { useTheme } from "styled-components";
|
|
982
|
-
import { jsx as
|
|
985
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
983
986
|
var FadeContainer = styled12.div.attrs((props) => ({
|
|
984
987
|
style: {
|
|
985
988
|
left: `${props.$left}px`,
|
|
@@ -1036,17 +1039,11 @@ var FadeOverlay = ({
|
|
|
1036
1039
|
const theme = useTheme();
|
|
1037
1040
|
if (width < 1) return null;
|
|
1038
1041
|
const fillColor = color || theme?.fadeOverlayColor || "rgba(0, 0, 0, 0.4)";
|
|
1039
|
-
return /* @__PURE__ */
|
|
1040
|
-
"path",
|
|
1041
|
-
{
|
|
1042
|
-
d: generateFadePath(width, 100, curveType),
|
|
1043
|
-
fill: fillColor
|
|
1044
|
-
}
|
|
1045
|
-
) }) });
|
|
1042
|
+
return /* @__PURE__ */ jsx9(FadeContainer, { $left: left, $width: width, $type: type, children: /* @__PURE__ */ jsx9(FadeSvg, { $type: type, viewBox: `0 0 ${width} 100`, preserveAspectRatio: "none", children: /* @__PURE__ */ jsx9("path", { d: generateFadePath(width, 100, curveType), fill: fillColor }) }) });
|
|
1046
1043
|
};
|
|
1047
1044
|
|
|
1048
1045
|
// src/components/Clip.tsx
|
|
1049
|
-
import { Fragment, jsx as
|
|
1046
|
+
import { Fragment, jsx as jsx10, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1050
1047
|
var ClipContainer = styled13.div.attrs((props) => ({
|
|
1051
1048
|
style: props.$isOverlay ? {} : {
|
|
1052
1049
|
left: `${props.$left}px`,
|
|
@@ -1144,7 +1141,7 @@ var Clip = ({
|
|
|
1144
1141
|
"data-track-id": trackId,
|
|
1145
1142
|
onMouseDown,
|
|
1146
1143
|
children: [
|
|
1147
|
-
showHeader && /* @__PURE__ */
|
|
1144
|
+
showHeader && /* @__PURE__ */ jsx10(
|
|
1148
1145
|
ClipHeader,
|
|
1149
1146
|
{
|
|
1150
1147
|
clipId,
|
|
@@ -1156,9 +1153,9 @@ var Clip = ({
|
|
|
1156
1153
|
dragHandleProps: enableDrag ? { attributes, listeners, setActivatorNodeRef } : void 0
|
|
1157
1154
|
}
|
|
1158
1155
|
),
|
|
1159
|
-
/* @__PURE__ */ jsxs2(ChannelsWrapper, { $isOverlay: isOverlay, children: [
|
|
1156
|
+
/* @__PURE__ */ jsx10(ClipViewportOriginProvider, { originX: left, children: /* @__PURE__ */ jsxs2(ChannelsWrapper, { $isOverlay: isOverlay, children: [
|
|
1160
1157
|
children,
|
|
1161
|
-
showFades && fadeIn && fadeIn.duration > 0 && /* @__PURE__ */
|
|
1158
|
+
showFades && fadeIn && fadeIn.duration > 0 && /* @__PURE__ */ jsx10(
|
|
1162
1159
|
FadeOverlay,
|
|
1163
1160
|
{
|
|
1164
1161
|
left: 0,
|
|
@@ -1167,7 +1164,7 @@ var Clip = ({
|
|
|
1167
1164
|
curveType: fadeIn.type
|
|
1168
1165
|
}
|
|
1169
1166
|
),
|
|
1170
|
-
showFades && fadeOut && fadeOut.duration > 0 && /* @__PURE__ */
|
|
1167
|
+
showFades && fadeOut && fadeOut.duration > 0 && /* @__PURE__ */ jsx10(
|
|
1171
1168
|
FadeOverlay,
|
|
1172
1169
|
{
|
|
1173
1170
|
left: width - Math.floor(fadeOut.duration * sampleRate / samplesPerPixel),
|
|
@@ -1176,9 +1173,9 @@ var Clip = ({
|
|
|
1176
1173
|
curveType: fadeOut.type
|
|
1177
1174
|
}
|
|
1178
1175
|
)
|
|
1179
|
-
] }),
|
|
1176
|
+
] }) }),
|
|
1180
1177
|
showHeader && !disableHeaderDrag && !isOverlay && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1181
|
-
/* @__PURE__ */
|
|
1178
|
+
/* @__PURE__ */ jsx10(
|
|
1182
1179
|
ClipBoundary,
|
|
1183
1180
|
{
|
|
1184
1181
|
clipId,
|
|
@@ -1194,7 +1191,7 @@ var Clip = ({
|
|
|
1194
1191
|
}
|
|
1195
1192
|
}
|
|
1196
1193
|
),
|
|
1197
|
-
/* @__PURE__ */
|
|
1194
|
+
/* @__PURE__ */ jsx10(
|
|
1198
1195
|
ClipBoundary,
|
|
1199
1196
|
{
|
|
1200
1197
|
clipId,
|
|
@@ -1218,7 +1215,7 @@ var Clip = ({
|
|
|
1218
1215
|
|
|
1219
1216
|
// src/components/MasterVolumeControl.tsx
|
|
1220
1217
|
import styled14 from "styled-components";
|
|
1221
|
-
import { jsx as
|
|
1218
|
+
import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1222
1219
|
var VolumeContainer = styled14.div`
|
|
1223
1220
|
display: inline-flex;
|
|
1224
1221
|
align-items: center;
|
|
@@ -1241,8 +1238,8 @@ var MasterVolumeControl = ({
|
|
|
1241
1238
|
onChange(parseFloat(e.target.value) / 100);
|
|
1242
1239
|
};
|
|
1243
1240
|
return /* @__PURE__ */ jsxs3(VolumeContainer, { className, children: [
|
|
1244
|
-
/* @__PURE__ */
|
|
1245
|
-
/* @__PURE__ */
|
|
1241
|
+
/* @__PURE__ */ jsx11(VolumeLabel, { htmlFor: "master-gain", children: "Master Volume" }),
|
|
1242
|
+
/* @__PURE__ */ jsx11(
|
|
1246
1243
|
VolumeSlider,
|
|
1247
1244
|
{
|
|
1248
1245
|
min: "0",
|
|
@@ -1259,7 +1256,7 @@ var MasterVolumeControl = ({
|
|
|
1259
1256
|
// src/components/Playhead.tsx
|
|
1260
1257
|
import { useRef as useRef3, useEffect as useEffect3 } from "react";
|
|
1261
1258
|
import styled15 from "styled-components";
|
|
1262
|
-
import { jsx as
|
|
1259
|
+
import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1263
1260
|
var PlayheadLine = styled15.div.attrs((props) => ({
|
|
1264
1261
|
style: {
|
|
1265
1262
|
transform: `translate3d(${props.$position}px, 0, 0)`
|
|
@@ -1276,7 +1273,7 @@ var PlayheadLine = styled15.div.attrs((props) => ({
|
|
|
1276
1273
|
will-change: transform;
|
|
1277
1274
|
`;
|
|
1278
1275
|
var Playhead = ({ position, color = "#ff0000" }) => {
|
|
1279
|
-
return /* @__PURE__ */
|
|
1276
|
+
return /* @__PURE__ */ jsx12(PlayheadLine, { $position: position, $color: color });
|
|
1280
1277
|
};
|
|
1281
1278
|
var PlayheadWithMarkerContainer = styled15.div`
|
|
1282
1279
|
position: absolute;
|
|
@@ -1346,7 +1343,16 @@ var PlayheadWithMarker = ({
|
|
|
1346
1343
|
animationFrameRef.current = null;
|
|
1347
1344
|
}
|
|
1348
1345
|
};
|
|
1349
|
-
}, [
|
|
1346
|
+
}, [
|
|
1347
|
+
isPlaying,
|
|
1348
|
+
sampleRate,
|
|
1349
|
+
samplesPerPixel,
|
|
1350
|
+
controlsOffset,
|
|
1351
|
+
currentTimeRef,
|
|
1352
|
+
playbackStartTimeRef,
|
|
1353
|
+
audioStartPositionRef,
|
|
1354
|
+
getAudioContextTime
|
|
1355
|
+
]);
|
|
1350
1356
|
useEffect3(() => {
|
|
1351
1357
|
if (!isPlaying && containerRef.current) {
|
|
1352
1358
|
const time = currentTimeRef.current ?? 0;
|
|
@@ -1355,15 +1361,15 @@ var PlayheadWithMarker = ({
|
|
|
1355
1361
|
}
|
|
1356
1362
|
});
|
|
1357
1363
|
return /* @__PURE__ */ jsxs4(PlayheadWithMarkerContainer, { ref: containerRef, $color: color, children: [
|
|
1358
|
-
/* @__PURE__ */
|
|
1359
|
-
/* @__PURE__ */
|
|
1364
|
+
/* @__PURE__ */ jsx12(MarkerTriangle, { $color: color }),
|
|
1365
|
+
/* @__PURE__ */ jsx12(MarkerLine, { $color: color })
|
|
1360
1366
|
] });
|
|
1361
1367
|
};
|
|
1362
1368
|
|
|
1363
1369
|
// src/components/Playlist.tsx
|
|
1364
1370
|
import styled16, { withTheme } from "styled-components";
|
|
1365
1371
|
import { useRef as useRef4, useCallback as useCallback3 } from "react";
|
|
1366
|
-
import { jsx as
|
|
1372
|
+
import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1367
1373
|
var Wrapper2 = styled16.div`
|
|
1368
1374
|
overflow-y: hidden;
|
|
1369
1375
|
overflow-x: auto;
|
|
@@ -1418,40 +1424,36 @@ var Playlist = ({
|
|
|
1418
1424
|
"data-playlist-state": playlistState
|
|
1419
1425
|
}) => {
|
|
1420
1426
|
const wrapperRef = useRef4(null);
|
|
1421
|
-
const handleRef = useCallback3(
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
] })
|
|
1446
|
-
]
|
|
1447
|
-
}
|
|
1448
|
-
) }) });
|
|
1427
|
+
const handleRef = useCallback3(
|
|
1428
|
+
(el) => {
|
|
1429
|
+
wrapperRef.current = el;
|
|
1430
|
+
scrollContainerRef?.(el);
|
|
1431
|
+
},
|
|
1432
|
+
[scrollContainerRef]
|
|
1433
|
+
);
|
|
1434
|
+
return /* @__PURE__ */ jsx13(Wrapper2, { "data-scroll-container": "true", "data-playlist-state": playlistState, ref: handleRef, children: /* @__PURE__ */ jsx13(ScrollViewportProvider, { containerRef: wrapperRef, children: /* @__PURE__ */ jsxs5(ScrollContainer, { $backgroundColor: backgroundColor, $width: scrollContainerWidth, children: [
|
|
1435
|
+
timescale && /* @__PURE__ */ jsx13(TimescaleWrapper, { $width: timescaleWidth, $backgroundColor: timescaleBackgroundColor, children: timescale }),
|
|
1436
|
+
/* @__PURE__ */ jsxs5(TracksContainer, { $width: tracksWidth, $backgroundColor: backgroundColor, children: [
|
|
1437
|
+
children,
|
|
1438
|
+
(onTracksClick || onTracksMouseDown) && /* @__PURE__ */ jsx13(
|
|
1439
|
+
ClickOverlay,
|
|
1440
|
+
{
|
|
1441
|
+
$controlsWidth: controlsWidth,
|
|
1442
|
+
$isSelecting: isSelecting,
|
|
1443
|
+
onClick: onTracksClick,
|
|
1444
|
+
onMouseDown: onTracksMouseDown,
|
|
1445
|
+
onMouseMove: onTracksMouseMove,
|
|
1446
|
+
onMouseUp: onTracksMouseUp
|
|
1447
|
+
}
|
|
1448
|
+
)
|
|
1449
|
+
] })
|
|
1450
|
+
] }) }) });
|
|
1449
1451
|
};
|
|
1450
1452
|
var StyledPlaylist = withTheme(Playlist);
|
|
1451
1453
|
|
|
1452
1454
|
// src/components/Selection.tsx
|
|
1453
1455
|
import styled17 from "styled-components";
|
|
1454
|
-
import { jsx as
|
|
1456
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1455
1457
|
var SelectionOverlay = styled17.div.attrs((props) => ({
|
|
1456
1458
|
style: {
|
|
1457
1459
|
left: `${props.$left}px`,
|
|
@@ -1475,13 +1477,13 @@ var Selection = ({
|
|
|
1475
1477
|
if (width <= 0) {
|
|
1476
1478
|
return null;
|
|
1477
1479
|
}
|
|
1478
|
-
return /* @__PURE__ */
|
|
1480
|
+
return /* @__PURE__ */ jsx14(SelectionOverlay, { $left: startPosition, $width: width, $color: color, "data-selection": true });
|
|
1479
1481
|
};
|
|
1480
1482
|
|
|
1481
1483
|
// src/components/LoopRegion.tsx
|
|
1482
1484
|
import { useCallback as useCallback4, useRef as useRef5, useState } from "react";
|
|
1483
1485
|
import styled18 from "styled-components";
|
|
1484
|
-
import { Fragment as Fragment2, jsx as
|
|
1486
|
+
import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1485
1487
|
var LoopRegionOverlayDiv = styled18.div.attrs((props) => ({
|
|
1486
1488
|
style: {
|
|
1487
1489
|
left: `${props.$left}px`,
|
|
@@ -1531,7 +1533,7 @@ var LoopRegion = ({
|
|
|
1531
1533
|
return null;
|
|
1532
1534
|
}
|
|
1533
1535
|
return /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1534
|
-
/* @__PURE__ */
|
|
1536
|
+
/* @__PURE__ */ jsx15(
|
|
1535
1537
|
LoopRegionOverlayDiv,
|
|
1536
1538
|
{
|
|
1537
1539
|
$left: startPosition,
|
|
@@ -1540,7 +1542,7 @@ var LoopRegion = ({
|
|
|
1540
1542
|
"data-loop-region": true
|
|
1541
1543
|
}
|
|
1542
1544
|
),
|
|
1543
|
-
/* @__PURE__ */
|
|
1545
|
+
/* @__PURE__ */ jsx15(
|
|
1544
1546
|
LoopMarker,
|
|
1545
1547
|
{
|
|
1546
1548
|
$left: startPosition,
|
|
@@ -1549,7 +1551,7 @@ var LoopRegion = ({
|
|
|
1549
1551
|
"data-loop-marker": "start"
|
|
1550
1552
|
}
|
|
1551
1553
|
),
|
|
1552
|
-
/* @__PURE__ */
|
|
1554
|
+
/* @__PURE__ */ jsx15(
|
|
1553
1555
|
LoopMarker,
|
|
1554
1556
|
{
|
|
1555
1557
|
$left: endPosition - 2,
|
|
@@ -1635,66 +1637,72 @@ var LoopRegionMarkers = ({
|
|
|
1635
1637
|
const dragStartPosition = useRef5(0);
|
|
1636
1638
|
const dragStartEnd = useRef5(0);
|
|
1637
1639
|
const width = Math.max(0, endPosition - startPosition);
|
|
1638
|
-
const handleMarkerMouseDown = useCallback4(
|
|
1639
|
-
e
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
const
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1640
|
+
const handleMarkerMouseDown = useCallback4(
|
|
1641
|
+
(e, marker) => {
|
|
1642
|
+
e.preventDefault();
|
|
1643
|
+
e.stopPropagation();
|
|
1644
|
+
setDraggingMarker(marker);
|
|
1645
|
+
dragStartX.current = e.clientX;
|
|
1646
|
+
dragStartPosition.current = marker === "start" ? startPosition : endPosition;
|
|
1647
|
+
const handleMouseMove = (moveEvent) => {
|
|
1648
|
+
const delta = moveEvent.clientX - dragStartX.current;
|
|
1649
|
+
const newPosition = dragStartPosition.current + delta;
|
|
1650
|
+
if (marker === "start") {
|
|
1651
|
+
const clampedPosition = Math.max(minPosition, Math.min(endPosition - 10, newPosition));
|
|
1652
|
+
onLoopStartChange?.(clampedPosition);
|
|
1653
|
+
} else {
|
|
1654
|
+
const clampedPosition = Math.max(startPosition + 10, Math.min(maxPosition, newPosition));
|
|
1655
|
+
onLoopEndChange?.(clampedPosition);
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
const handleMouseUp = () => {
|
|
1659
|
+
setDraggingMarker(null);
|
|
1660
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
1661
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
1662
|
+
};
|
|
1663
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
1664
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
1665
|
+
},
|
|
1666
|
+
[startPosition, endPosition, minPosition, maxPosition, onLoopStartChange, onLoopEndChange]
|
|
1667
|
+
);
|
|
1668
|
+
const handleRegionMouseDown = useCallback4(
|
|
1669
|
+
(e) => {
|
|
1670
|
+
e.preventDefault();
|
|
1671
|
+
e.stopPropagation();
|
|
1672
|
+
setDraggingMarker("region");
|
|
1673
|
+
dragStartX.current = e.clientX;
|
|
1674
|
+
dragStartPosition.current = startPosition;
|
|
1675
|
+
dragStartEnd.current = endPosition;
|
|
1676
|
+
const regionWidth = endPosition - startPosition;
|
|
1677
|
+
const handleMouseMove = (moveEvent) => {
|
|
1678
|
+
const delta = moveEvent.clientX - dragStartX.current;
|
|
1679
|
+
let newStart = dragStartPosition.current + delta;
|
|
1680
|
+
let newEnd = dragStartEnd.current + delta;
|
|
1681
|
+
if (newStart < minPosition) {
|
|
1682
|
+
newStart = minPosition;
|
|
1683
|
+
newEnd = minPosition + regionWidth;
|
|
1684
|
+
}
|
|
1685
|
+
if (newEnd > maxPosition) {
|
|
1686
|
+
newEnd = maxPosition;
|
|
1687
|
+
newStart = maxPosition - regionWidth;
|
|
1688
|
+
}
|
|
1689
|
+
onLoopRegionMove?.(newStart, newEnd);
|
|
1690
|
+
};
|
|
1691
|
+
const handleMouseUp = () => {
|
|
1692
|
+
setDraggingMarker(null);
|
|
1693
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
1694
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
1695
|
+
};
|
|
1696
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
1697
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
1698
|
+
},
|
|
1699
|
+
[startPosition, endPosition, minPosition, maxPosition, onLoopRegionMove]
|
|
1700
|
+
);
|
|
1693
1701
|
if (width <= 0) {
|
|
1694
1702
|
return null;
|
|
1695
1703
|
}
|
|
1696
1704
|
return /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1697
|
-
/* @__PURE__ */
|
|
1705
|
+
/* @__PURE__ */ jsx15(
|
|
1698
1706
|
TimescaleLoopShade,
|
|
1699
1707
|
{
|
|
1700
1708
|
$left: startPosition,
|
|
@@ -1705,7 +1713,7 @@ var LoopRegionMarkers = ({
|
|
|
1705
1713
|
"data-loop-region-timescale": true
|
|
1706
1714
|
}
|
|
1707
1715
|
),
|
|
1708
|
-
/* @__PURE__ */
|
|
1716
|
+
/* @__PURE__ */ jsx15(
|
|
1709
1717
|
DraggableMarkerHandle,
|
|
1710
1718
|
{
|
|
1711
1719
|
$left: startPosition,
|
|
@@ -1716,7 +1724,7 @@ var LoopRegionMarkers = ({
|
|
|
1716
1724
|
"data-loop-marker-handle": "start"
|
|
1717
1725
|
}
|
|
1718
1726
|
),
|
|
1719
|
-
/* @__PURE__ */
|
|
1727
|
+
/* @__PURE__ */ jsx15(
|
|
1720
1728
|
DraggableMarkerHandle,
|
|
1721
1729
|
{
|
|
1722
1730
|
$left: endPosition,
|
|
@@ -1755,42 +1763,45 @@ var TimescaleLoopRegion = ({
|
|
|
1755
1763
|
const createStartX = useRef5(0);
|
|
1756
1764
|
const containerRef = useRef5(null);
|
|
1757
1765
|
const hasLoopRegion = endPosition > startPosition;
|
|
1758
|
-
const handleBackgroundMouseDown = useCallback4(
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
const
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1766
|
+
const handleBackgroundMouseDown = useCallback4(
|
|
1767
|
+
(e) => {
|
|
1768
|
+
const target = e.target;
|
|
1769
|
+
if (target.closest("[data-loop-marker-handle]") || target.closest("[data-loop-region-timescale]")) {
|
|
1770
|
+
return;
|
|
1771
|
+
}
|
|
1772
|
+
e.preventDefault();
|
|
1773
|
+
setIsCreating(true);
|
|
1774
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
1775
|
+
if (!rect) return;
|
|
1776
|
+
const clickX = e.clientX - rect.left;
|
|
1777
|
+
const clampedX = Math.max(minPosition, Math.min(maxPosition, clickX));
|
|
1778
|
+
createStartX.current = clampedX;
|
|
1779
|
+
onLoopRegionChange?.(clampedX, clampedX);
|
|
1780
|
+
const handleMouseMove = (moveEvent) => {
|
|
1781
|
+
const currentX = moveEvent.clientX - rect.left;
|
|
1782
|
+
const clampedCurrentX = Math.max(minPosition, Math.min(maxPosition, currentX));
|
|
1783
|
+
const newStart = Math.min(createStartX.current, clampedCurrentX);
|
|
1784
|
+
const newEnd = Math.max(createStartX.current, clampedCurrentX);
|
|
1785
|
+
onLoopRegionChange?.(newStart, newEnd);
|
|
1786
|
+
};
|
|
1787
|
+
const handleMouseUp = () => {
|
|
1788
|
+
setIsCreating(false);
|
|
1789
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
1790
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
1791
|
+
};
|
|
1792
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
1793
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
1794
|
+
},
|
|
1795
|
+
[minPosition, maxPosition, onLoopRegionChange]
|
|
1796
|
+
);
|
|
1797
|
+
return /* @__PURE__ */ jsx15(
|
|
1787
1798
|
TimescaleLoopCreator,
|
|
1788
1799
|
{
|
|
1789
1800
|
ref: containerRef,
|
|
1790
1801
|
$leftOffset: controlsOffset,
|
|
1791
1802
|
onMouseDown: handleBackgroundMouseDown,
|
|
1792
1803
|
"data-timescale-loop-creator": true,
|
|
1793
|
-
children: hasLoopRegion && /* @__PURE__ */
|
|
1804
|
+
children: hasLoopRegion && /* @__PURE__ */ jsx15(
|
|
1794
1805
|
LoopRegionMarkers,
|
|
1795
1806
|
{
|
|
1796
1807
|
startPosition,
|
|
@@ -1862,7 +1873,7 @@ function parseTime(timeStr, format) {
|
|
|
1862
1873
|
}
|
|
1863
1874
|
|
|
1864
1875
|
// src/components/TimeInput.tsx
|
|
1865
|
-
import { Fragment as Fragment3, jsx as
|
|
1876
|
+
import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1866
1877
|
var TimeInput = ({
|
|
1867
1878
|
id,
|
|
1868
1879
|
label,
|
|
@@ -1894,8 +1905,8 @@ var TimeInput = ({
|
|
|
1894
1905
|
}
|
|
1895
1906
|
};
|
|
1896
1907
|
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
1897
|
-
/* @__PURE__ */
|
|
1898
|
-
/* @__PURE__ */
|
|
1908
|
+
/* @__PURE__ */ jsx16(ScreenReaderOnly, { as: "label", htmlFor: id, children: label }),
|
|
1909
|
+
/* @__PURE__ */ jsx16(
|
|
1899
1910
|
BaseInput,
|
|
1900
1911
|
{
|
|
1901
1912
|
type: "text",
|
|
@@ -1912,7 +1923,7 @@ var TimeInput = ({
|
|
|
1912
1923
|
};
|
|
1913
1924
|
|
|
1914
1925
|
// src/components/SelectionTimeInputs.tsx
|
|
1915
|
-
import { jsx as
|
|
1926
|
+
import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1916
1927
|
var SelectionTimeInputs = ({
|
|
1917
1928
|
selectionStart,
|
|
1918
1929
|
selectionEnd,
|
|
@@ -1946,7 +1957,7 @@ var SelectionTimeInputs = ({
|
|
|
1946
1957
|
}
|
|
1947
1958
|
};
|
|
1948
1959
|
return /* @__PURE__ */ jsxs8("div", { className, children: [
|
|
1949
|
-
/* @__PURE__ */
|
|
1960
|
+
/* @__PURE__ */ jsx17(
|
|
1950
1961
|
TimeInput,
|
|
1951
1962
|
{
|
|
1952
1963
|
id: "audio_start",
|
|
@@ -1957,7 +1968,7 @@ var SelectionTimeInputs = ({
|
|
|
1957
1968
|
onChange: handleStartChange
|
|
1958
1969
|
}
|
|
1959
1970
|
),
|
|
1960
|
-
/* @__PURE__ */
|
|
1971
|
+
/* @__PURE__ */ jsx17(
|
|
1961
1972
|
TimeInput,
|
|
1962
1973
|
{
|
|
1963
1974
|
id: "audio_end",
|
|
@@ -1972,12 +1983,12 @@ var SelectionTimeInputs = ({
|
|
|
1972
1983
|
};
|
|
1973
1984
|
|
|
1974
1985
|
// src/contexts/DevicePixelRatio.tsx
|
|
1975
|
-
import { useState as useState4, createContext as
|
|
1976
|
-
import { jsx as
|
|
1986
|
+
import { useState as useState4, createContext as createContext3, useContext as useContext3 } from "react";
|
|
1987
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1977
1988
|
function getScale() {
|
|
1978
1989
|
return window.devicePixelRatio;
|
|
1979
1990
|
}
|
|
1980
|
-
var DevicePixelRatioContext =
|
|
1991
|
+
var DevicePixelRatioContext = createContext3(getScale());
|
|
1981
1992
|
var DevicePixelRatioProvider = ({ children }) => {
|
|
1982
1993
|
const [scale, setScale] = useState4(getScale());
|
|
1983
1994
|
matchMedia(`(resolution: ${getScale()}dppx)`).addEventListener(
|
|
@@ -1987,13 +1998,13 @@ var DevicePixelRatioProvider = ({ children }) => {
|
|
|
1987
1998
|
},
|
|
1988
1999
|
{ once: true }
|
|
1989
2000
|
);
|
|
1990
|
-
return /* @__PURE__ */
|
|
2001
|
+
return /* @__PURE__ */ jsx18(DevicePixelRatioContext.Provider, { value: Math.ceil(scale), children });
|
|
1991
2002
|
};
|
|
1992
|
-
var useDevicePixelRatio = () =>
|
|
2003
|
+
var useDevicePixelRatio = () => useContext3(DevicePixelRatioContext);
|
|
1993
2004
|
|
|
1994
2005
|
// src/contexts/PlaylistInfo.tsx
|
|
1995
|
-
import { createContext as
|
|
1996
|
-
var PlaylistInfoContext =
|
|
2006
|
+
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
2007
|
+
var PlaylistInfoContext = createContext4({
|
|
1997
2008
|
sampleRate: 48e3,
|
|
1998
2009
|
samplesPerPixel: 1e3,
|
|
1999
2010
|
zoomLevels: [1e3, 1500, 2e3, 2500],
|
|
@@ -2007,26 +2018,26 @@ var PlaylistInfoContext = createContext3({
|
|
|
2007
2018
|
barWidth: 1,
|
|
2008
2019
|
barGap: 0
|
|
2009
2020
|
});
|
|
2010
|
-
var usePlaylistInfo = () =>
|
|
2021
|
+
var usePlaylistInfo = () => useContext4(PlaylistInfoContext);
|
|
2011
2022
|
|
|
2012
2023
|
// src/contexts/Theme.tsx
|
|
2013
|
-
import { useContext as
|
|
2024
|
+
import { useContext as useContext5 } from "react";
|
|
2014
2025
|
import { ThemeContext } from "styled-components";
|
|
2015
|
-
var useTheme2 = () =>
|
|
2026
|
+
var useTheme2 = () => useContext5(ThemeContext);
|
|
2016
2027
|
|
|
2017
2028
|
// src/contexts/TrackControls.tsx
|
|
2018
|
-
import { createContext as
|
|
2019
|
-
import { jsx as
|
|
2020
|
-
var TrackControlsContext =
|
|
2021
|
-
var useTrackControls = () =>
|
|
2029
|
+
import { createContext as createContext5, useContext as useContext6, Fragment as Fragment4 } from "react";
|
|
2030
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2031
|
+
var TrackControlsContext = createContext5(/* @__PURE__ */ jsx19(Fragment4, {}));
|
|
2032
|
+
var useTrackControls = () => useContext6(TrackControlsContext);
|
|
2022
2033
|
|
|
2023
2034
|
// src/contexts/Playout.tsx
|
|
2024
2035
|
import {
|
|
2025
2036
|
useState as useState5,
|
|
2026
|
-
createContext as
|
|
2027
|
-
useContext as
|
|
2037
|
+
createContext as createContext6,
|
|
2038
|
+
useContext as useContext7
|
|
2028
2039
|
} from "react";
|
|
2029
|
-
import { jsx as
|
|
2040
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
2030
2041
|
var defaultProgress = 0;
|
|
2031
2042
|
var defaultIsPlaying = false;
|
|
2032
2043
|
var defaultSelectionStart = 0;
|
|
@@ -2037,8 +2048,8 @@ var defaultPlayout = {
|
|
|
2037
2048
|
selectionStart: defaultSelectionStart,
|
|
2038
2049
|
selectionEnd: defaultSelectionEnd
|
|
2039
2050
|
};
|
|
2040
|
-
var PlayoutStatusContext =
|
|
2041
|
-
var PlayoutStatusUpdateContext =
|
|
2051
|
+
var PlayoutStatusContext = createContext6(defaultPlayout);
|
|
2052
|
+
var PlayoutStatusUpdateContext = createContext6({
|
|
2042
2053
|
setIsPlaying: () => {
|
|
2043
2054
|
},
|
|
2044
2055
|
setProgress: () => {
|
|
@@ -2055,15 +2066,16 @@ var PlayoutProvider = ({ children }) => {
|
|
|
2055
2066
|
setSelectionStart(start);
|
|
2056
2067
|
setSelectionEnd(end);
|
|
2057
2068
|
};
|
|
2058
|
-
return /* @__PURE__ */
|
|
2069
|
+
return /* @__PURE__ */ jsx20(PlayoutStatusUpdateContext.Provider, { value: { setIsPlaying, setProgress, setSelection }, children: /* @__PURE__ */ jsx20(PlayoutStatusContext.Provider, { value: { isPlaying, progress, selectionStart, selectionEnd }, children }) });
|
|
2059
2070
|
};
|
|
2060
|
-
var usePlayoutStatus = () =>
|
|
2061
|
-
var usePlayoutStatusUpdate = () =>
|
|
2071
|
+
var usePlayoutStatus = () => useContext7(PlayoutStatusContext);
|
|
2072
|
+
var usePlayoutStatusUpdate = () => useContext7(PlayoutStatusUpdateContext);
|
|
2062
2073
|
|
|
2063
2074
|
// src/components/SpectrogramChannel.tsx
|
|
2064
|
-
import { useLayoutEffect as useLayoutEffect2,
|
|
2075
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef6, useEffect as useEffect6 } from "react";
|
|
2065
2076
|
import styled19 from "styled-components";
|
|
2066
|
-
import {
|
|
2077
|
+
import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH2 } from "@waveform-playlist/core";
|
|
2078
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
2067
2079
|
var LINEAR_FREQUENCY_SCALE = (f, minF, maxF) => (f - minF) / (maxF - minF);
|
|
2068
2080
|
var Wrapper3 = styled19.div.attrs((props) => ({
|
|
2069
2081
|
style: {
|
|
@@ -2116,38 +2128,14 @@ var SpectrogramChannel = ({
|
|
|
2116
2128
|
onCanvasesReady
|
|
2117
2129
|
}) => {
|
|
2118
2130
|
const channelIndex = channelIndexProp ?? index;
|
|
2119
|
-
const
|
|
2131
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2120
2132
|
const registeredIdsRef = useRef6([]);
|
|
2121
2133
|
const transferredCanvasesRef = useRef6(/* @__PURE__ */ new WeakSet());
|
|
2122
2134
|
const workerApiRef = useRef6(workerApi);
|
|
2123
2135
|
const onCanvasesReadyRef = useRef6(onCanvasesReady);
|
|
2124
2136
|
const isWorkerMode = !!(workerApi && clipId);
|
|
2125
|
-
const
|
|
2126
|
-
|
|
2127
|
-
const indices = [];
|
|
2128
|
-
for (let i = 0; i < totalChunks; i++) {
|
|
2129
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
2130
|
-
const chunkWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
2131
|
-
if (viewport) {
|
|
2132
|
-
const chunkEnd = chunkLeft + chunkWidth;
|
|
2133
|
-
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
2134
|
-
continue;
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
indices.push(i);
|
|
2138
|
-
}
|
|
2139
|
-
return indices.join(",");
|
|
2140
|
-
});
|
|
2141
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
2142
|
-
const canvasRef = useCallback5(
|
|
2143
|
-
(canvas) => {
|
|
2144
|
-
if (canvas !== null) {
|
|
2145
|
-
const idx = parseInt(canvas.dataset.index, 10);
|
|
2146
|
-
canvasesRef.current[idx] = canvas;
|
|
2147
|
-
}
|
|
2148
|
-
},
|
|
2149
|
-
[]
|
|
2150
|
-
);
|
|
2137
|
+
const clipOriginX = useClipViewportOrigin();
|
|
2138
|
+
const visibleChunkIndices = useVisibleChunkIndices(length, MAX_CANVAS_WIDTH2, clipOriginX);
|
|
2151
2139
|
const lut = colorLUT ?? DEFAULT_COLOR_LUT;
|
|
2152
2140
|
const maxF = maxFrequency ?? (data ? data.sampleRate / 2 : 22050);
|
|
2153
2141
|
const scaleFn = frequencyScaleFn ?? LINEAR_FREQUENCY_SCALE;
|
|
@@ -2162,14 +2150,30 @@ var SpectrogramChannel = ({
|
|
|
2162
2150
|
if (!isWorkerMode) return;
|
|
2163
2151
|
const currentWorkerApi = workerApiRef.current;
|
|
2164
2152
|
if (!currentWorkerApi || !clipId) return;
|
|
2165
|
-
const
|
|
2153
|
+
const previousCount = registeredIdsRef.current.length;
|
|
2154
|
+
const remaining = [];
|
|
2155
|
+
for (const id of registeredIdsRef.current) {
|
|
2156
|
+
const match = id.match(/chunk(\d+)$/);
|
|
2157
|
+
if (!match) {
|
|
2158
|
+
remaining.push(id);
|
|
2159
|
+
continue;
|
|
2160
|
+
}
|
|
2161
|
+
const chunkIdx = parseInt(match[1], 10);
|
|
2162
|
+
const canvas = canvasMapRef.current.get(chunkIdx);
|
|
2163
|
+
if (canvas && canvas.isConnected) {
|
|
2164
|
+
remaining.push(id);
|
|
2165
|
+
} else {
|
|
2166
|
+
try {
|
|
2167
|
+
currentWorkerApi.unregisterCanvas(id);
|
|
2168
|
+
} catch (err) {
|
|
2169
|
+
console.warn(`[spectrogram] unregisterCanvas failed for ${id}:`, err);
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
registeredIdsRef.current = remaining;
|
|
2166
2174
|
const newIds = [];
|
|
2167
|
-
const
|
|
2168
|
-
for (let i = 0; i < canvases2.length; i++) {
|
|
2169
|
-
const canvas = canvases2[i];
|
|
2170
|
-
if (!canvas) continue;
|
|
2175
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2171
2176
|
if (transferredCanvasesRef.current.has(canvas)) continue;
|
|
2172
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
2173
2177
|
const canvasId = `${clipId}-ch${channelIndex}-chunk${canvasIdx}`;
|
|
2174
2178
|
let offscreen;
|
|
2175
2179
|
try {
|
|
@@ -2182,7 +2186,6 @@ var SpectrogramChannel = ({
|
|
|
2182
2186
|
try {
|
|
2183
2187
|
currentWorkerApi.registerCanvas(canvasId, offscreen);
|
|
2184
2188
|
newIds.push(canvasId);
|
|
2185
|
-
newWidths.push(Math.min(length - canvasIdx * MAX_CANVAS_WIDTH, MAX_CANVAS_WIDTH));
|
|
2186
2189
|
} catch (err) {
|
|
2187
2190
|
console.warn(`[spectrogram] registerCanvas failed for ${canvasId}:`, err);
|
|
2188
2191
|
continue;
|
|
@@ -2190,34 +2193,22 @@ var SpectrogramChannel = ({
|
|
|
2190
2193
|
}
|
|
2191
2194
|
if (newIds.length > 0) {
|
|
2192
2195
|
registeredIdsRef.current = [...registeredIdsRef.current, ...newIds];
|
|
2193
|
-
onCanvasesReadyRef.current?.(newIds, newWidths);
|
|
2194
2196
|
}
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
if (!match) {
|
|
2204
|
-
remaining.push(id);
|
|
2205
|
-
continue;
|
|
2206
|
-
}
|
|
2207
|
-
const chunkIdx = parseInt(match[1], 10);
|
|
2208
|
-
const canvas = canvasesRef.current[chunkIdx];
|
|
2209
|
-
if (canvas && canvas.isConnected) {
|
|
2210
|
-
remaining.push(id);
|
|
2211
|
-
} else {
|
|
2212
|
-
try {
|
|
2213
|
-
currentWorkerApi.unregisterCanvas(id);
|
|
2214
|
-
} catch (err) {
|
|
2215
|
-
console.warn(`[spectrogram] unregisterCanvas failed for ${id}:`, err);
|
|
2197
|
+
const canvasSetChanged = newIds.length > 0 || remaining.length < previousCount;
|
|
2198
|
+
if (canvasSetChanged) {
|
|
2199
|
+
const allIds = registeredIdsRef.current;
|
|
2200
|
+
const allWidths = allIds.map((id) => {
|
|
2201
|
+
const match = id.match(/chunk(\d+)$/);
|
|
2202
|
+
if (!match) {
|
|
2203
|
+
console.warn(`[spectrogram] Unexpected canvas ID format: ${id}`);
|
|
2204
|
+
return MAX_CANVAS_WIDTH2;
|
|
2216
2205
|
}
|
|
2217
|
-
|
|
2206
|
+
const chunkIdx = parseInt(match[1], 10);
|
|
2207
|
+
return Math.min(length - chunkIdx * MAX_CANVAS_WIDTH2, MAX_CANVAS_WIDTH2);
|
|
2208
|
+
});
|
|
2209
|
+
onCanvasesReadyRef.current?.(allIds, allWidths);
|
|
2218
2210
|
}
|
|
2219
|
-
|
|
2220
|
-
});
|
|
2211
|
+
}, [canvasMapRef, isWorkerMode, clipId, channelIndex, length, visibleChunkIndices]);
|
|
2221
2212
|
useEffect6(() => {
|
|
2222
2213
|
return () => {
|
|
2223
2214
|
const api = workerApiRef.current;
|
|
@@ -2234,15 +2225,18 @@ var SpectrogramChannel = ({
|
|
|
2234
2225
|
}, []);
|
|
2235
2226
|
useLayoutEffect2(() => {
|
|
2236
2227
|
if (isWorkerMode || !data) return;
|
|
2237
|
-
const
|
|
2238
|
-
|
|
2228
|
+
const {
|
|
2229
|
+
frequencyBinCount,
|
|
2230
|
+
frameCount,
|
|
2231
|
+
hopSize,
|
|
2232
|
+
sampleRate,
|
|
2233
|
+
gainDb,
|
|
2234
|
+
rangeDb: rawRangeDb
|
|
2235
|
+
} = data;
|
|
2239
2236
|
const rangeDb = rawRangeDb === 0 ? 1 : rawRangeDb;
|
|
2240
2237
|
const binToFreq = (bin) => bin / frequencyBinCount * (sampleRate / 2);
|
|
2241
|
-
for (
|
|
2242
|
-
const
|
|
2243
|
-
if (!canvas) continue;
|
|
2244
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
2245
|
-
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
|
|
2238
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2239
|
+
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH2;
|
|
2246
2240
|
const ctx = canvas.getContext("2d");
|
|
2247
2241
|
if (!ctx) continue;
|
|
2248
2242
|
const canvasWidth = canvas.width / devicePixelRatio;
|
|
@@ -2302,11 +2296,25 @@ var SpectrogramChannel = ({
|
|
|
2302
2296
|
ctx.drawImage(tmpCanvas, 0, 0, canvas.width, canvas.height);
|
|
2303
2297
|
}
|
|
2304
2298
|
}
|
|
2305
|
-
}, [
|
|
2299
|
+
}, [
|
|
2300
|
+
canvasMapRef,
|
|
2301
|
+
isWorkerMode,
|
|
2302
|
+
data,
|
|
2303
|
+
length,
|
|
2304
|
+
waveHeight,
|
|
2305
|
+
devicePixelRatio,
|
|
2306
|
+
samplesPerPixel,
|
|
2307
|
+
lut,
|
|
2308
|
+
minFrequency,
|
|
2309
|
+
maxF,
|
|
2310
|
+
scaleFn,
|
|
2311
|
+
hasCustomFrequencyScale,
|
|
2312
|
+
visibleChunkIndices
|
|
2313
|
+
]);
|
|
2306
2314
|
const canvases = visibleChunkIndices.map((i) => {
|
|
2307
|
-
const chunkLeft = i *
|
|
2308
|
-
const currentWidth = Math.min(length - chunkLeft,
|
|
2309
|
-
return /* @__PURE__ */
|
|
2315
|
+
const chunkLeft = i * MAX_CANVAS_WIDTH2;
|
|
2316
|
+
const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH2);
|
|
2317
|
+
return /* @__PURE__ */ jsx21(
|
|
2310
2318
|
SpectrogramCanvas,
|
|
2311
2319
|
{
|
|
2312
2320
|
$cssWidth: currentWidth,
|
|
@@ -2320,11 +2328,11 @@ var SpectrogramChannel = ({
|
|
|
2320
2328
|
`${length}-${i}`
|
|
2321
2329
|
);
|
|
2322
2330
|
});
|
|
2323
|
-
return /* @__PURE__ */
|
|
2331
|
+
return /* @__PURE__ */ jsx21(Wrapper3, { $index: index, $cssWidth: length, $waveHeight: waveHeight, children: canvases });
|
|
2324
2332
|
};
|
|
2325
2333
|
|
|
2326
2334
|
// src/components/SmartChannel.tsx
|
|
2327
|
-
import { Fragment as Fragment5, jsx as
|
|
2335
|
+
import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2328
2336
|
var SmartChannel = ({
|
|
2329
2337
|
isSelected,
|
|
2330
2338
|
transparentBackground,
|
|
@@ -2349,7 +2357,7 @@ var SmartChannel = ({
|
|
|
2349
2357
|
const drawMode = theme?.waveformDrawMode || "inverted";
|
|
2350
2358
|
const hasSpectrogram = spectrogramData || spectrogramWorkerApi;
|
|
2351
2359
|
if (renderMode === "spectrogram" && hasSpectrogram) {
|
|
2352
|
-
return /* @__PURE__ */
|
|
2360
|
+
return /* @__PURE__ */ jsx22(
|
|
2353
2361
|
SpectrogramChannel,
|
|
2354
2362
|
{
|
|
2355
2363
|
index: props.index,
|
|
@@ -2371,7 +2379,7 @@ var SmartChannel = ({
|
|
|
2371
2379
|
if (renderMode === "both" && hasSpectrogram) {
|
|
2372
2380
|
const halfHeight = Math.floor(waveHeight / 2);
|
|
2373
2381
|
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2374
|
-
/* @__PURE__ */
|
|
2382
|
+
/* @__PURE__ */ jsx22(
|
|
2375
2383
|
SpectrogramChannel,
|
|
2376
2384
|
{
|
|
2377
2385
|
index: props.index * 2,
|
|
@@ -2390,24 +2398,35 @@ var SmartChannel = ({
|
|
|
2390
2398
|
onCanvasesReady: spectrogramOnCanvasesReady
|
|
2391
2399
|
}
|
|
2392
2400
|
),
|
|
2393
|
-
/* @__PURE__ */
|
|
2394
|
-
|
|
2401
|
+
/* @__PURE__ */ jsx22(
|
|
2402
|
+
"div",
|
|
2395
2403
|
{
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2404
|
+
style: {
|
|
2405
|
+
position: "absolute",
|
|
2406
|
+
top: (props.index * 2 + 1) * halfHeight,
|
|
2407
|
+
width: props.length,
|
|
2408
|
+
height: halfHeight
|
|
2409
|
+
},
|
|
2410
|
+
children: /* @__PURE__ */ jsx22(
|
|
2411
|
+
Channel,
|
|
2412
|
+
{
|
|
2413
|
+
...props,
|
|
2414
|
+
index: 0,
|
|
2415
|
+
waveOutlineColor,
|
|
2416
|
+
waveFillColor,
|
|
2417
|
+
waveHeight: halfHeight,
|
|
2418
|
+
devicePixelRatio,
|
|
2419
|
+
barWidth,
|
|
2420
|
+
barGap,
|
|
2421
|
+
transparentBackground,
|
|
2422
|
+
drawMode
|
|
2423
|
+
}
|
|
2424
|
+
)
|
|
2406
2425
|
}
|
|
2407
|
-
)
|
|
2426
|
+
)
|
|
2408
2427
|
] });
|
|
2409
2428
|
}
|
|
2410
|
-
return /* @__PURE__ */
|
|
2429
|
+
return /* @__PURE__ */ jsx22(
|
|
2411
2430
|
Channel,
|
|
2412
2431
|
{
|
|
2413
2432
|
...props,
|
|
@@ -2426,7 +2445,7 @@ var SmartChannel = ({
|
|
|
2426
2445
|
// src/components/SpectrogramLabels.tsx
|
|
2427
2446
|
import { useRef as useRef7, useLayoutEffect as useLayoutEffect3 } from "react";
|
|
2428
2447
|
import styled20 from "styled-components";
|
|
2429
|
-
import { jsx as
|
|
2448
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2430
2449
|
var LABELS_WIDTH = 72;
|
|
2431
2450
|
var LabelsStickyWrapper = styled20.div`
|
|
2432
2451
|
position: sticky;
|
|
@@ -2507,8 +2526,19 @@ var SpectrogramLabels = ({
|
|
|
2507
2526
|
ctx.fillText(text, padding, y);
|
|
2508
2527
|
}
|
|
2509
2528
|
}
|
|
2510
|
-
}, [
|
|
2511
|
-
|
|
2529
|
+
}, [
|
|
2530
|
+
waveHeight,
|
|
2531
|
+
numChannels,
|
|
2532
|
+
frequencyScaleFn,
|
|
2533
|
+
minFrequency,
|
|
2534
|
+
maxFrequency,
|
|
2535
|
+
labelsColor,
|
|
2536
|
+
labelsBackground,
|
|
2537
|
+
devicePixelRatio,
|
|
2538
|
+
spectrogramHeight,
|
|
2539
|
+
clipHeaderOffset
|
|
2540
|
+
]);
|
|
2541
|
+
return /* @__PURE__ */ jsx23(LabelsStickyWrapper, { $height: totalHeight + clipHeaderOffset, children: /* @__PURE__ */ jsx23(
|
|
2512
2542
|
"canvas",
|
|
2513
2543
|
{
|
|
2514
2544
|
ref: canvasRef,
|
|
@@ -2524,10 +2554,10 @@ var SpectrogramLabels = ({
|
|
|
2524
2554
|
};
|
|
2525
2555
|
|
|
2526
2556
|
// src/components/SmartScale.tsx
|
|
2527
|
-
import { useContext as
|
|
2557
|
+
import { useContext as useContext9 } from "react";
|
|
2528
2558
|
|
|
2529
2559
|
// src/components/TimeScale.tsx
|
|
2530
|
-
import
|
|
2560
|
+
import React16, { useLayoutEffect as useLayoutEffect4, useContext as useContext8, useMemo as useMemo2 } from "react";
|
|
2531
2561
|
import styled21, { withTheme as withTheme2 } from "styled-components";
|
|
2532
2562
|
|
|
2533
2563
|
// src/utils/conversions.ts
|
|
@@ -2551,7 +2581,8 @@ function secondsToPixels(seconds, samplesPerPixel, sampleRate) {
|
|
|
2551
2581
|
}
|
|
2552
2582
|
|
|
2553
2583
|
// src/components/TimeScale.tsx
|
|
2554
|
-
import {
|
|
2584
|
+
import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH3 } from "@waveform-playlist/core";
|
|
2585
|
+
import { jsx as jsx24, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2555
2586
|
function formatTime2(milliseconds) {
|
|
2556
2587
|
const seconds = Math.floor(milliseconds / 1e3);
|
|
2557
2588
|
const s = seconds % 60;
|
|
@@ -2602,21 +2633,15 @@ var TimeScale = (props) => {
|
|
|
2602
2633
|
secondStep,
|
|
2603
2634
|
renderTimestamp
|
|
2604
2635
|
} = props;
|
|
2605
|
-
const
|
|
2636
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2606
2637
|
const {
|
|
2607
2638
|
sampleRate,
|
|
2608
2639
|
samplesPerPixel,
|
|
2609
2640
|
timeScaleHeight,
|
|
2610
2641
|
controls: { show: showControls, width: controlWidth }
|
|
2611
|
-
} =
|
|
2642
|
+
} = useContext8(PlaylistInfoContext);
|
|
2612
2643
|
const devicePixelRatio = useDevicePixelRatio();
|
|
2613
|
-
const
|
|
2614
|
-
if (canvas !== null) {
|
|
2615
|
-
const idx = parseInt(canvas.dataset.index, 10);
|
|
2616
|
-
canvasRefsMap.current.set(idx, canvas);
|
|
2617
|
-
}
|
|
2618
|
-
}, []);
|
|
2619
|
-
const { widthX, canvasInfo, timeMarkersWithPositions } = useMemo(() => {
|
|
2644
|
+
const { widthX, canvasInfo, timeMarkersWithPositions } = useMemo2(() => {
|
|
2620
2645
|
const nextCanvasInfo = /* @__PURE__ */ new Map();
|
|
2621
2646
|
const nextMarkers = [];
|
|
2622
2647
|
const nextWidthX = secondsToPixels(duration / 1e3, samplesPerPixel, sampleRate);
|
|
@@ -2627,7 +2652,7 @@ var TimeScale = (props) => {
|
|
|
2627
2652
|
if (counter % marker === 0) {
|
|
2628
2653
|
const timeMs = counter;
|
|
2629
2654
|
const timestamp = formatTime2(timeMs);
|
|
2630
|
-
const element = renderTimestamp ? /* @__PURE__ */
|
|
2655
|
+
const element = renderTimestamp ? /* @__PURE__ */ jsx24(React16.Fragment, { children: renderTimestamp(timeMs, pix) }, `timestamp-${counter}`) : /* @__PURE__ */ jsx24(TimeStamp, { $left: pix, children: timestamp }, timestamp);
|
|
2631
2656
|
nextMarkers.push({ pix, element });
|
|
2632
2657
|
nextCanvasInfo.set(pix, timeScaleHeight);
|
|
2633
2658
|
} else if (counter % bigStep === 0) {
|
|
@@ -2642,28 +2667,21 @@ var TimeScale = (props) => {
|
|
|
2642
2667
|
canvasInfo: nextCanvasInfo,
|
|
2643
2668
|
timeMarkersWithPositions: nextMarkers
|
|
2644
2669
|
};
|
|
2645
|
-
}, [
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
indices.push(i);
|
|
2659
|
-
}
|
|
2660
|
-
return indices.join(",");
|
|
2661
|
-
});
|
|
2662
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
2670
|
+
}, [
|
|
2671
|
+
duration,
|
|
2672
|
+
samplesPerPixel,
|
|
2673
|
+
sampleRate,
|
|
2674
|
+
marker,
|
|
2675
|
+
bigStep,
|
|
2676
|
+
secondStep,
|
|
2677
|
+
renderTimestamp,
|
|
2678
|
+
timeScaleHeight
|
|
2679
|
+
]);
|
|
2680
|
+
const visibleChunkIndices = useVisibleChunkIndices(widthX, MAX_CANVAS_WIDTH3);
|
|
2663
2681
|
const visibleChunks = visibleChunkIndices.map((i) => {
|
|
2664
|
-
const chunkLeft = i *
|
|
2665
|
-
const chunkWidth = Math.min(widthX - chunkLeft,
|
|
2666
|
-
return /* @__PURE__ */
|
|
2682
|
+
const chunkLeft = i * MAX_CANVAS_WIDTH3;
|
|
2683
|
+
const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH3);
|
|
2684
|
+
return /* @__PURE__ */ jsx24(
|
|
2667
2685
|
TimeTickChunk,
|
|
2668
2686
|
{
|
|
2669
2687
|
$cssWidth: chunkWidth,
|
|
@@ -2672,27 +2690,19 @@ var TimeScale = (props) => {
|
|
|
2672
2690
|
width: chunkWidth * devicePixelRatio,
|
|
2673
2691
|
height: timeScaleHeight * devicePixelRatio,
|
|
2674
2692
|
"data-index": i,
|
|
2675
|
-
ref:
|
|
2693
|
+
ref: canvasRef
|
|
2676
2694
|
},
|
|
2677
2695
|
`timescale-${i}`
|
|
2678
2696
|
);
|
|
2679
2697
|
});
|
|
2680
|
-
const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] *
|
|
2681
|
-
const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) *
|
|
2698
|
+
const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] * MAX_CANVAS_WIDTH3 : 0;
|
|
2699
|
+
const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) * MAX_CANVAS_WIDTH3 : Infinity;
|
|
2682
2700
|
const visibleMarkers = visibleChunkIndices.length > 0 ? timeMarkersWithPositions.filter(({ pix }) => pix >= firstChunkLeft && pix < lastChunkRight).map(({ element }) => element) : timeMarkersWithPositions.map(({ element }) => element);
|
|
2683
|
-
useEffect7(() => {
|
|
2684
|
-
const currentMap = canvasRefsMap.current;
|
|
2685
|
-
for (const [idx, canvas] of currentMap.entries()) {
|
|
2686
|
-
if (!canvas.isConnected) {
|
|
2687
|
-
currentMap.delete(idx);
|
|
2688
|
-
}
|
|
2689
|
-
}
|
|
2690
|
-
});
|
|
2691
2701
|
useLayoutEffect4(() => {
|
|
2692
|
-
for (const [chunkIdx, canvas] of
|
|
2702
|
+
for (const [chunkIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2693
2703
|
const ctx = canvas.getContext("2d");
|
|
2694
2704
|
if (!ctx) continue;
|
|
2695
|
-
const chunkLeft = chunkIdx *
|
|
2705
|
+
const chunkLeft = chunkIdx * MAX_CANVAS_WIDTH3;
|
|
2696
2706
|
const chunkWidth = canvas.width / devicePixelRatio;
|
|
2697
2707
|
ctx.resetTransform();
|
|
2698
2708
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
@@ -2706,7 +2716,15 @@ var TimeScale = (props) => {
|
|
|
2706
2716
|
ctx.fillRect(localX, scaleY, 1, scaleHeight);
|
|
2707
2717
|
}
|
|
2708
2718
|
}
|
|
2709
|
-
}, [
|
|
2719
|
+
}, [
|
|
2720
|
+
canvasMapRef,
|
|
2721
|
+
duration,
|
|
2722
|
+
devicePixelRatio,
|
|
2723
|
+
timeColor,
|
|
2724
|
+
timeScaleHeight,
|
|
2725
|
+
canvasInfo,
|
|
2726
|
+
visibleChunkIndices
|
|
2727
|
+
]);
|
|
2710
2728
|
return /* @__PURE__ */ jsxs10(
|
|
2711
2729
|
PlaylistTimeScaleScroll,
|
|
2712
2730
|
{
|
|
@@ -2723,7 +2741,7 @@ var TimeScale = (props) => {
|
|
|
2723
2741
|
var StyledTimeScale = withTheme2(TimeScale);
|
|
2724
2742
|
|
|
2725
2743
|
// src/components/SmartScale.tsx
|
|
2726
|
-
import { jsx as
|
|
2744
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
2727
2745
|
var timeinfo = /* @__PURE__ */ new Map([
|
|
2728
2746
|
[
|
|
2729
2747
|
700,
|
|
@@ -2797,9 +2815,9 @@ function getScaleInfo(samplesPerPixel) {
|
|
|
2797
2815
|
return config;
|
|
2798
2816
|
}
|
|
2799
2817
|
var SmartScale = ({ renderTimestamp }) => {
|
|
2800
|
-
const { samplesPerPixel, duration } =
|
|
2818
|
+
const { samplesPerPixel, duration } = useContext9(PlaylistInfoContext);
|
|
2801
2819
|
let config = getScaleInfo(samplesPerPixel);
|
|
2802
|
-
return /* @__PURE__ */
|
|
2820
|
+
return /* @__PURE__ */ jsx25(
|
|
2803
2821
|
StyledTimeScale,
|
|
2804
2822
|
{
|
|
2805
2823
|
marker: config.marker,
|
|
@@ -2813,7 +2831,7 @@ var SmartScale = ({ renderTimestamp }) => {
|
|
|
2813
2831
|
|
|
2814
2832
|
// src/components/TimeFormatSelect.tsx
|
|
2815
2833
|
import styled22 from "styled-components";
|
|
2816
|
-
import { jsx as
|
|
2834
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
2817
2835
|
var SelectWrapper = styled22.div`
|
|
2818
2836
|
display: inline-flex;
|
|
2819
2837
|
align-items: center;
|
|
@@ -2836,7 +2854,7 @@ var TimeFormatSelect = ({
|
|
|
2836
2854
|
const handleChange = (e) => {
|
|
2837
2855
|
onChange(e.target.value);
|
|
2838
2856
|
};
|
|
2839
|
-
return /* @__PURE__ */
|
|
2857
|
+
return /* @__PURE__ */ jsx26(SelectWrapper, { className, children: /* @__PURE__ */ jsx26(
|
|
2840
2858
|
BaseSelect,
|
|
2841
2859
|
{
|
|
2842
2860
|
className: "time-format",
|
|
@@ -2844,14 +2862,14 @@ var TimeFormatSelect = ({
|
|
|
2844
2862
|
onChange: handleChange,
|
|
2845
2863
|
disabled,
|
|
2846
2864
|
"aria-label": "Time format selection",
|
|
2847
|
-
children: TIME_FORMAT_OPTIONS.map((option) => /* @__PURE__ */
|
|
2865
|
+
children: TIME_FORMAT_OPTIONS.map((option) => /* @__PURE__ */ jsx26("option", { value: option.value, children: option.label }, option.value))
|
|
2848
2866
|
}
|
|
2849
2867
|
) });
|
|
2850
2868
|
};
|
|
2851
2869
|
|
|
2852
2870
|
// src/components/Track.tsx
|
|
2853
2871
|
import styled23 from "styled-components";
|
|
2854
|
-
import { jsx as
|
|
2872
|
+
import { jsx as jsx27, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2855
2873
|
var Container = styled23.div.attrs((props) => ({
|
|
2856
2874
|
style: {
|
|
2857
2875
|
height: `${props.$waveHeight * props.$numChannels + (props.$hasClipHeaders ? CLIP_HEADER_HEIGHT : 0)}px`
|
|
@@ -2917,15 +2935,8 @@ var Track = ({
|
|
|
2917
2935
|
$hasClipHeaders: hasClipHeaders,
|
|
2918
2936
|
$isSelected: isSelected,
|
|
2919
2937
|
children: [
|
|
2920
|
-
/* @__PURE__ */
|
|
2921
|
-
|
|
2922
|
-
{
|
|
2923
|
-
$controlWidth: show ? controlWidth : 0,
|
|
2924
|
-
$isSelected: isSelected,
|
|
2925
|
-
children: controls
|
|
2926
|
-
}
|
|
2927
|
-
),
|
|
2928
|
-
/* @__PURE__ */ jsx26(
|
|
2938
|
+
/* @__PURE__ */ jsx27(ControlsWrapper, { $controlWidth: show ? controlWidth : 0, $isSelected: isSelected, children: controls }),
|
|
2939
|
+
/* @__PURE__ */ jsx27(
|
|
2929
2940
|
ChannelContainer,
|
|
2930
2941
|
{
|
|
2931
2942
|
$controlWidth: show ? controlWidth : 0,
|
|
@@ -2956,8 +2967,11 @@ var Button = styled24.button.attrs({
|
|
|
2956
2967
|
font-size: ${(props) => props.theme.fontSizeSmall};
|
|
2957
2968
|
line-height: 1;
|
|
2958
2969
|
border-radius: ${(props) => props.theme.borderRadius};
|
|
2959
|
-
transition:
|
|
2960
|
-
|
|
2970
|
+
transition:
|
|
2971
|
+
color 0.15s ease-in-out,
|
|
2972
|
+
background-color 0.15s ease-in-out,
|
|
2973
|
+
border-color 0.15s ease-in-out,
|
|
2974
|
+
box-shadow 0.15s ease-in-out;
|
|
2961
2975
|
cursor: pointer;
|
|
2962
2976
|
|
|
2963
2977
|
${(props) => {
|
|
@@ -3033,7 +3047,7 @@ var ButtonGroup = styled25.div`
|
|
|
3033
3047
|
// src/components/TrackControls/CloseButton.tsx
|
|
3034
3048
|
import styled26 from "styled-components";
|
|
3035
3049
|
import { X as XIcon } from "@phosphor-icons/react";
|
|
3036
|
-
import { jsx as
|
|
3050
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
3037
3051
|
var StyledCloseButton = styled26.button`
|
|
3038
3052
|
position: absolute;
|
|
3039
3053
|
left: 0;
|
|
@@ -3048,17 +3062,16 @@ var StyledCloseButton = styled26.button`
|
|
|
3048
3062
|
align-items: center;
|
|
3049
3063
|
justify-content: center;
|
|
3050
3064
|
opacity: 0.7;
|
|
3051
|
-
transition:
|
|
3065
|
+
transition:
|
|
3066
|
+
opacity 0.15s,
|
|
3067
|
+
color 0.15s;
|
|
3052
3068
|
|
|
3053
3069
|
&:hover {
|
|
3054
3070
|
opacity: 1;
|
|
3055
3071
|
color: #dc3545;
|
|
3056
3072
|
}
|
|
3057
3073
|
`;
|
|
3058
|
-
var CloseButton = ({
|
|
3059
|
-
onClick,
|
|
3060
|
-
title = "Remove track"
|
|
3061
|
-
}) => /* @__PURE__ */ jsx27(StyledCloseButton, { onClick, title, children: /* @__PURE__ */ jsx27(XIcon, { size: 12, weight: "bold" }) });
|
|
3074
|
+
var CloseButton = ({ onClick, title = "Remove track" }) => /* @__PURE__ */ jsx28(StyledCloseButton, { onClick, title, children: /* @__PURE__ */ jsx28(XIcon, { size: 12, weight: "bold" }) });
|
|
3062
3075
|
|
|
3063
3076
|
// src/components/TrackControls/Controls.tsx
|
|
3064
3077
|
import styled27 from "styled-components";
|
|
@@ -3094,23 +3107,23 @@ var Header = styled28.header`
|
|
|
3094
3107
|
|
|
3095
3108
|
// src/components/TrackControls/VolumeDownIcon.tsx
|
|
3096
3109
|
import { SpeakerLowIcon } from "@phosphor-icons/react";
|
|
3097
|
-
import { jsx as
|
|
3098
|
-
var VolumeDownIcon = (props) => /* @__PURE__ */
|
|
3110
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
3111
|
+
var VolumeDownIcon = (props) => /* @__PURE__ */ jsx29(SpeakerLowIcon, { weight: "light", ...props });
|
|
3099
3112
|
|
|
3100
3113
|
// src/components/TrackControls/VolumeUpIcon.tsx
|
|
3101
3114
|
import { SpeakerHighIcon } from "@phosphor-icons/react";
|
|
3102
|
-
import { jsx as
|
|
3103
|
-
var VolumeUpIcon = (props) => /* @__PURE__ */
|
|
3115
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
3116
|
+
var VolumeUpIcon = (props) => /* @__PURE__ */ jsx30(SpeakerHighIcon, { weight: "light", ...props });
|
|
3104
3117
|
|
|
3105
3118
|
// src/components/TrackControls/TrashIcon.tsx
|
|
3106
3119
|
import { TrashIcon as PhosphorTrashIcon } from "@phosphor-icons/react";
|
|
3107
|
-
import { jsx as
|
|
3108
|
-
var TrashIcon = (props) => /* @__PURE__ */
|
|
3120
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
3121
|
+
var TrashIcon = (props) => /* @__PURE__ */ jsx31(PhosphorTrashIcon, { weight: "light", ...props });
|
|
3109
3122
|
|
|
3110
3123
|
// src/components/TrackControls/DotsIcon.tsx
|
|
3111
3124
|
import { DotsThreeIcon } from "@phosphor-icons/react";
|
|
3112
|
-
import { jsx as
|
|
3113
|
-
var DotsIcon = (props) => /* @__PURE__ */
|
|
3125
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
3126
|
+
var DotsIcon = (props) => /* @__PURE__ */ jsx32(DotsThreeIcon, { weight: "bold", ...props });
|
|
3114
3127
|
|
|
3115
3128
|
// src/components/TrackControls/Slider.tsx
|
|
3116
3129
|
import styled29 from "styled-components";
|
|
@@ -3178,10 +3191,10 @@ var SliderWrapper = styled30.label`
|
|
|
3178
3191
|
`;
|
|
3179
3192
|
|
|
3180
3193
|
// src/components/TrackMenu.tsx
|
|
3181
|
-
import
|
|
3194
|
+
import React18, { useState as useState6, useEffect as useEffect7, useRef as useRef8 } from "react";
|
|
3182
3195
|
import { createPortal } from "react-dom";
|
|
3183
3196
|
import styled31 from "styled-components";
|
|
3184
|
-
import { jsx as
|
|
3197
|
+
import { jsx as jsx33, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3185
3198
|
var MenuContainer = styled31.div`
|
|
3186
3199
|
position: relative;
|
|
3187
3200
|
display: inline-block;
|
|
@@ -3219,16 +3232,14 @@ var Divider = styled31.hr`
|
|
|
3219
3232
|
border-top: 1px solid rgba(128, 128, 128, 0.3);
|
|
3220
3233
|
margin: 0.35rem 0;
|
|
3221
3234
|
`;
|
|
3222
|
-
var TrackMenu = ({
|
|
3223
|
-
items: itemsProp
|
|
3224
|
-
}) => {
|
|
3235
|
+
var TrackMenu = ({ items: itemsProp }) => {
|
|
3225
3236
|
const [open, setOpen] = useState6(false);
|
|
3226
3237
|
const close = () => setOpen(false);
|
|
3227
3238
|
const items = typeof itemsProp === "function" ? itemsProp(close) : itemsProp;
|
|
3228
3239
|
const [dropdownPos, setDropdownPos] = useState6({ top: 0, left: 0 });
|
|
3229
|
-
const buttonRef =
|
|
3230
|
-
const dropdownRef =
|
|
3231
|
-
|
|
3240
|
+
const buttonRef = useRef8(null);
|
|
3241
|
+
const dropdownRef = useRef8(null);
|
|
3242
|
+
useEffect7(() => {
|
|
3232
3243
|
if (open && buttonRef.current) {
|
|
3233
3244
|
const rect = buttonRef.current.getBoundingClientRect();
|
|
3234
3245
|
setDropdownPos({
|
|
@@ -3237,7 +3248,7 @@ var TrackMenu = ({
|
|
|
3237
3248
|
});
|
|
3238
3249
|
}
|
|
3239
3250
|
}, [open]);
|
|
3240
|
-
|
|
3251
|
+
useEffect7(() => {
|
|
3241
3252
|
if (!open) return;
|
|
3242
3253
|
const handleClick = (e) => {
|
|
3243
3254
|
const target = e.target;
|
|
@@ -3249,7 +3260,7 @@ var TrackMenu = ({
|
|
|
3249
3260
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
3250
3261
|
}, [open]);
|
|
3251
3262
|
return /* @__PURE__ */ jsxs12(MenuContainer, { children: [
|
|
3252
|
-
/* @__PURE__ */
|
|
3263
|
+
/* @__PURE__ */ jsx33(
|
|
3253
3264
|
MenuButton,
|
|
3254
3265
|
{
|
|
3255
3266
|
ref: buttonRef,
|
|
@@ -3260,19 +3271,19 @@ var TrackMenu = ({
|
|
|
3260
3271
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3261
3272
|
title: "Track menu",
|
|
3262
3273
|
"aria-label": "Track menu",
|
|
3263
|
-
children: /* @__PURE__ */
|
|
3274
|
+
children: /* @__PURE__ */ jsx33(DotsIcon, { size: 16 })
|
|
3264
3275
|
}
|
|
3265
3276
|
),
|
|
3266
3277
|
open && typeof document !== "undefined" && createPortal(
|
|
3267
|
-
/* @__PURE__ */
|
|
3278
|
+
/* @__PURE__ */ jsx33(
|
|
3268
3279
|
Dropdown,
|
|
3269
3280
|
{
|
|
3270
3281
|
ref: dropdownRef,
|
|
3271
3282
|
$top: dropdownPos.top,
|
|
3272
3283
|
$left: dropdownPos.left,
|
|
3273
3284
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3274
|
-
children: items.map((item, index) => /* @__PURE__ */ jsxs12(
|
|
3275
|
-
index > 0 && /* @__PURE__ */
|
|
3285
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs12(React18.Fragment, { children: [
|
|
3286
|
+
index > 0 && /* @__PURE__ */ jsx33(Divider, {}),
|
|
3276
3287
|
item.content
|
|
3277
3288
|
] }, item.id))
|
|
3278
3289
|
}
|
|
@@ -3303,6 +3314,7 @@ export {
|
|
|
3303
3314
|
ClipBoundary,
|
|
3304
3315
|
ClipHeader,
|
|
3305
3316
|
ClipHeaderPresentational,
|
|
3317
|
+
ClipViewportOriginProvider,
|
|
3306
3318
|
CloseButton,
|
|
3307
3319
|
Controls,
|
|
3308
3320
|
DevicePixelRatioProvider,
|
|
@@ -3312,7 +3324,6 @@ export {
|
|
|
3312
3324
|
InlineLabel,
|
|
3313
3325
|
LoopRegion,
|
|
3314
3326
|
LoopRegionMarkers,
|
|
3315
|
-
MAX_CANVAS_WIDTH,
|
|
3316
3327
|
MasterVolumeControl,
|
|
3317
3328
|
Playhead,
|
|
3318
3329
|
PlayheadWithMarker,
|
|
@@ -3353,6 +3364,7 @@ export {
|
|
|
3353
3364
|
samplesToSeconds,
|
|
3354
3365
|
secondsToPixels,
|
|
3355
3366
|
secondsToSamples,
|
|
3367
|
+
useClipViewportOrigin,
|
|
3356
3368
|
useDevicePixelRatio,
|
|
3357
3369
|
usePlaylistInfo,
|
|
3358
3370
|
usePlayoutStatus,
|
|
@@ -3361,6 +3373,7 @@ export {
|
|
|
3361
3373
|
useScrollViewportSelector,
|
|
3362
3374
|
useTheme2 as useTheme,
|
|
3363
3375
|
useTrackControls,
|
|
3376
|
+
useVisibleChunkIndices,
|
|
3364
3377
|
waveformColorToCss
|
|
3365
3378
|
};
|
|
3366
3379
|
//# sourceMappingURL=index.mjs.map
|