diff --git a/hooks/useSpeechRecognition.ts b/hooks/useSpeechRecognition.ts deleted file mode 100644 index f2f854f..0000000 --- a/hooks/useSpeechRecognition.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { useState, useEffect, useCallback, useRef } from 'react'; -import { Platform, Alert } from 'react-native'; -import { debugLogger } from '@/services/DebugLogger'; - -// Try to import native module -let ExpoSpeechRecognitionModule: any = null; -let SPEECH_RECOGNITION_AVAILABLE = false; -try { - const speechRecognition = require('expo-speech-recognition'); - ExpoSpeechRecognitionModule = speechRecognition.ExpoSpeechRecognitionModule; - if (ExpoSpeechRecognitionModule) { - SPEECH_RECOGNITION_AVAILABLE = true; - debugLogger.info('STT', 'Speech recognition module loaded successfully'); - } -} catch (e) { - debugLogger.warn('STT', 'Speech recognition not available', e); - console.log('[useSpeechRecognition] expo-speech-recognition not available'); -} - -export interface SpeechRecognitionResult { - transcript: string; - isFinal: boolean; -} - -export interface UseSpeechRecognitionReturn { - isListening: boolean; - recognizedText: string; - startListening: (options?: { continuous?: boolean }) => Promise; - stopListening: () => void; - isAvailable: boolean; - hasPermission: boolean; - requestPermission: () => Promise; -} - -export function useSpeechRecognition(): UseSpeechRecognitionReturn { - const [isListening, setIsListening] = useState(false); - const [recognizedText, setRecognizedText] = useState(''); - const [hasPermission, setHasPermission] = useState(false); - - // Callbacks - const onResultRef = useRef<((result: SpeechRecognitionResult) => void) | null>(null); - - useEffect(() => { - if (!SPEECH_RECOGNITION_AVAILABLE || !ExpoSpeechRecognitionModule) { - debugLogger.warn('STT', 'Cannot setup listeners - module not available'); - return; - } - - debugLogger.info('STT', 'Setting up speech recognition event listeners'); - const subscriptions: any[] = []; - - if (ExpoSpeechRecognitionModule.addListener) { - subscriptions.push( - ExpoSpeechRecognitionModule.addListener('start', () => { - debugLogger.info('STT', 'Speech recognition started'); - setIsListening(true); - }) - ); - subscriptions.push( - ExpoSpeechRecognitionModule.addListener('end', () => { - debugLogger.info('STT', 'Speech recognition ended'); - setIsListening(false); - }) - ); - subscriptions.push( - ExpoSpeechRecognitionModule.addListener('result', (event: any) => { - const transcript = event.results?.[0]?.transcript || ''; - const isFinal = event.results?.[0]?.isFinal || false; - debugLogger.log('STT', `Recognized: "${transcript}" (${isFinal ? 'FINAL' : 'interim'})`); - setRecognizedText(transcript); - }) - ); - subscriptions.push( - ExpoSpeechRecognitionModule.addListener('error', (event: any) => { - debugLogger.error('STT', 'Speech recognition error', event); - setIsListening(false); - console.warn('[Speech] Error:', event); - }) - ); - } - - return () => { - debugLogger.info('STT', 'Cleaning up speech recognition listeners'); - subscriptions.forEach(sub => sub.remove?.()); - }; - }, []); - - const requestPermission = async () => { - if (!SPEECH_RECOGNITION_AVAILABLE) { - debugLogger.warn('STT', 'Cannot request permission - module not available'); - return false; - } - debugLogger.info('STT', 'Requesting microphone permissions'); - const result = await ExpoSpeechRecognitionModule.requestPermissionsAsync(); - setHasPermission(result.granted); - debugLogger.log('STT', `Permission ${result.granted ? 'granted' : 'denied'}`); - return result.granted; - }; - - const startListening = async (options?: { continuous?: boolean }) => { - if (!SPEECH_RECOGNITION_AVAILABLE) { - debugLogger.error('STT', 'Cannot start - speech recognition not available'); - Alert.alert('Not Available', 'Voice recognition is not available on this device.'); - return; - } - - try { - // Reset text - setRecognizedText(''); - debugLogger.info('STT', `Starting speech recognition (continuous: ${options?.continuous ?? false})`); - - await ExpoSpeechRecognitionModule.start({ - lang: 'en-US', - interimResults: true, - maxAlternatives: 1, - continuous: options?.continuous ?? false, - }); - } catch (e) { - debugLogger.error('STT', 'Failed to start listening', e); - console.error('Failed to start listening', e); - setIsListening(false); - } - }; - - const stopListening = () => { - debugLogger.info('STT', 'Stopping speech recognition'); - if (SPEECH_RECOGNITION_AVAILABLE) { - ExpoSpeechRecognitionModule.stop(); - } - setIsListening(false); - }; - - return { - isListening, - recognizedText, - startListening, - stopListening, - isAvailable: SPEECH_RECOGNITION_AVAILABLE, - hasPermission, - requestPermission - }; -} diff --git a/package-lock.json b/package-lock.json index 4a3fb8c..c695350 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,8 +29,6 @@ "expo-linking": "~8.0.10", "expo-router": "~6.0.19", "expo-secure-store": "^15.0.8", - "expo-speech": "~14.0.8", - "expo-speech-recognition": "^3.0.1", "expo-splash-screen": "~31.0.12", "expo-status-bar": "~3.0.9", "expo-symbols": "~1.0.8", @@ -7387,26 +7385,6 @@ "node": ">=20.16.0" } }, - "node_modules/expo-speech": { - "version": "14.0.8", - "resolved": "https://registry.npmjs.org/expo-speech/-/expo-speech-14.0.8.tgz", - "integrity": "sha512-UjBFCFv58nutlLw92L7kUS0ZjbOOfaTdiEv/HbjvMrT6BfldoOLLBZbaEcEhDdZK36NY/kass0Kzxk+co6vxSQ==", - "license": "MIT", - "peerDependencies": { - "expo": "*" - } - }, - "node_modules/expo-speech-recognition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/expo-speech-recognition/-/expo-speech-recognition-3.0.1.tgz", - "integrity": "sha512-sMyOE1Vq1635B2oG0irgv6MZo0axIva3yNMmy86fwSqcFI+y9GhfOqZnYx3PFq7A0tNP2AlaNZLA9+tkgBcLhQ==", - "license": "MIT", - "peerDependencies": { - "expo": "*", - "react": "*", - "react-native": "*" - } - }, "node_modules/expo-splash-screen": { "version": "31.0.12", "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-31.0.12.tgz", diff --git a/package.json b/package.json index 3a222b9..d8104b0 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,6 @@ "expo-linking": "~8.0.10", "expo-router": "~6.0.19", "expo-secure-store": "^15.0.8", - "expo-speech": "~14.0.8", - "expo-speech-recognition": "^3.0.1", "expo-splash-screen": "~31.0.12", "expo-status-bar": "~3.0.9", "expo-symbols": "~1.0.8",