// offscreen.js - Handles webkitSpeechRecognition in isolation let recognition = null; let isRecording = false; // Initialize recognition early if possible, or wait until start function initRecognition(language) { if (recognition) return recognition; const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; if (!SpeechRecognition) { throw new Error('Speech recognition not supported'); } recognition = new SpeechRecognition(); recognition.continuous = true; recognition.interimResults = true; recognition.lang = language || 'ar-SA'; recognition.maxAlternatives = 1; recognition.onresult = (event) => { let interimText = ''; let finalText = ''; for (let i = event.resultIndex; i < event.results.length; i++) { const result = event.results[i]; if (result.isFinal) { finalText += result[0].transcript + ' '; } else { interimText += result[0].transcript; } } // Send results back to background script chrome.runtime.sendMessage({ type: 'OFFSCREEN_RECORDING_RESULT', payload: { interimText, finalText } }); }; recognition.onerror = (event) => { console.error('[Offscreen] Recognition error:', event.error); chrome.runtime.sendMessage({ type: 'OFFSCREEN_RECORDING_ERROR', payload: { error: event.error } }); }; recognition.onend = () => { // If we still want to be recording, restart if (isRecording) { try { recognition.start(); } catch (e) { console.warn('[Offscreen] Restart failed:', e); } } else { chrome.runtime.sendMessage({ type: 'OFFSCREEN_RECORDING_END' }); } }; return recognition; } // Listen for messages from background script chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === 'START_RECORDING') { try { const lang = message.payload?.language || 'ar-SA'; // Re-init if language changed or not init yet if (!recognition || recognition.lang !== lang) { recognition = initRecognition(lang); } if (!isRecording) { recognition.start(); isRecording = true; sendResponse({ success: true }); } else { sendResponse({ success: true, warning: 'Already recording' }); } } catch (e) { console.error('[Offscreen] Failed to start:', e); sendResponse({ success: false, error: e.message }); } return true; } if (message.type === 'STOP_RECORDING') { if (isRecording && recognition) { isRecording = false; try { recognition.stop(); } catch (e) { console.warn('[Offscreen] Stop failed:', e); } } sendResponse({ success: true }); return true; } });