@waveform-playlist/ui-components 7.1.2 → 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 +26 -3
- package/dist/index.d.ts +26 -3
- package/dist/index.js +434 -371
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +365 -304
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -5
package/dist/index.js
CHANGED
|
@@ -51,6 +51,7 @@ __export(index_exports, {
|
|
|
51
51
|
ClipBoundary: () => ClipBoundary,
|
|
52
52
|
ClipHeader: () => ClipHeader,
|
|
53
53
|
ClipHeaderPresentational: () => ClipHeaderPresentational,
|
|
54
|
+
ClipViewportOriginProvider: () => ClipViewportOriginProvider,
|
|
54
55
|
CloseButton: () => CloseButton,
|
|
55
56
|
Controls: () => Controls,
|
|
56
57
|
DevicePixelRatioProvider: () => DevicePixelRatioProvider,
|
|
@@ -100,6 +101,7 @@ __export(index_exports, {
|
|
|
100
101
|
samplesToSeconds: () => samplesToSeconds,
|
|
101
102
|
secondsToPixels: () => secondsToPixels,
|
|
102
103
|
secondsToSamples: () => secondsToSamples,
|
|
104
|
+
useClipViewportOrigin: () => useClipViewportOrigin,
|
|
103
105
|
useDevicePixelRatio: () => useDevicePixelRatio,
|
|
104
106
|
usePlaylistInfo: () => usePlaylistInfo,
|
|
105
107
|
usePlayoutStatus: () => usePlayoutStatus,
|
|
@@ -123,10 +125,7 @@ var PositionDisplay = import_styled_components.default.span`
|
|
|
123
125
|
color: ${(props) => props.theme?.textColor || "#333"};
|
|
124
126
|
user-select: none;
|
|
125
127
|
`;
|
|
126
|
-
var AudioPosition = ({
|
|
127
|
-
formattedTime,
|
|
128
|
-
className
|
|
129
|
-
}) => {
|
|
128
|
+
var AudioPosition = ({ formattedTime, className }) => {
|
|
130
129
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PositionDisplay, { className, "aria-label": "Audio position", children: formattedTime });
|
|
131
130
|
};
|
|
132
131
|
|
|
@@ -146,7 +145,9 @@ var BaseButton = import_styled_components2.default.button`
|
|
|
146
145
|
border-radius: ${(props) => props.theme.borderRadius};
|
|
147
146
|
cursor: pointer;
|
|
148
147
|
outline: none;
|
|
149
|
-
transition:
|
|
148
|
+
transition:
|
|
149
|
+
background-color 0.15s ease-in-out,
|
|
150
|
+
border-color 0.15s ease-in-out,
|
|
150
151
|
box-shadow 0.15s ease-in-out;
|
|
151
152
|
|
|
152
153
|
&:hover:not(:disabled) {
|
|
@@ -243,7 +244,9 @@ var BaseInput = import_styled_components5.default.input`
|
|
|
243
244
|
border: 1px solid ${(props) => props.theme.inputBorder};
|
|
244
245
|
border-radius: ${(props) => props.theme.borderRadius};
|
|
245
246
|
outline: none;
|
|
246
|
-
transition:
|
|
247
|
+
transition:
|
|
248
|
+
border-color 0.15s ease-in-out,
|
|
249
|
+
box-shadow 0.15s ease-in-out;
|
|
247
250
|
|
|
248
251
|
&::placeholder {
|
|
249
252
|
color: ${(props) => props.theme.inputPlaceholder};
|
|
@@ -311,7 +314,9 @@ var BaseSelect = import_styled_components7.default.select`
|
|
|
311
314
|
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");
|
|
312
315
|
background-repeat: no-repeat;
|
|
313
316
|
background-position: right 0.75rem center;
|
|
314
|
-
transition:
|
|
317
|
+
transition:
|
|
318
|
+
border-color 0.15s ease-in-out,
|
|
319
|
+
box-shadow 0.15s ease-in-out;
|
|
315
320
|
|
|
316
321
|
&:focus {
|
|
317
322
|
border-color: ${(props) => props.theme.inputFocusBorder};
|
|
@@ -357,7 +362,9 @@ var BaseSlider = import_styled_components8.default.input.attrs({ type: "range" }
|
|
|
357
362
|
border-radius: 50%;
|
|
358
363
|
cursor: pointer;
|
|
359
364
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
360
|
-
transition:
|
|
365
|
+
transition:
|
|
366
|
+
transform 0.15s ease,
|
|
367
|
+
box-shadow 0.15s ease;
|
|
361
368
|
}
|
|
362
369
|
|
|
363
370
|
&::-webkit-slider-thumb:hover {
|
|
@@ -374,7 +381,9 @@ var BaseSlider = import_styled_components8.default.input.attrs({ type: "range" }
|
|
|
374
381
|
border-radius: 50%;
|
|
375
382
|
cursor: pointer;
|
|
376
383
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
377
|
-
transition:
|
|
384
|
+
transition:
|
|
385
|
+
transform 0.15s ease,
|
|
386
|
+
box-shadow 0.15s ease;
|
|
378
387
|
}
|
|
379
388
|
|
|
380
389
|
&::-moz-range-thumb:hover {
|
|
@@ -442,7 +451,7 @@ var AutomaticScrollCheckbox = ({
|
|
|
442
451
|
};
|
|
443
452
|
|
|
444
453
|
// src/components/Channel.tsx
|
|
445
|
-
var
|
|
454
|
+
var import_react4 = require("react");
|
|
446
455
|
var import_styled_components9 = __toESM(require("styled-components"));
|
|
447
456
|
|
|
448
457
|
// src/wfpl-theme.ts
|
|
@@ -637,10 +646,7 @@ var ViewportStoreContext = (0, import_react.createContext)(null);
|
|
|
637
646
|
var EMPTY_SUBSCRIBE = () => () => {
|
|
638
647
|
};
|
|
639
648
|
var NULL_SNAPSHOT = () => null;
|
|
640
|
-
var ScrollViewportProvider = ({
|
|
641
|
-
containerRef,
|
|
642
|
-
children
|
|
643
|
-
}) => {
|
|
649
|
+
var ScrollViewportProvider = ({ containerRef, children }) => {
|
|
644
650
|
const storeRef = (0, import_react.useRef)(null);
|
|
645
651
|
if (storeRef.current === null) {
|
|
646
652
|
storeRef.current = new ViewportStore();
|
|
@@ -695,7 +701,7 @@ function useScrollViewportSelector(selector) {
|
|
|
695
701
|
() => selector(null)
|
|
696
702
|
);
|
|
697
703
|
}
|
|
698
|
-
function useVisibleChunkIndices(totalWidth, chunkWidth) {
|
|
704
|
+
function useVisibleChunkIndices(totalWidth, chunkWidth, originX = 0) {
|
|
699
705
|
const visibleChunkKey = useScrollViewportSelector((viewport) => {
|
|
700
706
|
const totalChunks = Math.ceil(totalWidth / chunkWidth);
|
|
701
707
|
const indices = [];
|
|
@@ -703,8 +709,9 @@ function useVisibleChunkIndices(totalWidth, chunkWidth) {
|
|
|
703
709
|
const chunkLeft = i * chunkWidth;
|
|
704
710
|
const thisChunkWidth = Math.min(totalWidth - chunkLeft, chunkWidth);
|
|
705
711
|
if (viewport) {
|
|
706
|
-
const
|
|
707
|
-
|
|
712
|
+
const chunkLeftGlobal = originX + chunkLeft;
|
|
713
|
+
const chunkEndGlobal = chunkLeftGlobal + thisChunkWidth;
|
|
714
|
+
if (chunkEndGlobal <= viewport.visibleStart || chunkLeftGlobal >= viewport.visibleEnd) {
|
|
708
715
|
continue;
|
|
709
716
|
}
|
|
710
717
|
}
|
|
@@ -718,17 +725,27 @@ function useVisibleChunkIndices(totalWidth, chunkWidth) {
|
|
|
718
725
|
);
|
|
719
726
|
}
|
|
720
727
|
|
|
721
|
-
// src/
|
|
728
|
+
// src/contexts/ClipViewportOrigin.tsx
|
|
722
729
|
var import_react2 = require("react");
|
|
730
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
731
|
+
var ClipViewportOriginContext = (0, import_react2.createContext)(0);
|
|
732
|
+
var ClipViewportOriginProvider = ({
|
|
733
|
+
originX,
|
|
734
|
+
children
|
|
735
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ClipViewportOriginContext.Provider, { value: originX, children });
|
|
736
|
+
var useClipViewportOrigin = () => (0, import_react2.useContext)(ClipViewportOriginContext);
|
|
737
|
+
|
|
738
|
+
// src/hooks/useChunkedCanvasRefs.ts
|
|
739
|
+
var import_react3 = require("react");
|
|
723
740
|
function useChunkedCanvasRefs() {
|
|
724
|
-
const canvasMapRef = (0,
|
|
725
|
-
const canvasRef = (0,
|
|
741
|
+
const canvasMapRef = (0, import_react3.useRef)(/* @__PURE__ */ new Map());
|
|
742
|
+
const canvasRef = (0, import_react3.useCallback)((canvas) => {
|
|
726
743
|
if (canvas !== null) {
|
|
727
744
|
const idx = parseInt(canvas.dataset.index, 10);
|
|
728
745
|
canvasMapRef.current.set(idx, canvas);
|
|
729
746
|
}
|
|
730
747
|
}, []);
|
|
731
|
-
(0,
|
|
748
|
+
(0, import_react3.useEffect)(() => {
|
|
732
749
|
const map = canvasMapRef.current;
|
|
733
750
|
for (const [idx, canvas] of map.entries()) {
|
|
734
751
|
if (!canvas.isConnected) {
|
|
@@ -741,7 +758,7 @@ function useChunkedCanvasRefs() {
|
|
|
741
758
|
|
|
742
759
|
// src/components/Channel.tsx
|
|
743
760
|
var import_core = require("@waveform-playlist/core");
|
|
744
|
-
var
|
|
761
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
745
762
|
function createCanvasFillStyle(ctx, color, width, height) {
|
|
746
763
|
if (!isWaveformGradient(color)) {
|
|
747
764
|
return color;
|
|
@@ -802,8 +819,9 @@ var Channel = (props) => {
|
|
|
802
819
|
drawMode = "inverted"
|
|
803
820
|
} = props;
|
|
804
821
|
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
805
|
-
const
|
|
806
|
-
(
|
|
822
|
+
const clipOriginX = useClipViewportOrigin();
|
|
823
|
+
const visibleChunkIndices = useVisibleChunkIndices(length, import_core.MAX_CANVAS_WIDTH, clipOriginX);
|
|
824
|
+
(0, import_react4.useLayoutEffect)(() => {
|
|
807
825
|
const step = barWidth + barGap;
|
|
808
826
|
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
809
827
|
const globalPixelOffset = canvasIdx * import_core.MAX_CANVAS_WIDTH;
|
|
@@ -822,12 +840,7 @@ var Channel = (props) => {
|
|
|
822
840
|
} else {
|
|
823
841
|
fillColor = waveOutlineColor;
|
|
824
842
|
}
|
|
825
|
-
ctx.fillStyle = createCanvasFillStyle(
|
|
826
|
-
ctx,
|
|
827
|
-
fillColor,
|
|
828
|
-
canvasWidth,
|
|
829
|
-
waveHeight
|
|
830
|
-
);
|
|
843
|
+
ctx.fillStyle = createCanvasFillStyle(ctx, fillColor, canvasWidth, waveHeight);
|
|
831
844
|
const canvasStartGlobal = globalPixelOffset;
|
|
832
845
|
const canvasEndGlobal = globalPixelOffset + canvasWidth;
|
|
833
846
|
const firstBarGlobal = Math.floor((canvasStartGlobal - barWidth + step) / step) * step;
|
|
@@ -867,7 +880,7 @@ var Channel = (props) => {
|
|
|
867
880
|
const waveforms = visibleChunkIndices.map((i) => {
|
|
868
881
|
const chunkLeft = i * import_core.MAX_CANVAS_WIDTH;
|
|
869
882
|
const currentWidth = Math.min(length - chunkLeft, import_core.MAX_CANVAS_WIDTH);
|
|
870
|
-
return /* @__PURE__ */ (0,
|
|
883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
871
884
|
Waveform,
|
|
872
885
|
{
|
|
873
886
|
$cssWidth: currentWidth,
|
|
@@ -883,7 +896,7 @@ var Channel = (props) => {
|
|
|
883
896
|
});
|
|
884
897
|
const bgColor = waveFillColor;
|
|
885
898
|
const backgroundCss = transparentBackground ? "transparent" : waveformColorToCss(bgColor);
|
|
886
|
-
return /* @__PURE__ */ (0,
|
|
899
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
887
900
|
Wrapper,
|
|
888
901
|
{
|
|
889
902
|
$index: index,
|
|
@@ -897,8 +910,8 @@ var Channel = (props) => {
|
|
|
897
910
|
};
|
|
898
911
|
|
|
899
912
|
// src/components/ErrorBoundary.tsx
|
|
900
|
-
var
|
|
901
|
-
var
|
|
913
|
+
var import_react5 = __toESM(require("react"));
|
|
914
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
902
915
|
var errorContainerStyle = {
|
|
903
916
|
padding: "16px",
|
|
904
917
|
background: "#1a1a2e",
|
|
@@ -912,7 +925,7 @@ var errorContainerStyle = {
|
|
|
912
925
|
alignItems: "center",
|
|
913
926
|
justifyContent: "center"
|
|
914
927
|
};
|
|
915
|
-
var PlaylistErrorBoundary = class extends
|
|
928
|
+
var PlaylistErrorBoundary = class extends import_react5.default.Component {
|
|
916
929
|
constructor(props) {
|
|
917
930
|
super(props);
|
|
918
931
|
this.state = { hasError: false, error: null };
|
|
@@ -928,7 +941,7 @@ var PlaylistErrorBoundary = class extends import_react4.default.Component {
|
|
|
928
941
|
if (this.props.fallback) {
|
|
929
942
|
return this.props.fallback;
|
|
930
943
|
}
|
|
931
|
-
return /* @__PURE__ */ (0,
|
|
944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: errorContainerStyle, children: "Waveform playlist encountered an error. Check console for details." });
|
|
932
945
|
}
|
|
933
946
|
return this.props.children;
|
|
934
947
|
}
|
|
@@ -941,7 +954,7 @@ var import_utilities = require("@dnd-kit/utilities");
|
|
|
941
954
|
|
|
942
955
|
// src/components/ClipHeader.tsx
|
|
943
956
|
var import_styled_components10 = __toESM(require("styled-components"));
|
|
944
|
-
var
|
|
957
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
945
958
|
var CLIP_HEADER_HEIGHT = 22;
|
|
946
959
|
var HeaderContainer = import_styled_components10.default.div`
|
|
947
960
|
position: relative;
|
|
@@ -981,15 +994,7 @@ var ClipHeaderPresentational = ({
|
|
|
981
994
|
trackName,
|
|
982
995
|
isSelected = false
|
|
983
996
|
}) => {
|
|
984
|
-
return /* @__PURE__ */ (0,
|
|
985
|
-
HeaderContainer,
|
|
986
|
-
{
|
|
987
|
-
$isDragging: false,
|
|
988
|
-
$interactive: false,
|
|
989
|
-
$isSelected: isSelected,
|
|
990
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TrackName, { children: trackName })
|
|
991
|
-
}
|
|
992
|
-
);
|
|
997
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderContainer, { $isDragging: false, $interactive: false, $isSelected: isSelected, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TrackName, { children: trackName }) });
|
|
993
998
|
};
|
|
994
999
|
var ClipHeader = ({
|
|
995
1000
|
clipId,
|
|
@@ -1001,16 +1006,10 @@ var ClipHeader = ({
|
|
|
1001
1006
|
dragHandleProps
|
|
1002
1007
|
}) => {
|
|
1003
1008
|
if (disableDrag || !dragHandleProps) {
|
|
1004
|
-
return /* @__PURE__ */ (0,
|
|
1005
|
-
ClipHeaderPresentational,
|
|
1006
|
-
{
|
|
1007
|
-
trackName,
|
|
1008
|
-
isSelected
|
|
1009
|
-
}
|
|
1010
|
-
);
|
|
1009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ClipHeaderPresentational, { trackName, isSelected });
|
|
1011
1010
|
}
|
|
1012
1011
|
const { attributes, listeners, setActivatorNodeRef } = dragHandleProps;
|
|
1013
|
-
return /* @__PURE__ */ (0,
|
|
1012
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1014
1013
|
HeaderContainer,
|
|
1015
1014
|
{
|
|
1016
1015
|
ref: setActivatorNodeRef,
|
|
@@ -1019,15 +1018,15 @@ var ClipHeader = ({
|
|
|
1019
1018
|
$isSelected: isSelected,
|
|
1020
1019
|
...listeners,
|
|
1021
1020
|
...attributes,
|
|
1022
|
-
children: /* @__PURE__ */ (0,
|
|
1021
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TrackName, { children: trackName })
|
|
1023
1022
|
}
|
|
1024
1023
|
);
|
|
1025
1024
|
};
|
|
1026
1025
|
|
|
1027
1026
|
// src/components/ClipBoundary.tsx
|
|
1028
|
-
var
|
|
1027
|
+
var import_react6 = __toESM(require("react"));
|
|
1029
1028
|
var import_styled_components11 = __toESM(require("styled-components"));
|
|
1030
|
-
var
|
|
1029
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1031
1030
|
var CLIP_BOUNDARY_WIDTH = 8;
|
|
1032
1031
|
var CLIP_BOUNDARY_WIDTH_TOUCH = 24;
|
|
1033
1032
|
var BoundaryContainer = import_styled_components11.default.div`
|
|
@@ -1067,12 +1066,12 @@ var ClipBoundary = ({
|
|
|
1067
1066
|
dragHandleProps,
|
|
1068
1067
|
touchOptimized = false
|
|
1069
1068
|
}) => {
|
|
1070
|
-
const [isHovered, setIsHovered] =
|
|
1069
|
+
const [isHovered, setIsHovered] = import_react6.default.useState(false);
|
|
1071
1070
|
if (!dragHandleProps) {
|
|
1072
1071
|
return null;
|
|
1073
1072
|
}
|
|
1074
1073
|
const { attributes, listeners, setActivatorNodeRef, isDragging } = dragHandleProps;
|
|
1075
|
-
return /* @__PURE__ */ (0,
|
|
1074
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1076
1075
|
BoundaryContainer,
|
|
1077
1076
|
{
|
|
1078
1077
|
ref: setActivatorNodeRef,
|
|
@@ -1092,7 +1091,7 @@ var ClipBoundary = ({
|
|
|
1092
1091
|
|
|
1093
1092
|
// src/components/FadeOverlay.tsx
|
|
1094
1093
|
var import_styled_components12 = __toESM(require("styled-components"));
|
|
1095
|
-
var
|
|
1094
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1096
1095
|
var FadeContainer = import_styled_components12.default.div.attrs((props) => ({
|
|
1097
1096
|
style: {
|
|
1098
1097
|
left: `${props.$left}px`,
|
|
@@ -1149,17 +1148,11 @@ var FadeOverlay = ({
|
|
|
1149
1148
|
const theme = (0, import_styled_components12.useTheme)();
|
|
1150
1149
|
if (width < 1) return null;
|
|
1151
1150
|
const fillColor = color || theme?.fadeOverlayColor || "rgba(0, 0, 0, 0.4)";
|
|
1152
|
-
return /* @__PURE__ */ (0,
|
|
1153
|
-
"path",
|
|
1154
|
-
{
|
|
1155
|
-
d: generateFadePath(width, 100, curveType),
|
|
1156
|
-
fill: fillColor
|
|
1157
|
-
}
|
|
1158
|
-
) }) });
|
|
1151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FadeContainer, { $left: left, $width: width, $type: type, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FadeSvg, { $type: type, viewBox: `0 0 ${width} 100`, preserveAspectRatio: "none", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: generateFadePath(width, 100, curveType), fill: fillColor }) }) });
|
|
1159
1152
|
};
|
|
1160
1153
|
|
|
1161
1154
|
// src/components/Clip.tsx
|
|
1162
|
-
var
|
|
1155
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1163
1156
|
var ClipContainer = import_styled_components13.default.div.attrs((props) => ({
|
|
1164
1157
|
style: props.$isOverlay ? {} : {
|
|
1165
1158
|
left: `${props.$left}px`,
|
|
@@ -1244,7 +1237,7 @@ var Clip = ({
|
|
|
1244
1237
|
zIndex: isDragging ? 100 : void 0
|
|
1245
1238
|
// Below controls (z-index: 999) but above other clips
|
|
1246
1239
|
} : void 0;
|
|
1247
|
-
return /* @__PURE__ */ (0,
|
|
1240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1248
1241
|
ClipContainer,
|
|
1249
1242
|
{
|
|
1250
1243
|
ref: setNodeRef,
|
|
@@ -1257,7 +1250,7 @@ var Clip = ({
|
|
|
1257
1250
|
"data-track-id": trackId,
|
|
1258
1251
|
onMouseDown,
|
|
1259
1252
|
children: [
|
|
1260
|
-
showHeader && /* @__PURE__ */ (0,
|
|
1253
|
+
showHeader && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1261
1254
|
ClipHeader,
|
|
1262
1255
|
{
|
|
1263
1256
|
clipId,
|
|
@@ -1269,9 +1262,9 @@ var Clip = ({
|
|
|
1269
1262
|
dragHandleProps: enableDrag ? { attributes, listeners, setActivatorNodeRef } : void 0
|
|
1270
1263
|
}
|
|
1271
1264
|
),
|
|
1272
|
-
/* @__PURE__ */ (0,
|
|
1265
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ClipViewportOriginProvider, { originX: left, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ChannelsWrapper, { $isOverlay: isOverlay, children: [
|
|
1273
1266
|
children,
|
|
1274
|
-
showFades && fadeIn && fadeIn.duration > 0 && /* @__PURE__ */ (0,
|
|
1267
|
+
showFades && fadeIn && fadeIn.duration > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1275
1268
|
FadeOverlay,
|
|
1276
1269
|
{
|
|
1277
1270
|
left: 0,
|
|
@@ -1280,7 +1273,7 @@ var Clip = ({
|
|
|
1280
1273
|
curveType: fadeIn.type
|
|
1281
1274
|
}
|
|
1282
1275
|
),
|
|
1283
|
-
showFades && fadeOut && fadeOut.duration > 0 && /* @__PURE__ */ (0,
|
|
1276
|
+
showFades && fadeOut && fadeOut.duration > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1284
1277
|
FadeOverlay,
|
|
1285
1278
|
{
|
|
1286
1279
|
left: width - Math.floor(fadeOut.duration * sampleRate / samplesPerPixel),
|
|
@@ -1289,9 +1282,9 @@ var Clip = ({
|
|
|
1289
1282
|
curveType: fadeOut.type
|
|
1290
1283
|
}
|
|
1291
1284
|
)
|
|
1292
|
-
] }),
|
|
1293
|
-
showHeader && !disableHeaderDrag && !isOverlay && /* @__PURE__ */ (0,
|
|
1294
|
-
/* @__PURE__ */ (0,
|
|
1285
|
+
] }) }),
|
|
1286
|
+
showHeader && !disableHeaderDrag && !isOverlay && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1287
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1295
1288
|
ClipBoundary,
|
|
1296
1289
|
{
|
|
1297
1290
|
clipId,
|
|
@@ -1307,7 +1300,7 @@ var Clip = ({
|
|
|
1307
1300
|
}
|
|
1308
1301
|
}
|
|
1309
1302
|
),
|
|
1310
|
-
/* @__PURE__ */ (0,
|
|
1303
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1311
1304
|
ClipBoundary,
|
|
1312
1305
|
{
|
|
1313
1306
|
clipId,
|
|
@@ -1331,7 +1324,7 @@ var Clip = ({
|
|
|
1331
1324
|
|
|
1332
1325
|
// src/components/MasterVolumeControl.tsx
|
|
1333
1326
|
var import_styled_components14 = __toESM(require("styled-components"));
|
|
1334
|
-
var
|
|
1327
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1335
1328
|
var VolumeContainer = import_styled_components14.default.div`
|
|
1336
1329
|
display: inline-flex;
|
|
1337
1330
|
align-items: center;
|
|
@@ -1353,9 +1346,9 @@ var MasterVolumeControl = ({
|
|
|
1353
1346
|
const handleChange = (e) => {
|
|
1354
1347
|
onChange(parseFloat(e.target.value) / 100);
|
|
1355
1348
|
};
|
|
1356
|
-
return /* @__PURE__ */ (0,
|
|
1357
|
-
/* @__PURE__ */ (0,
|
|
1358
|
-
/* @__PURE__ */ (0,
|
|
1349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(VolumeContainer, { className, children: [
|
|
1350
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VolumeLabel, { htmlFor: "master-gain", children: "Master Volume" }),
|
|
1351
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1359
1352
|
VolumeSlider,
|
|
1360
1353
|
{
|
|
1361
1354
|
min: "0",
|
|
@@ -1370,9 +1363,9 @@ var MasterVolumeControl = ({
|
|
|
1370
1363
|
};
|
|
1371
1364
|
|
|
1372
1365
|
// src/components/Playhead.tsx
|
|
1373
|
-
var
|
|
1366
|
+
var import_react7 = require("react");
|
|
1374
1367
|
var import_styled_components15 = __toESM(require("styled-components"));
|
|
1375
|
-
var
|
|
1368
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1376
1369
|
var PlayheadLine = import_styled_components15.default.div.attrs((props) => ({
|
|
1377
1370
|
style: {
|
|
1378
1371
|
transform: `translate3d(${props.$position}px, 0, 0)`
|
|
@@ -1389,7 +1382,7 @@ var PlayheadLine = import_styled_components15.default.div.attrs((props) => ({
|
|
|
1389
1382
|
will-change: transform;
|
|
1390
1383
|
`;
|
|
1391
1384
|
var Playhead = ({ position, color = "#ff0000" }) => {
|
|
1392
|
-
return /* @__PURE__ */ (0,
|
|
1385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PlayheadLine, { $position: position, $color: color });
|
|
1393
1386
|
};
|
|
1394
1387
|
var PlayheadWithMarkerContainer = import_styled_components15.default.div`
|
|
1395
1388
|
position: absolute;
|
|
@@ -1429,9 +1422,9 @@ var PlayheadWithMarker = ({
|
|
|
1429
1422
|
controlsOffset,
|
|
1430
1423
|
getAudioContextTime
|
|
1431
1424
|
}) => {
|
|
1432
|
-
const containerRef = (0,
|
|
1433
|
-
const animationFrameRef = (0,
|
|
1434
|
-
(0,
|
|
1425
|
+
const containerRef = (0, import_react7.useRef)(null);
|
|
1426
|
+
const animationFrameRef = (0, import_react7.useRef)(null);
|
|
1427
|
+
(0, import_react7.useEffect)(() => {
|
|
1435
1428
|
const updatePosition = () => {
|
|
1436
1429
|
if (containerRef.current) {
|
|
1437
1430
|
let time;
|
|
@@ -1459,24 +1452,33 @@ var PlayheadWithMarker = ({
|
|
|
1459
1452
|
animationFrameRef.current = null;
|
|
1460
1453
|
}
|
|
1461
1454
|
};
|
|
1462
|
-
}, [
|
|
1463
|
-
|
|
1455
|
+
}, [
|
|
1456
|
+
isPlaying,
|
|
1457
|
+
sampleRate,
|
|
1458
|
+
samplesPerPixel,
|
|
1459
|
+
controlsOffset,
|
|
1460
|
+
currentTimeRef,
|
|
1461
|
+
playbackStartTimeRef,
|
|
1462
|
+
audioStartPositionRef,
|
|
1463
|
+
getAudioContextTime
|
|
1464
|
+
]);
|
|
1465
|
+
(0, import_react7.useEffect)(() => {
|
|
1464
1466
|
if (!isPlaying && containerRef.current) {
|
|
1465
1467
|
const time = currentTimeRef.current ?? 0;
|
|
1466
1468
|
const pos = time * sampleRate / samplesPerPixel + controlsOffset;
|
|
1467
1469
|
containerRef.current.style.transform = `translate3d(${pos}px, 0, 0)`;
|
|
1468
1470
|
}
|
|
1469
1471
|
});
|
|
1470
|
-
return /* @__PURE__ */ (0,
|
|
1471
|
-
/* @__PURE__ */ (0,
|
|
1472
|
-
/* @__PURE__ */ (0,
|
|
1472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(PlayheadWithMarkerContainer, { ref: containerRef, $color: color, children: [
|
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MarkerTriangle, { $color: color }),
|
|
1474
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MarkerLine, { $color: color })
|
|
1473
1475
|
] });
|
|
1474
1476
|
};
|
|
1475
1477
|
|
|
1476
1478
|
// src/components/Playlist.tsx
|
|
1477
1479
|
var import_styled_components16 = __toESM(require("styled-components"));
|
|
1478
|
-
var
|
|
1479
|
-
var
|
|
1480
|
+
var import_react8 = require("react");
|
|
1481
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1480
1482
|
var Wrapper2 = import_styled_components16.default.div`
|
|
1481
1483
|
overflow-y: hidden;
|
|
1482
1484
|
overflow-x: auto;
|
|
@@ -1530,41 +1532,37 @@ var Playlist = ({
|
|
|
1530
1532
|
isSelecting,
|
|
1531
1533
|
"data-playlist-state": playlistState
|
|
1532
1534
|
}) => {
|
|
1533
|
-
const wrapperRef = (0,
|
|
1534
|
-
const handleRef = (0,
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
] })
|
|
1559
|
-
]
|
|
1560
|
-
}
|
|
1561
|
-
) }) });
|
|
1535
|
+
const wrapperRef = (0, import_react8.useRef)(null);
|
|
1536
|
+
const handleRef = (0, import_react8.useCallback)(
|
|
1537
|
+
(el) => {
|
|
1538
|
+
wrapperRef.current = el;
|
|
1539
|
+
scrollContainerRef?.(el);
|
|
1540
|
+
},
|
|
1541
|
+
[scrollContainerRef]
|
|
1542
|
+
);
|
|
1543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Wrapper2, { "data-scroll-container": "true", "data-playlist-state": playlistState, ref: handleRef, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ScrollViewportProvider, { containerRef: wrapperRef, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ScrollContainer, { $backgroundColor: backgroundColor, $width: scrollContainerWidth, children: [
|
|
1544
|
+
timescale && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TimescaleWrapper, { $width: timescaleWidth, $backgroundColor: timescaleBackgroundColor, children: timescale }),
|
|
1545
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(TracksContainer, { $width: tracksWidth, $backgroundColor: backgroundColor, children: [
|
|
1546
|
+
children,
|
|
1547
|
+
(onTracksClick || onTracksMouseDown) && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1548
|
+
ClickOverlay,
|
|
1549
|
+
{
|
|
1550
|
+
$controlsWidth: controlsWidth,
|
|
1551
|
+
$isSelecting: isSelecting,
|
|
1552
|
+
onClick: onTracksClick,
|
|
1553
|
+
onMouseDown: onTracksMouseDown,
|
|
1554
|
+
onMouseMove: onTracksMouseMove,
|
|
1555
|
+
onMouseUp: onTracksMouseUp
|
|
1556
|
+
}
|
|
1557
|
+
)
|
|
1558
|
+
] })
|
|
1559
|
+
] }) }) });
|
|
1562
1560
|
};
|
|
1563
1561
|
var StyledPlaylist = (0, import_styled_components16.withTheme)(Playlist);
|
|
1564
1562
|
|
|
1565
1563
|
// src/components/Selection.tsx
|
|
1566
1564
|
var import_styled_components17 = __toESM(require("styled-components"));
|
|
1567
|
-
var
|
|
1565
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1568
1566
|
var SelectionOverlay = import_styled_components17.default.div.attrs((props) => ({
|
|
1569
1567
|
style: {
|
|
1570
1568
|
left: `${props.$left}px`,
|
|
@@ -1588,13 +1586,13 @@ var Selection = ({
|
|
|
1588
1586
|
if (width <= 0) {
|
|
1589
1587
|
return null;
|
|
1590
1588
|
}
|
|
1591
|
-
return /* @__PURE__ */ (0,
|
|
1589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SelectionOverlay, { $left: startPosition, $width: width, $color: color, "data-selection": true });
|
|
1592
1590
|
};
|
|
1593
1591
|
|
|
1594
1592
|
// src/components/LoopRegion.tsx
|
|
1595
|
-
var
|
|
1593
|
+
var import_react9 = require("react");
|
|
1596
1594
|
var import_styled_components18 = __toESM(require("styled-components"));
|
|
1597
|
-
var
|
|
1595
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1598
1596
|
var LoopRegionOverlayDiv = import_styled_components18.default.div.attrs((props) => ({
|
|
1599
1597
|
style: {
|
|
1600
1598
|
left: `${props.$left}px`,
|
|
@@ -1643,8 +1641,8 @@ var LoopRegion = ({
|
|
|
1643
1641
|
if (width <= 0) {
|
|
1644
1642
|
return null;
|
|
1645
1643
|
}
|
|
1646
|
-
return /* @__PURE__ */ (0,
|
|
1647
|
-
/* @__PURE__ */ (0,
|
|
1644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1645
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1648
1646
|
LoopRegionOverlayDiv,
|
|
1649
1647
|
{
|
|
1650
1648
|
$left: startPosition,
|
|
@@ -1653,7 +1651,7 @@ var LoopRegion = ({
|
|
|
1653
1651
|
"data-loop-region": true
|
|
1654
1652
|
}
|
|
1655
1653
|
),
|
|
1656
|
-
/* @__PURE__ */ (0,
|
|
1654
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1657
1655
|
LoopMarker,
|
|
1658
1656
|
{
|
|
1659
1657
|
$left: startPosition,
|
|
@@ -1662,7 +1660,7 @@ var LoopRegion = ({
|
|
|
1662
1660
|
"data-loop-marker": "start"
|
|
1663
1661
|
}
|
|
1664
1662
|
),
|
|
1665
|
-
/* @__PURE__ */ (0,
|
|
1663
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1666
1664
|
LoopMarker,
|
|
1667
1665
|
{
|
|
1668
1666
|
$left: endPosition - 2,
|
|
@@ -1743,71 +1741,77 @@ var LoopRegionMarkers = ({
|
|
|
1743
1741
|
minPosition = 0,
|
|
1744
1742
|
maxPosition = Infinity
|
|
1745
1743
|
}) => {
|
|
1746
|
-
const [draggingMarker, setDraggingMarker] = (0,
|
|
1747
|
-
const dragStartX = (0,
|
|
1748
|
-
const dragStartPosition = (0,
|
|
1749
|
-
const dragStartEnd = (0,
|
|
1744
|
+
const [draggingMarker, setDraggingMarker] = (0, import_react9.useState)(null);
|
|
1745
|
+
const dragStartX = (0, import_react9.useRef)(0);
|
|
1746
|
+
const dragStartPosition = (0, import_react9.useRef)(0);
|
|
1747
|
+
const dragStartEnd = (0, import_react9.useRef)(0);
|
|
1750
1748
|
const width = Math.max(0, endPosition - startPosition);
|
|
1751
|
-
const handleMarkerMouseDown = (0,
|
|
1752
|
-
e
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
const
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1749
|
+
const handleMarkerMouseDown = (0, import_react9.useCallback)(
|
|
1750
|
+
(e, marker) => {
|
|
1751
|
+
e.preventDefault();
|
|
1752
|
+
e.stopPropagation();
|
|
1753
|
+
setDraggingMarker(marker);
|
|
1754
|
+
dragStartX.current = e.clientX;
|
|
1755
|
+
dragStartPosition.current = marker === "start" ? startPosition : endPosition;
|
|
1756
|
+
const handleMouseMove = (moveEvent) => {
|
|
1757
|
+
const delta = moveEvent.clientX - dragStartX.current;
|
|
1758
|
+
const newPosition = dragStartPosition.current + delta;
|
|
1759
|
+
if (marker === "start") {
|
|
1760
|
+
const clampedPosition = Math.max(minPosition, Math.min(endPosition - 10, newPosition));
|
|
1761
|
+
onLoopStartChange?.(clampedPosition);
|
|
1762
|
+
} else {
|
|
1763
|
+
const clampedPosition = Math.max(startPosition + 10, Math.min(maxPosition, newPosition));
|
|
1764
|
+
onLoopEndChange?.(clampedPosition);
|
|
1765
|
+
}
|
|
1766
|
+
};
|
|
1767
|
+
const handleMouseUp = () => {
|
|
1768
|
+
setDraggingMarker(null);
|
|
1769
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
1770
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
1771
|
+
};
|
|
1772
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
1773
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
1774
|
+
},
|
|
1775
|
+
[startPosition, endPosition, minPosition, maxPosition, onLoopStartChange, onLoopEndChange]
|
|
1776
|
+
);
|
|
1777
|
+
const handleRegionMouseDown = (0, import_react9.useCallback)(
|
|
1778
|
+
(e) => {
|
|
1779
|
+
e.preventDefault();
|
|
1780
|
+
e.stopPropagation();
|
|
1781
|
+
setDraggingMarker("region");
|
|
1782
|
+
dragStartX.current = e.clientX;
|
|
1783
|
+
dragStartPosition.current = startPosition;
|
|
1784
|
+
dragStartEnd.current = endPosition;
|
|
1785
|
+
const regionWidth = endPosition - startPosition;
|
|
1786
|
+
const handleMouseMove = (moveEvent) => {
|
|
1787
|
+
const delta = moveEvent.clientX - dragStartX.current;
|
|
1788
|
+
let newStart = dragStartPosition.current + delta;
|
|
1789
|
+
let newEnd = dragStartEnd.current + delta;
|
|
1790
|
+
if (newStart < minPosition) {
|
|
1791
|
+
newStart = minPosition;
|
|
1792
|
+
newEnd = minPosition + regionWidth;
|
|
1793
|
+
}
|
|
1794
|
+
if (newEnd > maxPosition) {
|
|
1795
|
+
newEnd = maxPosition;
|
|
1796
|
+
newStart = maxPosition - regionWidth;
|
|
1797
|
+
}
|
|
1798
|
+
onLoopRegionMove?.(newStart, newEnd);
|
|
1799
|
+
};
|
|
1800
|
+
const handleMouseUp = () => {
|
|
1801
|
+
setDraggingMarker(null);
|
|
1802
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
1803
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
1804
|
+
};
|
|
1805
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
1806
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
1807
|
+
},
|
|
1808
|
+
[startPosition, endPosition, minPosition, maxPosition, onLoopRegionMove]
|
|
1809
|
+
);
|
|
1806
1810
|
if (width <= 0) {
|
|
1807
1811
|
return null;
|
|
1808
1812
|
}
|
|
1809
|
-
return /* @__PURE__ */ (0,
|
|
1810
|
-
/* @__PURE__ */ (0,
|
|
1813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1814
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1811
1815
|
TimescaleLoopShade,
|
|
1812
1816
|
{
|
|
1813
1817
|
$left: startPosition,
|
|
@@ -1818,7 +1822,7 @@ var LoopRegionMarkers = ({
|
|
|
1818
1822
|
"data-loop-region-timescale": true
|
|
1819
1823
|
}
|
|
1820
1824
|
),
|
|
1821
|
-
/* @__PURE__ */ (0,
|
|
1825
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1822
1826
|
DraggableMarkerHandle,
|
|
1823
1827
|
{
|
|
1824
1828
|
$left: startPosition,
|
|
@@ -1829,7 +1833,7 @@ var LoopRegionMarkers = ({
|
|
|
1829
1833
|
"data-loop-marker-handle": "start"
|
|
1830
1834
|
}
|
|
1831
1835
|
),
|
|
1832
|
-
/* @__PURE__ */ (0,
|
|
1836
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1833
1837
|
DraggableMarkerHandle,
|
|
1834
1838
|
{
|
|
1835
1839
|
$left: endPosition,
|
|
@@ -1864,46 +1868,49 @@ var TimescaleLoopRegion = ({
|
|
|
1864
1868
|
maxPosition = Infinity,
|
|
1865
1869
|
controlsOffset = 0
|
|
1866
1870
|
}) => {
|
|
1867
|
-
const [, setIsCreating] = (0,
|
|
1868
|
-
const createStartX = (0,
|
|
1869
|
-
const containerRef = (0,
|
|
1871
|
+
const [, setIsCreating] = (0, import_react9.useState)(false);
|
|
1872
|
+
const createStartX = (0, import_react9.useRef)(0);
|
|
1873
|
+
const containerRef = (0, import_react9.useRef)(null);
|
|
1870
1874
|
const hasLoopRegion = endPosition > startPosition;
|
|
1871
|
-
const handleBackgroundMouseDown = (0,
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
const
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1875
|
+
const handleBackgroundMouseDown = (0, import_react9.useCallback)(
|
|
1876
|
+
(e) => {
|
|
1877
|
+
const target = e.target;
|
|
1878
|
+
if (target.closest("[data-loop-marker-handle]") || target.closest("[data-loop-region-timescale]")) {
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
e.preventDefault();
|
|
1882
|
+
setIsCreating(true);
|
|
1883
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
1884
|
+
if (!rect) return;
|
|
1885
|
+
const clickX = e.clientX - rect.left;
|
|
1886
|
+
const clampedX = Math.max(minPosition, Math.min(maxPosition, clickX));
|
|
1887
|
+
createStartX.current = clampedX;
|
|
1888
|
+
onLoopRegionChange?.(clampedX, clampedX);
|
|
1889
|
+
const handleMouseMove = (moveEvent) => {
|
|
1890
|
+
const currentX = moveEvent.clientX - rect.left;
|
|
1891
|
+
const clampedCurrentX = Math.max(minPosition, Math.min(maxPosition, currentX));
|
|
1892
|
+
const newStart = Math.min(createStartX.current, clampedCurrentX);
|
|
1893
|
+
const newEnd = Math.max(createStartX.current, clampedCurrentX);
|
|
1894
|
+
onLoopRegionChange?.(newStart, newEnd);
|
|
1895
|
+
};
|
|
1896
|
+
const handleMouseUp = () => {
|
|
1897
|
+
setIsCreating(false);
|
|
1898
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
1899
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
1900
|
+
};
|
|
1901
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
1902
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
1903
|
+
},
|
|
1904
|
+
[minPosition, maxPosition, onLoopRegionChange]
|
|
1905
|
+
);
|
|
1906
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1900
1907
|
TimescaleLoopCreator,
|
|
1901
1908
|
{
|
|
1902
1909
|
ref: containerRef,
|
|
1903
1910
|
$leftOffset: controlsOffset,
|
|
1904
1911
|
onMouseDown: handleBackgroundMouseDown,
|
|
1905
1912
|
"data-timescale-loop-creator": true,
|
|
1906
|
-
children: hasLoopRegion && /* @__PURE__ */ (0,
|
|
1913
|
+
children: hasLoopRegion && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1907
1914
|
LoopRegionMarkers,
|
|
1908
1915
|
{
|
|
1909
1916
|
startPosition,
|
|
@@ -1922,10 +1929,10 @@ var TimescaleLoopRegion = ({
|
|
|
1922
1929
|
};
|
|
1923
1930
|
|
|
1924
1931
|
// src/components/SelectionTimeInputs.tsx
|
|
1925
|
-
var
|
|
1932
|
+
var import_react11 = require("react");
|
|
1926
1933
|
|
|
1927
1934
|
// src/components/TimeInput.tsx
|
|
1928
|
-
var
|
|
1935
|
+
var import_react10 = require("react");
|
|
1929
1936
|
|
|
1930
1937
|
// src/utils/timeFormat.ts
|
|
1931
1938
|
function clockFormat(seconds, decimals) {
|
|
@@ -1975,7 +1982,7 @@ function parseTime(timeStr, format) {
|
|
|
1975
1982
|
}
|
|
1976
1983
|
|
|
1977
1984
|
// src/components/TimeInput.tsx
|
|
1978
|
-
var
|
|
1985
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1979
1986
|
var TimeInput = ({
|
|
1980
1987
|
id,
|
|
1981
1988
|
label,
|
|
@@ -1985,8 +1992,8 @@ var TimeInput = ({
|
|
|
1985
1992
|
onChange,
|
|
1986
1993
|
readOnly = false
|
|
1987
1994
|
}) => {
|
|
1988
|
-
const [displayValue, setDisplayValue] = (0,
|
|
1989
|
-
(0,
|
|
1995
|
+
const [displayValue, setDisplayValue] = (0, import_react10.useState)("");
|
|
1996
|
+
(0, import_react10.useEffect)(() => {
|
|
1990
1997
|
const formatted = formatTime(value, format);
|
|
1991
1998
|
setDisplayValue(formatted);
|
|
1992
1999
|
}, [value, format, id]);
|
|
@@ -2006,9 +2013,9 @@ var TimeInput = ({
|
|
|
2006
2013
|
e.currentTarget.blur();
|
|
2007
2014
|
}
|
|
2008
2015
|
};
|
|
2009
|
-
return /* @__PURE__ */ (0,
|
|
2010
|
-
/* @__PURE__ */ (0,
|
|
2011
|
-
/* @__PURE__ */ (0,
|
|
2016
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
2017
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ScreenReaderOnly, { as: "label", htmlFor: id, children: label }),
|
|
2018
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2012
2019
|
BaseInput,
|
|
2013
2020
|
{
|
|
2014
2021
|
type: "text",
|
|
@@ -2025,15 +2032,15 @@ var TimeInput = ({
|
|
|
2025
2032
|
};
|
|
2026
2033
|
|
|
2027
2034
|
// src/components/SelectionTimeInputs.tsx
|
|
2028
|
-
var
|
|
2035
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2029
2036
|
var SelectionTimeInputs = ({
|
|
2030
2037
|
selectionStart,
|
|
2031
2038
|
selectionEnd,
|
|
2032
2039
|
onSelectionChange,
|
|
2033
2040
|
className
|
|
2034
2041
|
}) => {
|
|
2035
|
-
const [timeFormat, setTimeFormat] = (0,
|
|
2036
|
-
(0,
|
|
2042
|
+
const [timeFormat, setTimeFormat] = (0, import_react11.useState)("hh:mm:ss.uuu");
|
|
2043
|
+
(0, import_react11.useEffect)(() => {
|
|
2037
2044
|
const timeFormatSelect = document.querySelector(".time-format");
|
|
2038
2045
|
const handleFormatChange = () => {
|
|
2039
2046
|
if (timeFormatSelect) {
|
|
@@ -2058,8 +2065,8 @@ var SelectionTimeInputs = ({
|
|
|
2058
2065
|
onSelectionChange(selectionStart, value);
|
|
2059
2066
|
}
|
|
2060
2067
|
};
|
|
2061
|
-
return /* @__PURE__ */ (0,
|
|
2062
|
-
/* @__PURE__ */ (0,
|
|
2068
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className, children: [
|
|
2069
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2063
2070
|
TimeInput,
|
|
2064
2071
|
{
|
|
2065
2072
|
id: "audio_start",
|
|
@@ -2070,7 +2077,7 @@ var SelectionTimeInputs = ({
|
|
|
2070
2077
|
onChange: handleStartChange
|
|
2071
2078
|
}
|
|
2072
2079
|
),
|
|
2073
|
-
/* @__PURE__ */ (0,
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2074
2081
|
TimeInput,
|
|
2075
2082
|
{
|
|
2076
2083
|
id: "audio_end",
|
|
@@ -2085,14 +2092,14 @@ var SelectionTimeInputs = ({
|
|
|
2085
2092
|
};
|
|
2086
2093
|
|
|
2087
2094
|
// src/contexts/DevicePixelRatio.tsx
|
|
2088
|
-
var
|
|
2089
|
-
var
|
|
2095
|
+
var import_react12 = require("react");
|
|
2096
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2090
2097
|
function getScale() {
|
|
2091
2098
|
return window.devicePixelRatio;
|
|
2092
2099
|
}
|
|
2093
|
-
var DevicePixelRatioContext = (0,
|
|
2100
|
+
var DevicePixelRatioContext = (0, import_react12.createContext)(getScale());
|
|
2094
2101
|
var DevicePixelRatioProvider = ({ children }) => {
|
|
2095
|
-
const [scale, setScale] = (0,
|
|
2102
|
+
const [scale, setScale] = (0, import_react12.useState)(getScale());
|
|
2096
2103
|
matchMedia(`(resolution: ${getScale()}dppx)`).addEventListener(
|
|
2097
2104
|
"change",
|
|
2098
2105
|
() => {
|
|
@@ -2100,13 +2107,13 @@ var DevicePixelRatioProvider = ({ children }) => {
|
|
|
2100
2107
|
},
|
|
2101
2108
|
{ once: true }
|
|
2102
2109
|
);
|
|
2103
|
-
return /* @__PURE__ */ (0,
|
|
2110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DevicePixelRatioContext.Provider, { value: Math.ceil(scale), children });
|
|
2104
2111
|
};
|
|
2105
|
-
var useDevicePixelRatio = () => (0,
|
|
2112
|
+
var useDevicePixelRatio = () => (0, import_react12.useContext)(DevicePixelRatioContext);
|
|
2106
2113
|
|
|
2107
2114
|
// src/contexts/PlaylistInfo.tsx
|
|
2108
|
-
var
|
|
2109
|
-
var PlaylistInfoContext = (0,
|
|
2115
|
+
var import_react13 = require("react");
|
|
2116
|
+
var PlaylistInfoContext = (0, import_react13.createContext)({
|
|
2110
2117
|
sampleRate: 48e3,
|
|
2111
2118
|
samplesPerPixel: 1e3,
|
|
2112
2119
|
zoomLevels: [1e3, 1500, 2e3, 2500],
|
|
@@ -2120,22 +2127,22 @@ var PlaylistInfoContext = (0, import_react12.createContext)({
|
|
|
2120
2127
|
barWidth: 1,
|
|
2121
2128
|
barGap: 0
|
|
2122
2129
|
});
|
|
2123
|
-
var usePlaylistInfo = () => (0,
|
|
2130
|
+
var usePlaylistInfo = () => (0, import_react13.useContext)(PlaylistInfoContext);
|
|
2124
2131
|
|
|
2125
2132
|
// src/contexts/Theme.tsx
|
|
2126
|
-
var
|
|
2133
|
+
var import_react14 = require("react");
|
|
2127
2134
|
var import_styled_components19 = require("styled-components");
|
|
2128
|
-
var useTheme2 = () => (0,
|
|
2135
|
+
var useTheme2 = () => (0, import_react14.useContext)(import_styled_components19.ThemeContext);
|
|
2129
2136
|
|
|
2130
2137
|
// src/contexts/TrackControls.tsx
|
|
2131
|
-
var import_react14 = require("react");
|
|
2132
|
-
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2133
|
-
var TrackControlsContext = (0, import_react14.createContext)(/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react14.Fragment, {}));
|
|
2134
|
-
var useTrackControls = () => (0, import_react14.useContext)(TrackControlsContext);
|
|
2135
|
-
|
|
2136
|
-
// src/contexts/Playout.tsx
|
|
2137
2138
|
var import_react15 = require("react");
|
|
2138
2139
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2140
|
+
var TrackControlsContext = (0, import_react15.createContext)(/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react15.Fragment, {}));
|
|
2141
|
+
var useTrackControls = () => (0, import_react15.useContext)(TrackControlsContext);
|
|
2142
|
+
|
|
2143
|
+
// src/contexts/Playout.tsx
|
|
2144
|
+
var import_react16 = require("react");
|
|
2145
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2139
2146
|
var defaultProgress = 0;
|
|
2140
2147
|
var defaultIsPlaying = false;
|
|
2141
2148
|
var defaultSelectionStart = 0;
|
|
@@ -2146,8 +2153,8 @@ var defaultPlayout = {
|
|
|
2146
2153
|
selectionStart: defaultSelectionStart,
|
|
2147
2154
|
selectionEnd: defaultSelectionEnd
|
|
2148
2155
|
};
|
|
2149
|
-
var PlayoutStatusContext = (0,
|
|
2150
|
-
var PlayoutStatusUpdateContext = (0,
|
|
2156
|
+
var PlayoutStatusContext = (0, import_react16.createContext)(defaultPlayout);
|
|
2157
|
+
var PlayoutStatusUpdateContext = (0, import_react16.createContext)({
|
|
2151
2158
|
setIsPlaying: () => {
|
|
2152
2159
|
},
|
|
2153
2160
|
setProgress: () => {
|
|
@@ -2156,24 +2163,24 @@ var PlayoutStatusUpdateContext = (0, import_react15.createContext)({
|
|
|
2156
2163
|
}
|
|
2157
2164
|
});
|
|
2158
2165
|
var PlayoutProvider = ({ children }) => {
|
|
2159
|
-
const [isPlaying, setIsPlaying] = (0,
|
|
2160
|
-
const [progress, setProgress] = (0,
|
|
2161
|
-
const [selectionStart, setSelectionStart] = (0,
|
|
2162
|
-
const [selectionEnd, setSelectionEnd] = (0,
|
|
2166
|
+
const [isPlaying, setIsPlaying] = (0, import_react16.useState)(defaultIsPlaying);
|
|
2167
|
+
const [progress, setProgress] = (0, import_react16.useState)(defaultProgress);
|
|
2168
|
+
const [selectionStart, setSelectionStart] = (0, import_react16.useState)(defaultSelectionStart);
|
|
2169
|
+
const [selectionEnd, setSelectionEnd] = (0, import_react16.useState)(defaultSelectionEnd);
|
|
2163
2170
|
const setSelection = (start, end) => {
|
|
2164
2171
|
setSelectionStart(start);
|
|
2165
2172
|
setSelectionEnd(end);
|
|
2166
2173
|
};
|
|
2167
|
-
return /* @__PURE__ */ (0,
|
|
2174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PlayoutStatusUpdateContext.Provider, { value: { setIsPlaying, setProgress, setSelection }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PlayoutStatusContext.Provider, { value: { isPlaying, progress, selectionStart, selectionEnd }, children }) });
|
|
2168
2175
|
};
|
|
2169
|
-
var usePlayoutStatus = () => (0,
|
|
2170
|
-
var usePlayoutStatusUpdate = () => (0,
|
|
2176
|
+
var usePlayoutStatus = () => (0, import_react16.useContext)(PlayoutStatusContext);
|
|
2177
|
+
var usePlayoutStatusUpdate = () => (0, import_react16.useContext)(PlayoutStatusUpdateContext);
|
|
2171
2178
|
|
|
2172
2179
|
// src/components/SpectrogramChannel.tsx
|
|
2173
|
-
var
|
|
2180
|
+
var import_react17 = require("react");
|
|
2174
2181
|
var import_styled_components20 = __toESM(require("styled-components"));
|
|
2175
2182
|
var import_core3 = require("@waveform-playlist/core");
|
|
2176
|
-
var
|
|
2183
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2177
2184
|
var LINEAR_FREQUENCY_SCALE = (f, minF, maxF) => (f - minF) / (maxF - minF);
|
|
2178
2185
|
var Wrapper3 = import_styled_components20.default.div.attrs((props) => ({
|
|
2179
2186
|
style: {
|
|
@@ -2227,23 +2234,24 @@ var SpectrogramChannel = ({
|
|
|
2227
2234
|
}) => {
|
|
2228
2235
|
const channelIndex = channelIndexProp ?? index;
|
|
2229
2236
|
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2230
|
-
const registeredIdsRef = (0,
|
|
2231
|
-
const transferredCanvasesRef = (0,
|
|
2232
|
-
const workerApiRef = (0,
|
|
2233
|
-
const onCanvasesReadyRef = (0,
|
|
2237
|
+
const registeredIdsRef = (0, import_react17.useRef)([]);
|
|
2238
|
+
const transferredCanvasesRef = (0, import_react17.useRef)(/* @__PURE__ */ new WeakSet());
|
|
2239
|
+
const workerApiRef = (0, import_react17.useRef)(workerApi);
|
|
2240
|
+
const onCanvasesReadyRef = (0, import_react17.useRef)(onCanvasesReady);
|
|
2234
2241
|
const isWorkerMode = !!(workerApi && clipId);
|
|
2235
|
-
const
|
|
2242
|
+
const clipOriginX = useClipViewportOrigin();
|
|
2243
|
+
const visibleChunkIndices = useVisibleChunkIndices(length, import_core3.MAX_CANVAS_WIDTH, clipOriginX);
|
|
2236
2244
|
const lut = colorLUT ?? DEFAULT_COLOR_LUT;
|
|
2237
2245
|
const maxF = maxFrequency ?? (data ? data.sampleRate / 2 : 22050);
|
|
2238
2246
|
const scaleFn = frequencyScaleFn ?? LINEAR_FREQUENCY_SCALE;
|
|
2239
2247
|
const hasCustomFrequencyScale = Boolean(frequencyScaleFn);
|
|
2240
|
-
(0,
|
|
2248
|
+
(0, import_react17.useEffect)(() => {
|
|
2241
2249
|
workerApiRef.current = workerApi;
|
|
2242
2250
|
}, [workerApi]);
|
|
2243
|
-
(0,
|
|
2251
|
+
(0, import_react17.useEffect)(() => {
|
|
2244
2252
|
onCanvasesReadyRef.current = onCanvasesReady;
|
|
2245
2253
|
}, [onCanvasesReady]);
|
|
2246
|
-
(0,
|
|
2254
|
+
(0, import_react17.useEffect)(() => {
|
|
2247
2255
|
if (!isWorkerMode) return;
|
|
2248
2256
|
const currentWorkerApi = workerApiRef.current;
|
|
2249
2257
|
if (!currentWorkerApi || !clipId) return;
|
|
@@ -2306,7 +2314,7 @@ var SpectrogramChannel = ({
|
|
|
2306
2314
|
onCanvasesReadyRef.current?.(allIds, allWidths);
|
|
2307
2315
|
}
|
|
2308
2316
|
}, [canvasMapRef, isWorkerMode, clipId, channelIndex, length, visibleChunkIndices]);
|
|
2309
|
-
(0,
|
|
2317
|
+
(0, import_react17.useEffect)(() => {
|
|
2310
2318
|
return () => {
|
|
2311
2319
|
const api = workerApiRef.current;
|
|
2312
2320
|
if (!api) return;
|
|
@@ -2320,9 +2328,16 @@ var SpectrogramChannel = ({
|
|
|
2320
2328
|
registeredIdsRef.current = [];
|
|
2321
2329
|
};
|
|
2322
2330
|
}, []);
|
|
2323
|
-
(0,
|
|
2331
|
+
(0, import_react17.useLayoutEffect)(() => {
|
|
2324
2332
|
if (isWorkerMode || !data) return;
|
|
2325
|
-
const {
|
|
2333
|
+
const {
|
|
2334
|
+
frequencyBinCount,
|
|
2335
|
+
frameCount,
|
|
2336
|
+
hopSize,
|
|
2337
|
+
sampleRate,
|
|
2338
|
+
gainDb,
|
|
2339
|
+
rangeDb: rawRangeDb
|
|
2340
|
+
} = data;
|
|
2326
2341
|
const rangeDb = rawRangeDb === 0 ? 1 : rawRangeDb;
|
|
2327
2342
|
const binToFreq = (bin) => bin / frequencyBinCount * (sampleRate / 2);
|
|
2328
2343
|
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
@@ -2386,11 +2401,25 @@ var SpectrogramChannel = ({
|
|
|
2386
2401
|
ctx.drawImage(tmpCanvas, 0, 0, canvas.width, canvas.height);
|
|
2387
2402
|
}
|
|
2388
2403
|
}
|
|
2389
|
-
}, [
|
|
2404
|
+
}, [
|
|
2405
|
+
canvasMapRef,
|
|
2406
|
+
isWorkerMode,
|
|
2407
|
+
data,
|
|
2408
|
+
length,
|
|
2409
|
+
waveHeight,
|
|
2410
|
+
devicePixelRatio,
|
|
2411
|
+
samplesPerPixel,
|
|
2412
|
+
lut,
|
|
2413
|
+
minFrequency,
|
|
2414
|
+
maxF,
|
|
2415
|
+
scaleFn,
|
|
2416
|
+
hasCustomFrequencyScale,
|
|
2417
|
+
visibleChunkIndices
|
|
2418
|
+
]);
|
|
2390
2419
|
const canvases = visibleChunkIndices.map((i) => {
|
|
2391
2420
|
const chunkLeft = i * import_core3.MAX_CANVAS_WIDTH;
|
|
2392
2421
|
const currentWidth = Math.min(length - chunkLeft, import_core3.MAX_CANVAS_WIDTH);
|
|
2393
|
-
return /* @__PURE__ */ (0,
|
|
2422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2394
2423
|
SpectrogramCanvas,
|
|
2395
2424
|
{
|
|
2396
2425
|
$cssWidth: currentWidth,
|
|
@@ -2404,11 +2433,11 @@ var SpectrogramChannel = ({
|
|
|
2404
2433
|
`${length}-${i}`
|
|
2405
2434
|
);
|
|
2406
2435
|
});
|
|
2407
|
-
return /* @__PURE__ */ (0,
|
|
2436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Wrapper3, { $index: index, $cssWidth: length, $waveHeight: waveHeight, children: canvases });
|
|
2408
2437
|
};
|
|
2409
2438
|
|
|
2410
2439
|
// src/components/SmartChannel.tsx
|
|
2411
|
-
var
|
|
2440
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2412
2441
|
var SmartChannel = ({
|
|
2413
2442
|
isSelected,
|
|
2414
2443
|
transparentBackground,
|
|
@@ -2433,7 +2462,7 @@ var SmartChannel = ({
|
|
|
2433
2462
|
const drawMode = theme?.waveformDrawMode || "inverted";
|
|
2434
2463
|
const hasSpectrogram = spectrogramData || spectrogramWorkerApi;
|
|
2435
2464
|
if (renderMode === "spectrogram" && hasSpectrogram) {
|
|
2436
|
-
return /* @__PURE__ */ (0,
|
|
2465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2437
2466
|
SpectrogramChannel,
|
|
2438
2467
|
{
|
|
2439
2468
|
index: props.index,
|
|
@@ -2454,8 +2483,8 @@ var SmartChannel = ({
|
|
|
2454
2483
|
}
|
|
2455
2484
|
if (renderMode === "both" && hasSpectrogram) {
|
|
2456
2485
|
const halfHeight = Math.floor(waveHeight / 2);
|
|
2457
|
-
return /* @__PURE__ */ (0,
|
|
2458
|
-
/* @__PURE__ */ (0,
|
|
2486
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
2487
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2459
2488
|
SpectrogramChannel,
|
|
2460
2489
|
{
|
|
2461
2490
|
index: props.index * 2,
|
|
@@ -2474,24 +2503,35 @@ var SmartChannel = ({
|
|
|
2474
2503
|
onCanvasesReady: spectrogramOnCanvasesReady
|
|
2475
2504
|
}
|
|
2476
2505
|
),
|
|
2477
|
-
/* @__PURE__ */ (0,
|
|
2478
|
-
|
|
2506
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2507
|
+
"div",
|
|
2479
2508
|
{
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2509
|
+
style: {
|
|
2510
|
+
position: "absolute",
|
|
2511
|
+
top: (props.index * 2 + 1) * halfHeight,
|
|
2512
|
+
width: props.length,
|
|
2513
|
+
height: halfHeight
|
|
2514
|
+
},
|
|
2515
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2516
|
+
Channel,
|
|
2517
|
+
{
|
|
2518
|
+
...props,
|
|
2519
|
+
index: 0,
|
|
2520
|
+
waveOutlineColor,
|
|
2521
|
+
waveFillColor,
|
|
2522
|
+
waveHeight: halfHeight,
|
|
2523
|
+
devicePixelRatio,
|
|
2524
|
+
barWidth,
|
|
2525
|
+
barGap,
|
|
2526
|
+
transparentBackground,
|
|
2527
|
+
drawMode
|
|
2528
|
+
}
|
|
2529
|
+
)
|
|
2490
2530
|
}
|
|
2491
|
-
)
|
|
2531
|
+
)
|
|
2492
2532
|
] });
|
|
2493
2533
|
}
|
|
2494
|
-
return /* @__PURE__ */ (0,
|
|
2534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2495
2535
|
Channel,
|
|
2496
2536
|
{
|
|
2497
2537
|
...props,
|
|
@@ -2508,9 +2548,9 @@ var SmartChannel = ({
|
|
|
2508
2548
|
};
|
|
2509
2549
|
|
|
2510
2550
|
// src/components/SpectrogramLabels.tsx
|
|
2511
|
-
var
|
|
2551
|
+
var import_react18 = require("react");
|
|
2512
2552
|
var import_styled_components21 = __toESM(require("styled-components"));
|
|
2513
|
-
var
|
|
2553
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2514
2554
|
var LABELS_WIDTH = 72;
|
|
2515
2555
|
var LabelsStickyWrapper = import_styled_components21.default.div`
|
|
2516
2556
|
position: sticky;
|
|
@@ -2560,12 +2600,12 @@ var SpectrogramLabels = ({
|
|
|
2560
2600
|
renderMode = "spectrogram",
|
|
2561
2601
|
hasClipHeaders = false
|
|
2562
2602
|
}) => {
|
|
2563
|
-
const canvasRef = (0,
|
|
2603
|
+
const canvasRef = (0, import_react18.useRef)(null);
|
|
2564
2604
|
const devicePixelRatio = useDevicePixelRatio();
|
|
2565
2605
|
const spectrogramHeight = renderMode === "both" ? Math.floor(waveHeight / 2) : waveHeight;
|
|
2566
2606
|
const totalHeight = numChannels * waveHeight;
|
|
2567
2607
|
const clipHeaderOffset = hasClipHeaders ? 22 : 0;
|
|
2568
|
-
(0,
|
|
2608
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
2569
2609
|
const canvas = canvasRef.current;
|
|
2570
2610
|
if (!canvas) return;
|
|
2571
2611
|
const ctx = canvas.getContext("2d");
|
|
@@ -2591,8 +2631,19 @@ var SpectrogramLabels = ({
|
|
|
2591
2631
|
ctx.fillText(text, padding, y);
|
|
2592
2632
|
}
|
|
2593
2633
|
}
|
|
2594
|
-
}, [
|
|
2595
|
-
|
|
2634
|
+
}, [
|
|
2635
|
+
waveHeight,
|
|
2636
|
+
numChannels,
|
|
2637
|
+
frequencyScaleFn,
|
|
2638
|
+
minFrequency,
|
|
2639
|
+
maxFrequency,
|
|
2640
|
+
labelsColor,
|
|
2641
|
+
labelsBackground,
|
|
2642
|
+
devicePixelRatio,
|
|
2643
|
+
spectrogramHeight,
|
|
2644
|
+
clipHeaderOffset
|
|
2645
|
+
]);
|
|
2646
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LabelsStickyWrapper, { $height: totalHeight + clipHeaderOffset, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2596
2647
|
"canvas",
|
|
2597
2648
|
{
|
|
2598
2649
|
ref: canvasRef,
|
|
@@ -2608,10 +2659,10 @@ var SpectrogramLabels = ({
|
|
|
2608
2659
|
};
|
|
2609
2660
|
|
|
2610
2661
|
// src/components/SmartScale.tsx
|
|
2611
|
-
var
|
|
2662
|
+
var import_react20 = require("react");
|
|
2612
2663
|
|
|
2613
2664
|
// src/components/TimeScale.tsx
|
|
2614
|
-
var
|
|
2665
|
+
var import_react19 = __toESM(require("react"));
|
|
2615
2666
|
var import_styled_components22 = __toESM(require("styled-components"));
|
|
2616
2667
|
|
|
2617
2668
|
// src/utils/conversions.ts
|
|
@@ -2636,7 +2687,7 @@ function secondsToPixels(seconds, samplesPerPixel, sampleRate) {
|
|
|
2636
2687
|
|
|
2637
2688
|
// src/components/TimeScale.tsx
|
|
2638
2689
|
var import_core4 = require("@waveform-playlist/core");
|
|
2639
|
-
var
|
|
2690
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2640
2691
|
function formatTime2(milliseconds) {
|
|
2641
2692
|
const seconds = Math.floor(milliseconds / 1e3);
|
|
2642
2693
|
const s = seconds % 60;
|
|
@@ -2693,9 +2744,9 @@ var TimeScale = (props) => {
|
|
|
2693
2744
|
samplesPerPixel,
|
|
2694
2745
|
timeScaleHeight,
|
|
2695
2746
|
controls: { show: showControls, width: controlWidth }
|
|
2696
|
-
} = (0,
|
|
2747
|
+
} = (0, import_react19.useContext)(PlaylistInfoContext);
|
|
2697
2748
|
const devicePixelRatio = useDevicePixelRatio();
|
|
2698
|
-
const { widthX, canvasInfo, timeMarkersWithPositions } = (0,
|
|
2749
|
+
const { widthX, canvasInfo, timeMarkersWithPositions } = (0, import_react19.useMemo)(() => {
|
|
2699
2750
|
const nextCanvasInfo = /* @__PURE__ */ new Map();
|
|
2700
2751
|
const nextMarkers = [];
|
|
2701
2752
|
const nextWidthX = secondsToPixels(duration / 1e3, samplesPerPixel, sampleRate);
|
|
@@ -2706,7 +2757,7 @@ var TimeScale = (props) => {
|
|
|
2706
2757
|
if (counter % marker === 0) {
|
|
2707
2758
|
const timeMs = counter;
|
|
2708
2759
|
const timestamp = formatTime2(timeMs);
|
|
2709
|
-
const element = renderTimestamp ? /* @__PURE__ */ (0,
|
|
2760
|
+
const element = renderTimestamp ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react19.default.Fragment, { children: renderTimestamp(timeMs, pix) }, `timestamp-${counter}`) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TimeStamp, { $left: pix, children: timestamp }, timestamp);
|
|
2710
2761
|
nextMarkers.push({ pix, element });
|
|
2711
2762
|
nextCanvasInfo.set(pix, timeScaleHeight);
|
|
2712
2763
|
} else if (counter % bigStep === 0) {
|
|
@@ -2721,12 +2772,21 @@ var TimeScale = (props) => {
|
|
|
2721
2772
|
canvasInfo: nextCanvasInfo,
|
|
2722
2773
|
timeMarkersWithPositions: nextMarkers
|
|
2723
2774
|
};
|
|
2724
|
-
}, [
|
|
2775
|
+
}, [
|
|
2776
|
+
duration,
|
|
2777
|
+
samplesPerPixel,
|
|
2778
|
+
sampleRate,
|
|
2779
|
+
marker,
|
|
2780
|
+
bigStep,
|
|
2781
|
+
secondStep,
|
|
2782
|
+
renderTimestamp,
|
|
2783
|
+
timeScaleHeight
|
|
2784
|
+
]);
|
|
2725
2785
|
const visibleChunkIndices = useVisibleChunkIndices(widthX, import_core4.MAX_CANVAS_WIDTH);
|
|
2726
2786
|
const visibleChunks = visibleChunkIndices.map((i) => {
|
|
2727
2787
|
const chunkLeft = i * import_core4.MAX_CANVAS_WIDTH;
|
|
2728
2788
|
const chunkWidth = Math.min(widthX - chunkLeft, import_core4.MAX_CANVAS_WIDTH);
|
|
2729
|
-
return /* @__PURE__ */ (0,
|
|
2789
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2730
2790
|
TimeTickChunk,
|
|
2731
2791
|
{
|
|
2732
2792
|
$cssWidth: chunkWidth,
|
|
@@ -2743,7 +2803,7 @@ var TimeScale = (props) => {
|
|
|
2743
2803
|
const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] * import_core4.MAX_CANVAS_WIDTH : 0;
|
|
2744
2804
|
const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) * import_core4.MAX_CANVAS_WIDTH : Infinity;
|
|
2745
2805
|
const visibleMarkers = visibleChunkIndices.length > 0 ? timeMarkersWithPositions.filter(({ pix }) => pix >= firstChunkLeft && pix < lastChunkRight).map(({ element }) => element) : timeMarkersWithPositions.map(({ element }) => element);
|
|
2746
|
-
(0,
|
|
2806
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
2747
2807
|
for (const [chunkIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2748
2808
|
const ctx = canvas.getContext("2d");
|
|
2749
2809
|
if (!ctx) continue;
|
|
@@ -2761,8 +2821,16 @@ var TimeScale = (props) => {
|
|
|
2761
2821
|
ctx.fillRect(localX, scaleY, 1, scaleHeight);
|
|
2762
2822
|
}
|
|
2763
2823
|
}
|
|
2764
|
-
}, [
|
|
2765
|
-
|
|
2824
|
+
}, [
|
|
2825
|
+
canvasMapRef,
|
|
2826
|
+
duration,
|
|
2827
|
+
devicePixelRatio,
|
|
2828
|
+
timeColor,
|
|
2829
|
+
timeScaleHeight,
|
|
2830
|
+
canvasInfo,
|
|
2831
|
+
visibleChunkIndices
|
|
2832
|
+
]);
|
|
2833
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
2766
2834
|
PlaylistTimeScaleScroll,
|
|
2767
2835
|
{
|
|
2768
2836
|
$cssWidth: widthX,
|
|
@@ -2778,7 +2846,7 @@ var TimeScale = (props) => {
|
|
|
2778
2846
|
var StyledTimeScale = (0, import_styled_components22.withTheme)(TimeScale);
|
|
2779
2847
|
|
|
2780
2848
|
// src/components/SmartScale.tsx
|
|
2781
|
-
var
|
|
2849
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2782
2850
|
var timeinfo = /* @__PURE__ */ new Map([
|
|
2783
2851
|
[
|
|
2784
2852
|
700,
|
|
@@ -2852,9 +2920,9 @@ function getScaleInfo(samplesPerPixel) {
|
|
|
2852
2920
|
return config;
|
|
2853
2921
|
}
|
|
2854
2922
|
var SmartScale = ({ renderTimestamp }) => {
|
|
2855
|
-
const { samplesPerPixel, duration } = (0,
|
|
2923
|
+
const { samplesPerPixel, duration } = (0, import_react20.useContext)(PlaylistInfoContext);
|
|
2856
2924
|
let config = getScaleInfo(samplesPerPixel);
|
|
2857
|
-
return /* @__PURE__ */ (0,
|
|
2925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2858
2926
|
StyledTimeScale,
|
|
2859
2927
|
{
|
|
2860
2928
|
marker: config.marker,
|
|
@@ -2868,7 +2936,7 @@ var SmartScale = ({ renderTimestamp }) => {
|
|
|
2868
2936
|
|
|
2869
2937
|
// src/components/TimeFormatSelect.tsx
|
|
2870
2938
|
var import_styled_components23 = __toESM(require("styled-components"));
|
|
2871
|
-
var
|
|
2939
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2872
2940
|
var SelectWrapper = import_styled_components23.default.div`
|
|
2873
2941
|
display: inline-flex;
|
|
2874
2942
|
align-items: center;
|
|
@@ -2891,7 +2959,7 @@ var TimeFormatSelect = ({
|
|
|
2891
2959
|
const handleChange = (e) => {
|
|
2892
2960
|
onChange(e.target.value);
|
|
2893
2961
|
};
|
|
2894
|
-
return /* @__PURE__ */ (0,
|
|
2962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SelectWrapper, { className, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2895
2963
|
BaseSelect,
|
|
2896
2964
|
{
|
|
2897
2965
|
className: "time-format",
|
|
@@ -2899,14 +2967,14 @@ var TimeFormatSelect = ({
|
|
|
2899
2967
|
onChange: handleChange,
|
|
2900
2968
|
disabled,
|
|
2901
2969
|
"aria-label": "Time format selection",
|
|
2902
|
-
children: TIME_FORMAT_OPTIONS.map((option) => /* @__PURE__ */ (0,
|
|
2970
|
+
children: TIME_FORMAT_OPTIONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: option.value, children: option.label }, option.value))
|
|
2903
2971
|
}
|
|
2904
2972
|
) });
|
|
2905
2973
|
};
|
|
2906
2974
|
|
|
2907
2975
|
// src/components/Track.tsx
|
|
2908
2976
|
var import_styled_components24 = __toESM(require("styled-components"));
|
|
2909
|
-
var
|
|
2977
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2910
2978
|
var Container = import_styled_components24.default.div.attrs((props) => ({
|
|
2911
2979
|
style: {
|
|
2912
2980
|
height: `${props.$waveHeight * props.$numChannels + (props.$hasClipHeaders ? CLIP_HEADER_HEIGHT : 0)}px`
|
|
@@ -2961,7 +3029,7 @@ var Track = ({
|
|
|
2961
3029
|
controls: { show, width: controlWidth }
|
|
2962
3030
|
} = usePlaylistInfo();
|
|
2963
3031
|
const controls = useTrackControls();
|
|
2964
|
-
return /* @__PURE__ */ (0,
|
|
3032
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
2965
3033
|
Container,
|
|
2966
3034
|
{
|
|
2967
3035
|
$numChannels: numChannels,
|
|
@@ -2972,15 +3040,8 @@ var Track = ({
|
|
|
2972
3040
|
$hasClipHeaders: hasClipHeaders,
|
|
2973
3041
|
$isSelected: isSelected,
|
|
2974
3042
|
children: [
|
|
2975
|
-
/* @__PURE__ */ (0,
|
|
2976
|
-
|
|
2977
|
-
{
|
|
2978
|
-
$controlWidth: show ? controlWidth : 0,
|
|
2979
|
-
$isSelected: isSelected,
|
|
2980
|
-
children: controls
|
|
2981
|
-
}
|
|
2982
|
-
),
|
|
2983
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3043
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ControlsWrapper, { $controlWidth: show ? controlWidth : 0, $isSelected: isSelected, children: controls }),
|
|
3044
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2984
3045
|
ChannelContainer,
|
|
2985
3046
|
{
|
|
2986
3047
|
$controlWidth: show ? controlWidth : 0,
|
|
@@ -3011,8 +3072,11 @@ var Button = import_styled_components25.default.button.attrs({
|
|
|
3011
3072
|
font-size: ${(props) => props.theme.fontSizeSmall};
|
|
3012
3073
|
line-height: 1;
|
|
3013
3074
|
border-radius: ${(props) => props.theme.borderRadius};
|
|
3014
|
-
transition:
|
|
3015
|
-
|
|
3075
|
+
transition:
|
|
3076
|
+
color 0.15s ease-in-out,
|
|
3077
|
+
background-color 0.15s ease-in-out,
|
|
3078
|
+
border-color 0.15s ease-in-out,
|
|
3079
|
+
box-shadow 0.15s ease-in-out;
|
|
3016
3080
|
cursor: pointer;
|
|
3017
3081
|
|
|
3018
3082
|
${(props) => {
|
|
@@ -3087,8 +3151,8 @@ var ButtonGroup = import_styled_components26.default.div`
|
|
|
3087
3151
|
|
|
3088
3152
|
// src/components/TrackControls/CloseButton.tsx
|
|
3089
3153
|
var import_styled_components27 = __toESM(require("styled-components"));
|
|
3090
|
-
var
|
|
3091
|
-
var
|
|
3154
|
+
var import_react21 = require("@phosphor-icons/react");
|
|
3155
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3092
3156
|
var StyledCloseButton = import_styled_components27.default.button`
|
|
3093
3157
|
position: absolute;
|
|
3094
3158
|
left: 0;
|
|
@@ -3103,17 +3167,16 @@ var StyledCloseButton = import_styled_components27.default.button`
|
|
|
3103
3167
|
align-items: center;
|
|
3104
3168
|
justify-content: center;
|
|
3105
3169
|
opacity: 0.7;
|
|
3106
|
-
transition:
|
|
3170
|
+
transition:
|
|
3171
|
+
opacity 0.15s,
|
|
3172
|
+
color 0.15s;
|
|
3107
3173
|
|
|
3108
3174
|
&:hover {
|
|
3109
3175
|
opacity: 1;
|
|
3110
3176
|
color: #dc3545;
|
|
3111
3177
|
}
|
|
3112
3178
|
`;
|
|
3113
|
-
var CloseButton = ({
|
|
3114
|
-
onClick,
|
|
3115
|
-
title = "Remove track"
|
|
3116
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(StyledCloseButton, { onClick, title, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react20.X, { size: 12, weight: "bold" }) });
|
|
3179
|
+
var CloseButton = ({ onClick, title = "Remove track" }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(StyledCloseButton, { onClick, title, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react21.X, { size: 12, weight: "bold" }) });
|
|
3117
3180
|
|
|
3118
3181
|
// src/components/TrackControls/Controls.tsx
|
|
3119
3182
|
var import_styled_components28 = __toESM(require("styled-components"));
|
|
@@ -3148,24 +3211,24 @@ var Header = import_styled_components29.default.header`
|
|
|
3148
3211
|
`;
|
|
3149
3212
|
|
|
3150
3213
|
// src/components/TrackControls/VolumeDownIcon.tsx
|
|
3151
|
-
var import_react21 = require("@phosphor-icons/react");
|
|
3152
|
-
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3153
|
-
var VolumeDownIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react21.SpeakerLowIcon, { weight: "light", ...props });
|
|
3154
|
-
|
|
3155
|
-
// src/components/TrackControls/VolumeUpIcon.tsx
|
|
3156
3214
|
var import_react22 = require("@phosphor-icons/react");
|
|
3157
3215
|
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
3158
|
-
var
|
|
3216
|
+
var VolumeDownIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react22.SpeakerLowIcon, { weight: "light", ...props });
|
|
3159
3217
|
|
|
3160
|
-
// src/components/TrackControls/
|
|
3218
|
+
// src/components/TrackControls/VolumeUpIcon.tsx
|
|
3161
3219
|
var import_react23 = require("@phosphor-icons/react");
|
|
3162
3220
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
3163
|
-
var
|
|
3221
|
+
var VolumeUpIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react23.SpeakerHighIcon, { weight: "light", ...props });
|
|
3164
3222
|
|
|
3165
|
-
// src/components/TrackControls/
|
|
3223
|
+
// src/components/TrackControls/TrashIcon.tsx
|
|
3166
3224
|
var import_react24 = require("@phosphor-icons/react");
|
|
3167
3225
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
3168
|
-
var
|
|
3226
|
+
var TrashIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react24.TrashIcon, { weight: "light", ...props });
|
|
3227
|
+
|
|
3228
|
+
// src/components/TrackControls/DotsIcon.tsx
|
|
3229
|
+
var import_react25 = require("@phosphor-icons/react");
|
|
3230
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
3231
|
+
var DotsIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react25.DotsThreeIcon, { weight: "bold", ...props });
|
|
3169
3232
|
|
|
3170
3233
|
// src/components/TrackControls/Slider.tsx
|
|
3171
3234
|
var import_styled_components30 = __toESM(require("styled-components"));
|
|
@@ -3233,10 +3296,10 @@ var SliderWrapper = import_styled_components31.default.label`
|
|
|
3233
3296
|
`;
|
|
3234
3297
|
|
|
3235
3298
|
// src/components/TrackMenu.tsx
|
|
3236
|
-
var
|
|
3299
|
+
var import_react26 = __toESM(require("react"));
|
|
3237
3300
|
var import_react_dom = require("react-dom");
|
|
3238
3301
|
var import_styled_components32 = __toESM(require("styled-components"));
|
|
3239
|
-
var
|
|
3302
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
3240
3303
|
var MenuContainer = import_styled_components32.default.div`
|
|
3241
3304
|
position: relative;
|
|
3242
3305
|
display: inline-block;
|
|
@@ -3274,16 +3337,14 @@ var Divider = import_styled_components32.default.hr`
|
|
|
3274
3337
|
border-top: 1px solid rgba(128, 128, 128, 0.3);
|
|
3275
3338
|
margin: 0.35rem 0;
|
|
3276
3339
|
`;
|
|
3277
|
-
var TrackMenu = ({
|
|
3278
|
-
|
|
3279
|
-
}) => {
|
|
3280
|
-
const [open, setOpen] = (0, import_react25.useState)(false);
|
|
3340
|
+
var TrackMenu = ({ items: itemsProp }) => {
|
|
3341
|
+
const [open, setOpen] = (0, import_react26.useState)(false);
|
|
3281
3342
|
const close = () => setOpen(false);
|
|
3282
3343
|
const items = typeof itemsProp === "function" ? itemsProp(close) : itemsProp;
|
|
3283
|
-
const [dropdownPos, setDropdownPos] = (0,
|
|
3284
|
-
const buttonRef = (0,
|
|
3285
|
-
const dropdownRef = (0,
|
|
3286
|
-
(0,
|
|
3344
|
+
const [dropdownPos, setDropdownPos] = (0, import_react26.useState)({ top: 0, left: 0 });
|
|
3345
|
+
const buttonRef = (0, import_react26.useRef)(null);
|
|
3346
|
+
const dropdownRef = (0, import_react26.useRef)(null);
|
|
3347
|
+
(0, import_react26.useEffect)(() => {
|
|
3287
3348
|
if (open && buttonRef.current) {
|
|
3288
3349
|
const rect = buttonRef.current.getBoundingClientRect();
|
|
3289
3350
|
setDropdownPos({
|
|
@@ -3292,7 +3353,7 @@ var TrackMenu = ({
|
|
|
3292
3353
|
});
|
|
3293
3354
|
}
|
|
3294
3355
|
}, [open]);
|
|
3295
|
-
(0,
|
|
3356
|
+
(0, import_react26.useEffect)(() => {
|
|
3296
3357
|
if (!open) return;
|
|
3297
3358
|
const handleClick = (e) => {
|
|
3298
3359
|
const target = e.target;
|
|
@@ -3303,8 +3364,8 @@ var TrackMenu = ({
|
|
|
3303
3364
|
document.addEventListener("mousedown", handleClick);
|
|
3304
3365
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
3305
3366
|
}, [open]);
|
|
3306
|
-
return /* @__PURE__ */ (0,
|
|
3307
|
-
/* @__PURE__ */ (0,
|
|
3367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(MenuContainer, { children: [
|
|
3368
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3308
3369
|
MenuButton,
|
|
3309
3370
|
{
|
|
3310
3371
|
ref: buttonRef,
|
|
@@ -3315,19 +3376,19 @@ var TrackMenu = ({
|
|
|
3315
3376
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3316
3377
|
title: "Track menu",
|
|
3317
3378
|
"aria-label": "Track menu",
|
|
3318
|
-
children: /* @__PURE__ */ (0,
|
|
3379
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(DotsIcon, { size: 16 })
|
|
3319
3380
|
}
|
|
3320
3381
|
),
|
|
3321
3382
|
open && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
|
|
3322
|
-
/* @__PURE__ */ (0,
|
|
3383
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3323
3384
|
Dropdown,
|
|
3324
3385
|
{
|
|
3325
3386
|
ref: dropdownRef,
|
|
3326
3387
|
$top: dropdownPos.top,
|
|
3327
3388
|
$left: dropdownPos.left,
|
|
3328
3389
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3329
|
-
children: items.map((item, index) => /* @__PURE__ */ (0,
|
|
3330
|
-
index > 0 && /* @__PURE__ */ (0,
|
|
3390
|
+
children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react26.default.Fragment, { children: [
|
|
3391
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Divider, {}),
|
|
3331
3392
|
item.content
|
|
3332
3393
|
] }, item.id))
|
|
3333
3394
|
}
|
|
@@ -3359,6 +3420,7 @@ var TrackMenu = ({
|
|
|
3359
3420
|
ClipBoundary,
|
|
3360
3421
|
ClipHeader,
|
|
3361
3422
|
ClipHeaderPresentational,
|
|
3423
|
+
ClipViewportOriginProvider,
|
|
3362
3424
|
CloseButton,
|
|
3363
3425
|
Controls,
|
|
3364
3426
|
DevicePixelRatioProvider,
|
|
@@ -3408,6 +3470,7 @@ var TrackMenu = ({
|
|
|
3408
3470
|
samplesToSeconds,
|
|
3409
3471
|
secondsToPixels,
|
|
3410
3472
|
secondsToSamples,
|
|
3473
|
+
useClipViewportOrigin,
|
|
3411
3474
|
useDevicePixelRatio,
|
|
3412
3475
|
usePlaylistInfo,
|
|
3413
3476
|
usePlayoutStatus,
|