diff --git a/jam-ui/src/components/client/JKSessionJamTrackPlayer.js b/jam-ui/src/components/client/JKSessionJamTrackPlayer.js index 0a2c23f99..20edd8a11 100644 --- a/jam-ui/src/components/client/JKSessionJamTrackPlayer.js +++ b/jam-ui/src/components/client/JKSessionJamTrackPlayer.js @@ -241,6 +241,46 @@ const JKSessionJamTrackPlayer = ({ } }, [isOperating, jamClient, jamTrackState.isPaused, dispatch]); + // Mixdown change handler + const handleMixdownChange = useCallback(async (mixdownId) => { + if (isOperating || !jamClient || !fqIdRef.current) return; + + try { + setIsOperating(true); + setError(null); + + // Find the new mixdown + const mixdown = availableMixdowns.find(m => m.id === mixdownId); + if (!mixdown) { + throw new Error('Mixdown not found'); + } + + // Update local state + setSelectedMixdownId(mixdownId); + dispatch(setActiveMixdown(mixdown)); + + // If currently playing, stop and restart with new mixdown + if (jamTrackState.isPlaying || jamTrackState.isPaused) { + await jamClient.JamTrackStop(fqIdRef.current); + + await dispatch(loadJamTrack({ + jamTrack, + mixdownId, + autoPlay: true, + jamClient + })).unwrap(); + } + + } catch (err) { + console.error('[JamTrack] Mixdown change error:', err); + setError({ type: 'playback', message: 'Failed to change mixdown' }); + } finally { + if (mountedRef.current) { + setIsOperating(false); + } + } + }, [isOperating, jamClient, jamTrack, jamTrackState, availableMixdowns, dispatch]); + // Helper: Format milliseconds to MM:SS const formatTime = (ms) => { if (!ms || isNaN(ms)) return '00:00'; @@ -354,6 +394,37 @@ const JKSessionJamTrackPlayer = ({ {formatTime(jamTrackState.currentPositionMs)} / {formatTime(jamTrackState.durationMs)}
+ + {availableMixdowns.length > 0 && ( +