@@ -21,6 +21,7 @@ export default function usePracticePanelState({
2121 metronomeDefaults,
2222 randomizeConfig,
2323} ) {
24+ const { selectedRoot, selectedScale } = randomizeConfig ;
2425 const [ randomizeMode , setRandomizeMode ] = React . useState (
2526 RANDOMIZE_MODES . Both ,
2627 ) ;
@@ -65,6 +66,57 @@ export default function usePracticePanelState({
6566 const [ barsRemaining , setBarsRemaining ] = React . useState ( safeBarsPerScale ) ;
6667 const barsRemainingRef = React . useRef ( safeBarsPerScale ) ;
6768 const pendingRandomizedScaleRef = React . useRef ( null ) ;
69+ const practiceStartSelectionRef = React . useRef ( null ) ;
70+ const randomizedDuringPracticeRef = React . useRef ( false ) ;
71+ const isPlayingRef = React . useRef ( false ) ;
72+
73+ const capturePracticeStartSelection = useCallback ( ( ) => {
74+ if ( practiceStartSelectionRef . current ) return ;
75+ practiceStartSelectionRef . current = {
76+ root : selectedRoot ,
77+ scale : selectedScale ,
78+ } ;
79+ } , [ selectedRoot , selectedScale ] ) ;
80+
81+ const markRandomizedDuringPractice = useCallback ( ( ) => {
82+ if ( ! isPlayingRef . current ) return ;
83+ capturePracticeStartSelection ( ) ;
84+ randomizedDuringPracticeRef . current = true ;
85+ } , [ capturePracticeStartSelection ] ) ;
86+
87+ const restorePracticeStartSelection = useCallback ( ( ) => {
88+ if ( ! randomizedDuringPracticeRef . current ) return ;
89+
90+ const originalSelection = practiceStartSelectionRef . current ;
91+ if ( ! originalSelection ) return ;
92+
93+ if (
94+ typeof originalSelection . root === "string" &&
95+ originalSelection . root . length
96+ ) {
97+ randomizeConfig . setRoot ?. ( originalSelection . root ) ;
98+ }
99+ if (
100+ typeof originalSelection . scale === "string" &&
101+ originalSelection . scale . length
102+ ) {
103+ randomizeConfig . setScale ?. ( originalSelection . scale ) ;
104+ }
105+ } , [ randomizeConfig ] ) ;
106+
107+ const randomizeNowForPractice = useCallback ( ( ) => {
108+ markRandomizedDuringPractice ( ) ;
109+ randomizeNow ?. ( ) ;
110+ } , [ markRandomizedDuringPractice , randomizeNow ] ) ;
111+
112+ const applyPickedScaleForPractice = useCallback (
113+ ( result ) => {
114+ markRandomizedDuringPractice ( ) ;
115+ applyPickedScale ?. ( result ) ;
116+ } ,
117+ [ applyPickedScale , markRandomizedDuringPractice ] ,
118+ ) ;
119+
68120 const handleMetronomeBeat = useCallback (
69121 ( { beat } ) => {
70122 if ( beat !== 1 || ! autoAdvanceEnabled ) return ;
@@ -91,9 +143,9 @@ export default function usePracticePanelState({
91143 const pendingResult = pendingRandomizedScaleRef . current ;
92144
93145 if ( pendingResult ) {
94- applyPickedScale ?. ( pendingResult ) ;
146+ applyPickedScaleForPractice ?. ( pendingResult ) ;
95147 } else {
96- randomizeNow ?. ( ) ;
148+ randomizeNowForPractice ?. ( ) ;
97149 }
98150
99151 pendingRandomizedScaleRef . current = null ;
@@ -108,10 +160,10 @@ export default function usePracticePanelState({
108160 [
109161 announceCountInBeforeChange ,
110162 autoAdvanceEnabled ,
111- applyPickedScale ,
163+ applyPickedScaleForPractice ,
112164 pickRandomizedScale ,
113165 randomizeMode ,
114- randomizeNow ,
166+ randomizeNowForPractice ,
115167 safeBarsPerScale ,
116168 ] ,
117169 ) ;
@@ -129,12 +181,33 @@ export default function usePracticePanelState({
129181 onBeat : handleMetronomeBeat ,
130182 } ) ;
131183
184+ React . useEffect ( ( ) => {
185+ if ( metronomeEngine . isPlaying && ! isPlayingRef . current ) {
186+ practiceStartSelectionRef . current = null ;
187+ randomizedDuringPracticeRef . current = false ;
188+ capturePracticeStartSelection ( ) ;
189+ }
190+
191+ if ( ! metronomeEngine . isPlaying && isPlayingRef . current ) {
192+ restorePracticeStartSelection ( ) ;
193+ practiceStartSelectionRef . current = null ;
194+ randomizedDuringPracticeRef . current = false ;
195+ pendingRandomizedScaleRef . current = null ;
196+ }
197+
198+ isPlayingRef . current = metronomeEngine . isPlaying ;
199+ } , [
200+ capturePracticeStartSelection ,
201+ metronomeEngine . isPlaying ,
202+ restorePracticeStartSelection ,
203+ ] ) ;
204+
132205 const practiceActions = usePracticeActions ( {
133206 isPlaying : metronomeEngine . isPlaying ,
134207 startMetronome : metronomeEngine . start ,
135208 stopMetronome : metronomeEngine . stop ,
136209 setBpm : metronomeSetters . setBpm ,
137- randomizeNow,
210+ randomizeNow : randomizeNowForPractice ,
138211 randomizeFromHotkey,
139212 } ) ;
140213
@@ -152,10 +225,15 @@ export default function usePracticePanelState({
152225 ( ) => ( {
153226 randomizeMode,
154227 setRandomizeMode,
155- randomizeNow,
228+ randomizeNow : randomizeNowForPractice ,
156229 randomizeFromHotkey,
157230 } ) ,
158- [ randomizeMode , setRandomizeMode , randomizeNow , randomizeFromHotkey ] ,
231+ [
232+ randomizeMode ,
233+ setRandomizeMode ,
234+ randomizeNowForPractice ,
235+ randomizeFromHotkey ,
236+ ] ,
159237 ) ;
160238 const metronome = useMemo (
161239 ( ) => ( {
0 commit comments