Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions packages/studio/src/components/editor/PropertyPanel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,52 @@ function audioElement() {
};
}

describe("PropertyPanel — STUDIO_VST_ENABLED gate", () => {
it(
"does not render the VST FX section for an audio element by default (flag off)",
async () => {
const { host, root } = await renderPanel(false, audioElement() as never);
expect(host.querySelector('[data-vst-install-hint="true"]')).toBeNull();
expect(host.querySelector("[data-vst-add-effect]")).toBeNull();
act(() => root.unmount());
},
RENDER_TIMEOUT_MS,
);

it(
"renders the VST FX section for an audio element once STUDIO_VST_ENABLED is on",
async () => {
vi.doMock("./manualEditingAvailability", async () => {
const actual = await vi.importActual<typeof import("./manualEditingAvailability")>(
"./manualEditingAvailability",
);
return { ...actual, STUDIO_FLAT_INSPECTOR_ENABLED: false, STUDIO_VST_ENABLED: true };
});
vi.resetModules();
const { PropertyPanel } = await import("./PropertyPanel");
const host = document.createElement("div");
document.body.append(host);
const root = createRoot(host);
const props = {
element: audioElement(),
assets: [],
onSetStyle: vi.fn(),
onSetText: vi.fn(),
onSetAttributeLive: vi.fn(),
} as unknown as PropertyPanelProps;
act(() => {
root.render(<PropertyPanel {...props} />);
});
expect(
host.querySelector('[data-vst-install-hint="true"]') ||
host.querySelector("[data-vst-add-effect]"),
).not.toBeNull();
act(() => root.unmount());
},
RENDER_TIMEOUT_MS,
);
});

// All FlatGroup titles currently mounted (open row + every collapsed row).
function flatGroupTitles(host: HTMLElement): string[] {
const open = Array.from(
Expand Down
3 changes: 2 additions & 1 deletion packages/studio/src/components/editor/PropertyPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
STUDIO_FLAT_INSPECTOR_ENABLED,
STUDIO_GSAP_PANEL_ENABLED,
STUDIO_KEYFRAMES_ENABLED,
STUDIO_VST_ENABLED,
} from "./manualEditingAvailability";
import { PropertyPanelFlat } from "./PropertyPanelFlat";
import { createGsapLivePreview } from "./gsapLivePreview";
Expand Down Expand Up @@ -374,7 +375,7 @@ export const PropertyPanel = memo(function PropertyPanel(props: PropertyPanelPro
/>
)}

{sections.vstFx && (
{STUDIO_VST_ENABLED && sections.vstFx && (
<VstSection
projectId={projectId}
element={element}
Expand Down
10 changes: 10 additions & 0 deletions packages/studio/src/components/editor/manualEditingAvailability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,14 @@ export const STUDIO_FLAT_INSPECTOR_ENABLED = resolveStudioBooleanEnvFlag(
false,
);

// VST FX chain editing (the property panel's "Make room for voiceover" carve
// control + per-plugin chain UI) and its live-preview PCM streaming through
// the VST host sidecar — new, unreleased surface, off by default pending
// broader rollout. Default false; enable via VITE_STUDIO_ENABLE_VST=true.
export const STUDIO_VST_ENABLED = resolveStudioBooleanEnvFlag(
env,
["VITE_STUDIO_ENABLE_VST", "VITE_STUDIO_VST_ENABLED"],
false,
);

export const STUDIO_MANUAL_EDITING_DISABLED_TITLE = "Manual editing is temporarily disabled";
4 changes: 4 additions & 0 deletions packages/studio/src/player/hooks/useVstPreview.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import { FakeSocket, required } from "../../hooks/vstSocketTestFixture";
import { liveTime, usePlayerStore } from "../store/playerStore";
import { decodePcmFrame, useVstPreview } from "./useVstPreview";

vi.mock("../../components/editor/manualEditingAvailability", () => ({
STUDIO_VST_ENABLED: true,
}));

(globalThis as unknown as { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;

// ── Fake Web Audio (this environment has none at all) ───────────────────────
Expand Down
2 changes: 2 additions & 0 deletions packages/studio/src/player/hooks/useVstPreview.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useRef, type RefObject } from "react";
import { liveTime, usePlayerStore } from "../store/playerStore";
import type { TransportMsg, UseVstHostResult } from "../../hooks/useVstHost";
import { STUDIO_VST_ENABLED } from "../../components/editor/manualEditingAvailability";
import {
collectVstChainAudioEls,
dbg,
Expand Down Expand Up @@ -121,6 +122,7 @@ export function useVstPreview(

// ── Lazily start the sidecar once a vst-chain track appears ─────────────
useEffect(() => {
if (!STUDIO_VST_ENABLED) return;
if (!projectId || status !== "idle") return;
const doc = iframeRef.current?.contentDocument;
if (!doc) return;
Expand Down
Loading