@@ -11,7 +11,7 @@ import { useEffect, useState } from 'react';
1111import { useSelector , useDispatch } from 'react-redux' ;
1212import { fetchActivities , fetchSingleStudentAssignment } from '../../../../../../../actions' ;
1313import StudentAssignment from '../../../../../../../components/student/assignment' ;
14- import { DAWProvider } from '../../../../../../../contexts/DAWProvider' ;
14+ import { DAWProvider , useAudio , useUI } from '../../../../../../../contexts/DAWProvider' ;
1515import { useActivityProgress } from '../../../../../../../hooks/useActivityProgress' ;
1616import {
1717 ActivityLayout ,
@@ -20,6 +20,24 @@ import {
2020} from '../../../../../../../components/activity' ;
2121import { getActivityConfig } from '../../../../../../../lib/activity/activityConfigs' ;
2222
23+ /**
24+ * Sets showDAW and dawMode when rendered inside DAWProvider.
25+ * Must be a child of DAWProvider since it needs context access.
26+ */
27+ function DAWInitializer ( { multitrack } ) {
28+ const { setShowDAW } = useUI ( ) ;
29+ const { setDawMode } = useAudio ( ) ;
30+
31+ useEffect ( ( ) => {
32+ setShowDAW ( true ) ;
33+ if ( multitrack ) {
34+ setDawMode ( 'multi' ) ;
35+ }
36+ } , [ multitrack , setShowDAW , setDawMode ] ) ;
37+
38+ return null ;
39+ }
40+
2341// Dynamically import components
2442const FlatEditor = dynamic ( ( ) => import ( '../../../../../../../components/flatEditor' ) , {
2543 ssr : false ,
@@ -263,11 +281,15 @@ export default function ActivityPage() {
263281 completedOpsArray : [ ...completedOps ] // Expand the array to see actual values
264282 } ) ;
265283
266- // Pre-populate bassline for Activity 3
267- const initialTracks = stepNumber === 3 ? [ {
268- name : 'Air for Band - Bassline' ,
284+ // Pre-populate bassline track for Activity 3 using the assignment's sample audio
285+ const basslineName = assignment ?. part ?. piece ?. name
286+ ? `${ assignment . part . piece . name } - Bassline`
287+ : 'Bassline' ;
288+ const basslineURL = preferredSample || null ;
289+ const initialTracks = ( stepNumber === 3 && basslineURL ) ? [ {
290+ name : basslineName ,
269291 type : 'audio' ,
270- audioURL : '/media/sample_audio/Air_for_Band_Bass_Line.mp3' ,
292+ audioURL : basslineURL ,
271293 volume : 1 ,
272294 pan : 0 ,
273295 muted : false ,
@@ -277,13 +299,17 @@ export default function ActivityPage() {
277299 start : 0 ,
278300 duration : 0 , // Will be set when audio loads
279301 color : '#4a9eff' ,
280- src : '/media/sample_audio/Air_for_Band_Bass_Line.mp3' ,
302+ src : basslineURL ,
281303 offset : 0 ,
282- name : 'Air for Band - Bassline' ,
304+ name : basslineName ,
283305 } ] ,
284306 } ] : [ ] ;
285307
286- if ( isLoading ) {
308+ // Wait for activity progress to load, and for Activity 3 also wait for the
309+ // sample audio URL so initialTracks is populated before MultitrackProvider mounts
310+ // (useState only reads initialTracks on first mount — late arrivals are ignored)
311+ const awaitingSample = stepNumber === 3 && ! preferredSample && ! ! assignment ;
312+ if ( isLoading || awaitingSample ) {
287313 return (
288314 < StudentAssignment assignment = { assignment } >
289315 < div className = "text-center py-5" >
@@ -301,6 +327,11 @@ export default function ActivityPage() {
301327 initialTracks = { initialTracks }
302328 persistenceConfig = { audioPersistenceConfig }
303329 >
330+ { /* Initialize DAW visibility and mode for multitrack activities */ }
331+ { ( stepNumber === 3 || stepNumber === 4 ) && (
332+ < DAWInitializer multitrack />
333+ ) }
334+
304335 { /* Consent Modal */ }
305336 < ConsentReminderModal
306337 show = { showConsentModal }
@@ -361,7 +392,6 @@ export default function ActivityPage() {
361392 onSubmit = { null } // No submission from DAW itself in study mode
362393 showSubmitButton = { false } // Hide DAW's submit button
363394 logOperation = { logOperation } // Pass operation logger to DAW
364- initialTracks = { initialTracks } // Pre-populate tracks for Activity 3
365395 />
366396 ) }
367397 </ ActivityLayout >
0 commit comments