All files / web/src/components/practice/hooks useGameBreakAudio.ts

100% Statements 54/54
100% Branches 11/11
100% Functions 2/2
100% Lines 54/54

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 551x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 26x 26x 26x 1x 1x 1x 1x 1x 1x 1x 1x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 19x 19x 20x 1x 1x 1x 18x 18x 20x 5x 5x 5x 5x 5x 20x 20x  
'use client'
 
import { useEffect, useRef } from 'react'
import { useTTS } from '@/hooks/useTTS'
import { GAME_BREAK_ANNOUNCEMENT_CLIPS, PICK_A_GAME } from '@/lib/audio/clips/practice'
 
type GameBreakPhase = 'initializing' | 'auto-starting' | 'selecting' | 'playing' | 'completed'
 
interface UseGameBreakAudioOptions {
  phase: GameBreakPhase
  isVisible: boolean
}
 
function pickRandom<T>(arr: readonly T[]): T {
  return arr[Math.floor(Math.random() * arr.length)]
}
 
/**
 * Speaks game break cues on phase transitions.
 *
 * - initializing → auto-starting: random game break announcement
 * - initializing → selecting: announcement + "Pick a game!" after delay
 */
export function useGameBreakAudio({ phase, isVisible }: UseGameBreakAudioOptions) {
  const prevPhaseRef = useRef<GameBreakPhase>(phase)
 
  const sayAnnouncement = useTTS(pickRandom(GAME_BREAK_ANNOUNCEMENT_CLIPS), {
    tone: 'celebration',
  })
  const sayPickAGame = useTTS(PICK_A_GAME, {
    tone: 'tutorial-instruction',
  })
 
  useEffect(() => {
    const prevPhase = prevPhaseRef.current
    prevPhaseRef.current = phase
 
    if (!isVisible) return
 
    // initializing → auto-starting: announce the game break
    if (prevPhase === 'initializing' && phase === 'auto-starting') {
      sayAnnouncement(pickRandom(GAME_BREAK_ANNOUNCEMENT_CLIPS))
      return
    }
 
    // initializing → selecting: announce + pick a game after a short delay
    if (prevPhase === 'initializing' && phase === 'selecting') {
      sayAnnouncement(pickRandom(GAME_BREAK_ANNOUNCEMENT_CLIPS)).then(() => {
        sayPickAGame()
      })
      return
    }
  }, [phase, isVisible, sayAnnouncement, sayPickAGame])
}