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 | 'use client' import { useEffect, useRef } from 'react' import { useTTS } from '@/hooks/useTTS' import type { TransitionMessage } from '../partTransitionMessages' interface UsePartTransitionAudioOptions { isVisible: boolean message: TransitionMessage abacusAction: string | null } /** * Speaks the part transition message when the transition screen becomes visible. * * Uses hash-based clip IDs since messages are randomly selected from pools. * Only plays once per visibility change. */ export function usePartTransitionAudio({ isVisible, message, abacusAction, }: UsePartTransitionAudioOptions) { const spokenText = [message.headline, message.subtitle, abacusAction].filter(Boolean).join('. ') const speak = useTTS({ say: { en: spokenText }, tone: 'tutorial-instruction' }) const hasPlayedRef = useRef(false) useEffect(() => { if (isVisible && !hasPlayedRef.current) { hasPlayedRef.current = true speak() } if (!isVisible) { hasPlayedRef.current = false } }, [isVisible, speak]) } |