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