diff --git a/package-lock.json b/package-lock.json index 91115fc..37f1ddb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@ant-design/plots": "^1.2.6", "@autocomplete/material-ui": "0.0.17", + "@capacitor-community/speech-recognition": "^7.0.1", "@capacitor-mlkit/barcode-scanning": "^8.0.1", "@capacitor/app": "^8.0.1", "@capacitor/core": "^8.1.0", @@ -962,6 +963,15 @@ "node": ">=6.9.0" } }, + "node_modules/@capacitor-community/speech-recognition": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@capacitor-community/speech-recognition/-/speech-recognition-7.0.1.tgz", + "integrity": "sha512-ykpBZziR575X0eURO5vXaD9gVrXXC/7Ra2qql/2KP6/jxWOqAFuw4eKjSPjwdAgGE6a/Z+v8FJm4SVh57MVwDA==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=7.0.0" + } + }, "node_modules/@capacitor-mlkit/barcode-scanning": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@capacitor-mlkit/barcode-scanning/-/barcode-scanning-8.0.1.tgz", diff --git a/package.json b/package.json index 8af1305..28f63d4 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "@ant-design/plots": "^1.2.6", "@autocomplete/material-ui": "0.0.17", + "@capacitor-community/speech-recognition": "^7.0.1", "@capacitor-mlkit/barcode-scanning": "^8.0.1", "@capacitor/app": "^8.0.1", "@capacitor/core": "^8.1.0", diff --git a/src/Pages/VoiceToText/VoiceToTextItemCard.jsx b/src/Pages/VoiceToText/VoiceToTextItemCard.jsx index 99547a0..3e11a4f 100644 --- a/src/Pages/VoiceToText/VoiceToTextItemCard.jsx +++ b/src/Pages/VoiceToText/VoiceToTextItemCard.jsx @@ -1,6 +1,9 @@ import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from "react"; import { FaMicrophone, FaMicrophoneSlash } from "react-icons/fa"; import './VoiceToText.scss' +import { Capacitor } from "@capacitor/core"; +import { SpeechRecognition } from "@capacitor-community/speech-recognition"; + const VoiceToTextItemCard = forwardRef(({ setVoiceData, setprodQty, uomNames = [] }, ref) => { const [formData, setFormData] = useState({ product: "", qty: "", uom: "" }); const [transcript, setTranscript] = useState(""); @@ -106,37 +109,126 @@ const VoiceToTextItemCard = forwardRef(({ setVoiceData, setprodQty, uomNames = [ // setTranscript(""); // setVoiceData && setVoiceData(""); // }; - const startListening = async () => { - try { - // Step 1: Check microphone access - const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); - stream.getTracks().forEach(track => track.stop()); // stop test mic stream + //sree coment line + // const startListening = async () => { + // try { + // // Step 1: Check microphone access + // const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + // stream.getTracks().forEach(track => track.stop()); // stop test mic stream + + // // Step 2: Try starting speech recognition + // try { + // recognitionRef.current?.start(); + // setIsListening(true); + // setTranscript(""); + // if (setVoiceData) setVoiceData(""); + // } catch (err) { + // console.error("SpeechRecognition start error:", err); + // alert("Unable to start speech recognition. Please check mic access or try again."); + // setIsListening(false); + // } + + // } catch (error) { + // console.error("Microphone access denied or not available", error); + // alert("Microphone not connected or permission denied."); + // setIsListening(false); + // } + // }; + + const startListening = async () => { + + // Detect platform + const platform = Capacitor.getPlatform(); + + if (platform === "web") { + try { + + // Check microphone permission + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + stream.getTracks().forEach(track => track.stop()); - // Step 2: Try starting speech recognition - try { recognitionRef.current?.start(); setIsListening(true); setTranscript(""); + if (setVoiceData) setVoiceData(""); - } catch (err) { - console.error("SpeechRecognition start error:", err); - alert("Unable to start speech recognition. Please check mic access or try again."); + + } catch (error) { + + console.error("Microphone access denied or not available", error); + alert("Microphone not connected or permission denied."); setIsListening(false); } +} + else { + // 📱 Capacitor Android / iOS + try { - } catch (error) { - console.error("Microphone access denied or not available", error); - alert("Microphone not connected or permission denied."); + const permission = await SpeechRecognition.requestPermissions(); + + if (!permission.speechRecognition) { + alert("Speech recognition permission denied"); + return; + } + + setIsListening(true); + + const result = await SpeechRecognition.start({ + language: "en-US", + maxResults: 1, + partialResults: false, + }); + + if (result.matches && result.matches.length > 0) { + + const spokenText = result.matches[0]; + + setTranscript(spokenText); + + const { product, qty, uom } = extractEntities(spokenText); + + setFormData({ product, qty, uom }); + + if (setVoiceData) setVoiceData({ product, qty, uom }); + if (setprodQty) setprodQty(qty); + } + + setIsListening(false); + + } catch (err) { + console.error(err); setIsListening(false); } + } }; - const stopListening = () => { + + // const stopListening = () => { + // if (recognitionRef.current) { + // console.log("Stopping voice recognition..."); + // recognitionRef.current.stop(); + // } else { + // console.warn("Recognition not initialized"); + // } + + // setIsListening(false); + // }; + +const stopListening = async () => { + const platform = Capacitor.getPlatform(); + + try { + if (platform === "web") { if (recognitionRef.current) { - console.log("Stopping voice recognition..."); recognitionRef.current.stop(); + console.log("Stopping voice recognition..."); + } } else { - console.warn("Recognition not initialized"); + await SpeechRecognition.stop(); + console.log("Stopping native speech recognition..."); + } + } catch (error) { + console.error("Error stopping speech recognition:", error); } setIsListening(false);