fix(27): populate backing track Redux state from native client
After opening a backing track file via native client: 1. Call SessionGetAllControlState(true) to get track info 2. Extract backing track data (id, rid, filename, shortFilename) 3. Dispatch to both Redux slices: - activeSessionSlice.addBackingTrack (for track sync) - mediaSlice.setBackingTracks (for session screen UI) Also fixes syncTracksToServer calls that incorrectly passed jamClient object instead of server.clientId. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e35163ec84
commit
2ea18d59ea
|
|
@ -5,7 +5,8 @@ import {
|
|||
loadJamTrack as loadJamTrackThunk,
|
||||
closeMedia as closeMediaThunk,
|
||||
clearJamTrackState,
|
||||
updateJamTrackState
|
||||
updateJamTrackState,
|
||||
setBackingTracks
|
||||
} from '../store/features/mediaSlice';
|
||||
import {
|
||||
setMetronome,
|
||||
|
|
@ -21,7 +22,10 @@ import {
|
|||
setCreatingMixdown,
|
||||
setCreateMixdownErrors
|
||||
} from '../store/features/sessionUISlice';
|
||||
import { selectSessionId } from '../store/features/activeSessionSlice';
|
||||
import {
|
||||
selectSessionId,
|
||||
addBackingTrack as addBackingTrackToActiveSession
|
||||
} from '../store/features/activeSessionSlice';
|
||||
import { useJamServerContext } from '../context/JamServerContext';
|
||||
import { syncTracksToServer } from '../services/trackSyncService';
|
||||
|
||||
|
|
@ -32,7 +36,7 @@ import { syncTracksToServer } from '../services/trackSyncService';
|
|||
const useMediaActions = () => {
|
||||
const dispatch = useDispatch();
|
||||
const sessionId = useSelector(selectSessionId);
|
||||
const { jamClient, subscribe, unsubscribe } = useJamServerContext();
|
||||
const { jamClient, subscribe, unsubscribe, server } = useJamServerContext();
|
||||
|
||||
// Create jamServer object with subscribe/unsubscribe for thunks
|
||||
const jamServer = useMemo(() => ({
|
||||
|
|
@ -46,7 +50,23 @@ const useMediaActions = () => {
|
|||
*/
|
||||
const openBackingTrack = useCallback(async (file) => {
|
||||
try {
|
||||
await dispatch(openBackingTrackThunk({ file, jamClient })).unwrap();
|
||||
const result = await dispatch(openBackingTrackThunk({ file, jamClient })).unwrap();
|
||||
|
||||
// Update backing tracks in both Redux slices
|
||||
// 1. activeSession slice (for syncTracksToServer)
|
||||
// 2. media slice (for session screen UI)
|
||||
if (result.backingTracks && result.backingTracks.length > 0) {
|
||||
console.log('[openBackingTrack] Updating Redux with backing tracks:', result.backingTracks);
|
||||
|
||||
// Add each backing track to activeSession (for track sync)
|
||||
for (const bt of result.backingTracks) {
|
||||
dispatch(addBackingTrackToActiveSession(bt));
|
||||
}
|
||||
|
||||
// Set backing tracks in media slice (for UI display)
|
||||
// Format for UI: { shortFilename, filename, mixers (will be added by mixer system) }
|
||||
dispatch(setBackingTracks(result.backingTracks));
|
||||
}
|
||||
|
||||
// Update media summary
|
||||
dispatch(updateMediaSummary({
|
||||
|
|
@ -55,15 +75,15 @@ const useMediaActions = () => {
|
|||
}));
|
||||
|
||||
// Sync tracks to server after opening backing track
|
||||
if (sessionId && jamClient) {
|
||||
if (sessionId && server?.clientId) {
|
||||
console.log('[Track Sync] Backing track opened, syncing tracks');
|
||||
dispatch(syncTracksToServer(sessionId, jamClient));
|
||||
dispatch(syncTracksToServer(sessionId, server.clientId));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error opening backing track:', error);
|
||||
throw error;
|
||||
}
|
||||
}, [dispatch, jamClient, sessionId]);
|
||||
}, [dispatch, jamClient, sessionId, server]);
|
||||
|
||||
/**
|
||||
* Close all media (backing tracks, jam tracks, recordings, metronome)
|
||||
|
|
@ -108,9 +128,9 @@ const useMediaActions = () => {
|
|||
}));
|
||||
|
||||
// Sync tracks to server after opening metronome
|
||||
if (sessionId && jamClient) {
|
||||
if (sessionId && server?.clientId) {
|
||||
console.log('[Track Sync] Metronome opened, syncing tracks');
|
||||
dispatch(syncTracksToServer(sessionId, jamClient));
|
||||
dispatch(syncTracksToServer(sessionId, server.clientId));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -118,7 +138,7 @@ const useMediaActions = () => {
|
|||
console.error('Error opening metronome:', error);
|
||||
throw error;
|
||||
}
|
||||
}, [dispatch, jamClient, sessionId]);
|
||||
}, [dispatch, jamClient, sessionId, server]);
|
||||
|
||||
/**
|
||||
* Close the metronome
|
||||
|
|
@ -134,15 +154,15 @@ const useMediaActions = () => {
|
|||
}));
|
||||
|
||||
// Sync tracks to server after closing metronome
|
||||
if (sessionId && jamClient) {
|
||||
if (sessionId && server?.clientId) {
|
||||
console.log('[Track Sync] Metronome closed, syncing tracks');
|
||||
dispatch(syncTracksToServer(sessionId, jamClient));
|
||||
dispatch(syncTracksToServer(sessionId, server.clientId));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error closing metronome:', error);
|
||||
throw error;
|
||||
}
|
||||
}, [dispatch, jamClient, sessionId]);
|
||||
}, [dispatch, jamClient, sessionId, server]);
|
||||
|
||||
/**
|
||||
* Load and play a JamTrack
|
||||
|
|
@ -159,15 +179,15 @@ const useMediaActions = () => {
|
|||
}));
|
||||
|
||||
// Sync tracks to server after opening jam track
|
||||
if (sessionId && jamClient) {
|
||||
if (sessionId && server?.clientId) {
|
||||
console.log('[Track Sync] Jam track opened, syncing tracks');
|
||||
dispatch(syncTracksToServer(sessionId, jamClient));
|
||||
dispatch(syncTracksToServer(sessionId, server.clientId));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading jam track:', error);
|
||||
throw error;
|
||||
}
|
||||
}, [dispatch, jamClient, jamServer, sessionId]);
|
||||
}, [dispatch, jamClient, jamServer, sessionId, server]);
|
||||
|
||||
/**
|
||||
* Stop and close the currently playing JamTrack
|
||||
|
|
|
|||
|
|
@ -1,13 +1,39 @@
|
|||
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
||||
import { enqueueMixdown } from '../../helpers/rest';
|
||||
|
||||
// Channel group IDs for track filtering
|
||||
const MEDIA_TRACK_GROUP = 8; // ChannelGroupIds.MediaTrackGroup
|
||||
|
||||
// Async thunks for media actions
|
||||
export const openBackingTrack = createAsyncThunk(
|
||||
'media/openBackingTrack',
|
||||
async ({ file, jamClient }, { rejectWithValue }) => {
|
||||
try {
|
||||
// Open the backing track file via native client
|
||||
await jamClient.SessionOpenBackingTrackFile(file, false);
|
||||
return { file };
|
||||
|
||||
// Get track info from native client to populate Redux state
|
||||
const allTracks = await jamClient.SessionGetAllControlState(true);
|
||||
|
||||
// Extract backing track data (same pattern as useTrackHelpers.getBackingTracks)
|
||||
const backingTracks = [];
|
||||
for (const track of allTracks) {
|
||||
if (track.group_id === MEDIA_TRACK_GROUP &&
|
||||
track.media_type === 'BackingTrack' &&
|
||||
!track.managed) {
|
||||
backingTracks.push({
|
||||
id: track.persisted_track_id,
|
||||
rid: track.rid,
|
||||
filename: track.filename,
|
||||
// Compute shortFilename from full path
|
||||
shortFilename: track.filename ? track.filename.split('/').pop().split('\\').pop() : 'Audio File'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[openBackingTrack] Got backing tracks from native client:', backingTracks);
|
||||
|
||||
return { file, backingTracks };
|
||||
} catch (error) {
|
||||
return rejectWithValue(error.message);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue