All files / web/src/components/toys/euclid GeometryTeacherContext.tsx

0% Statements 0/45
0% Branches 0/1
0% Functions 0/1
0% Lines 0/45

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                                                                                           
'use client'

/**
 * React context for the active geometry teacher character.
 *
 * Provides a GeometryTeacherConfig to all descendants, allowing
 * components and hooks to read character-specific config without
 * hardcoding imports.
 *
 * Also wraps children in a VoiceChainProvider so that any useTTS
 * calls within the subtree automatically use the character's voice.
 */

import { createContext, useContext, useMemo } from 'react'
import type { GeometryTeacherConfig } from './GeometryTeacherConfig'
import { VoiceChainProvider } from '@/lib/audio/VoiceChainContext'
import { PregeneratedVoice } from '@/lib/audio/voiceSource'

const GeometryTeacherContext = createContext<GeometryTeacherConfig | null>(null)

export function GeometryTeacherProvider({
  config,
  children,
}: {
  config: GeometryTeacherConfig
  children: React.ReactNode
}) {
  const ttsVoice = config.voice.ttsVoice ?? config.voice.id
  const characterChain = useMemo(() => [new PregeneratedVoice(ttsVoice)], [ttsVoice])

  return (
    <GeometryTeacherContext.Provider value={config}>
      <VoiceChainProvider voices={characterChain}>{children}</VoiceChainProvider>
    </GeometryTeacherContext.Provider>
  )
}

/** Read the active geometry teacher config. Throws if used outside a provider. */
export function useGeometryTeacher(): GeometryTeacherConfig {
  const config = useContext(GeometryTeacherContext)
  if (!config) {
    throw new Error('useGeometryTeacher must be used within a GeometryTeacherProvider')
  }
  return config
}