@signalsandsorcery/plugin-sdk 2.35.1 → 2.35.2
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 +154 -2
- package/dist/index.d.ts +154 -2
- package/dist/index.js +501 -210
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +500 -211
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4126,9 +4126,276 @@ function TransitionDesigner({
|
|
|
4126
4126
|
] });
|
|
4127
4127
|
}
|
|
4128
4128
|
|
|
4129
|
-
// src/components/
|
|
4130
|
-
import {
|
|
4129
|
+
// src/components/PanelMasterStrip.tsx
|
|
4130
|
+
import { useMemo as useMemo6, useState as useState12 } from "react";
|
|
4131
4131
|
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4132
|
+
function PanelMasterStrip({
|
|
4133
|
+
bus,
|
|
4134
|
+
availableFx = [],
|
|
4135
|
+
fxLoading = false,
|
|
4136
|
+
soloedOut = false,
|
|
4137
|
+
disabled = false,
|
|
4138
|
+
fxPickerOpen,
|
|
4139
|
+
onToggleFxPicker,
|
|
4140
|
+
onRefreshFx,
|
|
4141
|
+
onVolumeChange,
|
|
4142
|
+
onMuteToggle,
|
|
4143
|
+
onSoloToggle,
|
|
4144
|
+
onAddFx,
|
|
4145
|
+
onRemoveFx,
|
|
4146
|
+
onToggleFxEnabled,
|
|
4147
|
+
onShowFxEditor
|
|
4148
|
+
}) {
|
|
4149
|
+
const [search, setSearch] = useState12("");
|
|
4150
|
+
const filtered = useMemo6(() => {
|
|
4151
|
+
const q = search.trim().toLowerCase();
|
|
4152
|
+
if (!q) return availableFx;
|
|
4153
|
+
return availableFx.filter(
|
|
4154
|
+
(fx) => fx.name.toLowerCase().includes(q) || fx.manufacturer.toLowerCase().includes(q)
|
|
4155
|
+
);
|
|
4156
|
+
}, [availableFx, search]);
|
|
4157
|
+
return /* @__PURE__ */ jsxs14(
|
|
4158
|
+
"div",
|
|
4159
|
+
{
|
|
4160
|
+
"data-testid": "panel-master-strip",
|
|
4161
|
+
className: `flex flex-col gap-1 px-2 py-1.5 rounded-sm border border-sas-border bg-sas-panel-alt/50 transition-opacity ${soloedOut ? "opacity-40" : ""}`,
|
|
4162
|
+
children: [
|
|
4163
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4164
|
+
/* @__PURE__ */ jsx18(
|
|
4165
|
+
"span",
|
|
4166
|
+
{
|
|
4167
|
+
className: "text-[9px] font-bold tracking-widest text-sas-muted/70 select-none",
|
|
4168
|
+
title: "Panel mix bus \u2014 volume, mute/solo and FX applied to this panel's summed output",
|
|
4169
|
+
children: "BUS"
|
|
4170
|
+
}
|
|
4171
|
+
),
|
|
4172
|
+
/* @__PURE__ */ jsx18("div", { className: "w-24", children: /* @__PURE__ */ jsx18(
|
|
4173
|
+
VolumeSlider,
|
|
4174
|
+
{
|
|
4175
|
+
value: dbToSlider(bus.volume),
|
|
4176
|
+
onChange: (sliderValue) => onVolumeChange(sliderToDb(sliderValue)),
|
|
4177
|
+
disabled
|
|
4178
|
+
}
|
|
4179
|
+
) }),
|
|
4180
|
+
/* @__PURE__ */ jsx18(
|
|
4181
|
+
"button",
|
|
4182
|
+
{
|
|
4183
|
+
"data-testid": "bus-mute-button",
|
|
4184
|
+
onClick: onMuteToggle,
|
|
4185
|
+
disabled,
|
|
4186
|
+
className: `px-1.5 py-0.5 text-xs font-bold rounded transition-colors ${bus.muted ? "bg-red-600 text-white" : "bg-sas-panel-alt text-sas-muted hover:bg-sas-border"} disabled:opacity-50`,
|
|
4187
|
+
title: bus.muted ? "Unmute panel bus" : "Mute panel bus (silences the whole panel)",
|
|
4188
|
+
children: "M"
|
|
4189
|
+
}
|
|
4190
|
+
),
|
|
4191
|
+
/* @__PURE__ */ jsx18(
|
|
4192
|
+
"button",
|
|
4193
|
+
{
|
|
4194
|
+
"data-testid": "bus-solo-button",
|
|
4195
|
+
onClick: onSoloToggle,
|
|
4196
|
+
disabled,
|
|
4197
|
+
className: `px-1.5 py-0.5 text-xs font-bold rounded transition-colors ${bus.soloed ? "bg-amber-500 text-black" : "bg-sas-panel-alt text-sas-muted hover:bg-sas-border"} disabled:opacity-50`,
|
|
4198
|
+
title: bus.soloed ? "Unsolo panel bus" : "Solo this panel (silences other panels/tracks in scope)",
|
|
4199
|
+
children: "S"
|
|
4200
|
+
}
|
|
4201
|
+
),
|
|
4202
|
+
/* @__PURE__ */ jsx18("div", { className: "flex items-center gap-1 flex-1 min-w-0 overflow-x-auto", children: bus.fx.map((fx) => /* @__PURE__ */ jsxs14(
|
|
4203
|
+
"span",
|
|
4204
|
+
{
|
|
4205
|
+
"data-testid": `bus-fx-chip-${fx.index}`,
|
|
4206
|
+
className: `flex items-center gap-1 px-1.5 py-0.5 rounded-sm border text-[10px] whitespace-nowrap ${fx.enabled ? "border-sas-accent/60 text-sas-accent bg-sas-accent/10" : "border-sas-border text-sas-muted/50 bg-sas-panel"}`,
|
|
4207
|
+
title: `${fx.name}${fx.enabled ? "" : " (bypassed)"}`,
|
|
4208
|
+
children: [
|
|
4209
|
+
/* @__PURE__ */ jsx18(
|
|
4210
|
+
"button",
|
|
4211
|
+
{
|
|
4212
|
+
"data-testid": `bus-fx-toggle-${fx.index}`,
|
|
4213
|
+
onClick: () => onToggleFxEnabled(fx.index, !fx.enabled),
|
|
4214
|
+
disabled,
|
|
4215
|
+
className: "hover:opacity-70 disabled:opacity-50",
|
|
4216
|
+
title: fx.enabled ? `Bypass ${fx.name}` : `Enable ${fx.name}`,
|
|
4217
|
+
children: fx.enabled ? "\u25CF" : "\u25CB"
|
|
4218
|
+
}
|
|
4219
|
+
),
|
|
4220
|
+
onShowFxEditor ? /* @__PURE__ */ jsx18(
|
|
4221
|
+
"button",
|
|
4222
|
+
{
|
|
4223
|
+
"data-testid": `bus-fx-edit-${fx.index}`,
|
|
4224
|
+
onClick: () => onShowFxEditor(fx.index),
|
|
4225
|
+
disabled,
|
|
4226
|
+
className: "max-w-[80px] truncate hover:underline disabled:opacity-50",
|
|
4227
|
+
title: `Open ${fx.name} editor`,
|
|
4228
|
+
children: fx.name
|
|
4229
|
+
}
|
|
4230
|
+
) : /* @__PURE__ */ jsx18("span", { className: "max-w-[80px] truncate", children: fx.name }),
|
|
4231
|
+
/* @__PURE__ */ jsx18(
|
|
4232
|
+
"button",
|
|
4233
|
+
{
|
|
4234
|
+
"data-testid": `bus-fx-remove-${fx.index}`,
|
|
4235
|
+
onClick: () => onRemoveFx(fx.index),
|
|
4236
|
+
disabled,
|
|
4237
|
+
className: "text-sas-muted/60 hover:text-sas-danger disabled:opacity-50",
|
|
4238
|
+
title: `Remove ${fx.name} from the bus`,
|
|
4239
|
+
children: "\u2715"
|
|
4240
|
+
}
|
|
4241
|
+
)
|
|
4242
|
+
]
|
|
4243
|
+
},
|
|
4244
|
+
`${fx.index}:${fx.pluginId}`
|
|
4245
|
+
)) }),
|
|
4246
|
+
/* @__PURE__ */ jsx18(
|
|
4247
|
+
"button",
|
|
4248
|
+
{
|
|
4249
|
+
"data-testid": "bus-fx-add-button",
|
|
4250
|
+
onClick: () => onToggleFxPicker(!fxPickerOpen),
|
|
4251
|
+
disabled,
|
|
4252
|
+
className: `px-1.5 py-0.5 rounded-sm border text-xs whitespace-nowrap transition-colors ${fxPickerOpen ? "border-sas-accent text-sas-accent bg-sas-accent/10" : "border-sas-border text-sas-muted hover:border-sas-accent hover:text-sas-accent"} disabled:opacity-50`,
|
|
4253
|
+
title: "Add an FX plugin to the panel bus",
|
|
4254
|
+
children: "FX +"
|
|
4255
|
+
}
|
|
4256
|
+
)
|
|
4257
|
+
] }),
|
|
4258
|
+
fxPickerOpen && /* @__PURE__ */ jsxs14("div", { "data-testid": "bus-fx-picker", className: "flex flex-col gap-2 pt-1", children: [
|
|
4259
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4260
|
+
/* @__PURE__ */ jsx18(
|
|
4261
|
+
"input",
|
|
4262
|
+
{
|
|
4263
|
+
type: "text",
|
|
4264
|
+
value: search,
|
|
4265
|
+
onChange: (e) => setSearch(e.target.value),
|
|
4266
|
+
placeholder: "Search FX...",
|
|
4267
|
+
className: "sas-input flex-1 px-2 py-1 text-xs"
|
|
4268
|
+
}
|
|
4269
|
+
),
|
|
4270
|
+
onRefreshFx && /* @__PURE__ */ jsx18(
|
|
4271
|
+
"button",
|
|
4272
|
+
{
|
|
4273
|
+
onClick: () => onRefreshFx(),
|
|
4274
|
+
disabled: fxLoading,
|
|
4275
|
+
className: "px-2 py-1 text-xs rounded-sm border border-sas-border text-sas-muted hover:text-sas-accent hover:border-sas-accent transition-colors disabled:opacity-50",
|
|
4276
|
+
title: "Re-scan plugins",
|
|
4277
|
+
children: fxLoading ? "..." : "Refresh"
|
|
4278
|
+
}
|
|
4279
|
+
)
|
|
4280
|
+
] }),
|
|
4281
|
+
fxLoading && availableFx.length === 0 ? /* @__PURE__ */ jsx18("div", { className: "text-xs text-sas-muted/60 text-center py-3", children: "Scanning plugins..." }) : /* @__PURE__ */ jsxs14("div", { className: "grid grid-cols-3 gap-1 max-h-[140px] overflow-y-auto", children: [
|
|
4282
|
+
filtered.map((fx) => /* @__PURE__ */ jsxs14(
|
|
4283
|
+
"button",
|
|
4284
|
+
{
|
|
4285
|
+
"data-testid": `bus-fx-pick-${fx.pluginId}`,
|
|
4286
|
+
onClick: () => onAddFx(fx.pluginId),
|
|
4287
|
+
className: "flex flex-col items-start px-2 py-1.5 rounded-sm border text-left transition-colors border-sas-border bg-sas-panel-alt text-sas-muted hover:border-sas-accent hover:text-sas-accent",
|
|
4288
|
+
title: `${fx.name} by ${fx.manufacturer} (${fx.type.toUpperCase()})`,
|
|
4289
|
+
children: [
|
|
4290
|
+
/* @__PURE__ */ jsx18("span", { className: "text-xs font-medium truncate w-full", children: fx.name }),
|
|
4291
|
+
/* @__PURE__ */ jsx18("span", { className: "text-[9px] text-sas-muted/50 truncate w-full", children: fx.manufacturer || fx.type.toUpperCase() })
|
|
4292
|
+
]
|
|
4293
|
+
},
|
|
4294
|
+
fx.pluginId
|
|
4295
|
+
)),
|
|
4296
|
+
filtered.length === 0 && /* @__PURE__ */ jsx18("div", { className: "col-span-3 text-xs text-sas-muted/60 text-center py-2", children: search.trim() ? "No matches" : "No FX plugins found" })
|
|
4297
|
+
] })
|
|
4298
|
+
] })
|
|
4299
|
+
]
|
|
4300
|
+
}
|
|
4301
|
+
);
|
|
4302
|
+
}
|
|
4303
|
+
|
|
4304
|
+
// src/hooks/usePanelBus.ts
|
|
4305
|
+
import { useCallback as useCallback9, useEffect as useEffect10, useRef as useRef11, useState as useState13 } from "react";
|
|
4306
|
+
function usePanelBus(host, activeSceneId) {
|
|
4307
|
+
const supported = typeof host.getPanelBusState === "function";
|
|
4308
|
+
const [bus, setBus] = useState13(null);
|
|
4309
|
+
const [availableFx, setAvailableFx] = useState13([]);
|
|
4310
|
+
const [fxLoading, setFxLoading] = useState13(false);
|
|
4311
|
+
const [fxPickerOpen, setFxPickerOpen] = useState13(false);
|
|
4312
|
+
const fxLoadedRef = useRef11(false);
|
|
4313
|
+
const loadSeqRef = useRef11(0);
|
|
4314
|
+
const reload = useCallback9(async () => {
|
|
4315
|
+
if (!supported || !activeSceneId || !host.getPanelBusState) {
|
|
4316
|
+
setBus(null);
|
|
4317
|
+
return;
|
|
4318
|
+
}
|
|
4319
|
+
const seq = ++loadSeqRef.current;
|
|
4320
|
+
try {
|
|
4321
|
+
const state = await host.getPanelBusState(activeSceneId);
|
|
4322
|
+
if (loadSeqRef.current === seq) setBus(state);
|
|
4323
|
+
} catch {
|
|
4324
|
+
}
|
|
4325
|
+
}, [host, activeSceneId, supported]);
|
|
4326
|
+
useEffect10(() => {
|
|
4327
|
+
setBus(null);
|
|
4328
|
+
setFxPickerOpen(false);
|
|
4329
|
+
void reload();
|
|
4330
|
+
}, [reload]);
|
|
4331
|
+
const loadFxList = useCallback9(
|
|
4332
|
+
async (force) => {
|
|
4333
|
+
if (!supported || !host.getAvailableFx) return;
|
|
4334
|
+
if (fxLoadedRef.current && !force) return;
|
|
4335
|
+
setFxLoading(true);
|
|
4336
|
+
try {
|
|
4337
|
+
const list = await host.getAvailableFx();
|
|
4338
|
+
setAvailableFx(list);
|
|
4339
|
+
fxLoadedRef.current = true;
|
|
4340
|
+
} catch {
|
|
4341
|
+
} finally {
|
|
4342
|
+
setFxLoading(false);
|
|
4343
|
+
}
|
|
4344
|
+
},
|
|
4345
|
+
[host, supported]
|
|
4346
|
+
);
|
|
4347
|
+
const openPicker = useCallback9(
|
|
4348
|
+
(open) => {
|
|
4349
|
+
setFxPickerOpen(open);
|
|
4350
|
+
if (open) void loadFxList(false);
|
|
4351
|
+
},
|
|
4352
|
+
[loadFxList]
|
|
4353
|
+
);
|
|
4354
|
+
const mutate = useCallback9(
|
|
4355
|
+
(fn) => {
|
|
4356
|
+
if (!fn || !activeSceneId) return;
|
|
4357
|
+
void (async () => {
|
|
4358
|
+
try {
|
|
4359
|
+
await fn();
|
|
4360
|
+
} catch {
|
|
4361
|
+
}
|
|
4362
|
+
await reload();
|
|
4363
|
+
})();
|
|
4364
|
+
},
|
|
4365
|
+
[activeSceneId, reload]
|
|
4366
|
+
);
|
|
4367
|
+
return {
|
|
4368
|
+
supported,
|
|
4369
|
+
bus,
|
|
4370
|
+
availableFx,
|
|
4371
|
+
fxLoading,
|
|
4372
|
+
fxPickerOpen,
|
|
4373
|
+
setFxPickerOpen: openPicker,
|
|
4374
|
+
refreshFx: () => void loadFxList(true),
|
|
4375
|
+
reload,
|
|
4376
|
+
onVolumeChange: (volumeDb) => mutate(host.setPanelBusVolume && (() => host.setPanelBusVolume(activeSceneId, volumeDb))),
|
|
4377
|
+
onMuteToggle: () => mutate(
|
|
4378
|
+
host.setPanelBusMute && (() => host.setPanelBusMute(activeSceneId, !(bus?.muted ?? false)))
|
|
4379
|
+
),
|
|
4380
|
+
onSoloToggle: () => mutate(
|
|
4381
|
+
host.setPanelBusSolo && (() => host.setPanelBusSolo(activeSceneId, !(bus?.soloed ?? false)))
|
|
4382
|
+
),
|
|
4383
|
+
onAddFx: (pluginId) => mutate(host.loadPanelBusFx && (async () => {
|
|
4384
|
+
await host.loadPanelBusFx(activeSceneId, pluginId);
|
|
4385
|
+
})),
|
|
4386
|
+
onRemoveFx: (fxIndex) => mutate(host.removePanelBusFx && (() => host.removePanelBusFx(activeSceneId, fxIndex))),
|
|
4387
|
+
onToggleFxEnabled: (fxIndex, enabled) => mutate(
|
|
4388
|
+
host.setPanelBusFxEnabled && (() => host.setPanelBusFxEnabled(activeSceneId, fxIndex, enabled))
|
|
4389
|
+
),
|
|
4390
|
+
onShowFxEditor: (fxIndex) => mutate(
|
|
4391
|
+
host.showPanelBusFxEditor && (() => host.showPanelBusFxEditor(activeSceneId, fxIndex))
|
|
4392
|
+
)
|
|
4393
|
+
};
|
|
4394
|
+
}
|
|
4395
|
+
|
|
4396
|
+
// src/components/DownloadPackButton.tsx
|
|
4397
|
+
import { useCallback as useCallback10, useEffect as useEffect11, useState as useState14 } from "react";
|
|
4398
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4132
4399
|
function formatSize(bytes) {
|
|
4133
4400
|
if (!bytes || bytes <= 0) return "";
|
|
4134
4401
|
const gb = bytes / 1024 ** 3;
|
|
@@ -4144,10 +4411,10 @@ var DownloadPackButton = ({
|
|
|
4144
4411
|
variant = "compact",
|
|
4145
4412
|
onDownloadComplete
|
|
4146
4413
|
}) => {
|
|
4147
|
-
const [status, setStatus] =
|
|
4148
|
-
const [progress, setProgress] =
|
|
4149
|
-
const [errorMessage, setErrorMessage] =
|
|
4150
|
-
|
|
4414
|
+
const [status, setStatus] = useState14("idle");
|
|
4415
|
+
const [progress, setProgress] = useState14(0);
|
|
4416
|
+
const [errorMessage, setErrorMessage] = useState14(null);
|
|
4417
|
+
useEffect11(() => {
|
|
4151
4418
|
const unsub = host.onSamplePackProgress(packId, (p) => {
|
|
4152
4419
|
setStatus(p.status);
|
|
4153
4420
|
setProgress(p.progress);
|
|
@@ -4162,7 +4429,7 @@ var DownloadPackButton = ({
|
|
|
4162
4429
|
});
|
|
4163
4430
|
return unsub;
|
|
4164
4431
|
}, [host, packId, onDownloadComplete]);
|
|
4165
|
-
const handleClick =
|
|
4432
|
+
const handleClick = useCallback10(async () => {
|
|
4166
4433
|
if (status !== "idle" && status !== "error") return;
|
|
4167
4434
|
try {
|
|
4168
4435
|
setStatus("downloading");
|
|
@@ -4216,8 +4483,8 @@ var DownloadPackButton = ({
|
|
|
4216
4483
|
} else {
|
|
4217
4484
|
className = `${baseClasses} text-sas-muted hover:text-sas-accent border-sas-border hover:border-sas-accent`;
|
|
4218
4485
|
}
|
|
4219
|
-
return /* @__PURE__ */
|
|
4220
|
-
/* @__PURE__ */
|
|
4486
|
+
return /* @__PURE__ */ jsxs15("div", { children: [
|
|
4487
|
+
/* @__PURE__ */ jsx19(
|
|
4221
4488
|
"button",
|
|
4222
4489
|
{
|
|
4223
4490
|
"data-testid": `download-pack-button-${packId}`,
|
|
@@ -4228,12 +4495,12 @@ var DownloadPackButton = ({
|
|
|
4228
4495
|
children: buttonLabel
|
|
4229
4496
|
}
|
|
4230
4497
|
),
|
|
4231
|
-
variant === "large" && status === "error" && errorMessage && /* @__PURE__ */
|
|
4498
|
+
variant === "large" && status === "error" && errorMessage && /* @__PURE__ */ jsx19("div", { className: "text-xs text-sas-danger mt-2", "data-testid": `download-pack-error-${packId}`, children: errorMessage })
|
|
4232
4499
|
] });
|
|
4233
4500
|
};
|
|
4234
4501
|
|
|
4235
4502
|
// src/components/SamplePackCTACard.tsx
|
|
4236
|
-
import { jsx as
|
|
4503
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4237
4504
|
var SamplePackCTACard = ({
|
|
4238
4505
|
host,
|
|
4239
4506
|
pack,
|
|
@@ -4241,7 +4508,7 @@ var SamplePackCTACard = ({
|
|
|
4241
4508
|
onDownloadComplete
|
|
4242
4509
|
}) => {
|
|
4243
4510
|
if (status === "checking") {
|
|
4244
|
-
return /* @__PURE__ */
|
|
4511
|
+
return /* @__PURE__ */ jsx20(
|
|
4245
4512
|
"div",
|
|
4246
4513
|
{
|
|
4247
4514
|
"data-testid": `sample-pack-cta-checking-${pack.packId}`,
|
|
@@ -4252,16 +4519,16 @@ var SamplePackCTACard = ({
|
|
|
4252
4519
|
}
|
|
4253
4520
|
const headline = status === "stale" ? `${pack.displayName} update available` : `${pack.displayName} not installed`;
|
|
4254
4521
|
const sublabel = status === "stale" ? `A newer version is available for download.` : pack.description;
|
|
4255
|
-
return /* @__PURE__ */
|
|
4522
|
+
return /* @__PURE__ */ jsxs16(
|
|
4256
4523
|
"div",
|
|
4257
4524
|
{
|
|
4258
4525
|
"data-testid": `sample-pack-cta-${pack.packId}`,
|
|
4259
4526
|
className: "flex flex-col items-center justify-center py-12 px-6 text-center",
|
|
4260
4527
|
children: [
|
|
4261
|
-
/* @__PURE__ */
|
|
4262
|
-
/* @__PURE__ */
|
|
4263
|
-
/* @__PURE__ */
|
|
4264
|
-
/* @__PURE__ */
|
|
4528
|
+
/* @__PURE__ */ jsx20("div", { className: "text-sm uppercase tracking-wide text-sas-muted mb-2", children: status === "stale" ? "Update available" : "Sample library not installed" }),
|
|
4529
|
+
/* @__PURE__ */ jsx20("div", { className: "text-base text-sas-text mb-1", children: headline }),
|
|
4530
|
+
/* @__PURE__ */ jsx20("div", { className: "text-xs text-sas-muted mb-6 max-w-md", children: sublabel }),
|
|
4531
|
+
/* @__PURE__ */ jsx20(
|
|
4265
4532
|
DownloadPackButton,
|
|
4266
4533
|
{
|
|
4267
4534
|
host,
|
|
@@ -4278,7 +4545,7 @@ var SamplePackCTACard = ({
|
|
|
4278
4545
|
};
|
|
4279
4546
|
|
|
4280
4547
|
// src/components/WaveformView.tsx
|
|
4281
|
-
import { useEffect as
|
|
4548
|
+
import { useEffect as useEffect12, useRef as useRef12, useState as useState15 } from "react";
|
|
4282
4549
|
|
|
4283
4550
|
// src/components/waveform.ts
|
|
4284
4551
|
function computePeaks(audioBuffer, bins, targetSamples) {
|
|
@@ -4341,7 +4608,7 @@ function drawWaveform(canvas, peaks, options = {}) {
|
|
|
4341
4608
|
}
|
|
4342
4609
|
|
|
4343
4610
|
// src/components/WaveformView.tsx
|
|
4344
|
-
import { jsx as
|
|
4611
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
4345
4612
|
var WaveformView = ({
|
|
4346
4613
|
host,
|
|
4347
4614
|
filePath,
|
|
@@ -4350,9 +4617,9 @@ var WaveformView = ({
|
|
|
4350
4617
|
fillStyle,
|
|
4351
4618
|
targetSamples
|
|
4352
4619
|
}) => {
|
|
4353
|
-
const canvasRef =
|
|
4354
|
-
const [peaks, setPeaks] =
|
|
4355
|
-
|
|
4620
|
+
const canvasRef = useRef12(null);
|
|
4621
|
+
const [peaks, setPeaks] = useState15(null);
|
|
4622
|
+
useEffect12(() => {
|
|
4356
4623
|
let cancelled = false;
|
|
4357
4624
|
let audioContext = null;
|
|
4358
4625
|
(async () => {
|
|
@@ -4378,7 +4645,7 @@ var WaveformView = ({
|
|
|
4378
4645
|
cancelled = true;
|
|
4379
4646
|
};
|
|
4380
4647
|
}, [host, filePath, bins, targetSamples]);
|
|
4381
|
-
|
|
4648
|
+
useEffect12(() => {
|
|
4382
4649
|
if (!peaks) return;
|
|
4383
4650
|
const canvas = canvasRef.current;
|
|
4384
4651
|
if (!canvas) return;
|
|
@@ -4389,7 +4656,7 @@ var WaveformView = ({
|
|
|
4389
4656
|
observer.observe(canvas);
|
|
4390
4657
|
return () => observer.disconnect();
|
|
4391
4658
|
}, [peaks, fillStyle]);
|
|
4392
|
-
return /* @__PURE__ */
|
|
4659
|
+
return /* @__PURE__ */ jsx21(
|
|
4393
4660
|
"canvas",
|
|
4394
4661
|
{
|
|
4395
4662
|
ref: canvasRef,
|
|
@@ -4400,8 +4667,8 @@ var WaveformView = ({
|
|
|
4400
4667
|
};
|
|
4401
4668
|
|
|
4402
4669
|
// src/components/ScrollingWaveform.tsx
|
|
4403
|
-
import { useEffect as
|
|
4404
|
-
import { jsx as
|
|
4670
|
+
import { useEffect as useEffect13, useRef as useRef13 } from "react";
|
|
4671
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
4405
4672
|
var ScrollingWaveform = ({
|
|
4406
4673
|
getPeakDb,
|
|
4407
4674
|
active,
|
|
@@ -4409,11 +4676,11 @@ var ScrollingWaveform = ({
|
|
|
4409
4676
|
className,
|
|
4410
4677
|
fillStyle
|
|
4411
4678
|
}) => {
|
|
4412
|
-
const canvasRef =
|
|
4413
|
-
const ringRef =
|
|
4414
|
-
const writeIdxRef =
|
|
4415
|
-
const rafRef =
|
|
4416
|
-
|
|
4679
|
+
const canvasRef = useRef13(null);
|
|
4680
|
+
const ringRef = useRef13(new Float32Array(columns));
|
|
4681
|
+
const writeIdxRef = useRef13(0);
|
|
4682
|
+
const rafRef = useRef13(null);
|
|
4683
|
+
useEffect13(() => {
|
|
4417
4684
|
if (ringRef.current.length !== columns) {
|
|
4418
4685
|
const next = new Float32Array(columns);
|
|
4419
4686
|
const prev = ringRef.current;
|
|
@@ -4425,7 +4692,7 @@ var ScrollingWaveform = ({
|
|
|
4425
4692
|
writeIdxRef.current = writeIdxRef.current % columns;
|
|
4426
4693
|
}
|
|
4427
4694
|
}, [columns]);
|
|
4428
|
-
|
|
4695
|
+
useEffect13(() => {
|
|
4429
4696
|
if (!active) {
|
|
4430
4697
|
if (rafRef.current !== null) {
|
|
4431
4698
|
cancelAnimationFrame(rafRef.current);
|
|
@@ -4477,7 +4744,7 @@ var ScrollingWaveform = ({
|
|
|
4477
4744
|
}
|
|
4478
4745
|
};
|
|
4479
4746
|
}, [active, getPeakDb, fillStyle]);
|
|
4480
|
-
return /* @__PURE__ */
|
|
4747
|
+
return /* @__PURE__ */ jsx22(
|
|
4481
4748
|
"canvas",
|
|
4482
4749
|
{
|
|
4483
4750
|
ref: canvasRef,
|
|
@@ -4488,8 +4755,8 @@ var ScrollingWaveform = ({
|
|
|
4488
4755
|
};
|
|
4489
4756
|
|
|
4490
4757
|
// src/components/OffsetScrubber.tsx
|
|
4491
|
-
import { useCallback as
|
|
4492
|
-
import { jsx as
|
|
4758
|
+
import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo7, useRef as useRef14, useState as useState16 } from "react";
|
|
4759
|
+
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4493
4760
|
var SLIDER_HEIGHT_PX = 28;
|
|
4494
4761
|
var TICK_HEIGHT_PX = 14;
|
|
4495
4762
|
var DOWNBEAT_TICK_HEIGHT_PX = 22;
|
|
@@ -4502,40 +4769,40 @@ function OffsetScrubber({
|
|
|
4502
4769
|
onChange,
|
|
4503
4770
|
disabled = false
|
|
4504
4771
|
}) {
|
|
4505
|
-
const trackRef =
|
|
4506
|
-
const [draftOffset, setDraftOffset] =
|
|
4507
|
-
const [isDragging, setIsDragging] =
|
|
4508
|
-
|
|
4772
|
+
const trackRef = useRef14(null);
|
|
4773
|
+
const [draftOffset, setDraftOffset] = useState16(offsetSamples);
|
|
4774
|
+
const [isDragging, setIsDragging] = useState16(false);
|
|
4775
|
+
useEffect14(() => {
|
|
4509
4776
|
if (!isDragging) setDraftOffset(offsetSamples);
|
|
4510
4777
|
}, [offsetSamples, isDragging]);
|
|
4511
4778
|
const sampleRate = cuePoints?.sample_rate ?? 44100;
|
|
4512
4779
|
const detectedBpm = cuePoints?.detected_bpm ?? projectBpm;
|
|
4513
|
-
const beatsForRange =
|
|
4780
|
+
const beatsForRange = useMemo7(() => {
|
|
4514
4781
|
return Math.round(60 / projectBpm * sampleRate);
|
|
4515
4782
|
}, [projectBpm, sampleRate]);
|
|
4516
4783
|
const rangeSamples = beatsForRange * meter;
|
|
4517
|
-
const sampleToFraction =
|
|
4784
|
+
const sampleToFraction = useCallback11(
|
|
4518
4785
|
(sample) => {
|
|
4519
4786
|
const clamped = Math.max(-rangeSamples, Math.min(rangeSamples, sample));
|
|
4520
4787
|
return (clamped + rangeSamples) / (2 * rangeSamples);
|
|
4521
4788
|
},
|
|
4522
4789
|
[rangeSamples]
|
|
4523
4790
|
);
|
|
4524
|
-
const fractionToSample =
|
|
4791
|
+
const fractionToSample = useCallback11(
|
|
4525
4792
|
(fraction) => {
|
|
4526
4793
|
const clamped = Math.max(0, Math.min(1, fraction));
|
|
4527
4794
|
return Math.round(clamped * 2 * rangeSamples - rangeSamples);
|
|
4528
4795
|
},
|
|
4529
4796
|
[rangeSamples]
|
|
4530
4797
|
);
|
|
4531
|
-
const snapTargets =
|
|
4798
|
+
const snapTargets = useMemo7(() => {
|
|
4532
4799
|
if (!cuePoints || cuePoints.beats.length === 0) return [];
|
|
4533
4800
|
const downbeat = cuePoints.beats[0];
|
|
4534
4801
|
const positives = cuePoints.beats.map((b) => b - downbeat);
|
|
4535
4802
|
const negatives = positives.slice(1).map((p) => -p);
|
|
4536
4803
|
return [...negatives, ...positives].sort((a, b) => a - b);
|
|
4537
4804
|
}, [cuePoints]);
|
|
4538
|
-
const snapToBeat =
|
|
4805
|
+
const snapToBeat = useCallback11(
|
|
4539
4806
|
(sample) => {
|
|
4540
4807
|
if (snapTargets.length === 0) return sample;
|
|
4541
4808
|
let best = snapTargets[0];
|
|
@@ -4551,7 +4818,7 @@ function OffsetScrubber({
|
|
|
4551
4818
|
},
|
|
4552
4819
|
[snapTargets]
|
|
4553
4820
|
);
|
|
4554
|
-
const handlePointerDown =
|
|
4821
|
+
const handlePointerDown = useCallback11(
|
|
4555
4822
|
(e) => {
|
|
4556
4823
|
if (disabled || !cuePoints) return;
|
|
4557
4824
|
e.preventDefault();
|
|
@@ -4585,7 +4852,7 @@ function OffsetScrubber({
|
|
|
4585
4852
|
},
|
|
4586
4853
|
[disabled, cuePoints, fractionToSample, onChange, snapToBeat]
|
|
4587
4854
|
);
|
|
4588
|
-
const handleResetToZero =
|
|
4855
|
+
const handleResetToZero = useCallback11(() => {
|
|
4589
4856
|
if (disabled) return;
|
|
4590
4857
|
setDraftOffset(0);
|
|
4591
4858
|
onChange(0);
|
|
@@ -4593,7 +4860,7 @@ function OffsetScrubber({
|
|
|
4593
4860
|
const thumbFraction = sampleToFraction(draftOffset);
|
|
4594
4861
|
const thumbLeftPct = `${(thumbFraction * 100).toFixed(2)}%`;
|
|
4595
4862
|
const bpmMismatch = cuePoints?.detected_bpm != null && Math.abs(cuePoints.detected_bpm - projectBpm) > 1;
|
|
4596
|
-
const ticks =
|
|
4863
|
+
const ticks = useMemo7(() => {
|
|
4597
4864
|
if (!cuePoints) return [];
|
|
4598
4865
|
const downbeat = cuePoints.beats[0] ?? 0;
|
|
4599
4866
|
return cuePoints.beats.map((b, i) => {
|
|
@@ -4604,9 +4871,9 @@ function OffsetScrubber({
|
|
|
4604
4871
|
});
|
|
4605
4872
|
}, [cuePoints, sampleToFraction]);
|
|
4606
4873
|
const isDisabled = disabled || !cuePoints || cuePoints.beats.length === 0;
|
|
4607
|
-
return /* @__PURE__ */
|
|
4608
|
-
/* @__PURE__ */
|
|
4609
|
-
/* @__PURE__ */
|
|
4874
|
+
return /* @__PURE__ */ jsxs17("div", { "data-testid": "offset-scrubber", className: "flex items-center gap-2 w-full", children: [
|
|
4875
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[9px] text-sas-muted/60 uppercase tracking-wide flex-shrink-0", children: "Align" }),
|
|
4876
|
+
/* @__PURE__ */ jsxs17(
|
|
4610
4877
|
"div",
|
|
4611
4878
|
{
|
|
4612
4879
|
ref: trackRef,
|
|
@@ -4622,7 +4889,7 @@ function OffsetScrubber({
|
|
|
4622
4889
|
"aria-valuenow": draftOffset,
|
|
4623
4890
|
"aria-disabled": isDisabled,
|
|
4624
4891
|
children: [
|
|
4625
|
-
/* @__PURE__ */
|
|
4892
|
+
/* @__PURE__ */ jsx23(
|
|
4626
4893
|
"div",
|
|
4627
4894
|
{
|
|
4628
4895
|
"aria-hidden": "true",
|
|
@@ -4630,7 +4897,7 @@ function OffsetScrubber({
|
|
|
4630
4897
|
style: { left: "50%" }
|
|
4631
4898
|
}
|
|
4632
4899
|
),
|
|
4633
|
-
ticks.map((t) => /* @__PURE__ */
|
|
4900
|
+
ticks.map((t) => /* @__PURE__ */ jsx23(
|
|
4634
4901
|
"div",
|
|
4635
4902
|
{
|
|
4636
4903
|
"data-testid": t.isDownbeat ? "offset-tick-downbeat" : "offset-tick",
|
|
@@ -4645,7 +4912,7 @@ function OffsetScrubber({
|
|
|
4645
4912
|
},
|
|
4646
4913
|
t.i
|
|
4647
4914
|
)),
|
|
4648
|
-
/* @__PURE__ */
|
|
4915
|
+
/* @__PURE__ */ jsx23(
|
|
4649
4916
|
"div",
|
|
4650
4917
|
{
|
|
4651
4918
|
"data-testid": "offset-scrubber-thumb",
|
|
@@ -4662,7 +4929,7 @@ function OffsetScrubber({
|
|
|
4662
4929
|
]
|
|
4663
4930
|
}
|
|
4664
4931
|
),
|
|
4665
|
-
/* @__PURE__ */
|
|
4932
|
+
/* @__PURE__ */ jsx23(
|
|
4666
4933
|
"span",
|
|
4667
4934
|
{
|
|
4668
4935
|
"data-testid": "offset-scrubber-readout",
|
|
@@ -4670,7 +4937,7 @@ function OffsetScrubber({
|
|
|
4670
4937
|
children: formatOffset(draftOffset, sampleRate)
|
|
4671
4938
|
}
|
|
4672
4939
|
),
|
|
4673
|
-
/* @__PURE__ */
|
|
4940
|
+
/* @__PURE__ */ jsx23(
|
|
4674
4941
|
"button",
|
|
4675
4942
|
{
|
|
4676
4943
|
type: "button",
|
|
@@ -4682,7 +4949,7 @@ function OffsetScrubber({
|
|
|
4682
4949
|
children: "\u2316"
|
|
4683
4950
|
}
|
|
4684
4951
|
),
|
|
4685
|
-
bpmMismatch && /* @__PURE__ */
|
|
4952
|
+
bpmMismatch && /* @__PURE__ */ jsx23(
|
|
4686
4953
|
"span",
|
|
4687
4954
|
{
|
|
4688
4955
|
"data-testid": "offset-bpm-mismatch",
|
|
@@ -4754,16 +5021,16 @@ function synthesizeCuePoints({
|
|
|
4754
5021
|
}
|
|
4755
5022
|
|
|
4756
5023
|
// src/panel-core/useGeneratorPanelCore.tsx
|
|
4757
|
-
import { useState as
|
|
5024
|
+
import { useState as useState21, useEffect as useEffect17, useCallback as useCallback15, useRef as useRef18, useMemo as useMemo9 } from "react";
|
|
4758
5025
|
|
|
4759
5026
|
// src/hooks/useSceneState.ts
|
|
4760
|
-
import { useState as
|
|
5027
|
+
import { useState as useState17, useCallback as useCallback12, useRef as useRef15 } from "react";
|
|
4761
5028
|
function useSceneState(activeSceneId, initialValue) {
|
|
4762
|
-
const [stateMap, setStateMap] =
|
|
4763
|
-
const activeSceneIdRef =
|
|
5029
|
+
const [stateMap, setStateMap] = useState17(() => /* @__PURE__ */ new Map());
|
|
5030
|
+
const activeSceneIdRef = useRef15(activeSceneId);
|
|
4764
5031
|
activeSceneIdRef.current = activeSceneId;
|
|
4765
5032
|
const currentValue = activeSceneId !== null && stateMap.has(activeSceneId) ? stateMap.get(activeSceneId) : initialValue;
|
|
4766
|
-
const setForCurrentScene =
|
|
5033
|
+
const setForCurrentScene = useCallback12((value) => {
|
|
4767
5034
|
const sid = activeSceneIdRef.current;
|
|
4768
5035
|
if (sid === null) return;
|
|
4769
5036
|
setStateMap((prev) => {
|
|
@@ -4774,7 +5041,7 @@ function useSceneState(activeSceneId, initialValue) {
|
|
|
4774
5041
|
return newMap;
|
|
4775
5042
|
});
|
|
4776
5043
|
}, [initialValue]);
|
|
4777
|
-
const setForScene =
|
|
5044
|
+
const setForScene = useCallback12((sceneId, value) => {
|
|
4778
5045
|
setStateMap((prev) => {
|
|
4779
5046
|
const current = prev.has(sceneId) ? prev.get(sceneId) : initialValue;
|
|
4780
5047
|
const next = typeof value === "function" ? value(current) : value;
|
|
@@ -4787,10 +5054,10 @@ function useSceneState(activeSceneId, initialValue) {
|
|
|
4787
5054
|
}
|
|
4788
5055
|
|
|
4789
5056
|
// src/hooks/useAnySolo.ts
|
|
4790
|
-
import { useEffect as
|
|
5057
|
+
import { useEffect as useEffect15, useState as useState18 } from "react";
|
|
4791
5058
|
function useAnySolo(host) {
|
|
4792
|
-
const [anySolo, setAnySolo] =
|
|
4793
|
-
|
|
5059
|
+
const [anySolo, setAnySolo] = useState18(false);
|
|
5060
|
+
useEffect15(() => {
|
|
4794
5061
|
let active = true;
|
|
4795
5062
|
const refresh = () => {
|
|
4796
5063
|
host.isAnySoloActive().then((v) => {
|
|
@@ -4809,7 +5076,7 @@ function useAnySolo(host) {
|
|
|
4809
5076
|
}
|
|
4810
5077
|
|
|
4811
5078
|
// src/hooks/useSoundHistory.ts
|
|
4812
|
-
import { useCallback as
|
|
5079
|
+
import { useCallback as useCallback13, useMemo as useMemo8, useRef as useRef16, useState as useState19 } from "react";
|
|
4813
5080
|
var EMPTY = { entries: [], cursor: -1 };
|
|
4814
5081
|
function sameDescriptor(a, b) {
|
|
4815
5082
|
if (a === b) return true;
|
|
@@ -4821,14 +5088,14 @@ function sameDescriptor(a, b) {
|
|
|
4821
5088
|
}
|
|
4822
5089
|
function useSoundHistory(applySound, opts = {}) {
|
|
4823
5090
|
const max = Math.max(2, opts.max ?? 24);
|
|
4824
|
-
const applyRef =
|
|
5091
|
+
const applyRef = useRef16(applySound);
|
|
4825
5092
|
applyRef.current = applySound;
|
|
4826
|
-
const onChangeRef =
|
|
5093
|
+
const onChangeRef = useRef16(opts.onChange);
|
|
4827
5094
|
onChangeRef.current = opts.onChange;
|
|
4828
|
-
const dataRef =
|
|
4829
|
-
const [, setVersion] =
|
|
4830
|
-
const bump =
|
|
4831
|
-
const commit =
|
|
5095
|
+
const dataRef = useRef16({});
|
|
5096
|
+
const [, setVersion] = useState19(0);
|
|
5097
|
+
const bump = useCallback13(() => setVersion((v) => v + 1), []);
|
|
5098
|
+
const commit = useCallback13(
|
|
4832
5099
|
(trackId, next, notify) => {
|
|
4833
5100
|
dataRef.current = { ...dataRef.current, [trackId]: next };
|
|
4834
5101
|
bump();
|
|
@@ -4836,7 +5103,7 @@ function useSoundHistory(applySound, opts = {}) {
|
|
|
4836
5103
|
},
|
|
4837
5104
|
[bump]
|
|
4838
5105
|
);
|
|
4839
|
-
const record =
|
|
5106
|
+
const record = useCallback13(
|
|
4840
5107
|
(trackId, descriptor, label) => {
|
|
4841
5108
|
const h = dataRef.current[trackId];
|
|
4842
5109
|
const current = h && h.cursor >= 0 ? h.entries[h.cursor] : void 0;
|
|
@@ -4851,7 +5118,7 @@ function useSoundHistory(applySound, opts = {}) {
|
|
|
4851
5118
|
},
|
|
4852
5119
|
[max, commit]
|
|
4853
5120
|
);
|
|
4854
|
-
const restoreTo =
|
|
5121
|
+
const restoreTo = useCallback13(
|
|
4855
5122
|
async (trackId, index) => {
|
|
4856
5123
|
const h = dataRef.current[trackId];
|
|
4857
5124
|
if (!h || index < 0 || index >= h.entries.length || index === h.cursor) return false;
|
|
@@ -4861,7 +5128,7 @@ function useSoundHistory(applySound, opts = {}) {
|
|
|
4861
5128
|
},
|
|
4862
5129
|
[commit]
|
|
4863
5130
|
);
|
|
4864
|
-
const undo =
|
|
5131
|
+
const undo = useCallback13(
|
|
4865
5132
|
(trackId) => {
|
|
4866
5133
|
const h = dataRef.current[trackId];
|
|
4867
5134
|
if (!h || h.cursor <= 0) return Promise.resolve(false);
|
|
@@ -4869,7 +5136,7 @@ function useSoundHistory(applySound, opts = {}) {
|
|
|
4869
5136
|
},
|
|
4870
5137
|
[restoreTo]
|
|
4871
5138
|
);
|
|
4872
|
-
const toggleFavorite =
|
|
5139
|
+
const toggleFavorite = useCallback13(
|
|
4873
5140
|
(trackId, index) => {
|
|
4874
5141
|
const h = dataRef.current[trackId];
|
|
4875
5142
|
if (!h || index < 0 || index >= h.entries.length) return;
|
|
@@ -4878,7 +5145,7 @@ function useSoundHistory(applySound, opts = {}) {
|
|
|
4878
5145
|
},
|
|
4879
5146
|
[commit]
|
|
4880
5147
|
);
|
|
4881
|
-
const restore =
|
|
5148
|
+
const restore = useCallback13(
|
|
4882
5149
|
(trackId, state) => {
|
|
4883
5150
|
const entries = Array.isArray(state?.entries) ? [...state.entries] : [];
|
|
4884
5151
|
const raw = typeof state?.cursor === "number" ? state.cursor : entries.length - 1;
|
|
@@ -4887,15 +5154,15 @@ function useSoundHistory(applySound, opts = {}) {
|
|
|
4887
5154
|
},
|
|
4888
5155
|
[commit]
|
|
4889
5156
|
);
|
|
4890
|
-
const list =
|
|
5157
|
+
const list = useCallback13(
|
|
4891
5158
|
(trackId) => dataRef.current[trackId] ?? EMPTY,
|
|
4892
5159
|
[]
|
|
4893
5160
|
);
|
|
4894
|
-
const canUndo =
|
|
5161
|
+
const canUndo = useCallback13((trackId) => {
|
|
4895
5162
|
const h = dataRef.current[trackId];
|
|
4896
5163
|
return !!h && h.cursor > 0;
|
|
4897
5164
|
}, []);
|
|
4898
|
-
const clear =
|
|
5165
|
+
const clear = useCallback13(
|
|
4899
5166
|
(trackId) => {
|
|
4900
5167
|
if (dataRef.current[trackId]) {
|
|
4901
5168
|
const next = { ...dataRef.current };
|
|
@@ -4907,11 +5174,11 @@ function useSoundHistory(applySound, opts = {}) {
|
|
|
4907
5174
|
},
|
|
4908
5175
|
[bump]
|
|
4909
5176
|
);
|
|
4910
|
-
const reset =
|
|
5177
|
+
const reset = useCallback13(() => {
|
|
4911
5178
|
dataRef.current = {};
|
|
4912
5179
|
bump();
|
|
4913
5180
|
}, [bump]);
|
|
4914
|
-
return
|
|
5181
|
+
return useMemo8(
|
|
4915
5182
|
() => ({ record, undo, restoreTo, list, canUndo, clear, reset, restore, toggleFavorite }),
|
|
4916
5183
|
[record, undo, restoreTo, list, canUndo, clear, reset, restore, toggleFavorite]
|
|
4917
5184
|
);
|
|
@@ -5044,7 +5311,7 @@ function resolveTrackGroups(parsedGroups, tracks, getDbId, opts = {}) {
|
|
|
5044
5311
|
}
|
|
5045
5312
|
|
|
5046
5313
|
// src/panel-core/useTransitionOps.ts
|
|
5047
|
-
import { useCallback as
|
|
5314
|
+
import { useCallback as useCallback14, useEffect as useEffect16, useRef as useRef17, useState as useState20 } from "react";
|
|
5048
5315
|
function useTransitionOps({
|
|
5049
5316
|
host,
|
|
5050
5317
|
adapter,
|
|
@@ -5061,8 +5328,8 @@ function useTransitionOps({
|
|
|
5061
5328
|
resolvedFades
|
|
5062
5329
|
}) {
|
|
5063
5330
|
const { identity } = adapter;
|
|
5064
|
-
const appliedFadeAutomationRef =
|
|
5065
|
-
const applyCrossfadeAutomation =
|
|
5331
|
+
const appliedFadeAutomationRef = useRef17(/* @__PURE__ */ new Set());
|
|
5332
|
+
const applyCrossfadeAutomation = useCallback14(
|
|
5066
5333
|
async (originTrackId, targetTrackId, bars, bpm, sliderPos) => {
|
|
5067
5334
|
if (host.setTrackVolumeAutomation) {
|
|
5068
5335
|
const curves = buildCrossfadeVolumeCurves(bars, bpm, sliderPos);
|
|
@@ -5079,7 +5346,7 @@ function useTransitionOps({
|
|
|
5079
5346
|
},
|
|
5080
5347
|
[host]
|
|
5081
5348
|
);
|
|
5082
|
-
const applyFadeAutomation =
|
|
5349
|
+
const applyFadeAutomation = useCallback14(
|
|
5083
5350
|
async (trackId, direction, bars, bpm, sliderPos, gesture) => {
|
|
5084
5351
|
if (!host.setTrackVolumeAutomation) return;
|
|
5085
5352
|
const points = buildFadeVolumeCurve(bars, bpm, direction, sliderPos, gesture);
|
|
@@ -5088,8 +5355,8 @@ function useTransitionOps({
|
|
|
5088
5355
|
},
|
|
5089
5356
|
[host]
|
|
5090
5357
|
);
|
|
5091
|
-
const [isCreatingCrossfade, setIsCreatingCrossfade] =
|
|
5092
|
-
const handleCreateCrossfade =
|
|
5358
|
+
const [isCreatingCrossfade, setIsCreatingCrossfade] = useState20(false);
|
|
5359
|
+
const handleCreateCrossfade = useCallback14(
|
|
5093
5360
|
async (origin, target) => {
|
|
5094
5361
|
const scene = activeSceneId;
|
|
5095
5362
|
const fromSceneId = sceneContext?.transitionFromSceneId ?? "";
|
|
@@ -5217,8 +5484,8 @@ function useTransitionOps({
|
|
|
5217
5484
|
loadTracks
|
|
5218
5485
|
]
|
|
5219
5486
|
);
|
|
5220
|
-
const [isCreatingFade, setIsCreatingFade] =
|
|
5221
|
-
const handleCreateFade =
|
|
5487
|
+
const [isCreatingFade, setIsCreatingFade] = useState20(false);
|
|
5488
|
+
const handleCreateFade = useCallback14(
|
|
5222
5489
|
async (selection, direction, gesture) => {
|
|
5223
5490
|
const scene = activeSceneId;
|
|
5224
5491
|
const fromSceneId = sceneContext?.transitionFromSceneId ?? "";
|
|
@@ -5328,7 +5595,7 @@ function useTransitionOps({
|
|
|
5328
5595
|
loadTracks
|
|
5329
5596
|
]
|
|
5330
5597
|
);
|
|
5331
|
-
const handleCrossfadeMute =
|
|
5598
|
+
const handleCrossfadeMute = useCallback14(
|
|
5332
5599
|
(pair) => {
|
|
5333
5600
|
const newMuted = !pair.origin.runtimeState.muted;
|
|
5334
5601
|
for (const id of [pair.origin.handle.id, pair.target.handle.id]) {
|
|
@@ -5343,7 +5610,7 @@ function useTransitionOps({
|
|
|
5343
5610
|
},
|
|
5344
5611
|
[host, setTracks]
|
|
5345
5612
|
);
|
|
5346
|
-
const handleCrossfadeSolo =
|
|
5613
|
+
const handleCrossfadeSolo = useCallback14(
|
|
5347
5614
|
(pair) => {
|
|
5348
5615
|
const newSolo = !pair.origin.runtimeState.solo;
|
|
5349
5616
|
for (const id of [pair.origin.handle.id, pair.target.handle.id]) {
|
|
@@ -5358,7 +5625,7 @@ function useTransitionOps({
|
|
|
5358
5625
|
},
|
|
5359
5626
|
[host, setTracks]
|
|
5360
5627
|
);
|
|
5361
|
-
const handleCrossfadeDelete =
|
|
5628
|
+
const handleCrossfadeDelete = useCallback14(
|
|
5362
5629
|
async (pair) => {
|
|
5363
5630
|
try {
|
|
5364
5631
|
for (const member of [pair.origin, pair.target]) {
|
|
@@ -5384,8 +5651,8 @@ function useTransitionOps({
|
|
|
5384
5651
|
},
|
|
5385
5652
|
[host, activeSceneId, setCrossfadePairsMeta, setTracks]
|
|
5386
5653
|
);
|
|
5387
|
-
const crossfadeSliderTimers =
|
|
5388
|
-
const handleCrossfadeSlider =
|
|
5654
|
+
const crossfadeSliderTimers = useRef17({});
|
|
5655
|
+
const handleCrossfadeSlider = useCallback14(
|
|
5389
5656
|
(pair, pos) => {
|
|
5390
5657
|
setCrossfadePairsMeta(
|
|
5391
5658
|
(prev) => prev.map((p) => p.groupId === pair.groupId ? { ...p, sliderPos: pos } : p)
|
|
@@ -5418,7 +5685,7 @@ function useTransitionOps({
|
|
|
5418
5685
|
},
|
|
5419
5686
|
[host, activeSceneId, applyCrossfadeAutomation, setCrossfadePairsMeta]
|
|
5420
5687
|
);
|
|
5421
|
-
const handleFadeDelete =
|
|
5688
|
+
const handleFadeDelete = useCallback14(
|
|
5422
5689
|
async (fade) => {
|
|
5423
5690
|
try {
|
|
5424
5691
|
await host.deleteTrack(fade.track.handle.id);
|
|
@@ -5438,8 +5705,8 @@ function useTransitionOps({
|
|
|
5438
5705
|
},
|
|
5439
5706
|
[host, activeSceneId, setFadesMeta, setTracks]
|
|
5440
5707
|
);
|
|
5441
|
-
const fadeSliderTimers =
|
|
5442
|
-
const handleFadeSlider =
|
|
5708
|
+
const fadeSliderTimers = useRef17({});
|
|
5709
|
+
const handleFadeSlider = useCallback14(
|
|
5443
5710
|
(fade, pos) => {
|
|
5444
5711
|
setFadesMeta(
|
|
5445
5712
|
(prev) => prev.map((f) => f.dbId === fade.dbId ? { ...f, meta: { ...f.meta, sliderPos: pos } } : f)
|
|
@@ -5469,8 +5736,8 @@ function useTransitionOps({
|
|
|
5469
5736
|
},
|
|
5470
5737
|
[host, activeSceneId, applyFadeAutomation, setFadesMeta]
|
|
5471
5738
|
);
|
|
5472
|
-
const lastResyncKeyRef =
|
|
5473
|
-
|
|
5739
|
+
const lastResyncKeyRef = useRef17("");
|
|
5740
|
+
useEffect16(() => {
|
|
5474
5741
|
if (!host.getTrackSound || resolvedCrossfadePairs.length === 0 && resolvedFades.length === 0) {
|
|
5475
5742
|
return;
|
|
5476
5743
|
}
|
|
@@ -5511,7 +5778,7 @@ function useTransitionOps({
|
|
|
5511
5778
|
cancelled = true;
|
|
5512
5779
|
};
|
|
5513
5780
|
}, [resolvedCrossfadePairs, resolvedFades, host, adapter]);
|
|
5514
|
-
|
|
5781
|
+
useEffect16(() => {
|
|
5515
5782
|
if (!host.setTrackVolumeAutomation || resolvedFades.length === 0) return;
|
|
5516
5783
|
void (async () => {
|
|
5517
5784
|
const mc = await host.getMusicalContext();
|
|
@@ -5545,7 +5812,7 @@ function useTransitionOps({
|
|
|
5545
5812
|
}
|
|
5546
5813
|
|
|
5547
5814
|
// src/panel-core/useGeneratorPanelCore.tsx
|
|
5548
|
-
import { jsx as
|
|
5815
|
+
import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5549
5816
|
var EMPTY_PLACEHOLDERS = [];
|
|
5550
5817
|
function useGeneratorPanelCore({
|
|
5551
5818
|
ui,
|
|
@@ -5565,8 +5832,8 @@ function useGeneratorPanelCore({
|
|
|
5565
5832
|
} = ui;
|
|
5566
5833
|
const { identity, features } = adapter;
|
|
5567
5834
|
const logTag = identity.logTag;
|
|
5568
|
-
const adapterRef =
|
|
5569
|
-
|
|
5835
|
+
const adapterRef = useRef18(adapter);
|
|
5836
|
+
useEffect17(() => {
|
|
5570
5837
|
if (adapterRef.current !== adapter) {
|
|
5571
5838
|
adapterRef.current = adapter;
|
|
5572
5839
|
console.warn(
|
|
@@ -5576,27 +5843,27 @@ function useGeneratorPanelCore({
|
|
|
5576
5843
|
}, [adapter, logTag]);
|
|
5577
5844
|
const supportsMeters = typeof host.getTrackLevels === "function";
|
|
5578
5845
|
const trackLevels = useTrackLevels(host, isExpanded);
|
|
5579
|
-
const [tracks, setTracks] =
|
|
5580
|
-
const [isLoadingTracks, setIsLoadingTracks] =
|
|
5581
|
-
const [importOpen, setImportOpen] =
|
|
5582
|
-
const [soundImportTarget, setSoundImportTarget] =
|
|
5583
|
-
const [designerView, setDesignerView] =
|
|
5584
|
-
const [transitionSourceTotal, setTransitionSourceTotal] =
|
|
5585
|
-
const [crossfadePairsMeta, setCrossfadePairsMeta] =
|
|
5586
|
-
const [fadesMeta, setFadesMeta] =
|
|
5587
|
-
const [genericGroupMetas, setGenericGroupMetas] =
|
|
5846
|
+
const [tracks, setTracks] = useState21([]);
|
|
5847
|
+
const [isLoadingTracks, setIsLoadingTracks] = useState21(false);
|
|
5848
|
+
const [importOpen, setImportOpen] = useState21(false);
|
|
5849
|
+
const [soundImportTarget, setSoundImportTarget] = useState21(null);
|
|
5850
|
+
const [designerView, setDesignerView] = useState21(false);
|
|
5851
|
+
const [transitionSourceTotal, setTransitionSourceTotal] = useState21(0);
|
|
5852
|
+
const [crossfadePairsMeta, setCrossfadePairsMeta] = useState21([]);
|
|
5853
|
+
const [fadesMeta, setFadesMeta] = useState21([]);
|
|
5854
|
+
const [genericGroupMetas, setGenericGroupMetas] = useState21({});
|
|
5588
5855
|
const [isComposing, , setIsComposingForScene] = useSceneState(activeSceneId, false);
|
|
5589
5856
|
const [placeholders, , setPlaceholdersForScene] = useSceneState(
|
|
5590
5857
|
activeSceneId,
|
|
5591
5858
|
EMPTY_PLACEHOLDERS
|
|
5592
5859
|
);
|
|
5593
|
-
const saveTimeoutRefs =
|
|
5594
|
-
const editLoadStartedRef =
|
|
5595
|
-
const [availableInstruments, setAvailableInstruments] =
|
|
5596
|
-
const [instrumentsLoading, setInstrumentsLoading] =
|
|
5597
|
-
const engineToDbIdRef =
|
|
5598
|
-
const tracksLoadedForSceneRef =
|
|
5599
|
-
const persistSoundHistory =
|
|
5860
|
+
const saveTimeoutRefs = useRef18({});
|
|
5861
|
+
const editLoadStartedRef = useRef18(/* @__PURE__ */ new Set());
|
|
5862
|
+
const [availableInstruments, setAvailableInstruments] = useState21([]);
|
|
5863
|
+
const [instrumentsLoading, setInstrumentsLoading] = useState21(false);
|
|
5864
|
+
const engineToDbIdRef = useRef18(/* @__PURE__ */ new Map());
|
|
5865
|
+
const tracksLoadedForSceneRef = useRef18(null);
|
|
5866
|
+
const persistSoundHistory = useCallback15(
|
|
5600
5867
|
(trackId, state) => {
|
|
5601
5868
|
if (!activeSceneId) return;
|
|
5602
5869
|
const dbId = engineToDbIdRef.current.get(trackId) ?? trackId;
|
|
@@ -5616,7 +5883,7 @@ function useGeneratorPanelCore({
|
|
|
5616
5883
|
setItems: setTracks,
|
|
5617
5884
|
getId: (t) => t.handle.dbId
|
|
5618
5885
|
});
|
|
5619
|
-
const loadTracks =
|
|
5886
|
+
const loadTracks = useCallback15(
|
|
5620
5887
|
async (incremental = false) => {
|
|
5621
5888
|
const sceneAtStart = activeSceneId;
|
|
5622
5889
|
if (!sceneAtStart) {
|
|
@@ -5741,18 +6008,18 @@ function useGeneratorPanelCore({
|
|
|
5741
6008
|
},
|
|
5742
6009
|
[host, activeSceneId, soundHistory, adapter, logTag]
|
|
5743
6010
|
);
|
|
5744
|
-
|
|
6011
|
+
useEffect17(() => {
|
|
5745
6012
|
loadTracks();
|
|
5746
6013
|
}, [loadTracks]);
|
|
5747
|
-
|
|
6014
|
+
useEffect17(() => {
|
|
5748
6015
|
const map = /* @__PURE__ */ new Map();
|
|
5749
6016
|
for (const t of tracks) {
|
|
5750
6017
|
map.set(t.handle.id, t.handle.dbId);
|
|
5751
6018
|
}
|
|
5752
6019
|
engineToDbIdRef.current = map;
|
|
5753
6020
|
}, [tracks]);
|
|
5754
|
-
const loadedCompletedIdsRef =
|
|
5755
|
-
|
|
6021
|
+
const loadedCompletedIdsRef = useRef18(/* @__PURE__ */ new Set());
|
|
6022
|
+
useEffect17(() => {
|
|
5756
6023
|
if (placeholders.length === 0) {
|
|
5757
6024
|
loadedCompletedIdsRef.current.clear();
|
|
5758
6025
|
return;
|
|
@@ -5771,16 +6038,16 @@ function useGeneratorPanelCore({
|
|
|
5771
6038
|
loadTracks(true);
|
|
5772
6039
|
}
|
|
5773
6040
|
}, [placeholders, loadTracks, logTag]);
|
|
5774
|
-
const adoptAndLoad =
|
|
6041
|
+
const adoptAndLoad = useCallback15(() => {
|
|
5775
6042
|
loadTracks(true);
|
|
5776
6043
|
}, [loadTracks]);
|
|
5777
|
-
|
|
6044
|
+
useEffect17(() => {
|
|
5778
6045
|
const unsub = host.onEngineReady(() => {
|
|
5779
6046
|
adoptAndLoad();
|
|
5780
6047
|
});
|
|
5781
6048
|
return unsub;
|
|
5782
6049
|
}, [host, adoptAndLoad]);
|
|
5783
|
-
|
|
6050
|
+
useEffect17(() => {
|
|
5784
6051
|
if (typeof host.onAfterAgentMutation !== "function") return;
|
|
5785
6052
|
let timer = null;
|
|
5786
6053
|
const unsub = host.onAfterAgentMutation(() => {
|
|
@@ -5795,13 +6062,13 @@ function useGeneratorPanelCore({
|
|
|
5795
6062
|
if (timer) clearTimeout(timer);
|
|
5796
6063
|
};
|
|
5797
6064
|
}, [host, loadTracks]);
|
|
5798
|
-
|
|
6065
|
+
useEffect17(() => {
|
|
5799
6066
|
const unsub = host.onTrackStateChange((trackId, state) => {
|
|
5800
6067
|
setTracks((prev) => prev.map((t) => t.handle.id === trackId ? { ...t, runtimeState: state } : t));
|
|
5801
6068
|
});
|
|
5802
6069
|
return unsub;
|
|
5803
6070
|
}, [host]);
|
|
5804
|
-
|
|
6071
|
+
useEffect17(() => {
|
|
5805
6072
|
if (!features.bulkComposePlaceholders) return;
|
|
5806
6073
|
console.log(`[${logTag}] Subscribing to composeProgress`);
|
|
5807
6074
|
const unsub = host.onComposeProgress((event) => {
|
|
@@ -5835,7 +6102,7 @@ function useGeneratorPanelCore({
|
|
|
5835
6102
|
});
|
|
5836
6103
|
return unsub;
|
|
5837
6104
|
}, [host, setIsComposingForScene, setPlaceholdersForScene, features.bulkComposePlaceholders, logTag]);
|
|
5838
|
-
|
|
6105
|
+
useEffect17(() => {
|
|
5839
6106
|
const refs = saveTimeoutRefs;
|
|
5840
6107
|
return () => {
|
|
5841
6108
|
for (const timeout of Object.values(refs.current)) {
|
|
@@ -5843,9 +6110,9 @@ function useGeneratorPanelCore({
|
|
|
5843
6110
|
}
|
|
5844
6111
|
};
|
|
5845
6112
|
}, []);
|
|
5846
|
-
const isAddingTrackRef =
|
|
5847
|
-
const [isAddingTrack, setIsAddingTrack] =
|
|
5848
|
-
const handleAddTrack =
|
|
6113
|
+
const isAddingTrackRef = useRef18(false);
|
|
6114
|
+
const [isAddingTrack, setIsAddingTrack] = useState21(false);
|
|
6115
|
+
const handleAddTrack = useCallback15(async () => {
|
|
5849
6116
|
if (isAddingTrackRef.current) return;
|
|
5850
6117
|
if (!activeSceneId) {
|
|
5851
6118
|
host.showToast("warning", "Select SCENE");
|
|
@@ -5885,7 +6152,7 @@ function useGeneratorPanelCore({
|
|
|
5885
6152
|
setIsAddingTrack(false);
|
|
5886
6153
|
}
|
|
5887
6154
|
}, [host, adapter, identity, activeSceneId, isConnected, isAuthenticated, tracks.length, onExpandSelf]);
|
|
5888
|
-
const handlePortTrack =
|
|
6155
|
+
const handlePortTrack = useCallback15(
|
|
5889
6156
|
async (sel) => {
|
|
5890
6157
|
if (!activeSceneId) {
|
|
5891
6158
|
host.showToast("warning", "Select SCENE");
|
|
@@ -5942,7 +6209,7 @@ function useGeneratorPanelCore({
|
|
|
5942
6209
|
},
|
|
5943
6210
|
[host, adapter, identity, activeSceneId, isConnected, tracks.length, loadTracks]
|
|
5944
6211
|
);
|
|
5945
|
-
const handleSoundImportPick =
|
|
6212
|
+
const handleSoundImportPick = useCallback15(
|
|
5946
6213
|
async (sel) => {
|
|
5947
6214
|
const target = soundImportTarget;
|
|
5948
6215
|
if (!target || !host.getTrackSound) {
|
|
@@ -5973,8 +6240,8 @@ function useGeneratorPanelCore({
|
|
|
5973
6240
|
},
|
|
5974
6241
|
[soundImportTarget, host, adapter, identity.familyKey, soundHistory]
|
|
5975
6242
|
);
|
|
5976
|
-
const [isExportingMidi, setIsExportingMidi] =
|
|
5977
|
-
const handleExportMidi =
|
|
6243
|
+
const [isExportingMidi, setIsExportingMidi] = useState21(false);
|
|
6244
|
+
const handleExportMidi = useCallback15(async () => {
|
|
5978
6245
|
if (isExportingMidi) return;
|
|
5979
6246
|
setIsExportingMidi(true);
|
|
5980
6247
|
try {
|
|
@@ -6005,10 +6272,10 @@ function useGeneratorPanelCore({
|
|
|
6005
6272
|
const xfFromId = sceneContext?.transitionFromSceneId ?? null;
|
|
6006
6273
|
const xfToId = sceneContext?.transitionToSceneId ?? null;
|
|
6007
6274
|
const canCrossfade = features.transitionDesigner && sceneContext?.sceneType === "transition" && !!xfFromId && !!xfToId && !!host.listSceneFamilyTracks;
|
|
6008
|
-
|
|
6275
|
+
useEffect17(() => {
|
|
6009
6276
|
if (!canCrossfade) setDesignerView(false);
|
|
6010
6277
|
}, [canCrossfade]);
|
|
6011
|
-
|
|
6278
|
+
useEffect17(() => {
|
|
6012
6279
|
if (!canCrossfade || !xfFromId || !xfToId || !host.listSceneFamilyTracks) {
|
|
6013
6280
|
setTransitionSourceTotal(0);
|
|
6014
6281
|
return;
|
|
@@ -6024,12 +6291,12 @@ function useGeneratorPanelCore({
|
|
|
6024
6291
|
};
|
|
6025
6292
|
}, [canCrossfade, xfFromId, xfToId, host]);
|
|
6026
6293
|
const transitionDone = crossfadePairsMeta.length * 2 + fadesMeta.length;
|
|
6027
|
-
|
|
6294
|
+
useEffect17(() => {
|
|
6028
6295
|
if (!onHeaderContent) return;
|
|
6029
6296
|
const addDisabled = needsContract || !isConnected || !activeSceneId || tracks.length >= identity.maxTracks || isAddingTrack;
|
|
6030
6297
|
onHeaderContent(
|
|
6031
|
-
/* @__PURE__ */
|
|
6032
|
-
features.importTracks && (!canCrossfade || !designerView) && host.listImportableTracks && /* @__PURE__ */
|
|
6298
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex gap-1 items-center", children: [
|
|
6299
|
+
features.importTracks && (!canCrossfade || !designerView) && host.listImportableTracks && /* @__PURE__ */ jsx24(
|
|
6033
6300
|
"button",
|
|
6034
6301
|
{
|
|
6035
6302
|
"data-testid": `import-from-scene-${identity.familyKey}-button`,
|
|
@@ -6043,7 +6310,7 @@ function useGeneratorPanelCore({
|
|
|
6043
6310
|
children: identity.importTrackLabel ?? "Import Track"
|
|
6044
6311
|
}
|
|
6045
6312
|
),
|
|
6046
|
-
(!canCrossfade || !designerView) && /* @__PURE__ */
|
|
6313
|
+
(!canCrossfade || !designerView) && /* @__PURE__ */ jsx24(
|
|
6047
6314
|
"button",
|
|
6048
6315
|
{
|
|
6049
6316
|
"data-testid": `add-${identity.familyKey}-track-button`,
|
|
@@ -6059,7 +6326,7 @@ function useGeneratorPanelCore({
|
|
|
6059
6326
|
children: identity.addTrackLabel ?? "Add Track"
|
|
6060
6327
|
}
|
|
6061
6328
|
),
|
|
6062
|
-
canCrossfade && /* @__PURE__ */
|
|
6329
|
+
canCrossfade && /* @__PURE__ */ jsxs18(
|
|
6063
6330
|
"button",
|
|
6064
6331
|
{
|
|
6065
6332
|
"data-testid": `${identity.familyKey}-view-toggle`,
|
|
@@ -6078,7 +6345,7 @@ function useGeneratorPanelCore({
|
|
|
6078
6345
|
title: designerView ? "Back to the track list" : "Open the transition designer",
|
|
6079
6346
|
className: "relative overflow-hidden px-2 py-0.5 text-[10px] font-medium rounded-sm border border-sas-accent/40 text-sas-accent transition-colors hover:border-sas-accent disabled:opacity-50",
|
|
6080
6347
|
children: [
|
|
6081
|
-
transitionSourceTotal > 0 && /* @__PURE__ */
|
|
6348
|
+
transitionSourceTotal > 0 && /* @__PURE__ */ jsx24(
|
|
6082
6349
|
"span",
|
|
6083
6350
|
{
|
|
6084
6351
|
className: "absolute inset-y-0 left-0 bg-sas-accent/25",
|
|
@@ -6086,7 +6353,7 @@ function useGeneratorPanelCore({
|
|
|
6086
6353
|
"aria-hidden": true
|
|
6087
6354
|
}
|
|
6088
6355
|
),
|
|
6089
|
-
/* @__PURE__ */
|
|
6356
|
+
/* @__PURE__ */ jsxs18("span", { className: "relative", children: [
|
|
6090
6357
|
"\u21C4 ",
|
|
6091
6358
|
designerView ? "Transition" : "Tracks",
|
|
6092
6359
|
transitionSourceTotal > 0 ? ` ${transitionDone}/${transitionSourceTotal}` : ""
|
|
@@ -6117,7 +6384,7 @@ function useGeneratorPanelCore({
|
|
|
6117
6384
|
identity,
|
|
6118
6385
|
features.importTracks
|
|
6119
6386
|
]);
|
|
6120
|
-
|
|
6387
|
+
useEffect17(() => {
|
|
6121
6388
|
if (!onLoading) return;
|
|
6122
6389
|
const anyGenerating = tracks.some((t) => t.isGenerating);
|
|
6123
6390
|
onLoading(isLoadingTracks || anyGenerating || isBulkActive);
|
|
@@ -6125,7 +6392,7 @@ function useGeneratorPanelCore({
|
|
|
6125
6392
|
onLoading(false);
|
|
6126
6393
|
};
|
|
6127
6394
|
}, [onLoading, isLoadingTracks, tracks, isBulkActive]);
|
|
6128
|
-
const handleDeleteTrack =
|
|
6395
|
+
const handleDeleteTrack = useCallback15(
|
|
6129
6396
|
async (trackId) => {
|
|
6130
6397
|
try {
|
|
6131
6398
|
await host.deleteTrack(trackId);
|
|
@@ -6141,7 +6408,7 @@ function useGeneratorPanelCore({
|
|
|
6141
6408
|
},
|
|
6142
6409
|
[host, activeSceneId]
|
|
6143
6410
|
);
|
|
6144
|
-
const handlePromptChange =
|
|
6411
|
+
const handlePromptChange = useCallback15(
|
|
6145
6412
|
(trackId, prompt) => {
|
|
6146
6413
|
setTracks((prev) => prev.map((t) => t.handle.id === trackId ? { ...t, prompt } : t));
|
|
6147
6414
|
const dbId = engineToDbIdRef.current.get(trackId) ?? trackId;
|
|
@@ -6157,7 +6424,7 @@ function useGeneratorPanelCore({
|
|
|
6157
6424
|
},
|
|
6158
6425
|
[host, activeSceneId]
|
|
6159
6426
|
);
|
|
6160
|
-
const resolvedGenericGroups =
|
|
6427
|
+
const resolvedGenericGroups = useMemo9(() => {
|
|
6161
6428
|
const out = {};
|
|
6162
6429
|
for (const ext of adapter.groupExtensions ?? []) {
|
|
6163
6430
|
out[ext.metaKey] = resolveTrackGroups(
|
|
@@ -6171,18 +6438,18 @@ function useGeneratorPanelCore({
|
|
|
6171
6438
|
}
|
|
6172
6439
|
return out;
|
|
6173
6440
|
}, [adapter, genericGroupMetas, tracks]);
|
|
6174
|
-
const genericGroupMemberDbIds =
|
|
6441
|
+
const genericGroupMemberDbIds = useMemo9(() => {
|
|
6175
6442
|
const s = /* @__PURE__ */ new Set();
|
|
6176
6443
|
for (const r of Object.values(resolvedGenericGroups)) {
|
|
6177
6444
|
for (const dbId of r.memberDbIds) s.add(dbId);
|
|
6178
6445
|
}
|
|
6179
6446
|
return s;
|
|
6180
6447
|
}, [resolvedGenericGroups]);
|
|
6181
|
-
const engineToDbId =
|
|
6448
|
+
const engineToDbId = useCallback15(
|
|
6182
6449
|
(trackId) => engineToDbIdRef.current.get(trackId) ?? trackId,
|
|
6183
6450
|
[]
|
|
6184
6451
|
);
|
|
6185
|
-
const updateTrack =
|
|
6452
|
+
const updateTrack = useCallback15(
|
|
6186
6453
|
(trackId, patch) => {
|
|
6187
6454
|
setTracks(
|
|
6188
6455
|
(prev) => prev.map(
|
|
@@ -6192,18 +6459,18 @@ function useGeneratorPanelCore({
|
|
|
6192
6459
|
},
|
|
6193
6460
|
[]
|
|
6194
6461
|
);
|
|
6195
|
-
const markEditLoaded =
|
|
6462
|
+
const markEditLoaded = useCallback15((trackId) => {
|
|
6196
6463
|
editLoadStartedRef.current.add(trackId);
|
|
6197
6464
|
}, []);
|
|
6198
|
-
const tracksRef =
|
|
6199
|
-
|
|
6465
|
+
const tracksRef = useRef18(tracks);
|
|
6466
|
+
useEffect17(() => {
|
|
6200
6467
|
tracksRef.current = tracks;
|
|
6201
6468
|
}, [tracks]);
|
|
6202
|
-
const resolvedGenericGroupsRef =
|
|
6203
|
-
|
|
6469
|
+
const resolvedGenericGroupsRef = useRef18(resolvedGenericGroups);
|
|
6470
|
+
useEffect17(() => {
|
|
6204
6471
|
resolvedGenericGroupsRef.current = resolvedGenericGroups;
|
|
6205
6472
|
}, [resolvedGenericGroups]);
|
|
6206
|
-
const makeServices =
|
|
6473
|
+
const makeServices = useCallback15(() => {
|
|
6207
6474
|
return {
|
|
6208
6475
|
host,
|
|
6209
6476
|
activeSceneId,
|
|
@@ -6222,7 +6489,7 @@ function useGeneratorPanelCore({
|
|
|
6222
6489
|
resolvedGroups: (metaKey) => resolvedGenericGroupsRef.current[metaKey]?.resolved ?? []
|
|
6223
6490
|
};
|
|
6224
6491
|
}, [host, activeSceneId, updateTrack, loadTracks, soundHistory, engineToDbId, markEditLoaded, identity, adapter]);
|
|
6225
|
-
const handleGenerate =
|
|
6492
|
+
const handleGenerate = useCallback15(
|
|
6226
6493
|
async (trackId) => {
|
|
6227
6494
|
const track = tracks.find((t) => t.handle.id === trackId);
|
|
6228
6495
|
if (!track || !track.prompt.trim()) return;
|
|
@@ -6249,7 +6516,7 @@ function useGeneratorPanelCore({
|
|
|
6249
6516
|
},
|
|
6250
6517
|
[host, adapter, tracks, isAuthenticated, makeServices]
|
|
6251
6518
|
);
|
|
6252
|
-
const handleMuteToggle =
|
|
6519
|
+
const handleMuteToggle = useCallback15(
|
|
6253
6520
|
(trackId) => {
|
|
6254
6521
|
const track = tracks.find((t) => t.handle.id === trackId);
|
|
6255
6522
|
if (!track) return;
|
|
@@ -6269,7 +6536,7 @@ function useGeneratorPanelCore({
|
|
|
6269
6536
|
},
|
|
6270
6537
|
[host, tracks]
|
|
6271
6538
|
);
|
|
6272
|
-
const handleSoloToggle =
|
|
6539
|
+
const handleSoloToggle = useCallback15(
|
|
6273
6540
|
(trackId) => {
|
|
6274
6541
|
const track = tracks.find((t) => t.handle.id === trackId);
|
|
6275
6542
|
if (!track) return;
|
|
@@ -6289,7 +6556,7 @@ function useGeneratorPanelCore({
|
|
|
6289
6556
|
},
|
|
6290
6557
|
[host, tracks]
|
|
6291
6558
|
);
|
|
6292
|
-
const handleVolumeChange =
|
|
6559
|
+
const handleVolumeChange = useCallback15(
|
|
6293
6560
|
(trackId, volume) => {
|
|
6294
6561
|
setTracks(
|
|
6295
6562
|
(prev) => prev.map((t) => t.handle.id === trackId ? { ...t, runtimeState: { ...t.runtimeState, volume } } : t)
|
|
@@ -6299,7 +6566,7 @@ function useGeneratorPanelCore({
|
|
|
6299
6566
|
},
|
|
6300
6567
|
[host]
|
|
6301
6568
|
);
|
|
6302
|
-
const handlePanChange =
|
|
6569
|
+
const handlePanChange = useCallback15(
|
|
6303
6570
|
(trackId, pan) => {
|
|
6304
6571
|
setTracks(
|
|
6305
6572
|
(prev) => prev.map((t) => t.handle.id === trackId ? { ...t, runtimeState: { ...t.runtimeState, pan } } : t)
|
|
@@ -6309,7 +6576,7 @@ function useGeneratorPanelCore({
|
|
|
6309
6576
|
},
|
|
6310
6577
|
[host]
|
|
6311
6578
|
);
|
|
6312
|
-
const handleShuffle =
|
|
6579
|
+
const handleShuffle = useCallback15(
|
|
6313
6580
|
async (trackId) => {
|
|
6314
6581
|
const track = tracks.find((t) => t.handle.id === trackId);
|
|
6315
6582
|
if (!track) return;
|
|
@@ -6351,7 +6618,7 @@ function useGeneratorPanelCore({
|
|
|
6351
6618
|
},
|
|
6352
6619
|
[host, adapter, tracks, soundHistory, logTag]
|
|
6353
6620
|
);
|
|
6354
|
-
const handleCopy =
|
|
6621
|
+
const handleCopy = useCallback15(
|
|
6355
6622
|
async (trackId) => {
|
|
6356
6623
|
try {
|
|
6357
6624
|
const newHandle = await host.duplicateTrack(trackId);
|
|
@@ -6364,7 +6631,7 @@ function useGeneratorPanelCore({
|
|
|
6364
6631
|
},
|
|
6365
6632
|
[host, loadTracks]
|
|
6366
6633
|
);
|
|
6367
|
-
const handleFxToggle =
|
|
6634
|
+
const handleFxToggle = useCallback15(
|
|
6368
6635
|
(trackId, category, enabled) => {
|
|
6369
6636
|
setTracks(
|
|
6370
6637
|
(prev) => prev.map(
|
|
@@ -6387,7 +6654,7 @@ function useGeneratorPanelCore({
|
|
|
6387
6654
|
},
|
|
6388
6655
|
[host]
|
|
6389
6656
|
);
|
|
6390
|
-
const handleFxPresetChange =
|
|
6657
|
+
const handleFxPresetChange = useCallback15(
|
|
6391
6658
|
(trackId, category, presetIndex) => {
|
|
6392
6659
|
setTracks(
|
|
6393
6660
|
(prev) => prev.map(
|
|
@@ -6413,7 +6680,7 @@ function useGeneratorPanelCore({
|
|
|
6413
6680
|
},
|
|
6414
6681
|
[host]
|
|
6415
6682
|
);
|
|
6416
|
-
const handleFxDryWetChange =
|
|
6683
|
+
const handleFxDryWetChange = useCallback15(
|
|
6417
6684
|
(trackId, category, value) => {
|
|
6418
6685
|
setTracks(
|
|
6419
6686
|
(prev) => prev.map(
|
|
@@ -6425,7 +6692,7 @@ function useGeneratorPanelCore({
|
|
|
6425
6692
|
},
|
|
6426
6693
|
[host]
|
|
6427
6694
|
);
|
|
6428
|
-
const toggleFxDrawer =
|
|
6695
|
+
const toggleFxDrawer = useCallback15(
|
|
6429
6696
|
(trackId) => {
|
|
6430
6697
|
setTracks(
|
|
6431
6698
|
(prev) => prev.map((t) => {
|
|
@@ -6447,7 +6714,7 @@ function useGeneratorPanelCore({
|
|
|
6447
6714
|
},
|
|
6448
6715
|
[host, tracks]
|
|
6449
6716
|
);
|
|
6450
|
-
const loadEditNotes =
|
|
6717
|
+
const loadEditNotes = useCallback15(
|
|
6451
6718
|
async (trackId) => {
|
|
6452
6719
|
try {
|
|
6453
6720
|
const mc = await host.getMusicalContext();
|
|
@@ -6465,7 +6732,7 @@ function useGeneratorPanelCore({
|
|
|
6465
6732
|
},
|
|
6466
6733
|
[host, logTag]
|
|
6467
6734
|
);
|
|
6468
|
-
const handleNotesChange =
|
|
6735
|
+
const handleNotesChange = useCallback15(
|
|
6469
6736
|
(trackId, notes) => {
|
|
6470
6737
|
setTracks((prev) => prev.map((t) => t.handle.id === trackId ? { ...t, editNotes: notes } : t));
|
|
6471
6738
|
const key = `edit:${trackId}`;
|
|
@@ -6495,7 +6762,7 @@ function useGeneratorPanelCore({
|
|
|
6495
6762
|
},
|
|
6496
6763
|
[host]
|
|
6497
6764
|
);
|
|
6498
|
-
const handleTabChange =
|
|
6765
|
+
const handleTabChange = useCallback15(
|
|
6499
6766
|
(trackId, tab) => {
|
|
6500
6767
|
setTracks((prev) => prev.map((t) => t.handle.id === trackId ? { ...t, drawerOpen: true, drawerTab: tab } : t));
|
|
6501
6768
|
if (tab === "fx") {
|
|
@@ -6520,10 +6787,10 @@ function useGeneratorPanelCore({
|
|
|
6520
6787
|
},
|
|
6521
6788
|
[host, availableInstruments.length, instrumentsLoading, loadEditNotes]
|
|
6522
6789
|
);
|
|
6523
|
-
const handleProgressChange =
|
|
6790
|
+
const handleProgressChange = useCallback15((trackId, pct) => {
|
|
6524
6791
|
setTracks((prev) => prev.map((t) => t.handle.id === trackId ? { ...t, generationProgress: pct } : t));
|
|
6525
6792
|
}, []);
|
|
6526
|
-
const handleToggleDrawer =
|
|
6793
|
+
const handleToggleDrawer = useCallback15((trackId) => {
|
|
6527
6794
|
setTracks(
|
|
6528
6795
|
(prev) => prev.map((t) => {
|
|
6529
6796
|
if (t.handle.id !== trackId) return t;
|
|
@@ -6532,7 +6799,7 @@ function useGeneratorPanelCore({
|
|
|
6532
6799
|
})
|
|
6533
6800
|
);
|
|
6534
6801
|
}, []);
|
|
6535
|
-
const handleInstrumentSelect =
|
|
6802
|
+
const handleInstrumentSelect = useCallback15(
|
|
6536
6803
|
async (trackId, pluginId) => {
|
|
6537
6804
|
const isDefaultInstrument = pluginId === (identity.defaultInstrumentPluginId ?? "Surge XT");
|
|
6538
6805
|
if (isDefaultInstrument) {
|
|
@@ -6585,7 +6852,7 @@ function useGeneratorPanelCore({
|
|
|
6585
6852
|
},
|
|
6586
6853
|
[host, identity.defaultInstrumentPluginId, logTag]
|
|
6587
6854
|
);
|
|
6588
|
-
const handleShowEditor =
|
|
6855
|
+
const handleShowEditor = useCallback15(
|
|
6589
6856
|
async (trackId) => {
|
|
6590
6857
|
try {
|
|
6591
6858
|
await host.showInstrumentEditor(trackId);
|
|
@@ -6596,12 +6863,12 @@ function useGeneratorPanelCore({
|
|
|
6596
6863
|
},
|
|
6597
6864
|
[host]
|
|
6598
6865
|
);
|
|
6599
|
-
const handleBackToInstruments =
|
|
6866
|
+
const handleBackToInstruments = useCallback15((trackId) => {
|
|
6600
6867
|
setTracks(
|
|
6601
6868
|
(prev) => prev.map((t) => t.handle.id === trackId ? { ...t, editorStage: false } : t)
|
|
6602
6869
|
);
|
|
6603
6870
|
}, []);
|
|
6604
|
-
const handleRefreshInstruments =
|
|
6871
|
+
const handleRefreshInstruments = useCallback15(() => {
|
|
6605
6872
|
setInstrumentsLoading(true);
|
|
6606
6873
|
host.getAvailableInstruments().then((instruments) => {
|
|
6607
6874
|
setAvailableInstruments(instruments);
|
|
@@ -6610,13 +6877,13 @@ function useGeneratorPanelCore({
|
|
|
6610
6877
|
setInstrumentsLoading(false);
|
|
6611
6878
|
});
|
|
6612
6879
|
}, [host]);
|
|
6613
|
-
const onAuditionNote =
|
|
6880
|
+
const onAuditionNote = useCallback15(
|
|
6614
6881
|
(trackId, pitch, velocity, ms) => {
|
|
6615
6882
|
void host.auditionNote(trackId, pitch, velocity, ms);
|
|
6616
6883
|
},
|
|
6617
6884
|
[host]
|
|
6618
6885
|
);
|
|
6619
|
-
const { resolvedCrossfadePairs, crossfadeMemberDbIds } =
|
|
6886
|
+
const { resolvedCrossfadePairs, crossfadeMemberDbIds } = useMemo9(() => {
|
|
6620
6887
|
const byDbId = new Map(tracks.map((t) => [t.handle.dbId, t]));
|
|
6621
6888
|
const pairs = [];
|
|
6622
6889
|
const members = /* @__PURE__ */ new Set();
|
|
@@ -6631,7 +6898,7 @@ function useGeneratorPanelCore({
|
|
|
6631
6898
|
}
|
|
6632
6899
|
return { resolvedCrossfadePairs: pairs, crossfadeMemberDbIds: members };
|
|
6633
6900
|
}, [tracks, crossfadePairsMeta]);
|
|
6634
|
-
const { resolvedFades, fadeMemberDbIds } =
|
|
6901
|
+
const { resolvedFades, fadeMemberDbIds } = useMemo9(() => {
|
|
6635
6902
|
const byDbId = new Map(tracks.map((t) => [t.handle.dbId, t]));
|
|
6636
6903
|
const list = [];
|
|
6637
6904
|
const members = /* @__PURE__ */ new Set();
|
|
@@ -6659,7 +6926,7 @@ function useGeneratorPanelCore({
|
|
|
6659
6926
|
resolvedCrossfadePairs,
|
|
6660
6927
|
resolvedFades
|
|
6661
6928
|
});
|
|
6662
|
-
const setGroupMute =
|
|
6929
|
+
const setGroupMute = useCallback15(
|
|
6663
6930
|
(trackIds, muted) => {
|
|
6664
6931
|
for (const id of trackIds) {
|
|
6665
6932
|
setTracks(
|
|
@@ -6671,7 +6938,7 @@ function useGeneratorPanelCore({
|
|
|
6671
6938
|
},
|
|
6672
6939
|
[host]
|
|
6673
6940
|
);
|
|
6674
|
-
const setGroupSolo =
|
|
6941
|
+
const setGroupSolo = useCallback15(
|
|
6675
6942
|
(trackIds, solo) => {
|
|
6676
6943
|
for (const id of trackIds) {
|
|
6677
6944
|
setTracks(
|
|
@@ -6683,7 +6950,7 @@ function useGeneratorPanelCore({
|
|
|
6683
6950
|
},
|
|
6684
6951
|
[host]
|
|
6685
6952
|
);
|
|
6686
|
-
const deleteGroup =
|
|
6953
|
+
const deleteGroup = useCallback15(
|
|
6687
6954
|
async (members, cleanupKeySuffixes) => {
|
|
6688
6955
|
for (const member of members) {
|
|
6689
6956
|
try {
|
|
@@ -6703,7 +6970,7 @@ function useGeneratorPanelCore({
|
|
|
6703
6970
|
},
|
|
6704
6971
|
[host, activeSceneId, loadTracks]
|
|
6705
6972
|
);
|
|
6706
|
-
const handlers =
|
|
6973
|
+
const handlers = useMemo9(
|
|
6707
6974
|
() => ({
|
|
6708
6975
|
promptChange: handlePromptChange,
|
|
6709
6976
|
generate: (trackId) => {
|
|
@@ -6817,8 +7084,8 @@ function useGeneratorPanelCore({
|
|
|
6817
7084
|
}
|
|
6818
7085
|
|
|
6819
7086
|
// src/panel-core/GeneratorPanelShell.tsx
|
|
6820
|
-
import
|
|
6821
|
-
import { Fragment as Fragment6, jsx as
|
|
7087
|
+
import React21, { useCallback as useCallback16 } from "react";
|
|
7088
|
+
import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
6822
7089
|
function GeneratorPanelShell({ core, slots }) {
|
|
6823
7090
|
const {
|
|
6824
7091
|
ui,
|
|
@@ -6871,8 +7138,9 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
6871
7138
|
deleteGroup
|
|
6872
7139
|
} = core;
|
|
6873
7140
|
const { host, activeSceneId, isAuthenticated, sceneContext, onSelectScene, onOpenContract } = ui;
|
|
7141
|
+
const panelBus = usePanelBus(host, activeSceneId);
|
|
6874
7142
|
const { identity, features } = adapter;
|
|
6875
|
-
const buildRowProps =
|
|
7143
|
+
const buildRowProps = useCallback16(
|
|
6876
7144
|
(track, drag) => {
|
|
6877
7145
|
const id = track.handle.id;
|
|
6878
7146
|
const pickerProps = features.instrumentPicker ? {
|
|
@@ -6971,12 +7239,12 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
6971
7239
|
]
|
|
6972
7240
|
);
|
|
6973
7241
|
if (!activeSceneId) {
|
|
6974
|
-
return /* @__PURE__ */
|
|
7242
|
+
return /* @__PURE__ */ jsx25(
|
|
6975
7243
|
"div",
|
|
6976
7244
|
{
|
|
6977
7245
|
"data-testid": `no-scene-placeholder-${identity.familyKey}`,
|
|
6978
7246
|
className: "flex items-center justify-center py-8",
|
|
6979
|
-
children: /* @__PURE__ */
|
|
7247
|
+
children: /* @__PURE__ */ jsx25(
|
|
6980
7248
|
"button",
|
|
6981
7249
|
{
|
|
6982
7250
|
onClick: () => onSelectScene?.(),
|
|
@@ -6988,12 +7256,12 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
6988
7256
|
);
|
|
6989
7257
|
}
|
|
6990
7258
|
if (!sceneContext?.hasContract) {
|
|
6991
|
-
return /* @__PURE__ */
|
|
7259
|
+
return /* @__PURE__ */ jsx25(
|
|
6992
7260
|
"div",
|
|
6993
7261
|
{
|
|
6994
7262
|
"data-testid": `no-contract-placeholder-${identity.familyKey}`,
|
|
6995
7263
|
className: "flex items-center justify-center py-8",
|
|
6996
|
-
children: /* @__PURE__ */
|
|
7264
|
+
children: /* @__PURE__ */ jsx25(
|
|
6997
7265
|
"button",
|
|
6998
7266
|
{
|
|
6999
7267
|
onClick: () => onOpenContract?.(),
|
|
@@ -7005,7 +7273,7 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
7005
7273
|
);
|
|
7006
7274
|
}
|
|
7007
7275
|
if (features.bulkComposePlaceholders && isComposing) {
|
|
7008
|
-
return /* @__PURE__ */
|
|
7276
|
+
return /* @__PURE__ */ jsx25("div", { "data-testid": `${identity.familyKey}-section`, className: "p-2", children: /* @__PURE__ */ jsx25(SorceryProgressBar, { isLoading: true, statusText: "COMPOSING...", heightClass: "h-10" }) });
|
|
7009
7277
|
}
|
|
7010
7278
|
const activePlaceholders = features.bulkComposePlaceholders ? placeholders : [];
|
|
7011
7279
|
if (activePlaceholders.length > 0) {
|
|
@@ -7016,18 +7284,18 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
7016
7284
|
tracksByDbId.set(t.handle.id, t);
|
|
7017
7285
|
}
|
|
7018
7286
|
}
|
|
7019
|
-
return /* @__PURE__ */
|
|
7287
|
+
return /* @__PURE__ */ jsx25("div", { "data-testid": `${identity.familyKey}-section`, className: "p-2 space-y-2", children: activePlaceholders.map((ph) => {
|
|
7020
7288
|
const loadedTrack = ph.status === "completed" ? tracksByDbId.get(ph.id) : void 0;
|
|
7021
7289
|
if (loadedTrack) {
|
|
7022
|
-
return /* @__PURE__ */
|
|
7290
|
+
return /* @__PURE__ */ jsx25(TrackRow, { ...buildRowProps(loadedTrack) }, ph.id);
|
|
7023
7291
|
}
|
|
7024
|
-
return /* @__PURE__ */
|
|
7292
|
+
return /* @__PURE__ */ jsx25(
|
|
7025
7293
|
"div",
|
|
7026
7294
|
{
|
|
7027
7295
|
"data-testid": "bulk-placeholder-track",
|
|
7028
7296
|
className: "relative rounded-sm border w-full overflow-hidden border-sas-border bg-sas-panel-alt",
|
|
7029
7297
|
style: { borderLeftColor: identity.placeholderAccentColor, borderLeftWidth: "3px" },
|
|
7030
|
-
children: /* @__PURE__ */
|
|
7298
|
+
children: /* @__PURE__ */ jsx25(SorceryProgressBar, { isLoading: true, statusText: "CONJURING MIDI...", heightClass: "h-10" })
|
|
7031
7299
|
},
|
|
7032
7300
|
ph.id
|
|
7033
7301
|
);
|
|
@@ -7039,13 +7307,13 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
7039
7307
|
supportsMeters,
|
|
7040
7308
|
levels: supportsMeters ? trackLevels : void 0,
|
|
7041
7309
|
handlers,
|
|
7042
|
-
renderDefaultTrackRow: (track, overrides, drag) => /* @__PURE__ */
|
|
7310
|
+
renderDefaultTrackRow: (track, overrides, drag) => /* @__PURE__ */ jsx25(TrackRow, { ...{ ...buildRowProps(track, drag), ...overrides ?? {} } }, track.handle.id),
|
|
7043
7311
|
setGroupMute,
|
|
7044
7312
|
setGroupSolo,
|
|
7045
7313
|
deleteGroup
|
|
7046
7314
|
};
|
|
7047
|
-
return /* @__PURE__ */
|
|
7048
|
-
features.importTracks && host.listImportableTracks && /* @__PURE__ */
|
|
7315
|
+
return /* @__PURE__ */ jsxs19("div", { "data-testid": `${identity.familyKey}-section`, className: "p-2 space-y-2", children: [
|
|
7316
|
+
features.importTracks && host.listImportableTracks && /* @__PURE__ */ jsx25(
|
|
7049
7317
|
ImportTrackModal,
|
|
7050
7318
|
{
|
|
7051
7319
|
host,
|
|
@@ -7058,7 +7326,7 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
7058
7326
|
testIdPrefix: `${identity.familyKey}-import`
|
|
7059
7327
|
}
|
|
7060
7328
|
),
|
|
7061
|
-
features.importTracks && host.listImportableTracks && host.getTrackSound && /* @__PURE__ */
|
|
7329
|
+
features.importTracks && host.listImportableTracks && host.getTrackSound && /* @__PURE__ */ jsx25(
|
|
7062
7330
|
ImportTrackModal,
|
|
7063
7331
|
{
|
|
7064
7332
|
host,
|
|
@@ -7073,7 +7341,7 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
7073
7341
|
}
|
|
7074
7342
|
),
|
|
7075
7343
|
slots?.modals,
|
|
7076
|
-
canCrossfade && xfFromId && xfToId && /* @__PURE__ */
|
|
7344
|
+
canCrossfade && xfFromId && xfToId && /* @__PURE__ */ jsx25("div", { className: designerView ? "contents" : "hidden", children: /* @__PURE__ */ jsx25(
|
|
7077
7345
|
TransitionDesigner,
|
|
7078
7346
|
{
|
|
7079
7347
|
host,
|
|
@@ -7090,9 +7358,28 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
7090
7358
|
testIdPrefix: `${identity.familyKey}-transition-designer`
|
|
7091
7359
|
}
|
|
7092
7360
|
) }),
|
|
7093
|
-
!(designerView && canCrossfade) && (isLoadingTracks ? /* @__PURE__ */
|
|
7361
|
+
!(designerView && canCrossfade) && (isLoadingTracks ? /* @__PURE__ */ jsx25("div", { className: "text-sas-muted text-xs text-center py-4", children: "Loading tracks..." }) : /* @__PURE__ */ jsxs19(Fragment6, { children: [
|
|
7362
|
+
panelBus.supported && panelBus.bus && /* @__PURE__ */ jsx25(
|
|
7363
|
+
PanelMasterStrip,
|
|
7364
|
+
{
|
|
7365
|
+
bus: panelBus.bus,
|
|
7366
|
+
availableFx: panelBus.availableFx,
|
|
7367
|
+
fxLoading: panelBus.fxLoading,
|
|
7368
|
+
soloedOut: anySolo && !panelBus.bus.soloed,
|
|
7369
|
+
fxPickerOpen: panelBus.fxPickerOpen,
|
|
7370
|
+
onToggleFxPicker: panelBus.setFxPickerOpen,
|
|
7371
|
+
onRefreshFx: panelBus.refreshFx,
|
|
7372
|
+
onVolumeChange: panelBus.onVolumeChange,
|
|
7373
|
+
onMuteToggle: panelBus.onMuteToggle,
|
|
7374
|
+
onSoloToggle: panelBus.onSoloToggle,
|
|
7375
|
+
onAddFx: panelBus.onAddFx,
|
|
7376
|
+
onRemoveFx: panelBus.onRemoveFx,
|
|
7377
|
+
onToggleFxEnabled: panelBus.onToggleFxEnabled,
|
|
7378
|
+
onShowFxEditor: panelBus.onShowFxEditor
|
|
7379
|
+
}
|
|
7380
|
+
),
|
|
7094
7381
|
slots?.beforeRows,
|
|
7095
|
-
resolvedCrossfadePairs.map((pair) => /* @__PURE__ */
|
|
7382
|
+
resolvedCrossfadePairs.map((pair) => /* @__PURE__ */ jsx25(
|
|
7096
7383
|
CrossfadeTrackRow,
|
|
7097
7384
|
{
|
|
7098
7385
|
accentColor: identity.transitionAccentColor,
|
|
@@ -7129,7 +7416,7 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
7129
7416
|
},
|
|
7130
7417
|
pair.groupId
|
|
7131
7418
|
)),
|
|
7132
|
-
resolvedFades.map((fade) => /* @__PURE__ */
|
|
7419
|
+
resolvedFades.map((fade) => /* @__PURE__ */ jsx25(
|
|
7133
7420
|
FadeTrackRow,
|
|
7134
7421
|
{
|
|
7135
7422
|
accentColor: identity.transitionAccentColor,
|
|
@@ -7155,20 +7442,20 @@ function GeneratorPanelShell({ core, slots }) {
|
|
|
7155
7442
|
fade.dbId
|
|
7156
7443
|
)),
|
|
7157
7444
|
(adapter.groupExtensions ?? []).flatMap(
|
|
7158
|
-
(ext) => (resolvedGenericGroups[ext.metaKey]?.resolved ?? []).map((group) => /* @__PURE__ */
|
|
7445
|
+
(ext) => (resolvedGenericGroups[ext.metaKey]?.resolved ?? []).map((group) => /* @__PURE__ */ jsx25(React21.Fragment, { children: ext.renderGroup(group, groupCtx) }, `${ext.metaKey}:${group.groupId}`))
|
|
7159
7446
|
),
|
|
7160
7447
|
tracks.map((track, index) => {
|
|
7161
7448
|
if (crossfadeMemberDbIds.has(track.handle.dbId) || fadeMemberDbIds.has(track.handle.dbId) || genericGroupMemberDbIds.has(track.handle.dbId)) {
|
|
7162
7449
|
return null;
|
|
7163
7450
|
}
|
|
7164
|
-
return /* @__PURE__ */
|
|
7451
|
+
return /* @__PURE__ */ jsx25(TrackRow, { ...buildRowProps(track, reorder.dragPropsFor(index)) }, track.handle.id);
|
|
7165
7452
|
}),
|
|
7166
7453
|
slots?.afterRows
|
|
7167
7454
|
] })),
|
|
7168
7455
|
features.exportMidi && !designerView && !isLoadingTracks && tracks.length > 0 && (() => {
|
|
7169
7456
|
const hasAnyMidi = tracks.some((t) => t.hasMidi);
|
|
7170
7457
|
const exportDisabled = isExportingMidi || !hasAnyMidi;
|
|
7171
|
-
return /* @__PURE__ */
|
|
7458
|
+
return /* @__PURE__ */ jsx25("div", { className: "pt-2", children: /* @__PURE__ */ jsx25(
|
|
7172
7459
|
"button",
|
|
7173
7460
|
{
|
|
7174
7461
|
"data-testid": "export-midi-tracks-button",
|
|
@@ -7236,7 +7523,7 @@ function createSurgeSoundAdapter(host, overrides = {}) {
|
|
|
7236
7523
|
}
|
|
7237
7524
|
|
|
7238
7525
|
// src/constants/sdk-version.ts
|
|
7239
|
-
var PLUGIN_SDK_VERSION = "2.
|
|
7526
|
+
var PLUGIN_SDK_VERSION = "2.37.0";
|
|
7240
7527
|
|
|
7241
7528
|
// src/utils/format-concurrent-tracks.ts
|
|
7242
7529
|
function formatConcurrentTracks(ctx) {
|
|
@@ -7411,6 +7698,7 @@ export {
|
|
|
7411
7698
|
PLUGIN_SDK_VERSION,
|
|
7412
7699
|
PX_PER_BEAT,
|
|
7413
7700
|
PanSlider,
|
|
7701
|
+
PanelMasterStrip,
|
|
7414
7702
|
PianoRollEditor,
|
|
7415
7703
|
PluginError,
|
|
7416
7704
|
RESIZE_HANDLE_PX,
|
|
@@ -7475,6 +7763,7 @@ export {
|
|
|
7475
7763
|
transposeNotes,
|
|
7476
7764
|
useAnySolo,
|
|
7477
7765
|
useGeneratorPanelCore,
|
|
7766
|
+
usePanelBus,
|
|
7478
7767
|
useSceneState,
|
|
7479
7768
|
useSoundHistory,
|
|
7480
7769
|
useTrackLevel,
|