@waveform-playlist/ui-components 9.1.1 → 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 +317 -315
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +268 -265
- 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,
|
|
@@ -1105,6 +1101,7 @@ var FadeOverlay = ({
|
|
|
1105
1101
|
};
|
|
1106
1102
|
|
|
1107
1103
|
// src/components/Clip.tsx
|
|
1104
|
+
import { clipPixelWidth } from "@waveform-playlist/core";
|
|
1108
1105
|
import { Fragment, jsx as jsx10, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1109
1106
|
var ClipContainer = styled13.div.attrs((props) => ({
|
|
1110
1107
|
style: props.$isOverlay ? {} : {
|
|
@@ -1118,13 +1115,8 @@ var ClipContainer = styled13.div.attrs((props) => ({
|
|
|
1118
1115
|
width: ${(props) => props.$isOverlay ? `${props.$width}px` : "auto"};
|
|
1119
1116
|
display: flex;
|
|
1120
1117
|
flex-direction: column;
|
|
1121
|
-
background: rgba(255, 255, 255, 0.05);
|
|
1122
1118
|
z-index: 10; /* Above progress overlay (z-index: 2) but below controls/playhead */
|
|
1123
1119
|
pointer-events: none; /* Let clicks pass through to ClickOverlay for playhead positioning */
|
|
1124
|
-
|
|
1125
|
-
&:hover {
|
|
1126
|
-
background: rgba(255, 255, 255, 0.08);
|
|
1127
|
-
}
|
|
1128
1120
|
`;
|
|
1129
1121
|
var ChannelsWrapper = styled13.div`
|
|
1130
1122
|
flex: 1;
|
|
@@ -1154,8 +1146,7 @@ var Clip = ({
|
|
|
1154
1146
|
touchOptimized = false
|
|
1155
1147
|
}) => {
|
|
1156
1148
|
const left = Math.floor(startSample / samplesPerPixel);
|
|
1157
|
-
const
|
|
1158
|
-
const width = endPixel - left;
|
|
1149
|
+
const width = clipPixelWidth(startSample, durationSamples, samplesPerPixel);
|
|
1159
1150
|
const enableDrag = showHeader && !disableHeaderDrag && !isOverlay;
|
|
1160
1151
|
const draggableId = `clip-${trackIndex}-${clipIndex}`;
|
|
1161
1152
|
const {
|
|
@@ -1164,20 +1155,20 @@ var Clip = ({
|
|
|
1164
1155
|
isDragSource
|
|
1165
1156
|
} = useDraggable({
|
|
1166
1157
|
id: draggableId,
|
|
1167
|
-
data: { clipId, trackIndex, clipIndex },
|
|
1158
|
+
data: { clipId, trackIndex, clipIndex, startSample, durationSamples },
|
|
1168
1159
|
disabled: !enableDrag
|
|
1169
1160
|
});
|
|
1170
1161
|
const leftBoundaryId = `clip-boundary-left-${trackIndex}-${clipIndex}`;
|
|
1171
1162
|
const { ref: leftBoundaryRef, isDragSource: isLeftBoundaryDragging } = useDraggable({
|
|
1172
1163
|
id: leftBoundaryId,
|
|
1173
|
-
data: { clipId, trackIndex, clipIndex, boundary: "left" },
|
|
1164
|
+
data: { clipId, trackIndex, clipIndex, boundary: "left", startSample, durationSamples },
|
|
1174
1165
|
disabled: !enableDrag,
|
|
1175
1166
|
feedback: "none"
|
|
1176
1167
|
});
|
|
1177
1168
|
const rightBoundaryId = `clip-boundary-right-${trackIndex}-${clipIndex}`;
|
|
1178
1169
|
const { ref: rightBoundaryRef, isDragSource: isRightBoundaryDragging } = useDraggable({
|
|
1179
1170
|
id: rightBoundaryId,
|
|
1180
|
-
data: { clipId, trackIndex, clipIndex, boundary: "right" },
|
|
1171
|
+
data: { clipId, trackIndex, clipIndex, boundary: "right", startSample, durationSamples },
|
|
1181
1172
|
disabled: !enableDrag,
|
|
1182
1173
|
feedback: "none"
|
|
1183
1174
|
});
|
|
@@ -1362,7 +1353,6 @@ var PianoRollChannel = ({
|
|
|
1362
1353
|
}, [midiNotes]);
|
|
1363
1354
|
const color = isSelected ? selectedNoteColor : noteColor;
|
|
1364
1355
|
useEffect4(() => {
|
|
1365
|
-
const tDraw = performance.now();
|
|
1366
1356
|
const noteRange = maxMidi - minMidi + 1;
|
|
1367
1357
|
const noteHeight = Math.max(2, waveHeight / noteRange);
|
|
1368
1358
|
const pixelsPerSecond = sampleRate / samplesPerPixel;
|
|
@@ -1394,9 +1384,6 @@ var PianoRollChannel = ({
|
|
|
1394
1384
|
}
|
|
1395
1385
|
ctx.globalAlpha = 1;
|
|
1396
1386
|
}
|
|
1397
|
-
console.log(
|
|
1398
|
-
`[piano-roll] draw ch${index}: ${canvasMapRef.current.size} chunks, ${midiNotes.length} notes, ${(performance.now() - tDraw).toFixed(1)}ms`
|
|
1399
|
-
);
|
|
1400
1387
|
}, [
|
|
1401
1388
|
canvasMapRef,
|
|
1402
1389
|
midiNotes,
|
|
@@ -2036,7 +2023,7 @@ function clockFormat(seconds, decimals) {
|
|
|
2036
2023
|
const hours = Math.floor(seconds / 3600) % 24;
|
|
2037
2024
|
const minutes = Math.floor(seconds / 60) % 60;
|
|
2038
2025
|
const secs = (seconds % 60).toFixed(decimals);
|
|
2039
|
-
return String(hours).padStart(2, "0") + ":" + String(minutes).padStart(2, "0") + ":" + secs.padStart(decimals + 3, "0");
|
|
2026
|
+
return String(hours).padStart(2, "0") + ":" + String(minutes).padStart(2, "0") + ":" + secs.padStart(decimals > 0 ? decimals + 3 : 2, "0");
|
|
2040
2027
|
}
|
|
2041
2028
|
function formatTime(seconds, format) {
|
|
2042
2029
|
switch (format) {
|
|
@@ -2188,13 +2175,43 @@ var SelectionTimeInputs = ({
|
|
|
2188
2175
|
] });
|
|
2189
2176
|
};
|
|
2190
2177
|
|
|
2191
|
-
// src/contexts/
|
|
2192
|
-
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";
|
|
2193
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";
|
|
2194
2211
|
function getScale() {
|
|
2195
2212
|
return window.devicePixelRatio;
|
|
2196
2213
|
}
|
|
2197
|
-
var DevicePixelRatioContext =
|
|
2214
|
+
var DevicePixelRatioContext = createContext4(getScale());
|
|
2198
2215
|
var DevicePixelRatioProvider = ({ children }) => {
|
|
2199
2216
|
const [scale, setScale] = useState4(getScale());
|
|
2200
2217
|
matchMedia(`(resolution: ${getScale()}dppx)`).addEventListener(
|
|
@@ -2204,13 +2221,13 @@ var DevicePixelRatioProvider = ({ children }) => {
|
|
|
2204
2221
|
},
|
|
2205
2222
|
{ once: true }
|
|
2206
2223
|
);
|
|
2207
|
-
return /* @__PURE__ */
|
|
2224
|
+
return /* @__PURE__ */ jsx20(DevicePixelRatioContext.Provider, { value: Math.ceil(scale), children });
|
|
2208
2225
|
};
|
|
2209
|
-
var useDevicePixelRatio = () =>
|
|
2226
|
+
var useDevicePixelRatio = () => useContext4(DevicePixelRatioContext);
|
|
2210
2227
|
|
|
2211
2228
|
// src/contexts/PlaylistInfo.tsx
|
|
2212
|
-
import { createContext as
|
|
2213
|
-
var PlaylistInfoContext =
|
|
2229
|
+
import { createContext as createContext5, useContext as useContext5 } from "react";
|
|
2230
|
+
var PlaylistInfoContext = createContext5({
|
|
2214
2231
|
sampleRate: 48e3,
|
|
2215
2232
|
samplesPerPixel: 1e3,
|
|
2216
2233
|
zoomLevels: [1e3, 1500, 2e3, 2500],
|
|
@@ -2224,26 +2241,26 @@ var PlaylistInfoContext = createContext4({
|
|
|
2224
2241
|
barWidth: 1,
|
|
2225
2242
|
barGap: 0
|
|
2226
2243
|
});
|
|
2227
|
-
var usePlaylistInfo = () =>
|
|
2244
|
+
var usePlaylistInfo = () => useContext5(PlaylistInfoContext);
|
|
2228
2245
|
|
|
2229
2246
|
// src/contexts/Theme.tsx
|
|
2230
|
-
import { useContext as
|
|
2247
|
+
import { useContext as useContext6 } from "react";
|
|
2231
2248
|
import { ThemeContext } from "styled-components";
|
|
2232
|
-
var useTheme2 = () =>
|
|
2249
|
+
var useTheme2 = () => useContext6(ThemeContext);
|
|
2233
2250
|
|
|
2234
2251
|
// src/contexts/TrackControls.tsx
|
|
2235
|
-
import { createContext as
|
|
2236
|
-
import { jsx as
|
|
2237
|
-
var TrackControlsContext =
|
|
2238
|
-
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);
|
|
2239
2256
|
|
|
2240
2257
|
// src/contexts/Playout.tsx
|
|
2241
2258
|
import {
|
|
2242
2259
|
useState as useState5,
|
|
2243
|
-
createContext as
|
|
2244
|
-
useContext as
|
|
2260
|
+
createContext as createContext7,
|
|
2261
|
+
useContext as useContext8
|
|
2245
2262
|
} from "react";
|
|
2246
|
-
import { jsx as
|
|
2263
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
2247
2264
|
var defaultProgress = 0;
|
|
2248
2265
|
var defaultIsPlaying = false;
|
|
2249
2266
|
var defaultSelectionStart = 0;
|
|
@@ -2254,8 +2271,8 @@ var defaultPlayout = {
|
|
|
2254
2271
|
selectionStart: defaultSelectionStart,
|
|
2255
2272
|
selectionEnd: defaultSelectionEnd
|
|
2256
2273
|
};
|
|
2257
|
-
var PlayoutStatusContext =
|
|
2258
|
-
var PlayoutStatusUpdateContext =
|
|
2274
|
+
var PlayoutStatusContext = createContext7(defaultPlayout);
|
|
2275
|
+
var PlayoutStatusUpdateContext = createContext7({
|
|
2259
2276
|
setIsPlaying: () => {
|
|
2260
2277
|
},
|
|
2261
2278
|
setProgress: () => {
|
|
@@ -2272,16 +2289,16 @@ var PlayoutProvider = ({ children }) => {
|
|
|
2272
2289
|
setSelectionStart(start);
|
|
2273
2290
|
setSelectionEnd(end);
|
|
2274
2291
|
};
|
|
2275
|
-
return /* @__PURE__ */
|
|
2292
|
+
return /* @__PURE__ */ jsx22(PlayoutStatusUpdateContext.Provider, { value: { setIsPlaying, setProgress, setSelection }, children: /* @__PURE__ */ jsx22(PlayoutStatusContext.Provider, { value: { isPlaying, progress, selectionStart, selectionEnd }, children }) });
|
|
2276
2293
|
};
|
|
2277
|
-
var usePlayoutStatus = () =>
|
|
2278
|
-
var usePlayoutStatusUpdate = () =>
|
|
2294
|
+
var usePlayoutStatus = () => useContext8(PlayoutStatusContext);
|
|
2295
|
+
var usePlayoutStatusUpdate = () => useContext8(PlayoutStatusUpdateContext);
|
|
2279
2296
|
|
|
2280
2297
|
// src/components/SpectrogramChannel.tsx
|
|
2281
2298
|
import { useRef as useRef6, useEffect as useEffect8 } from "react";
|
|
2282
2299
|
import styled20 from "styled-components";
|
|
2283
2300
|
import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH3 } from "@waveform-playlist/core";
|
|
2284
|
-
import { jsx as
|
|
2301
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2285
2302
|
var LINEAR_FREQUENCY_SCALE = (f, minF, maxF) => (f - minF) / (maxF - minF);
|
|
2286
2303
|
var Wrapper4 = styled20.div.attrs((props) => ({
|
|
2287
2304
|
style: {
|
|
@@ -2518,7 +2535,7 @@ var SpectrogramChannel = ({
|
|
|
2518
2535
|
const canvases = visibleChunkIndices.map((i) => {
|
|
2519
2536
|
const chunkLeft = i * MAX_CANVAS_WIDTH3;
|
|
2520
2537
|
const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH3);
|
|
2521
|
-
return /* @__PURE__ */
|
|
2538
|
+
return /* @__PURE__ */ jsx23(
|
|
2522
2539
|
SpectrogramCanvas,
|
|
2523
2540
|
{
|
|
2524
2541
|
$cssWidth: currentWidth,
|
|
@@ -2532,11 +2549,11 @@ var SpectrogramChannel = ({
|
|
|
2532
2549
|
`${length}-${i}`
|
|
2533
2550
|
);
|
|
2534
2551
|
});
|
|
2535
|
-
return /* @__PURE__ */
|
|
2552
|
+
return /* @__PURE__ */ jsx23(Wrapper4, { $index: index, $cssWidth: length, $waveHeight: waveHeight, children: canvases });
|
|
2536
2553
|
};
|
|
2537
2554
|
|
|
2538
2555
|
// src/components/SmartChannel.tsx
|
|
2539
|
-
import { Fragment as Fragment5, jsx as
|
|
2556
|
+
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2540
2557
|
var SmartChannel = ({
|
|
2541
2558
|
isSelected,
|
|
2542
2559
|
transparentBackground,
|
|
@@ -2570,7 +2587,7 @@ var SmartChannel = ({
|
|
|
2570
2587
|
const drawMode = theme?.waveformDrawMode || "inverted";
|
|
2571
2588
|
const hasSpectrogram = spectrogramData || spectrogramWorkerApi;
|
|
2572
2589
|
if (renderMode === "spectrogram" && hasSpectrogram) {
|
|
2573
|
-
return /* @__PURE__ */
|
|
2590
|
+
return /* @__PURE__ */ jsx24(
|
|
2574
2591
|
SpectrogramChannel,
|
|
2575
2592
|
{
|
|
2576
2593
|
index: props.index,
|
|
@@ -2592,7 +2609,7 @@ var SmartChannel = ({
|
|
|
2592
2609
|
if (renderMode === "both" && hasSpectrogram) {
|
|
2593
2610
|
const halfHeight = Math.floor(waveHeight / 2);
|
|
2594
2611
|
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2595
|
-
/* @__PURE__ */
|
|
2612
|
+
/* @__PURE__ */ jsx24(
|
|
2596
2613
|
SpectrogramChannel,
|
|
2597
2614
|
{
|
|
2598
2615
|
index: props.index * 2,
|
|
@@ -2611,7 +2628,7 @@ var SmartChannel = ({
|
|
|
2611
2628
|
onCanvasesReady: spectrogramOnCanvasesReady
|
|
2612
2629
|
}
|
|
2613
2630
|
),
|
|
2614
|
-
/* @__PURE__ */
|
|
2631
|
+
/* @__PURE__ */ jsx24(
|
|
2615
2632
|
"div",
|
|
2616
2633
|
{
|
|
2617
2634
|
style: {
|
|
@@ -2620,7 +2637,7 @@ var SmartChannel = ({
|
|
|
2620
2637
|
width: props.length,
|
|
2621
2638
|
height: halfHeight
|
|
2622
2639
|
},
|
|
2623
|
-
children: /* @__PURE__ */
|
|
2640
|
+
children: /* @__PURE__ */ jsx24(
|
|
2624
2641
|
Channel,
|
|
2625
2642
|
{
|
|
2626
2643
|
...props,
|
|
@@ -2640,7 +2657,7 @@ var SmartChannel = ({
|
|
|
2640
2657
|
] });
|
|
2641
2658
|
}
|
|
2642
2659
|
if (renderMode === "piano-roll") {
|
|
2643
|
-
return /* @__PURE__ */
|
|
2660
|
+
return /* @__PURE__ */ jsx24(
|
|
2644
2661
|
PianoRollChannel,
|
|
2645
2662
|
{
|
|
2646
2663
|
index: props.index,
|
|
@@ -2659,7 +2676,7 @@ var SmartChannel = ({
|
|
|
2659
2676
|
}
|
|
2660
2677
|
);
|
|
2661
2678
|
}
|
|
2662
|
-
return /* @__PURE__ */
|
|
2679
|
+
return /* @__PURE__ */ jsx24(
|
|
2663
2680
|
Channel,
|
|
2664
2681
|
{
|
|
2665
2682
|
...props,
|
|
@@ -2678,7 +2695,7 @@ var SmartChannel = ({
|
|
|
2678
2695
|
// src/components/SpectrogramLabels.tsx
|
|
2679
2696
|
import { useRef as useRef7, useLayoutEffect as useLayoutEffect2 } from "react";
|
|
2680
2697
|
import styled21 from "styled-components";
|
|
2681
|
-
import { jsx as
|
|
2698
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
2682
2699
|
var LABELS_WIDTH = 72;
|
|
2683
2700
|
var LabelsStickyWrapper = styled21.div`
|
|
2684
2701
|
position: sticky;
|
|
@@ -2771,7 +2788,7 @@ var SpectrogramLabels = ({
|
|
|
2771
2788
|
spectrogramHeight,
|
|
2772
2789
|
clipHeaderOffset
|
|
2773
2790
|
]);
|
|
2774
|
-
return /* @__PURE__ */
|
|
2791
|
+
return /* @__PURE__ */ jsx25(LabelsStickyWrapper, { $height: totalHeight + clipHeaderOffset, children: /* @__PURE__ */ jsx25(
|
|
2775
2792
|
"canvas",
|
|
2776
2793
|
{
|
|
2777
2794
|
ref: canvasRef,
|
|
@@ -2787,41 +2804,14 @@ var SpectrogramLabels = ({
|
|
|
2787
2804
|
};
|
|
2788
2805
|
|
|
2789
2806
|
// src/components/SmartScale.tsx
|
|
2790
|
-
import { useContext as
|
|
2807
|
+
import React19, { useContext as useContext10, useMemo as useMemo4 } from "react";
|
|
2808
|
+
import styled23 from "styled-components";
|
|
2791
2809
|
|
|
2792
2810
|
// src/components/TimeScale.tsx
|
|
2793
|
-
import
|
|
2811
|
+
import { useLayoutEffect as useLayoutEffect3, useContext as useContext9 } from "react";
|
|
2794
2812
|
import styled22, { withTheme as withTheme2 } from "styled-components";
|
|
2795
|
-
|
|
2796
|
-
// src/utils/conversions.ts
|
|
2797
|
-
function samplesToSeconds(samples, sampleRate) {
|
|
2798
|
-
return samples / sampleRate;
|
|
2799
|
-
}
|
|
2800
|
-
function secondsToSamples(seconds, sampleRate) {
|
|
2801
|
-
return Math.ceil(seconds * sampleRate);
|
|
2802
|
-
}
|
|
2803
|
-
function samplesToPixels(samples, samplesPerPixel) {
|
|
2804
|
-
return Math.floor(samples / samplesPerPixel);
|
|
2805
|
-
}
|
|
2806
|
-
function pixelsToSamples(pixels, samplesPerPixel) {
|
|
2807
|
-
return Math.floor(pixels * samplesPerPixel);
|
|
2808
|
-
}
|
|
2809
|
-
function pixelsToSeconds(pixels, samplesPerPixel, sampleRate) {
|
|
2810
|
-
return pixels * samplesPerPixel / sampleRate;
|
|
2811
|
-
}
|
|
2812
|
-
function secondsToPixels(seconds, samplesPerPixel, sampleRate) {
|
|
2813
|
-
return Math.ceil(seconds * sampleRate / samplesPerPixel);
|
|
2814
|
-
}
|
|
2815
|
-
|
|
2816
|
-
// src/components/TimeScale.tsx
|
|
2817
2813
|
import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH4 } from "@waveform-playlist/core";
|
|
2818
|
-
import { jsx as
|
|
2819
|
-
function formatTime2(milliseconds) {
|
|
2820
|
-
const seconds = Math.floor(milliseconds / 1e3);
|
|
2821
|
-
const s = seconds % 60;
|
|
2822
|
-
const m = (seconds - s) / 60;
|
|
2823
|
-
return `${m}:${String(s).padStart(2, "0")}`;
|
|
2824
|
-
}
|
|
2814
|
+
import { jsx as jsx26, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2825
2815
|
var PlaylistTimeScaleScroll = styled22.div.attrs((props) => ({
|
|
2826
2816
|
style: {
|
|
2827
2817
|
width: `${props.$cssWidth}px`,
|
|
@@ -2843,70 +2833,20 @@ var TimeTickChunk = styled22.canvas.attrs((props) => ({
|
|
|
2843
2833
|
position: absolute;
|
|
2844
2834
|
bottom: 0;
|
|
2845
2835
|
`;
|
|
2846
|
-
var TimeStamp = styled22.div.attrs((props) => ({
|
|
2847
|
-
style: {
|
|
2848
|
-
left: `${props.$left + 4}px`
|
|
2849
|
-
// Offset 4px to the right of the tick
|
|
2850
|
-
}
|
|
2851
|
-
}))`
|
|
2852
|
-
position: absolute;
|
|
2853
|
-
font-size: 0.75rem; /* Smaller font to prevent overflow */
|
|
2854
|
-
white-space: nowrap; /* Prevent text wrapping */
|
|
2855
|
-
color: ${(props) => props.theme.timeColor}; /* Use theme color instead of inheriting */
|
|
2856
|
-
`;
|
|
2857
2836
|
var TimeScale = (props) => {
|
|
2858
2837
|
const {
|
|
2859
2838
|
theme: { timeColor },
|
|
2860
|
-
|
|
2861
|
-
marker,
|
|
2862
|
-
bigStep,
|
|
2863
|
-
secondStep,
|
|
2864
|
-
renderTimestamp
|
|
2839
|
+
tickData
|
|
2865
2840
|
} = props;
|
|
2866
2841
|
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2867
|
-
const {
|
|
2842
|
+
const { timeScaleHeight } = useContext9(PlaylistInfoContext);
|
|
2868
2843
|
const devicePixelRatio = useDevicePixelRatio();
|
|
2869
|
-
const { widthX, canvasInfo, timeMarkersWithPositions } =
|
|
2870
|
-
const nextCanvasInfo = /* @__PURE__ */ new Map();
|
|
2871
|
-
const nextMarkers = [];
|
|
2872
|
-
const nextWidthX = secondsToPixels(duration / 1e3, samplesPerPixel, sampleRate);
|
|
2873
|
-
const pixPerSec = sampleRate / samplesPerPixel;
|
|
2874
|
-
let counter = 0;
|
|
2875
|
-
for (let i = 0; i < nextWidthX; i += pixPerSec * secondStep / 1e3) {
|
|
2876
|
-
const pix = Math.floor(i);
|
|
2877
|
-
if (counter % marker === 0) {
|
|
2878
|
-
const timeMs = counter;
|
|
2879
|
-
const timestamp = formatTime2(timeMs);
|
|
2880
|
-
const element = renderTimestamp ? /* @__PURE__ */ jsx25(React17.Fragment, { children: renderTimestamp(timeMs, pix) }, `timestamp-${counter}`) : /* @__PURE__ */ jsx25(TimeStamp, { $left: pix, children: timestamp }, timestamp);
|
|
2881
|
-
nextMarkers.push({ pix, element });
|
|
2882
|
-
nextCanvasInfo.set(pix, timeScaleHeight);
|
|
2883
|
-
} else if (counter % bigStep === 0) {
|
|
2884
|
-
nextCanvasInfo.set(pix, Math.floor(timeScaleHeight / 2));
|
|
2885
|
-
} else if (counter % secondStep === 0) {
|
|
2886
|
-
nextCanvasInfo.set(pix, Math.floor(timeScaleHeight / 5));
|
|
2887
|
-
}
|
|
2888
|
-
counter += secondStep;
|
|
2889
|
-
}
|
|
2890
|
-
return {
|
|
2891
|
-
widthX: nextWidthX,
|
|
2892
|
-
canvasInfo: nextCanvasInfo,
|
|
2893
|
-
timeMarkersWithPositions: nextMarkers
|
|
2894
|
-
};
|
|
2895
|
-
}, [
|
|
2896
|
-
duration,
|
|
2897
|
-
samplesPerPixel,
|
|
2898
|
-
sampleRate,
|
|
2899
|
-
marker,
|
|
2900
|
-
bigStep,
|
|
2901
|
-
secondStep,
|
|
2902
|
-
renderTimestamp,
|
|
2903
|
-
timeScaleHeight
|
|
2904
|
-
]);
|
|
2844
|
+
const { widthX, canvasInfo, timeMarkersWithPositions } = tickData;
|
|
2905
2845
|
const visibleChunkIndices = useVisibleChunkIndices(widthX, MAX_CANVAS_WIDTH4);
|
|
2906
2846
|
const visibleChunks = visibleChunkIndices.map((i) => {
|
|
2907
2847
|
const chunkLeft = i * MAX_CANVAS_WIDTH4;
|
|
2908
2848
|
const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH4);
|
|
2909
|
-
return /* @__PURE__ */
|
|
2849
|
+
return /* @__PURE__ */ jsx26(
|
|
2910
2850
|
TimeTickChunk,
|
|
2911
2851
|
{
|
|
2912
2852
|
$cssWidth: chunkWidth,
|
|
@@ -2941,15 +2881,7 @@ var TimeScale = (props) => {
|
|
|
2941
2881
|
ctx.fillRect(localX, scaleY, 1, scaleHeight);
|
|
2942
2882
|
}
|
|
2943
2883
|
}
|
|
2944
|
-
}, [
|
|
2945
|
-
canvasMapRef,
|
|
2946
|
-
duration,
|
|
2947
|
-
devicePixelRatio,
|
|
2948
|
-
timeColor,
|
|
2949
|
-
timeScaleHeight,
|
|
2950
|
-
canvasInfo,
|
|
2951
|
-
visibleChunkIndices
|
|
2952
|
-
]);
|
|
2884
|
+
}, [canvasMapRef, devicePixelRatio, timeColor, timeScaleHeight, canvasInfo, visibleChunkIndices]);
|
|
2953
2885
|
return /* @__PURE__ */ jsxs10(PlaylistTimeScaleScroll, { $cssWidth: widthX, $timeScaleHeight: timeScaleHeight, children: [
|
|
2954
2886
|
visibleMarkers,
|
|
2955
2887
|
visibleChunks
|
|
@@ -2958,64 +2890,22 @@ var TimeScale = (props) => {
|
|
|
2958
2890
|
var StyledTimeScale = withTheme2(TimeScale);
|
|
2959
2891
|
|
|
2960
2892
|
// src/components/SmartScale.tsx
|
|
2961
|
-
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";
|
|
2962
2901
|
var timeinfo = /* @__PURE__ */ new Map([
|
|
2963
|
-
[
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
],
|
|
2971
|
-
[
|
|
2972
|
-
1500,
|
|
2973
|
-
{
|
|
2974
|
-
marker: 2e3,
|
|
2975
|
-
bigStep: 1e3,
|
|
2976
|
-
smallStep: 200
|
|
2977
|
-
}
|
|
2978
|
-
],
|
|
2979
|
-
[
|
|
2980
|
-
2500,
|
|
2981
|
-
{
|
|
2982
|
-
marker: 2e3,
|
|
2983
|
-
bigStep: 1e3,
|
|
2984
|
-
smallStep: 500
|
|
2985
|
-
}
|
|
2986
|
-
],
|
|
2987
|
-
[
|
|
2988
|
-
5e3,
|
|
2989
|
-
{
|
|
2990
|
-
marker: 5e3,
|
|
2991
|
-
bigStep: 1e3,
|
|
2992
|
-
smallStep: 500
|
|
2993
|
-
}
|
|
2994
|
-
],
|
|
2995
|
-
[
|
|
2996
|
-
1e4,
|
|
2997
|
-
{
|
|
2998
|
-
marker: 1e4,
|
|
2999
|
-
bigStep: 5e3,
|
|
3000
|
-
smallStep: 1e3
|
|
3001
|
-
}
|
|
3002
|
-
],
|
|
3003
|
-
[
|
|
3004
|
-
12e3,
|
|
3005
|
-
{
|
|
3006
|
-
marker: 15e3,
|
|
3007
|
-
bigStep: 5e3,
|
|
3008
|
-
smallStep: 1e3
|
|
3009
|
-
}
|
|
3010
|
-
],
|
|
3011
|
-
[
|
|
3012
|
-
Infinity,
|
|
3013
|
-
{
|
|
3014
|
-
marker: 3e4,
|
|
3015
|
-
bigStep: 1e4,
|
|
3016
|
-
smallStep: 5e3
|
|
3017
|
-
}
|
|
3018
|
-
]
|
|
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 }]
|
|
3019
2909
|
]);
|
|
3020
2910
|
function getScaleInfo(samplesPerPixel) {
|
|
3021
2911
|
const keys = timeinfo.keys();
|
|
@@ -3031,25 +2921,113 @@ function getScaleInfo(samplesPerPixel) {
|
|
|
3031
2921
|
}
|
|
3032
2922
|
return config;
|
|
3033
2923
|
}
|
|
3034
|
-
|
|
3035
|
-
const
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
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 };
|
|
3045
3001
|
}
|
|
3046
|
-
|
|
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 });
|
|
3047
3025
|
};
|
|
3048
3026
|
|
|
3049
3027
|
// src/components/TimeFormatSelect.tsx
|
|
3050
|
-
import
|
|
3051
|
-
import { jsx as
|
|
3052
|
-
var SelectWrapper =
|
|
3028
|
+
import styled24 from "styled-components";
|
|
3029
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
3030
|
+
var SelectWrapper = styled24.div`
|
|
3053
3031
|
display: inline-flex;
|
|
3054
3032
|
align-items: center;
|
|
3055
3033
|
gap: 0.5rem;
|
|
@@ -3071,7 +3049,7 @@ var TimeFormatSelect = ({
|
|
|
3071
3049
|
const handleChange = (e) => {
|
|
3072
3050
|
onChange(e.target.value);
|
|
3073
3051
|
};
|
|
3074
|
-
return /* @__PURE__ */
|
|
3052
|
+
return /* @__PURE__ */ jsx28(SelectWrapper, { className, children: /* @__PURE__ */ jsx28(
|
|
3075
3053
|
BaseSelect,
|
|
3076
3054
|
{
|
|
3077
3055
|
className: "time-format",
|
|
@@ -3079,15 +3057,15 @@ var TimeFormatSelect = ({
|
|
|
3079
3057
|
onChange: handleChange,
|
|
3080
3058
|
disabled,
|
|
3081
3059
|
"aria-label": "Time format selection",
|
|
3082
|
-
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))
|
|
3083
3061
|
}
|
|
3084
3062
|
) });
|
|
3085
3063
|
};
|
|
3086
3064
|
|
|
3087
3065
|
// src/components/Track.tsx
|
|
3088
|
-
import
|
|
3089
|
-
import { jsx as
|
|
3090
|
-
var Container =
|
|
3066
|
+
import styled25 from "styled-components";
|
|
3067
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
3068
|
+
var Container = styled25.div.attrs((props) => ({
|
|
3091
3069
|
style: {
|
|
3092
3070
|
height: `${props.$waveHeight * props.$numChannels + (props.$hasClipHeaders ? CLIP_HEADER_HEIGHT : 0)}px`
|
|
3093
3071
|
}
|
|
@@ -3095,7 +3073,7 @@ var Container = styled24.div.attrs((props) => ({
|
|
|
3095
3073
|
position: relative;
|
|
3096
3074
|
${(props) => props.$width !== void 0 && `width: ${props.$width}px;`}
|
|
3097
3075
|
`;
|
|
3098
|
-
var ChannelContainer =
|
|
3076
|
+
var ChannelContainer = styled25.div.attrs((props) => ({
|
|
3099
3077
|
style: {
|
|
3100
3078
|
paddingLeft: `${props.$offset || 0}px`
|
|
3101
3079
|
}
|
|
@@ -3117,7 +3095,7 @@ var Track = ({
|
|
|
3117
3095
|
isSelected: _isSelected = false
|
|
3118
3096
|
}) => {
|
|
3119
3097
|
const { waveHeight } = usePlaylistInfo();
|
|
3120
|
-
return /* @__PURE__ */
|
|
3098
|
+
return /* @__PURE__ */ jsx29(
|
|
3121
3099
|
Container,
|
|
3122
3100
|
{
|
|
3123
3101
|
$numChannels: numChannels,
|
|
@@ -3125,7 +3103,7 @@ var Track = ({
|
|
|
3125
3103
|
$waveHeight: waveHeight,
|
|
3126
3104
|
$width: width,
|
|
3127
3105
|
$hasClipHeaders: hasClipHeaders,
|
|
3128
|
-
children: /* @__PURE__ */
|
|
3106
|
+
children: /* @__PURE__ */ jsx29(
|
|
3129
3107
|
ChannelContainer,
|
|
3130
3108
|
{
|
|
3131
3109
|
$backgroundColor: backgroundColor,
|
|
@@ -3140,8 +3118,8 @@ var Track = ({
|
|
|
3140
3118
|
};
|
|
3141
3119
|
|
|
3142
3120
|
// src/components/TrackControls/Button.tsx
|
|
3143
|
-
import
|
|
3144
|
-
var Button =
|
|
3121
|
+
import styled26 from "styled-components";
|
|
3122
|
+
var Button = styled26.button.attrs({
|
|
3145
3123
|
type: "button"
|
|
3146
3124
|
})`
|
|
3147
3125
|
display: inline-block;
|
|
@@ -3216,8 +3194,8 @@ var Button = styled25.button.attrs({
|
|
|
3216
3194
|
`;
|
|
3217
3195
|
|
|
3218
3196
|
// src/components/TrackControls/ButtonGroup.tsx
|
|
3219
|
-
import
|
|
3220
|
-
var ButtonGroup =
|
|
3197
|
+
import styled27 from "styled-components";
|
|
3198
|
+
var ButtonGroup = styled27.div`
|
|
3221
3199
|
margin-bottom: 0.3rem;
|
|
3222
3200
|
|
|
3223
3201
|
button:not(:first-child) {
|
|
@@ -3232,10 +3210,10 @@ var ButtonGroup = styled26.div`
|
|
|
3232
3210
|
`;
|
|
3233
3211
|
|
|
3234
3212
|
// src/components/TrackControls/CloseButton.tsx
|
|
3235
|
-
import
|
|
3213
|
+
import styled28 from "styled-components";
|
|
3236
3214
|
import { X as XIcon } from "@phosphor-icons/react";
|
|
3237
|
-
import { jsx as
|
|
3238
|
-
var StyledCloseButton =
|
|
3215
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
3216
|
+
var StyledCloseButton = styled28.button`
|
|
3239
3217
|
position: absolute;
|
|
3240
3218
|
left: 0;
|
|
3241
3219
|
top: 0;
|
|
@@ -3258,11 +3236,11 @@ var StyledCloseButton = styled27.button`
|
|
|
3258
3236
|
color: #dc3545;
|
|
3259
3237
|
}
|
|
3260
3238
|
`;
|
|
3261
|
-
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" }) });
|
|
3262
3240
|
|
|
3263
3241
|
// src/components/TrackControls/Controls.tsx
|
|
3264
|
-
import
|
|
3265
|
-
var Controls =
|
|
3242
|
+
import styled29 from "styled-components";
|
|
3243
|
+
var Controls = styled29.div`
|
|
3266
3244
|
background: transparent;
|
|
3267
3245
|
width: 100%;
|
|
3268
3246
|
height: 100%;
|
|
@@ -3278,8 +3256,8 @@ var Controls = styled28.div`
|
|
|
3278
3256
|
`;
|
|
3279
3257
|
|
|
3280
3258
|
// src/components/TrackControls/Header.tsx
|
|
3281
|
-
import
|
|
3282
|
-
var Header =
|
|
3259
|
+
import styled30 from "styled-components";
|
|
3260
|
+
var Header = styled30.header`
|
|
3283
3261
|
overflow: hidden;
|
|
3284
3262
|
height: 26px;
|
|
3285
3263
|
width: 100%;
|
|
@@ -3294,27 +3272,27 @@ var Header = styled29.header`
|
|
|
3294
3272
|
|
|
3295
3273
|
// src/components/TrackControls/VolumeDownIcon.tsx
|
|
3296
3274
|
import { SpeakerLowIcon } from "@phosphor-icons/react";
|
|
3297
|
-
import { jsx as
|
|
3298
|
-
var VolumeDownIcon = (props) => /* @__PURE__ */
|
|
3275
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
3276
|
+
var VolumeDownIcon = (props) => /* @__PURE__ */ jsx31(SpeakerLowIcon, { weight: "light", ...props });
|
|
3299
3277
|
|
|
3300
3278
|
// src/components/TrackControls/VolumeUpIcon.tsx
|
|
3301
3279
|
import { SpeakerHighIcon } from "@phosphor-icons/react";
|
|
3302
|
-
import { jsx as
|
|
3303
|
-
var VolumeUpIcon = (props) => /* @__PURE__ */
|
|
3280
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
3281
|
+
var VolumeUpIcon = (props) => /* @__PURE__ */ jsx32(SpeakerHighIcon, { weight: "light", ...props });
|
|
3304
3282
|
|
|
3305
3283
|
// src/components/TrackControls/TrashIcon.tsx
|
|
3306
3284
|
import { TrashIcon as PhosphorTrashIcon } from "@phosphor-icons/react";
|
|
3307
|
-
import { jsx as
|
|
3308
|
-
var TrashIcon = (props) => /* @__PURE__ */
|
|
3285
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
3286
|
+
var TrashIcon = (props) => /* @__PURE__ */ jsx33(PhosphorTrashIcon, { weight: "light", ...props });
|
|
3309
3287
|
|
|
3310
3288
|
// src/components/TrackControls/DotsIcon.tsx
|
|
3311
3289
|
import { DotsThreeIcon } from "@phosphor-icons/react";
|
|
3312
|
-
import { jsx as
|
|
3313
|
-
var DotsIcon = (props) => /* @__PURE__ */
|
|
3290
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
3291
|
+
var DotsIcon = (props) => /* @__PURE__ */ jsx34(DotsThreeIcon, { weight: "bold", ...props });
|
|
3314
3292
|
|
|
3315
3293
|
// src/components/TrackControls/Slider.tsx
|
|
3316
|
-
import
|
|
3317
|
-
var Slider =
|
|
3294
|
+
import styled31 from "styled-components";
|
|
3295
|
+
var Slider = styled31(BaseSlider)`
|
|
3318
3296
|
width: 75%;
|
|
3319
3297
|
height: 5px;
|
|
3320
3298
|
background: ${(props) => props.theme.sliderTrackColor};
|
|
@@ -3366,8 +3344,8 @@ var Slider = styled30(BaseSlider)`
|
|
|
3366
3344
|
`;
|
|
3367
3345
|
|
|
3368
3346
|
// src/components/TrackControls/SliderWrapper.tsx
|
|
3369
|
-
import
|
|
3370
|
-
var SliderWrapper =
|
|
3347
|
+
import styled32 from "styled-components";
|
|
3348
|
+
var SliderWrapper = styled32.label`
|
|
3371
3349
|
width: 100%;
|
|
3372
3350
|
display: flex;
|
|
3373
3351
|
justify-content: space-between;
|
|
@@ -3378,15 +3356,15 @@ var SliderWrapper = styled31.label`
|
|
|
3378
3356
|
`;
|
|
3379
3357
|
|
|
3380
3358
|
// src/components/TrackMenu.tsx
|
|
3381
|
-
import
|
|
3359
|
+
import React20, { useState as useState6, useEffect as useEffect9, useRef as useRef8, useCallback as useCallback5 } from "react";
|
|
3382
3360
|
import { createPortal } from "react-dom";
|
|
3383
|
-
import
|
|
3384
|
-
import { jsx as
|
|
3385
|
-
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`
|
|
3386
3364
|
position: relative;
|
|
3387
3365
|
display: inline-block;
|
|
3388
3366
|
`;
|
|
3389
|
-
var MenuButton =
|
|
3367
|
+
var MenuButton = styled33.button`
|
|
3390
3368
|
background: none;
|
|
3391
3369
|
border: none;
|
|
3392
3370
|
cursor: pointer;
|
|
@@ -3402,7 +3380,7 @@ var MenuButton = styled32.button`
|
|
|
3402
3380
|
}
|
|
3403
3381
|
`;
|
|
3404
3382
|
var DROPDOWN_MIN_WIDTH = 180;
|
|
3405
|
-
var Dropdown =
|
|
3383
|
+
var Dropdown = styled33.div`
|
|
3406
3384
|
position: fixed;
|
|
3407
3385
|
top: ${(p) => p.$top}px;
|
|
3408
3386
|
left: ${(p) => p.$left}px;
|
|
@@ -3415,7 +3393,7 @@ var Dropdown = styled32.div`
|
|
|
3415
3393
|
min-width: ${DROPDOWN_MIN_WIDTH}px;
|
|
3416
3394
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
3417
3395
|
`;
|
|
3418
|
-
var Divider =
|
|
3396
|
+
var Divider = styled33.hr`
|
|
3419
3397
|
border: none;
|
|
3420
3398
|
border-top: 1px solid rgba(128, 128, 128, 0.3);
|
|
3421
3399
|
margin: 0.35rem 0;
|
|
@@ -3479,7 +3457,7 @@ var TrackMenu = ({ items: itemsProp }) => {
|
|
|
3479
3457
|
};
|
|
3480
3458
|
}, [open]);
|
|
3481
3459
|
return /* @__PURE__ */ jsxs11(MenuContainer, { children: [
|
|
3482
|
-
/* @__PURE__ */
|
|
3460
|
+
/* @__PURE__ */ jsx35(
|
|
3483
3461
|
MenuButton,
|
|
3484
3462
|
{
|
|
3485
3463
|
ref: buttonRef,
|
|
@@ -3490,19 +3468,19 @@ var TrackMenu = ({ items: itemsProp }) => {
|
|
|
3490
3468
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3491
3469
|
title: "Track menu",
|
|
3492
3470
|
"aria-label": "Track menu",
|
|
3493
|
-
children: /* @__PURE__ */
|
|
3471
|
+
children: /* @__PURE__ */ jsx35(DotsIcon, { size: 16 })
|
|
3494
3472
|
}
|
|
3495
3473
|
),
|
|
3496
3474
|
open && typeof document !== "undefined" && createPortal(
|
|
3497
|
-
/* @__PURE__ */
|
|
3475
|
+
/* @__PURE__ */ jsx35(
|
|
3498
3476
|
Dropdown,
|
|
3499
3477
|
{
|
|
3500
3478
|
ref: dropdownRef,
|
|
3501
3479
|
$top: dropdownPos.top,
|
|
3502
3480
|
$left: dropdownPos.left,
|
|
3503
3481
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3504
|
-
children: items.map((item, index) => /* @__PURE__ */ jsxs11(
|
|
3505
|
-
index > 0 && /* @__PURE__ */
|
|
3482
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs11(React20.Fragment, { children: [
|
|
3483
|
+
index > 0 && /* @__PURE__ */ jsx35(Divider, {}),
|
|
3506
3484
|
item.content
|
|
3507
3485
|
] }, item.id))
|
|
3508
3486
|
}
|
|
@@ -3511,6 +3489,26 @@ var TrackMenu = ({ items: itemsProp }) => {
|
|
|
3511
3489
|
)
|
|
3512
3490
|
] });
|
|
3513
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
|
+
}
|
|
3514
3512
|
export {
|
|
3515
3513
|
AudioPosition,
|
|
3516
3514
|
AutomaticScrollCheckbox,
|
|
@@ -3520,9 +3518,12 @@ export {
|
|
|
3520
3518
|
BaseCheckboxWrapper,
|
|
3521
3519
|
BaseControlButton,
|
|
3522
3520
|
BaseInput,
|
|
3521
|
+
BaseInputSmall,
|
|
3523
3522
|
BaseLabel,
|
|
3524
3523
|
BaseSelect,
|
|
3524
|
+
BaseSelectSmall,
|
|
3525
3525
|
BaseSlider,
|
|
3526
|
+
BeatsAndBarsProvider,
|
|
3526
3527
|
Button,
|
|
3527
3528
|
ButtonGroup,
|
|
3528
3529
|
CLIP_BOUNDARY_WIDTH,
|
|
@@ -3576,14 +3577,16 @@ export {
|
|
|
3576
3577
|
darkTheme,
|
|
3577
3578
|
defaultTheme,
|
|
3578
3579
|
formatTime,
|
|
3580
|
+
getScaleInfo,
|
|
3579
3581
|
isWaveformGradient,
|
|
3580
3582
|
parseTime,
|
|
3581
3583
|
pixelsToSamples,
|
|
3582
3584
|
pixelsToSeconds,
|
|
3583
|
-
samplesToPixels,
|
|
3585
|
+
samplesToPixels2 as samplesToPixels,
|
|
3584
3586
|
samplesToSeconds,
|
|
3585
|
-
secondsToPixels,
|
|
3587
|
+
secondsToPixels2 as secondsToPixels,
|
|
3586
3588
|
secondsToSamples,
|
|
3589
|
+
useBeatsAndBars,
|
|
3587
3590
|
useClipViewportOrigin,
|
|
3588
3591
|
useDevicePixelRatio,
|
|
3589
3592
|
usePlaylistInfo,
|