fix(ui): persist VST plugin selection across page reloads
- Use FTUESave(true) instead of TrackSaveAssignments() to properly persist VST assignments to the profile file - Always call VSTLoad() when modal opens if VST not already loaded, removing unreliable hasVstAssignment() check - Pass correct trackIndex to JKSessionPluginModal for multi-track support - Add trackIndex prop to track data in useMixerHelper for VST operations Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
78cdafbb8a
commit
c344decea4
|
|
@ -21,6 +21,7 @@ import pluginIcon from '../../assets/img/client/plugin.svg';
|
|||
|
||||
const JKSessionMyTrack = ({
|
||||
track,
|
||||
trackIndex = 0, // 0-based index for native client VST operations
|
||||
mixers,
|
||||
hasMixer,
|
||||
name,
|
||||
|
|
@ -314,7 +315,7 @@ const JKSessionMyTrack = ({
|
|||
<JKSessionPluginModal
|
||||
isOpen={showPluginModal}
|
||||
toggle={() => setShowPluginModal(false)}
|
||||
trackNumber={ASSIGNMENT.TRACK1}
|
||||
trackNumber={trackIndex + 1}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
Label,
|
||||
Input,
|
||||
Spinner,
|
||||
Alert,
|
||||
} from 'reactstrap';
|
||||
import { useJamClient } from '../../context/JamClientContext';
|
||||
import JKSessionPluginFoldersModal from './JKSessionPluginFoldersModal';
|
||||
|
|
@ -34,18 +33,34 @@ const JKSessionPluginModal = ({ isOpen, toggle, trackNumber = 1 }) => {
|
|||
const loadAvailablePlugins = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
// Load the audio profile configuration first to restore saved VST assignments
|
||||
const profileName = await jamClient.LastUsedProfileName();
|
||||
if (profileName) {
|
||||
await jamClient.FTUELoadAudioConfiguration(profileName);
|
||||
}
|
||||
|
||||
// Always try to load VST assignments from profile after loading profile config
|
||||
const isVstLoaded = await jamClient.IsVstLoaded();
|
||||
if (!isVstLoaded) {
|
||||
await jamClient.VSTLoad();
|
||||
// Give the native client time to load the VST
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
}
|
||||
|
||||
const pluginsResponse = await jamClient.VSTListVsts();
|
||||
const plugins = pluginsResponse?.vsts || [];
|
||||
setAvailablePlugins(plugins);
|
||||
console.log('loadAvailablePlugins Available plugins:', plugins);
|
||||
|
||||
// Load current track assignments
|
||||
const assignmentsResponse = await jamClient.VSTListTrackAssignments();
|
||||
console.log('loadAvailablePlugins Current track assignments:', assignmentsResponse);
|
||||
const assignments = assignmentsResponse?.vsts || [];
|
||||
const currentAssignment = assignments.find(assignment => assignment.track === trackNumber - 1);
|
||||
|
||||
const targetTrackIndex = trackNumber - 1;
|
||||
const currentAssignment = assignments.find(assignment => assignment.track === targetTrackIndex);
|
||||
|
||||
if (currentAssignment) {
|
||||
setSelectedPlugin(currentAssignment.id || currentAssignment.file || '');
|
||||
setSelectedPlugin(currentAssignment.file || '');
|
||||
} else {
|
||||
setSelectedPlugin('');
|
||||
}
|
||||
|
|
@ -60,7 +75,6 @@ const JKSessionPluginModal = ({ isOpen, toggle, trackNumber = 1 }) => {
|
|||
|
||||
const handlePluginChange = async (event) => {
|
||||
const pluginFile = event.target.value;
|
||||
|
||||
setSelectedPlugin(pluginFile);
|
||||
|
||||
const selectedPluginObj = availablePlugins.find(plugin =>
|
||||
|
|
@ -69,8 +83,22 @@ const JKSessionPluginModal = ({ isOpen, toggle, trackNumber = 1 }) => {
|
|||
|
||||
if (pluginFile && selectedPluginObj) {
|
||||
try {
|
||||
console.log('handlePluginChange Selected plugin object:', selectedPluginObj, 'for track number: ', trackNumber - 1);
|
||||
// Establish profile context first
|
||||
const profileName = await jamClient.LastUsedProfileName();
|
||||
if (profileName) {
|
||||
await jamClient.FTUELoadAudioConfiguration(profileName);
|
||||
}
|
||||
|
||||
// Set the VST assignment
|
||||
await jamClient.VSTSetTrackAssignment(selectedPluginObj, trackNumber - 1);
|
||||
|
||||
// Save the entire profile to persist VST assignment
|
||||
// FTUESave(true) persists the profile to disk
|
||||
try {
|
||||
await jamClient.FTUESave(true);
|
||||
} catch (saveError) {
|
||||
console.warn('FTUESave failed:', saveError);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to assign VST plugin:', error);
|
||||
}
|
||||
|
|
@ -90,7 +118,6 @@ const JKSessionPluginModal = ({ isOpen, toggle, trackNumber = 1 }) => {
|
|||
setLoadingText('scanning');
|
||||
setIsLoading(true);
|
||||
await jamClient.VSTScan("window.ConfigureTracksStore.onVstScanComplete");
|
||||
// Callback after scan completes
|
||||
setIsLoading(false);
|
||||
setLoadingText('');
|
||||
loadAvailablePlugins();
|
||||
|
|
|
|||
|
|
@ -524,15 +524,25 @@ const useMixerHelper = () => {
|
|||
const name = participant.user.name;
|
||||
|
||||
// Get VST track assignments
|
||||
// First ensure VST is loaded from persistent storage (needed after page reload)
|
||||
let vstTrackAssignments = { vsts: [] };
|
||||
try {
|
||||
const isVstLoaded = jamClient.IsVstLoaded();
|
||||
const hasVstAssignment = jamClient.hasVstAssignment();
|
||||
if (hasVstAssignment && !isVstLoaded) {
|
||||
// Load VST from persistent storage - this is async but we proceed anyway
|
||||
// The UI will update on next render cycle after VST loads
|
||||
jamClient.VSTLoad();
|
||||
}
|
||||
const assignments = jamClient.VSTListTrackAssignments();
|
||||
vstTrackAssignments = assignments || { vsts: [] };
|
||||
} catch (error) {
|
||||
console.warn("Failed to get VST track assignments:", error);
|
||||
}
|
||||
|
||||
for (const track of participant.tracks || []) {
|
||||
const participantTracks = participant.tracks || [];
|
||||
for (let trackIndex = 0; trackIndex < participantTracks.length; trackIndex++) {
|
||||
const track = participantTracks[trackIndex];
|
||||
// Get mixers for BOTH modes to support independent Audio Mix (personal) and Session Mix (master) controls
|
||||
const masterMixerData = findMixerForTrack(participant.client_id, track, true, MIX_MODES.MASTER);
|
||||
const personalMixerData = findMixerForTrack(participant.client_id, track, true, MIX_MODES.PERSONAL);
|
||||
|
|
@ -543,8 +553,9 @@ const useMixerHelper = () => {
|
|||
const trackName = name;
|
||||
|
||||
// Check if this track has a VST plugin assigned
|
||||
// Native client uses 0-based track indices for VST assignments
|
||||
const hasVst = vstTrackAssignments.vsts && Array.isArray(vstTrackAssignments.vsts)
|
||||
? vstTrackAssignments.vsts.some(vst => vst.track === track.client_track_id)
|
||||
? vstTrackAssignments.vsts.some(vst => vst.track === trackIndex)
|
||||
: false;
|
||||
|
||||
tracks.push({
|
||||
|
|
@ -552,6 +563,7 @@ const useMixerHelper = () => {
|
|||
...track,
|
||||
hasVst
|
||||
},
|
||||
trackIndex, // 0-based index for native client VST operations
|
||||
mixerFinder: [participant.client_id, track, true],
|
||||
mixers: mixerData,
|
||||
// Store both master and personal mixers for independent control
|
||||
|
|
|
|||
Loading…
Reference in New Issue