fix(05-jamtrack): add jamTrackData state for player props

Added jamTrackData state to activeSessionSlice following the same
pattern as backingTrackData. This properly separates concerns:
- jamTrackData stores full player data (jamTrack, session, currentUser)
- Presence of jamTrackData indicates player should be shown

Changes to activeSessionSlice.js:
- Add jamTrackData: null to initial state
- Add setJamTrackData and clearJamTrackData reducers
- Export actions and selectJamTrackData selector

Changes to JKSessionScreen.js:
- Import setJamTrackData, clearJamTrackData, selectJamTrackData
- Remove openJamTrack usage from sessionUISlice
- Update handleJamTrackSelect to dispatch setJamTrackData
- Update selectors to use jamTrackData
- Update render to pass jamTrackData.jamTrack to player

Fixes "Cannot read properties of undefined (reading 'id')" error
where jamTrack prop was undefined due to incorrect state structure.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Nuwan 2026-01-15 01:51:21 +05:30
parent c721c97cfe
commit 40cb7fe908
2 changed files with 34 additions and 17 deletions

View File

@ -23,7 +23,7 @@ import { dkeys } from '../../helpers/utils.js';
import { getSessionHistory, getSession, joinSession as joinSessionRest, updateSessionSettings, getFriends, startRecording, stopRecording, submitSessionFeedback, getVideoConferencingRoomUrl, getJamTrack, closeJamTrack, openMetronome } from '../../helpers/rest';
// Redux imports
import { openModal, closeModal, toggleModal, selectModal, setOpenJamTrack, clearOpenJamTrack, selectOpenJamTrack } from '../../store/features/sessionUISlice';
import { openModal, closeModal, toggleModal, selectModal } from '../../store/features/sessionUISlice';
import { selectMediaSummary } from '../../store/features/mixersSlice';
import {
fetchActiveSession,
@ -38,6 +38,8 @@ import {
setJamTrackStems,
setBackingTrackData,
clearBackingTrackData,
setJamTrackData,
clearJamTrackData,
clearSession,
selectActiveSession,
selectJoinStatus,
@ -49,7 +51,8 @@ import {
selectInSession,
selectSelectedJamTrack,
selectJamTrackStems,
selectBackingTrackData
selectBackingTrackData,
selectJamTrackData
} from '../../store/features/activeSessionSlice';
import { CLIENT_ROLE, RECORD_TYPE_AUDIO, RECORD_TYPE_BOTH } from '../../helpers/globals';
@ -200,13 +203,13 @@ const JKSessionScreen = () => {
}, [closeMedia]);
// Redux JamTrack player state (modal visibility and data)
const openJamTrack = useSelector(selectOpenJamTrack);
const showJamTrackPlayer = Boolean(openJamTrack);
const jamTrackData = useSelector(selectJamTrackData);
const showJamTrackPlayer = Boolean(jamTrackData);
// Stable callback for JamTrack player popup close
const handleJamTrackPlayerClose = useCallback(() => {
console.log('JKSessionScreen: JamTrack Player Popup closing');
dispatch(clearOpenJamTrack());
dispatch(clearJamTrackData());
}, [dispatch]);
// State for media controls popup (modal visibility now in Redux)
@ -860,22 +863,22 @@ const JKSessionScreen = () => {
try {
// Fetch jam track details with stems
const response = await getJamTrack({ id: jamTrack.id });
const jamTrackData = await response.json();
const jamTrackWithStems = await response.json();
console.log('Jam track data:', jamTrackData);
console.log('Jam track data:', jamTrackWithStems);
// Set the selected jam track and stems (for display on session screen)
dispatch(setSelectedJamTrack(jamTrackData));
dispatch(setJamTrackStems(jamTrackData.tracks || []));
dispatch(setSelectedJamTrack(jamTrackWithStems));
dispatch(setJamTrackStems(jamTrackWithStems.tracks || []));
// Open the JamTrack player popup (with full data needed for player)
dispatch(setOpenJamTrack({
jamTrack: jamTrackData,
dispatch(setJamTrackData({
jamTrack: jamTrackWithStems,
session: currentSession,
currentUser: currentUser
}));
toast.success(`Loaded JamTrack: ${jamTrackData.name}`);
toast.success(`Loaded JamTrack: ${jamTrackWithStems.name}`);
} catch (error) {
console.error('Error loading jam track:', error);
toast.error('Failed to load JamTrack');
@ -1338,20 +1341,20 @@ const JKSessionScreen = () => {
)}
{/* JamTrack Player Popup */}
{showJamTrackPlayer && openJamTrack && (
{showJamTrackPlayer && jamTrackData && (
<WindowPortal
onClose={handleJamTrackPlayerClose}
windowFeatures="width=600,height=500,left=200,top=200,menubar=no,toolbar=no,status=no,scrollbars=yes,resizable=yes,location=no, addressbar=no"
>
<JKSessionJamTrackPlayer
jamTrack={openJamTrack.jamTrack}
jamTrack={jamTrackData.jamTrack}
jamClient={jamClient}
session={openJamTrack.session}
currentUser={openJamTrack.currentUser}
session={jamTrackData.session}
currentUser={jamTrackData.currentUser}
isPopup={true}
onClose={() => {
console.log('JKSessionScreen: JKSessionJamTrackPlayer onClose called');
dispatch(clearOpenJamTrack());
dispatch(clearJamTrackData());
}}
/>
</WindowPortal>

View File

@ -63,6 +63,9 @@ const initialState = {
// Backing track data (for currently active backing track)
backingTrackData: null,
// JamTrack data (for currently active JamTrack player)
jamTrackData: null,
// Mixdown management (Phase 5)
availableMixdowns: [], // Array of mixdown objects: { id, type: 'master'|'custom-mix'|'stem', name, jamTrackId, packageId }
activeMixdown: null, // Currently selected mixdown object
@ -191,6 +194,14 @@ export const activeSessionSlice = createSlice({
state.backingTrackData = null;
},
setJamTrackData: (state, action) => {
state.jamTrackData = action.payload;
},
clearJamTrackData: (state) => {
state.jamTrackData = null;
},
// Recording
startRecording: (state, action) => {
state.recordingState.isRecording = true;
@ -307,6 +318,8 @@ export const {
removeBackingTrack,
setBackingTrackData,
clearBackingTrackData,
setJamTrackData,
clearJamTrackData,
startRecording,
stopRecording,
addRecordedTrack,
@ -337,6 +350,7 @@ export const selectBackingTracks = (state) => state.activeSession.backingTracks;
export const selectSelectedJamTrack = (state) => state.activeSession.selectedJamTrack;
export const selectJamTrackStems = (state) => state.activeSession.jamTrackStems;
export const selectBackingTrackData = (state) => state.activeSession.backingTrackData;
export const selectJamTrackData = (state) => state.activeSession.jamTrackData;
export const selectConnectionStatus = (state) => state.activeSession.connectionStatus;
export const selectShowConnectionAlert = (state) => state.activeSession.showConnectionAlert;
export const selectRecordingState = (state) => state.activeSession.recordingState;