@@ -66,6 +66,8 @@ export function AudioPlayer({
6666 const playSegmentRef = useRef < ( ( segmentIndex : number ) => void ) | null > ( null ) ;
6767 const onEndedRef = useRef < ( ( ) => void ) | null > ( null ) ;
6868 const onErrorRef = useRef < ( ( ) => void ) | null > ( null ) ;
69+ const resumeTimeoutRef = useRef < ReturnType < typeof setTimeout > | null > ( null ) ;
70+ const isMountedRef = useRef ( true ) ;
6971
7072 // Reset when content changes
7173 // biome-ignore lint/correctness/useExhaustiveDependencies: contentId change should reset state
@@ -122,6 +124,19 @@ export function AudioPlayer({
122124 onErrorRef . current = null ;
123125 } , [ ] ) ;
124126
127+ // Stop audio on unmount (e.g. page navigation)
128+ useEffect ( ( ) => {
129+ isMountedRef . current = true ;
130+ return ( ) => {
131+ isMountedRef . current = false ;
132+ cleanupAudio ( ) ;
133+ if ( resumeTimeoutRef . current !== null ) {
134+ clearTimeout ( resumeTimeoutRef . current ) ;
135+ resumeTimeoutRef . current = null ;
136+ }
137+ } ;
138+ } , [ cleanupAudio ] ) ;
139+
125140 // Play a specific segment
126141 const playSegment = useCallback (
127142 ( segmentIndex : number ) => {
@@ -140,6 +155,7 @@ export function AudioPlayer({
140155 audioRef . current = audio ;
141156
142157 const onEnded = ( ) => {
158+ if ( ! isMountedRef . current ) return ;
143159 const next = getNextSelectedSegment ( segmentIndex ) ;
144160 if ( next !== null ) {
145161 setCurrentSegment ( next ) ;
@@ -160,6 +176,7 @@ export function AudioPlayer({
160176 } ;
161177
162178 const onError = ( ) => {
179+ if ( ! isMountedRef . current ) return ;
163180 setIsPlaying ( false ) ;
164181 setCurrentSegment ( null ) ;
165182 } ;
@@ -171,6 +188,7 @@ export function AudioPlayer({
171188 audio . addEventListener ( 'error' , onError ) ;
172189
173190 audio . play ( ) . catch ( ( error ) => {
191+ if ( ! isMountedRef . current ) return ;
174192 console . error ( 'Failed to play audio:' , error ) ;
175193 setIsPlaying ( false ) ;
176194 setCurrentSegment ( null ) ;
@@ -226,7 +244,12 @@ export function AudioPlayer({
226244
227245 // Resume playing if it was playing before
228246 if ( wasPlaying && wasSegment !== null ) {
229- setTimeout ( ( ) => {
247+ if ( resumeTimeoutRef . current !== null ) {
248+ clearTimeout ( resumeTimeoutRef . current ) ;
249+ }
250+ resumeTimeoutRef . current = setTimeout ( ( ) => {
251+ resumeTimeoutRef . current = null ;
252+ if ( ! isMountedRef . current ) return ;
230253 setIsPlaying ( true ) ;
231254 playSegment ( wasSegment ) ;
232255 } , 100 ) ;
0 commit comments