@waveform-playlist/ui-components 9.1.2 → 9.2.1
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 +50 -7
- package/dist/index.d.ts +50 -7
- package/dist/index.js +311 -302
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +267 -257
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -781,7 +781,6 @@ var Channel = (props) => {
|
|
|
781
781
|
const clipOriginX = useClipViewportOrigin();
|
|
782
782
|
const visibleChunkIndices = useVisibleChunkIndices(length, MAX_CANVAS_WIDTH, clipOriginX);
|
|
783
783
|
useEffect3(() => {
|
|
784
|
-
const tDraw = performance.now();
|
|
785
784
|
const step = barWidth + barGap;
|
|
786
785
|
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
787
786
|
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
|
|
@@ -817,9 +816,6 @@ var Channel = (props) => {
|
|
|
817
816
|
}
|
|
818
817
|
}
|
|
819
818
|
}
|
|
820
|
-
console.log(
|
|
821
|
-
`[waveform] draw ch${index}: ${canvasMapRef.current.size} chunks, ${(performance.now() - tDraw).toFixed(1)}ms`
|
|
822
|
-
);
|
|
823
819
|
}, [
|
|
824
820
|
canvasMapRef,
|
|
825
821
|
data,
|
|
@@ -1159,20 +1155,20 @@ var Clip = ({
|
|
|
1159
1155
|
isDragSource
|
|
1160
1156
|
} = useDraggable({
|
|
1161
1157
|
id: draggableId,
|
|
1162
|
-
data: { clipId, trackIndex, clipIndex },
|
|
1158
|
+
data: { clipId, trackIndex, clipIndex, startSample, durationSamples },
|
|
1163
1159
|
disabled: !enableDrag
|
|
1164
1160
|
});
|
|
1165
1161
|
const leftBoundaryId = `clip-boundary-left-${trackIndex}-${clipIndex}`;
|
|
1166
1162
|
const { ref: leftBoundaryRef, isDragSource: isLeftBoundaryDragging } = useDraggable({
|
|
1167
1163
|
id: leftBoundaryId,
|
|
1168
|
-
data: { clipId, trackIndex, clipIndex, boundary: "left" },
|
|
1164
|
+
data: { clipId, trackIndex, clipIndex, boundary: "left", startSample, durationSamples },
|
|
1169
1165
|
disabled: !enableDrag,
|
|
1170
1166
|
feedback: "none"
|
|
1171
1167
|
});
|
|
1172
1168
|
const rightBoundaryId = `clip-boundary-right-${trackIndex}-${clipIndex}`;
|
|
1173
1169
|
const { ref: rightBoundaryRef, isDragSource: isRightBoundaryDragging } = useDraggable({
|
|
1174
1170
|
id: rightBoundaryId,
|
|
1175
|
-
data: { clipId, trackIndex, clipIndex, boundary: "right" },
|
|
1171
|
+
data: { clipId, trackIndex, clipIndex, boundary: "right", startSample, durationSamples },
|
|
1176
1172
|
disabled: !enableDrag,
|
|
1177
1173
|
feedback: "none"
|
|
1178
1174
|
});
|
|
@@ -1357,7 +1353,6 @@ var PianoRollChannel = ({
|
|
|
1357
1353
|
}, [midiNotes]);
|
|
1358
1354
|
const color = isSelected ? selectedNoteColor : noteColor;
|
|
1359
1355
|
useEffect4(() => {
|
|
1360
|
-
const tDraw = performance.now();
|
|
1361
1356
|
const noteRange = maxMidi - minMidi + 1;
|
|
1362
1357
|
const noteHeight = Math.max(2, waveHeight / noteRange);
|
|
1363
1358
|
const pixelsPerSecond = sampleRate / samplesPerPixel;
|
|
@@ -1389,9 +1384,6 @@ var PianoRollChannel = ({
|
|
|
1389
1384
|
}
|
|
1390
1385
|
ctx.globalAlpha = 1;
|
|
1391
1386
|
}
|
|
1392
|
-
console.log(
|
|
1393
|
-
`[piano-roll] draw ch${index}: ${canvasMapRef.current.size} chunks, ${midiNotes.length} notes, ${(performance.now() - tDraw).toFixed(1)}ms`
|
|
1394
|
-
);
|
|
1395
1387
|
}, [
|
|
1396
1388
|
canvasMapRef,
|
|
1397
1389
|
midiNotes,
|
|
@@ -2183,13 +2175,45 @@ var SelectionTimeInputs = ({
|
|
|
2183
2175
|
] });
|
|
2184
2176
|
};
|
|
2185
2177
|
|
|
2186
|
-
// src/contexts/
|
|
2187
|
-
import {
|
|
2178
|
+
// src/contexts/BeatsAndBars.tsx
|
|
2179
|
+
import { createContext as createContext3, useContext as useContext3, useMemo as useMemo3 } from "react";
|
|
2180
|
+
import { ticksPerBeat, ticksPerBar } from "@waveform-playlist/core";
|
|
2188
2181
|
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2182
|
+
var BeatsAndBarsContext = createContext3(null);
|
|
2183
|
+
function BeatsAndBarsProvider({
|
|
2184
|
+
bpm,
|
|
2185
|
+
timeSignature,
|
|
2186
|
+
snapTo,
|
|
2187
|
+
scaleMode = "beats",
|
|
2188
|
+
children
|
|
2189
|
+
}) {
|
|
2190
|
+
const [numerator, denominator] = timeSignature;
|
|
2191
|
+
const value = useMemo3(() => {
|
|
2192
|
+
const ts = [numerator, denominator];
|
|
2193
|
+
const tpBeat = ticksPerBeat(ts);
|
|
2194
|
+
const tpBar = ticksPerBar(ts);
|
|
2195
|
+
return {
|
|
2196
|
+
bpm,
|
|
2197
|
+
timeSignature: ts,
|
|
2198
|
+
snapTo,
|
|
2199
|
+
scaleMode,
|
|
2200
|
+
ticksPerBeat: tpBeat,
|
|
2201
|
+
ticksPerBar: tpBar
|
|
2202
|
+
};
|
|
2203
|
+
}, [bpm, numerator, denominator, snapTo, scaleMode]);
|
|
2204
|
+
return /* @__PURE__ */ jsx19(BeatsAndBarsContext.Provider, { value, children });
|
|
2205
|
+
}
|
|
2206
|
+
function useBeatsAndBars() {
|
|
2207
|
+
return useContext3(BeatsAndBarsContext);
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
// src/contexts/DevicePixelRatio.tsx
|
|
2211
|
+
import { useState as useState4, createContext as createContext4, useContext as useContext4 } from "react";
|
|
2212
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
2189
2213
|
function getScale() {
|
|
2190
2214
|
return window.devicePixelRatio;
|
|
2191
2215
|
}
|
|
2192
|
-
var DevicePixelRatioContext =
|
|
2216
|
+
var DevicePixelRatioContext = createContext4(getScale());
|
|
2193
2217
|
var DevicePixelRatioProvider = ({ children }) => {
|
|
2194
2218
|
const [scale, setScale] = useState4(getScale());
|
|
2195
2219
|
matchMedia(`(resolution: ${getScale()}dppx)`).addEventListener(
|
|
@@ -2199,13 +2223,13 @@ var DevicePixelRatioProvider = ({ children }) => {
|
|
|
2199
2223
|
},
|
|
2200
2224
|
{ once: true }
|
|
2201
2225
|
);
|
|
2202
|
-
return /* @__PURE__ */
|
|
2226
|
+
return /* @__PURE__ */ jsx20(DevicePixelRatioContext.Provider, { value: Math.ceil(scale), children });
|
|
2203
2227
|
};
|
|
2204
|
-
var useDevicePixelRatio = () =>
|
|
2228
|
+
var useDevicePixelRatio = () => useContext4(DevicePixelRatioContext);
|
|
2205
2229
|
|
|
2206
2230
|
// src/contexts/PlaylistInfo.tsx
|
|
2207
|
-
import { createContext as
|
|
2208
|
-
var PlaylistInfoContext =
|
|
2231
|
+
import { createContext as createContext5, useContext as useContext5 } from "react";
|
|
2232
|
+
var PlaylistInfoContext = createContext5({
|
|
2209
2233
|
sampleRate: 48e3,
|
|
2210
2234
|
samplesPerPixel: 1e3,
|
|
2211
2235
|
zoomLevels: [1e3, 1500, 2e3, 2500],
|
|
@@ -2219,26 +2243,26 @@ var PlaylistInfoContext = createContext4({
|
|
|
2219
2243
|
barWidth: 1,
|
|
2220
2244
|
barGap: 0
|
|
2221
2245
|
});
|
|
2222
|
-
var usePlaylistInfo = () =>
|
|
2246
|
+
var usePlaylistInfo = () => useContext5(PlaylistInfoContext);
|
|
2223
2247
|
|
|
2224
2248
|
// src/contexts/Theme.tsx
|
|
2225
|
-
import { useContext as
|
|
2249
|
+
import { useContext as useContext6 } from "react";
|
|
2226
2250
|
import { ThemeContext } from "styled-components";
|
|
2227
|
-
var useTheme2 = () =>
|
|
2251
|
+
var useTheme2 = () => useContext6(ThemeContext);
|
|
2228
2252
|
|
|
2229
2253
|
// src/contexts/TrackControls.tsx
|
|
2230
|
-
import { createContext as
|
|
2231
|
-
import { jsx as
|
|
2232
|
-
var TrackControlsContext =
|
|
2233
|
-
var useTrackControls = () =>
|
|
2254
|
+
import { createContext as createContext6, useContext as useContext7, Fragment as Fragment4 } from "react";
|
|
2255
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
2256
|
+
var TrackControlsContext = createContext6(/* @__PURE__ */ jsx21(Fragment4, {}));
|
|
2257
|
+
var useTrackControls = () => useContext7(TrackControlsContext);
|
|
2234
2258
|
|
|
2235
2259
|
// src/contexts/Playout.tsx
|
|
2236
2260
|
import {
|
|
2237
2261
|
useState as useState5,
|
|
2238
|
-
createContext as
|
|
2239
|
-
useContext as
|
|
2262
|
+
createContext as createContext7,
|
|
2263
|
+
useContext as useContext8
|
|
2240
2264
|
} from "react";
|
|
2241
|
-
import { jsx as
|
|
2265
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
2242
2266
|
var defaultProgress = 0;
|
|
2243
2267
|
var defaultIsPlaying = false;
|
|
2244
2268
|
var defaultSelectionStart = 0;
|
|
@@ -2249,8 +2273,8 @@ var defaultPlayout = {
|
|
|
2249
2273
|
selectionStart: defaultSelectionStart,
|
|
2250
2274
|
selectionEnd: defaultSelectionEnd
|
|
2251
2275
|
};
|
|
2252
|
-
var PlayoutStatusContext =
|
|
2253
|
-
var PlayoutStatusUpdateContext =
|
|
2276
|
+
var PlayoutStatusContext = createContext7(defaultPlayout);
|
|
2277
|
+
var PlayoutStatusUpdateContext = createContext7({
|
|
2254
2278
|
setIsPlaying: () => {
|
|
2255
2279
|
},
|
|
2256
2280
|
setProgress: () => {
|
|
@@ -2267,16 +2291,16 @@ var PlayoutProvider = ({ children }) => {
|
|
|
2267
2291
|
setSelectionStart(start);
|
|
2268
2292
|
setSelectionEnd(end);
|
|
2269
2293
|
};
|
|
2270
|
-
return /* @__PURE__ */
|
|
2294
|
+
return /* @__PURE__ */ jsx22(PlayoutStatusUpdateContext.Provider, { value: { setIsPlaying, setProgress, setSelection }, children: /* @__PURE__ */ jsx22(PlayoutStatusContext.Provider, { value: { isPlaying, progress, selectionStart, selectionEnd }, children }) });
|
|
2271
2295
|
};
|
|
2272
|
-
var usePlayoutStatus = () =>
|
|
2273
|
-
var usePlayoutStatusUpdate = () =>
|
|
2296
|
+
var usePlayoutStatus = () => useContext8(PlayoutStatusContext);
|
|
2297
|
+
var usePlayoutStatusUpdate = () => useContext8(PlayoutStatusUpdateContext);
|
|
2274
2298
|
|
|
2275
2299
|
// src/components/SpectrogramChannel.tsx
|
|
2276
2300
|
import { useRef as useRef6, useEffect as useEffect8 } from "react";
|
|
2277
2301
|
import styled20 from "styled-components";
|
|
2278
2302
|
import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH3 } from "@waveform-playlist/core";
|
|
2279
|
-
import { jsx as
|
|
2303
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2280
2304
|
var LINEAR_FREQUENCY_SCALE = (f, minF, maxF) => (f - minF) / (maxF - minF);
|
|
2281
2305
|
var Wrapper4 = styled20.div.attrs((props) => ({
|
|
2282
2306
|
style: {
|
|
@@ -2513,7 +2537,7 @@ var SpectrogramChannel = ({
|
|
|
2513
2537
|
const canvases = visibleChunkIndices.map((i) => {
|
|
2514
2538
|
const chunkLeft = i * MAX_CANVAS_WIDTH3;
|
|
2515
2539
|
const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH3);
|
|
2516
|
-
return /* @__PURE__ */
|
|
2540
|
+
return /* @__PURE__ */ jsx23(
|
|
2517
2541
|
SpectrogramCanvas,
|
|
2518
2542
|
{
|
|
2519
2543
|
$cssWidth: currentWidth,
|
|
@@ -2527,11 +2551,11 @@ var SpectrogramChannel = ({
|
|
|
2527
2551
|
`${length}-${i}`
|
|
2528
2552
|
);
|
|
2529
2553
|
});
|
|
2530
|
-
return /* @__PURE__ */
|
|
2554
|
+
return /* @__PURE__ */ jsx23(Wrapper4, { $index: index, $cssWidth: length, $waveHeight: waveHeight, children: canvases });
|
|
2531
2555
|
};
|
|
2532
2556
|
|
|
2533
2557
|
// src/components/SmartChannel.tsx
|
|
2534
|
-
import { Fragment as Fragment5, jsx as
|
|
2558
|
+
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2535
2559
|
var SmartChannel = ({
|
|
2536
2560
|
isSelected,
|
|
2537
2561
|
transparentBackground,
|
|
@@ -2565,7 +2589,7 @@ var SmartChannel = ({
|
|
|
2565
2589
|
const drawMode = theme?.waveformDrawMode || "inverted";
|
|
2566
2590
|
const hasSpectrogram = spectrogramData || spectrogramWorkerApi;
|
|
2567
2591
|
if (renderMode === "spectrogram" && hasSpectrogram) {
|
|
2568
|
-
return /* @__PURE__ */
|
|
2592
|
+
return /* @__PURE__ */ jsx24(
|
|
2569
2593
|
SpectrogramChannel,
|
|
2570
2594
|
{
|
|
2571
2595
|
index: props.index,
|
|
@@ -2587,7 +2611,7 @@ var SmartChannel = ({
|
|
|
2587
2611
|
if (renderMode === "both" && hasSpectrogram) {
|
|
2588
2612
|
const halfHeight = Math.floor(waveHeight / 2);
|
|
2589
2613
|
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2590
|
-
/* @__PURE__ */
|
|
2614
|
+
/* @__PURE__ */ jsx24(
|
|
2591
2615
|
SpectrogramChannel,
|
|
2592
2616
|
{
|
|
2593
2617
|
index: props.index * 2,
|
|
@@ -2606,7 +2630,7 @@ var SmartChannel = ({
|
|
|
2606
2630
|
onCanvasesReady: spectrogramOnCanvasesReady
|
|
2607
2631
|
}
|
|
2608
2632
|
),
|
|
2609
|
-
/* @__PURE__ */
|
|
2633
|
+
/* @__PURE__ */ jsx24(
|
|
2610
2634
|
"div",
|
|
2611
2635
|
{
|
|
2612
2636
|
style: {
|
|
@@ -2615,7 +2639,7 @@ var SmartChannel = ({
|
|
|
2615
2639
|
width: props.length,
|
|
2616
2640
|
height: halfHeight
|
|
2617
2641
|
},
|
|
2618
|
-
children: /* @__PURE__ */
|
|
2642
|
+
children: /* @__PURE__ */ jsx24(
|
|
2619
2643
|
Channel,
|
|
2620
2644
|
{
|
|
2621
2645
|
...props,
|
|
@@ -2635,7 +2659,7 @@ var SmartChannel = ({
|
|
|
2635
2659
|
] });
|
|
2636
2660
|
}
|
|
2637
2661
|
if (renderMode === "piano-roll") {
|
|
2638
|
-
return /* @__PURE__ */
|
|
2662
|
+
return /* @__PURE__ */ jsx24(
|
|
2639
2663
|
PianoRollChannel,
|
|
2640
2664
|
{
|
|
2641
2665
|
index: props.index,
|
|
@@ -2654,7 +2678,7 @@ var SmartChannel = ({
|
|
|
2654
2678
|
}
|
|
2655
2679
|
);
|
|
2656
2680
|
}
|
|
2657
|
-
return /* @__PURE__ */
|
|
2681
|
+
return /* @__PURE__ */ jsx24(
|
|
2658
2682
|
Channel,
|
|
2659
2683
|
{
|
|
2660
2684
|
...props,
|
|
@@ -2673,7 +2697,7 @@ var SmartChannel = ({
|
|
|
2673
2697
|
// src/components/SpectrogramLabels.tsx
|
|
2674
2698
|
import { useRef as useRef7, useLayoutEffect as useLayoutEffect2 } from "react";
|
|
2675
2699
|
import styled21 from "styled-components";
|
|
2676
|
-
import { jsx as
|
|
2700
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
2677
2701
|
var LABELS_WIDTH = 72;
|
|
2678
2702
|
var LabelsStickyWrapper = styled21.div`
|
|
2679
2703
|
position: sticky;
|
|
@@ -2766,7 +2790,7 @@ var SpectrogramLabels = ({
|
|
|
2766
2790
|
spectrogramHeight,
|
|
2767
2791
|
clipHeaderOffset
|
|
2768
2792
|
]);
|
|
2769
|
-
return /* @__PURE__ */
|
|
2793
|
+
return /* @__PURE__ */ jsx25(LabelsStickyWrapper, { $height: totalHeight + clipHeaderOffset, children: /* @__PURE__ */ jsx25(
|
|
2770
2794
|
"canvas",
|
|
2771
2795
|
{
|
|
2772
2796
|
ref: canvasRef,
|
|
@@ -2782,41 +2806,14 @@ var SpectrogramLabels = ({
|
|
|
2782
2806
|
};
|
|
2783
2807
|
|
|
2784
2808
|
// src/components/SmartScale.tsx
|
|
2785
|
-
import { useContext as
|
|
2809
|
+
import React19, { useContext as useContext10, useMemo as useMemo4 } from "react";
|
|
2810
|
+
import styled23 from "styled-components";
|
|
2786
2811
|
|
|
2787
2812
|
// src/components/TimeScale.tsx
|
|
2788
|
-
import
|
|
2813
|
+
import { useLayoutEffect as useLayoutEffect3, useContext as useContext9 } from "react";
|
|
2789
2814
|
import styled22, { withTheme as withTheme2 } from "styled-components";
|
|
2790
|
-
|
|
2791
|
-
// src/utils/conversions.ts
|
|
2792
|
-
function samplesToSeconds(samples, sampleRate) {
|
|
2793
|
-
return samples / sampleRate;
|
|
2794
|
-
}
|
|
2795
|
-
function secondsToSamples(seconds, sampleRate) {
|
|
2796
|
-
return Math.ceil(seconds * sampleRate);
|
|
2797
|
-
}
|
|
2798
|
-
function samplesToPixels(samples, samplesPerPixel) {
|
|
2799
|
-
return Math.floor(samples / samplesPerPixel);
|
|
2800
|
-
}
|
|
2801
|
-
function pixelsToSamples(pixels, samplesPerPixel) {
|
|
2802
|
-
return Math.floor(pixels * samplesPerPixel);
|
|
2803
|
-
}
|
|
2804
|
-
function pixelsToSeconds(pixels, samplesPerPixel, sampleRate) {
|
|
2805
|
-
return pixels * samplesPerPixel / sampleRate;
|
|
2806
|
-
}
|
|
2807
|
-
function secondsToPixels(seconds, samplesPerPixel, sampleRate) {
|
|
2808
|
-
return Math.ceil(seconds * sampleRate / samplesPerPixel);
|
|
2809
|
-
}
|
|
2810
|
-
|
|
2811
|
-
// src/components/TimeScale.tsx
|
|
2812
2815
|
import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH4 } from "@waveform-playlist/core";
|
|
2813
|
-
import { jsx as
|
|
2814
|
-
function formatTime2(milliseconds) {
|
|
2815
|
-
const seconds = Math.floor(milliseconds / 1e3);
|
|
2816
|
-
const s = seconds % 60;
|
|
2817
|
-
const m = (seconds - s) / 60;
|
|
2818
|
-
return `${m}:${String(s).padStart(2, "0")}`;
|
|
2819
|
-
}
|
|
2816
|
+
import { jsx as jsx26, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2820
2817
|
var PlaylistTimeScaleScroll = styled22.div.attrs((props) => ({
|
|
2821
2818
|
style: {
|
|
2822
2819
|
width: `${props.$cssWidth}px`,
|
|
@@ -2838,70 +2835,20 @@ var TimeTickChunk = styled22.canvas.attrs((props) => ({
|
|
|
2838
2835
|
position: absolute;
|
|
2839
2836
|
bottom: 0;
|
|
2840
2837
|
`;
|
|
2841
|
-
var TimeStamp = styled22.div.attrs((props) => ({
|
|
2842
|
-
style: {
|
|
2843
|
-
left: `${props.$left + 4}px`
|
|
2844
|
-
// Offset 4px to the right of the tick
|
|
2845
|
-
}
|
|
2846
|
-
}))`
|
|
2847
|
-
position: absolute;
|
|
2848
|
-
font-size: 0.75rem; /* Smaller font to prevent overflow */
|
|
2849
|
-
white-space: nowrap; /* Prevent text wrapping */
|
|
2850
|
-
color: ${(props) => props.theme.timeColor}; /* Use theme color instead of inheriting */
|
|
2851
|
-
`;
|
|
2852
2838
|
var TimeScale = (props) => {
|
|
2853
2839
|
const {
|
|
2854
2840
|
theme: { timeColor },
|
|
2855
|
-
|
|
2856
|
-
marker,
|
|
2857
|
-
bigStep,
|
|
2858
|
-
secondStep,
|
|
2859
|
-
renderTimestamp
|
|
2841
|
+
tickData
|
|
2860
2842
|
} = props;
|
|
2861
2843
|
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2862
|
-
const {
|
|
2844
|
+
const { timeScaleHeight } = useContext9(PlaylistInfoContext);
|
|
2863
2845
|
const devicePixelRatio = useDevicePixelRatio();
|
|
2864
|
-
const { widthX, canvasInfo, timeMarkersWithPositions } =
|
|
2865
|
-
const nextCanvasInfo = /* @__PURE__ */ new Map();
|
|
2866
|
-
const nextMarkers = [];
|
|
2867
|
-
const nextWidthX = secondsToPixels(duration / 1e3, samplesPerPixel, sampleRate);
|
|
2868
|
-
const pixPerSec = sampleRate / samplesPerPixel;
|
|
2869
|
-
let counter = 0;
|
|
2870
|
-
for (let i = 0; i < nextWidthX; i += pixPerSec * secondStep / 1e3) {
|
|
2871
|
-
const pix = Math.floor(i);
|
|
2872
|
-
if (counter % marker === 0) {
|
|
2873
|
-
const timeMs = counter;
|
|
2874
|
-
const timestamp = formatTime2(timeMs);
|
|
2875
|
-
const element = renderTimestamp ? /* @__PURE__ */ jsx25(React17.Fragment, { children: renderTimestamp(timeMs, pix) }, `timestamp-${counter}`) : /* @__PURE__ */ jsx25(TimeStamp, { $left: pix, children: timestamp }, timestamp);
|
|
2876
|
-
nextMarkers.push({ pix, element });
|
|
2877
|
-
nextCanvasInfo.set(pix, timeScaleHeight);
|
|
2878
|
-
} else if (counter % bigStep === 0) {
|
|
2879
|
-
nextCanvasInfo.set(pix, Math.floor(timeScaleHeight / 2));
|
|
2880
|
-
} else if (counter % secondStep === 0) {
|
|
2881
|
-
nextCanvasInfo.set(pix, Math.floor(timeScaleHeight / 5));
|
|
2882
|
-
}
|
|
2883
|
-
counter += secondStep;
|
|
2884
|
-
}
|
|
2885
|
-
return {
|
|
2886
|
-
widthX: nextWidthX,
|
|
2887
|
-
canvasInfo: nextCanvasInfo,
|
|
2888
|
-
timeMarkersWithPositions: nextMarkers
|
|
2889
|
-
};
|
|
2890
|
-
}, [
|
|
2891
|
-
duration,
|
|
2892
|
-
samplesPerPixel,
|
|
2893
|
-
sampleRate,
|
|
2894
|
-
marker,
|
|
2895
|
-
bigStep,
|
|
2896
|
-
secondStep,
|
|
2897
|
-
renderTimestamp,
|
|
2898
|
-
timeScaleHeight
|
|
2899
|
-
]);
|
|
2846
|
+
const { widthX, canvasInfo, timeMarkersWithPositions } = tickData;
|
|
2900
2847
|
const visibleChunkIndices = useVisibleChunkIndices(widthX, MAX_CANVAS_WIDTH4);
|
|
2901
2848
|
const visibleChunks = visibleChunkIndices.map((i) => {
|
|
2902
2849
|
const chunkLeft = i * MAX_CANVAS_WIDTH4;
|
|
2903
2850
|
const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH4);
|
|
2904
|
-
return /* @__PURE__ */
|
|
2851
|
+
return /* @__PURE__ */ jsx26(
|
|
2905
2852
|
TimeTickChunk,
|
|
2906
2853
|
{
|
|
2907
2854
|
$cssWidth: chunkWidth,
|
|
@@ -2936,15 +2883,7 @@ var TimeScale = (props) => {
|
|
|
2936
2883
|
ctx.fillRect(localX, scaleY, 1, scaleHeight);
|
|
2937
2884
|
}
|
|
2938
2885
|
}
|
|
2939
|
-
}, [
|
|
2940
|
-
canvasMapRef,
|
|
2941
|
-
duration,
|
|
2942
|
-
devicePixelRatio,
|
|
2943
|
-
timeColor,
|
|
2944
|
-
timeScaleHeight,
|
|
2945
|
-
canvasInfo,
|
|
2946
|
-
visibleChunkIndices
|
|
2947
|
-
]);
|
|
2886
|
+
}, [canvasMapRef, devicePixelRatio, timeColor, timeScaleHeight, canvasInfo, visibleChunkIndices]);
|
|
2948
2887
|
return /* @__PURE__ */ jsxs10(PlaylistTimeScaleScroll, { $cssWidth: widthX, $timeScaleHeight: timeScaleHeight, children: [
|
|
2949
2888
|
visibleMarkers,
|
|
2950
2889
|
visibleChunks
|
|
@@ -2953,64 +2892,22 @@ var TimeScale = (props) => {
|
|
|
2953
2892
|
var StyledTimeScale = withTheme2(TimeScale);
|
|
2954
2893
|
|
|
2955
2894
|
// src/components/SmartScale.tsx
|
|
2956
|
-
import {
|
|
2895
|
+
import {
|
|
2896
|
+
PPQN,
|
|
2897
|
+
ticksToSamples,
|
|
2898
|
+
ticksToBarBeatLabel,
|
|
2899
|
+
samplesToPixels,
|
|
2900
|
+
secondsToPixels
|
|
2901
|
+
} from "@waveform-playlist/core";
|
|
2902
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
2957
2903
|
var timeinfo = /* @__PURE__ */ new Map([
|
|
2958
|
-
[
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
],
|
|
2966
|
-
[
|
|
2967
|
-
1500,
|
|
2968
|
-
{
|
|
2969
|
-
marker: 2e3,
|
|
2970
|
-
bigStep: 1e3,
|
|
2971
|
-
smallStep: 200
|
|
2972
|
-
}
|
|
2973
|
-
],
|
|
2974
|
-
[
|
|
2975
|
-
2500,
|
|
2976
|
-
{
|
|
2977
|
-
marker: 2e3,
|
|
2978
|
-
bigStep: 1e3,
|
|
2979
|
-
smallStep: 500
|
|
2980
|
-
}
|
|
2981
|
-
],
|
|
2982
|
-
[
|
|
2983
|
-
5e3,
|
|
2984
|
-
{
|
|
2985
|
-
marker: 5e3,
|
|
2986
|
-
bigStep: 1e3,
|
|
2987
|
-
smallStep: 500
|
|
2988
|
-
}
|
|
2989
|
-
],
|
|
2990
|
-
[
|
|
2991
|
-
1e4,
|
|
2992
|
-
{
|
|
2993
|
-
marker: 1e4,
|
|
2994
|
-
bigStep: 5e3,
|
|
2995
|
-
smallStep: 1e3
|
|
2996
|
-
}
|
|
2997
|
-
],
|
|
2998
|
-
[
|
|
2999
|
-
12e3,
|
|
3000
|
-
{
|
|
3001
|
-
marker: 15e3,
|
|
3002
|
-
bigStep: 5e3,
|
|
3003
|
-
smallStep: 1e3
|
|
3004
|
-
}
|
|
3005
|
-
],
|
|
3006
|
-
[
|
|
3007
|
-
Infinity,
|
|
3008
|
-
{
|
|
3009
|
-
marker: 3e4,
|
|
3010
|
-
bigStep: 1e4,
|
|
3011
|
-
smallStep: 5e3
|
|
3012
|
-
}
|
|
3013
|
-
]
|
|
2904
|
+
[700, { marker: 1e3, bigStep: 500, smallStep: 100 }],
|
|
2905
|
+
[1500, { marker: 2e3, bigStep: 1e3, smallStep: 200 }],
|
|
2906
|
+
[2500, { marker: 2e3, bigStep: 1e3, smallStep: 500 }],
|
|
2907
|
+
[5e3, { marker: 5e3, bigStep: 1e3, smallStep: 500 }],
|
|
2908
|
+
[1e4, { marker: 1e4, bigStep: 5e3, smallStep: 1e3 }],
|
|
2909
|
+
[12e3, { marker: 15e3, bigStep: 5e3, smallStep: 1e3 }],
|
|
2910
|
+
[Infinity, { marker: 3e4, bigStep: 1e4, smallStep: 5e3 }]
|
|
3014
2911
|
]);
|
|
3015
2912
|
function getScaleInfo(samplesPerPixel) {
|
|
3016
2913
|
const keys = timeinfo.keys();
|
|
@@ -3026,25 +2923,113 @@ function getScaleInfo(samplesPerPixel) {
|
|
|
3026
2923
|
}
|
|
3027
2924
|
return config;
|
|
3028
2925
|
}
|
|
3029
|
-
|
|
3030
|
-
const
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
2926
|
+
function formatTime2(milliseconds) {
|
|
2927
|
+
const seconds = Math.floor(milliseconds / 1e3);
|
|
2928
|
+
const s = seconds % 60;
|
|
2929
|
+
const m = (seconds - s) / 60;
|
|
2930
|
+
return `${m}:${String(s).padStart(2, "0")}`;
|
|
2931
|
+
}
|
|
2932
|
+
var TimeStamp = styled23.div.attrs((props) => ({
|
|
2933
|
+
style: {
|
|
2934
|
+
left: `${props.$left + 4}px`
|
|
2935
|
+
// Offset 4px to the right of the tick
|
|
2936
|
+
}
|
|
2937
|
+
}))`
|
|
2938
|
+
position: absolute;
|
|
2939
|
+
font-size: 0.75rem; /* Smaller font to prevent overflow */
|
|
2940
|
+
white-space: nowrap; /* Prevent text wrapping */
|
|
2941
|
+
color: ${(props) => props.theme.timeColor}; /* Use theme color instead of inheriting */
|
|
2942
|
+
`;
|
|
2943
|
+
var SmartScale = ({ renderTick }) => {
|
|
2944
|
+
const { samplesPerPixel, sampleRate, duration, timeScaleHeight } = useContext10(PlaylistInfoContext);
|
|
2945
|
+
const beatsAndBars = useBeatsAndBars();
|
|
2946
|
+
const tickData = useMemo4(() => {
|
|
2947
|
+
const widthX = secondsToPixels(duration / 1e3, samplesPerPixel, sampleRate);
|
|
2948
|
+
if (beatsAndBars && beatsAndBars.scaleMode === "beats") {
|
|
2949
|
+
const { bpm, timeSignature, ticksPerBar: tpBar, ticksPerBeat: tpBeat } = beatsAndBars;
|
|
2950
|
+
const canvasInfo2 = /* @__PURE__ */ new Map();
|
|
2951
|
+
const timeMarkersWithPositions2 = [];
|
|
2952
|
+
const durationSeconds = duration / 1e3;
|
|
2953
|
+
const totalTicks = Math.ceil(durationSeconds * bpm * PPQN / 60);
|
|
2954
|
+
const pixelsPerBeat = ticksToSamples(tpBeat, bpm, sampleRate) / samplesPerPixel;
|
|
2955
|
+
const pixelsPerBar = ticksToSamples(tpBar, bpm, sampleRate) / samplesPerPixel;
|
|
2956
|
+
const MIN_TICK_PX = 10;
|
|
2957
|
+
const MIN_LABEL_PX = 30;
|
|
2958
|
+
let tickStep;
|
|
2959
|
+
if (pixelsPerBeat >= MIN_TICK_PX) {
|
|
2960
|
+
tickStep = tpBeat;
|
|
2961
|
+
} else if (pixelsPerBar >= MIN_TICK_PX) {
|
|
2962
|
+
tickStep = tpBar;
|
|
2963
|
+
} else {
|
|
2964
|
+
const barsPerTick = Math.ceil(MIN_TICK_PX / pixelsPerBar);
|
|
2965
|
+
tickStep = tpBar * barsPerTick;
|
|
2966
|
+
}
|
|
2967
|
+
let labelStep;
|
|
2968
|
+
if (pixelsPerBeat >= MIN_LABEL_PX) {
|
|
2969
|
+
labelStep = tpBeat;
|
|
2970
|
+
} else if (pixelsPerBar >= MIN_LABEL_PX) {
|
|
2971
|
+
labelStep = tpBar;
|
|
2972
|
+
} else {
|
|
2973
|
+
const barsPerLabel = Math.ceil(MIN_LABEL_PX / pixelsPerBar);
|
|
2974
|
+
labelStep = tpBar * barsPerLabel;
|
|
2975
|
+
}
|
|
2976
|
+
for (let tick = 0; tick <= totalTicks; tick += tickStep) {
|
|
2977
|
+
const samples = ticksToSamples(tick, bpm, sampleRate);
|
|
2978
|
+
const pix = samplesToPixels(samples, samplesPerPixel);
|
|
2979
|
+
if (pix >= widthX) break;
|
|
2980
|
+
const isBarLine = tick % tpBar === 0;
|
|
2981
|
+
const isLabelTick = tick % labelStep === 0;
|
|
2982
|
+
const tickHeight = isBarLine ? timeScaleHeight : isLabelTick ? Math.floor(timeScaleHeight / 2) : Math.floor(timeScaleHeight / 5);
|
|
2983
|
+
canvasInfo2.set(pix, tickHeight);
|
|
2984
|
+
if (isLabelTick) {
|
|
2985
|
+
const label = ticksToBarBeatLabel(tick, timeSignature);
|
|
2986
|
+
const element = renderTick ? /* @__PURE__ */ jsx27(React19.Fragment, { children: renderTick(label, pix) }, `bb-${tick}`) : /* @__PURE__ */ jsx27(
|
|
2987
|
+
"div",
|
|
2988
|
+
{
|
|
2989
|
+
style: {
|
|
2990
|
+
position: "absolute",
|
|
2991
|
+
left: `${pix + 4}px`,
|
|
2992
|
+
fontSize: "0.75rem",
|
|
2993
|
+
whiteSpace: "nowrap"
|
|
2994
|
+
},
|
|
2995
|
+
children: label
|
|
2996
|
+
},
|
|
2997
|
+
`bb-${tick}`
|
|
2998
|
+
);
|
|
2999
|
+
timeMarkersWithPositions2.push({ pix, element });
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
return { widthX, canvasInfo: canvasInfo2, timeMarkersWithPositions: timeMarkersWithPositions2 };
|
|
3040
3003
|
}
|
|
3041
|
-
|
|
3004
|
+
const config = getScaleInfo(samplesPerPixel);
|
|
3005
|
+
const { marker, bigStep, smallStep } = config;
|
|
3006
|
+
const canvasInfo = /* @__PURE__ */ new Map();
|
|
3007
|
+
const timeMarkersWithPositions = [];
|
|
3008
|
+
const pixPerSec = sampleRate / samplesPerPixel;
|
|
3009
|
+
let counter = 0;
|
|
3010
|
+
for (let i = 0; i < widthX; i += pixPerSec * smallStep / 1e3) {
|
|
3011
|
+
const pix = Math.floor(i);
|
|
3012
|
+
if (counter % marker === 0) {
|
|
3013
|
+
const timestamp = formatTime2(counter);
|
|
3014
|
+
const element = renderTick ? /* @__PURE__ */ jsx27(React19.Fragment, { children: renderTick(timestamp, pix) }, `timestamp-${counter}`) : /* @__PURE__ */ jsx27(TimeStamp, { $left: pix, children: timestamp }, timestamp);
|
|
3015
|
+
timeMarkersWithPositions.push({ pix, element });
|
|
3016
|
+
canvasInfo.set(pix, timeScaleHeight);
|
|
3017
|
+
} else if (counter % bigStep === 0) {
|
|
3018
|
+
canvasInfo.set(pix, Math.floor(timeScaleHeight / 2));
|
|
3019
|
+
} else if (counter % smallStep === 0) {
|
|
3020
|
+
canvasInfo.set(pix, Math.floor(timeScaleHeight / 5));
|
|
3021
|
+
}
|
|
3022
|
+
counter += smallStep;
|
|
3023
|
+
}
|
|
3024
|
+
return { widthX, canvasInfo, timeMarkersWithPositions };
|
|
3025
|
+
}, [beatsAndBars, duration, samplesPerPixel, sampleRate, timeScaleHeight, renderTick]);
|
|
3026
|
+
return /* @__PURE__ */ jsx27(StyledTimeScale, { tickData });
|
|
3042
3027
|
};
|
|
3043
3028
|
|
|
3044
3029
|
// src/components/TimeFormatSelect.tsx
|
|
3045
|
-
import
|
|
3046
|
-
import { jsx as
|
|
3047
|
-
var SelectWrapper =
|
|
3030
|
+
import styled24 from "styled-components";
|
|
3031
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
3032
|
+
var SelectWrapper = styled24.div`
|
|
3048
3033
|
display: inline-flex;
|
|
3049
3034
|
align-items: center;
|
|
3050
3035
|
gap: 0.5rem;
|
|
@@ -3066,7 +3051,7 @@ var TimeFormatSelect = ({
|
|
|
3066
3051
|
const handleChange = (e) => {
|
|
3067
3052
|
onChange(e.target.value);
|
|
3068
3053
|
};
|
|
3069
|
-
return /* @__PURE__ */
|
|
3054
|
+
return /* @__PURE__ */ jsx28(SelectWrapper, { className, children: /* @__PURE__ */ jsx28(
|
|
3070
3055
|
BaseSelect,
|
|
3071
3056
|
{
|
|
3072
3057
|
className: "time-format",
|
|
@@ -3074,15 +3059,15 @@ var TimeFormatSelect = ({
|
|
|
3074
3059
|
onChange: handleChange,
|
|
3075
3060
|
disabled,
|
|
3076
3061
|
"aria-label": "Time format selection",
|
|
3077
|
-
children: TIME_FORMAT_OPTIONS.map((option) => /* @__PURE__ */
|
|
3062
|
+
children: TIME_FORMAT_OPTIONS.map((option) => /* @__PURE__ */ jsx28("option", { value: option.value, children: option.label }, option.value))
|
|
3078
3063
|
}
|
|
3079
3064
|
) });
|
|
3080
3065
|
};
|
|
3081
3066
|
|
|
3082
3067
|
// src/components/Track.tsx
|
|
3083
|
-
import
|
|
3084
|
-
import { jsx as
|
|
3085
|
-
var Container =
|
|
3068
|
+
import styled25 from "styled-components";
|
|
3069
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
3070
|
+
var Container = styled25.div.attrs((props) => ({
|
|
3086
3071
|
style: {
|
|
3087
3072
|
height: `${props.$waveHeight * props.$numChannels + (props.$hasClipHeaders ? CLIP_HEADER_HEIGHT : 0)}px`
|
|
3088
3073
|
}
|
|
@@ -3090,7 +3075,7 @@ var Container = styled24.div.attrs((props) => ({
|
|
|
3090
3075
|
position: relative;
|
|
3091
3076
|
${(props) => props.$width !== void 0 && `width: ${props.$width}px;`}
|
|
3092
3077
|
`;
|
|
3093
|
-
var ChannelContainer =
|
|
3078
|
+
var ChannelContainer = styled25.div.attrs((props) => ({
|
|
3094
3079
|
style: {
|
|
3095
3080
|
paddingLeft: `${props.$offset || 0}px`
|
|
3096
3081
|
}
|
|
@@ -3112,7 +3097,7 @@ var Track = ({
|
|
|
3112
3097
|
isSelected: _isSelected = false
|
|
3113
3098
|
}) => {
|
|
3114
3099
|
const { waveHeight } = usePlaylistInfo();
|
|
3115
|
-
return /* @__PURE__ */
|
|
3100
|
+
return /* @__PURE__ */ jsx29(
|
|
3116
3101
|
Container,
|
|
3117
3102
|
{
|
|
3118
3103
|
$numChannels: numChannels,
|
|
@@ -3120,7 +3105,7 @@ var Track = ({
|
|
|
3120
3105
|
$waveHeight: waveHeight,
|
|
3121
3106
|
$width: width,
|
|
3122
3107
|
$hasClipHeaders: hasClipHeaders,
|
|
3123
|
-
children: /* @__PURE__ */
|
|
3108
|
+
children: /* @__PURE__ */ jsx29(
|
|
3124
3109
|
ChannelContainer,
|
|
3125
3110
|
{
|
|
3126
3111
|
$backgroundColor: backgroundColor,
|
|
@@ -3135,8 +3120,8 @@ var Track = ({
|
|
|
3135
3120
|
};
|
|
3136
3121
|
|
|
3137
3122
|
// src/components/TrackControls/Button.tsx
|
|
3138
|
-
import
|
|
3139
|
-
var Button =
|
|
3123
|
+
import styled26 from "styled-components";
|
|
3124
|
+
var Button = styled26.button.attrs({
|
|
3140
3125
|
type: "button"
|
|
3141
3126
|
})`
|
|
3142
3127
|
display: inline-block;
|
|
@@ -3211,8 +3196,8 @@ var Button = styled25.button.attrs({
|
|
|
3211
3196
|
`;
|
|
3212
3197
|
|
|
3213
3198
|
// src/components/TrackControls/ButtonGroup.tsx
|
|
3214
|
-
import
|
|
3215
|
-
var ButtonGroup =
|
|
3199
|
+
import styled27 from "styled-components";
|
|
3200
|
+
var ButtonGroup = styled27.div`
|
|
3216
3201
|
margin-bottom: 0.3rem;
|
|
3217
3202
|
|
|
3218
3203
|
button:not(:first-child) {
|
|
@@ -3227,10 +3212,10 @@ var ButtonGroup = styled26.div`
|
|
|
3227
3212
|
`;
|
|
3228
3213
|
|
|
3229
3214
|
// src/components/TrackControls/CloseButton.tsx
|
|
3230
|
-
import
|
|
3215
|
+
import styled28 from "styled-components";
|
|
3231
3216
|
import { X as XIcon } from "@phosphor-icons/react";
|
|
3232
|
-
import { jsx as
|
|
3233
|
-
var StyledCloseButton =
|
|
3217
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
3218
|
+
var StyledCloseButton = styled28.button`
|
|
3234
3219
|
position: absolute;
|
|
3235
3220
|
left: 0;
|
|
3236
3221
|
top: 0;
|
|
@@ -3253,11 +3238,11 @@ var StyledCloseButton = styled27.button`
|
|
|
3253
3238
|
color: #dc3545;
|
|
3254
3239
|
}
|
|
3255
3240
|
`;
|
|
3256
|
-
var CloseButton = ({ onClick, title = "Remove track" }) => /* @__PURE__ */
|
|
3241
|
+
var CloseButton = ({ onClick, title = "Remove track" }) => /* @__PURE__ */ jsx30(StyledCloseButton, { onClick, title, children: /* @__PURE__ */ jsx30(XIcon, { size: 12, weight: "bold" }) });
|
|
3257
3242
|
|
|
3258
3243
|
// src/components/TrackControls/Controls.tsx
|
|
3259
|
-
import
|
|
3260
|
-
var Controls =
|
|
3244
|
+
import styled29 from "styled-components";
|
|
3245
|
+
var Controls = styled29.div`
|
|
3261
3246
|
background: transparent;
|
|
3262
3247
|
width: 100%;
|
|
3263
3248
|
height: 100%;
|
|
@@ -3273,8 +3258,8 @@ var Controls = styled28.div`
|
|
|
3273
3258
|
`;
|
|
3274
3259
|
|
|
3275
3260
|
// src/components/TrackControls/Header.tsx
|
|
3276
|
-
import
|
|
3277
|
-
var Header =
|
|
3261
|
+
import styled30 from "styled-components";
|
|
3262
|
+
var Header = styled30.header`
|
|
3278
3263
|
overflow: hidden;
|
|
3279
3264
|
height: 26px;
|
|
3280
3265
|
width: 100%;
|
|
@@ -3289,27 +3274,27 @@ var Header = styled29.header`
|
|
|
3289
3274
|
|
|
3290
3275
|
// src/components/TrackControls/VolumeDownIcon.tsx
|
|
3291
3276
|
import { SpeakerLowIcon } from "@phosphor-icons/react";
|
|
3292
|
-
import { jsx as
|
|
3293
|
-
var VolumeDownIcon = (props) => /* @__PURE__ */
|
|
3277
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
3278
|
+
var VolumeDownIcon = (props) => /* @__PURE__ */ jsx31(SpeakerLowIcon, { weight: "light", ...props });
|
|
3294
3279
|
|
|
3295
3280
|
// src/components/TrackControls/VolumeUpIcon.tsx
|
|
3296
3281
|
import { SpeakerHighIcon } from "@phosphor-icons/react";
|
|
3297
|
-
import { jsx as
|
|
3298
|
-
var VolumeUpIcon = (props) => /* @__PURE__ */
|
|
3282
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
3283
|
+
var VolumeUpIcon = (props) => /* @__PURE__ */ jsx32(SpeakerHighIcon, { weight: "light", ...props });
|
|
3299
3284
|
|
|
3300
3285
|
// src/components/TrackControls/TrashIcon.tsx
|
|
3301
3286
|
import { TrashIcon as PhosphorTrashIcon } from "@phosphor-icons/react";
|
|
3302
|
-
import { jsx as
|
|
3303
|
-
var TrashIcon = (props) => /* @__PURE__ */
|
|
3287
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
3288
|
+
var TrashIcon = (props) => /* @__PURE__ */ jsx33(PhosphorTrashIcon, { weight: "light", ...props });
|
|
3304
3289
|
|
|
3305
3290
|
// src/components/TrackControls/DotsIcon.tsx
|
|
3306
3291
|
import { DotsThreeIcon } from "@phosphor-icons/react";
|
|
3307
|
-
import { jsx as
|
|
3308
|
-
var DotsIcon = (props) => /* @__PURE__ */
|
|
3292
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
3293
|
+
var DotsIcon = (props) => /* @__PURE__ */ jsx34(DotsThreeIcon, { weight: "bold", ...props });
|
|
3309
3294
|
|
|
3310
3295
|
// src/components/TrackControls/Slider.tsx
|
|
3311
|
-
import
|
|
3312
|
-
var Slider =
|
|
3296
|
+
import styled31 from "styled-components";
|
|
3297
|
+
var Slider = styled31(BaseSlider)`
|
|
3313
3298
|
width: 75%;
|
|
3314
3299
|
height: 5px;
|
|
3315
3300
|
background: ${(props) => props.theme.sliderTrackColor};
|
|
@@ -3361,8 +3346,8 @@ var Slider = styled30(BaseSlider)`
|
|
|
3361
3346
|
`;
|
|
3362
3347
|
|
|
3363
3348
|
// src/components/TrackControls/SliderWrapper.tsx
|
|
3364
|
-
import
|
|
3365
|
-
var SliderWrapper =
|
|
3349
|
+
import styled32 from "styled-components";
|
|
3350
|
+
var SliderWrapper = styled32.label`
|
|
3366
3351
|
width: 100%;
|
|
3367
3352
|
display: flex;
|
|
3368
3353
|
justify-content: space-between;
|
|
@@ -3373,15 +3358,15 @@ var SliderWrapper = styled31.label`
|
|
|
3373
3358
|
`;
|
|
3374
3359
|
|
|
3375
3360
|
// src/components/TrackMenu.tsx
|
|
3376
|
-
import
|
|
3361
|
+
import React20, { useState as useState6, useEffect as useEffect9, useRef as useRef8, useCallback as useCallback5 } from "react";
|
|
3377
3362
|
import { createPortal } from "react-dom";
|
|
3378
|
-
import
|
|
3379
|
-
import { jsx as
|
|
3380
|
-
var MenuContainer =
|
|
3363
|
+
import styled33 from "styled-components";
|
|
3364
|
+
import { jsx as jsx35, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3365
|
+
var MenuContainer = styled33.div`
|
|
3381
3366
|
position: relative;
|
|
3382
3367
|
display: inline-block;
|
|
3383
3368
|
`;
|
|
3384
|
-
var MenuButton =
|
|
3369
|
+
var MenuButton = styled33.button`
|
|
3385
3370
|
background: none;
|
|
3386
3371
|
border: none;
|
|
3387
3372
|
cursor: pointer;
|
|
@@ -3397,7 +3382,7 @@ var MenuButton = styled32.button`
|
|
|
3397
3382
|
}
|
|
3398
3383
|
`;
|
|
3399
3384
|
var DROPDOWN_MIN_WIDTH = 180;
|
|
3400
|
-
var Dropdown =
|
|
3385
|
+
var Dropdown = styled33.div`
|
|
3401
3386
|
position: fixed;
|
|
3402
3387
|
top: ${(p) => p.$top}px;
|
|
3403
3388
|
left: ${(p) => p.$left}px;
|
|
@@ -3410,7 +3395,7 @@ var Dropdown = styled32.div`
|
|
|
3410
3395
|
min-width: ${DROPDOWN_MIN_WIDTH}px;
|
|
3411
3396
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
3412
3397
|
`;
|
|
3413
|
-
var Divider =
|
|
3398
|
+
var Divider = styled33.hr`
|
|
3414
3399
|
border: none;
|
|
3415
3400
|
border-top: 1px solid rgba(128, 128, 128, 0.3);
|
|
3416
3401
|
margin: 0.35rem 0;
|
|
@@ -3474,7 +3459,7 @@ var TrackMenu = ({ items: itemsProp }) => {
|
|
|
3474
3459
|
};
|
|
3475
3460
|
}, [open]);
|
|
3476
3461
|
return /* @__PURE__ */ jsxs11(MenuContainer, { children: [
|
|
3477
|
-
/* @__PURE__ */
|
|
3462
|
+
/* @__PURE__ */ jsx35(
|
|
3478
3463
|
MenuButton,
|
|
3479
3464
|
{
|
|
3480
3465
|
ref: buttonRef,
|
|
@@ -3485,19 +3470,19 @@ var TrackMenu = ({ items: itemsProp }) => {
|
|
|
3485
3470
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3486
3471
|
title: "Track menu",
|
|
3487
3472
|
"aria-label": "Track menu",
|
|
3488
|
-
children: /* @__PURE__ */
|
|
3473
|
+
children: /* @__PURE__ */ jsx35(DotsIcon, { size: 16 })
|
|
3489
3474
|
}
|
|
3490
3475
|
),
|
|
3491
3476
|
open && typeof document !== "undefined" && createPortal(
|
|
3492
|
-
/* @__PURE__ */
|
|
3477
|
+
/* @__PURE__ */ jsx35(
|
|
3493
3478
|
Dropdown,
|
|
3494
3479
|
{
|
|
3495
3480
|
ref: dropdownRef,
|
|
3496
3481
|
$top: dropdownPos.top,
|
|
3497
3482
|
$left: dropdownPos.left,
|
|
3498
3483
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3499
|
-
children: items.map((item, index) => /* @__PURE__ */ jsxs11(
|
|
3500
|
-
index > 0 && /* @__PURE__ */
|
|
3484
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs11(React20.Fragment, { children: [
|
|
3485
|
+
index > 0 && /* @__PURE__ */ jsx35(Divider, {}),
|
|
3501
3486
|
item.content
|
|
3502
3487
|
] }, item.id))
|
|
3503
3488
|
}
|
|
@@ -3506,6 +3491,26 @@ var TrackMenu = ({ items: itemsProp }) => {
|
|
|
3506
3491
|
)
|
|
3507
3492
|
] });
|
|
3508
3493
|
};
|
|
3494
|
+
|
|
3495
|
+
// src/utils/conversions.ts
|
|
3496
|
+
function samplesToSeconds(samples, sampleRate) {
|
|
3497
|
+
return samples / sampleRate;
|
|
3498
|
+
}
|
|
3499
|
+
function secondsToSamples(seconds, sampleRate) {
|
|
3500
|
+
return Math.ceil(seconds * sampleRate);
|
|
3501
|
+
}
|
|
3502
|
+
function samplesToPixels2(samples, samplesPerPixel) {
|
|
3503
|
+
return Math.floor(samples / samplesPerPixel);
|
|
3504
|
+
}
|
|
3505
|
+
function pixelsToSamples(pixels, samplesPerPixel) {
|
|
3506
|
+
return Math.floor(pixels * samplesPerPixel);
|
|
3507
|
+
}
|
|
3508
|
+
function pixelsToSeconds(pixels, samplesPerPixel, sampleRate) {
|
|
3509
|
+
return pixels * samplesPerPixel / sampleRate;
|
|
3510
|
+
}
|
|
3511
|
+
function secondsToPixels2(seconds, samplesPerPixel, sampleRate) {
|
|
3512
|
+
return Math.ceil(seconds * sampleRate / samplesPerPixel);
|
|
3513
|
+
}
|
|
3509
3514
|
export {
|
|
3510
3515
|
AudioPosition,
|
|
3511
3516
|
AutomaticScrollCheckbox,
|
|
@@ -3515,9 +3520,12 @@ export {
|
|
|
3515
3520
|
BaseCheckboxWrapper,
|
|
3516
3521
|
BaseControlButton,
|
|
3517
3522
|
BaseInput,
|
|
3523
|
+
BaseInputSmall,
|
|
3518
3524
|
BaseLabel,
|
|
3519
3525
|
BaseSelect,
|
|
3526
|
+
BaseSelectSmall,
|
|
3520
3527
|
BaseSlider,
|
|
3528
|
+
BeatsAndBarsProvider,
|
|
3521
3529
|
Button,
|
|
3522
3530
|
ButtonGroup,
|
|
3523
3531
|
CLIP_BOUNDARY_WIDTH,
|
|
@@ -3571,14 +3579,16 @@ export {
|
|
|
3571
3579
|
darkTheme,
|
|
3572
3580
|
defaultTheme,
|
|
3573
3581
|
formatTime,
|
|
3582
|
+
getScaleInfo,
|
|
3574
3583
|
isWaveformGradient,
|
|
3575
3584
|
parseTime,
|
|
3576
3585
|
pixelsToSamples,
|
|
3577
3586
|
pixelsToSeconds,
|
|
3578
|
-
samplesToPixels,
|
|
3587
|
+
samplesToPixels2 as samplesToPixels,
|
|
3579
3588
|
samplesToSeconds,
|
|
3580
|
-
secondsToPixels,
|
|
3589
|
+
secondsToPixels2 as secondsToPixels,
|
|
3581
3590
|
secondsToSamples,
|
|
3591
|
+
useBeatsAndBars,
|
|
3582
3592
|
useClipViewportOrigin,
|
|
3583
3593
|
useDevicePixelRatio,
|
|
3584
3594
|
usePlaylistInfo,
|