diff --git a/client/package.json b/client/package.json
index 832a710..d6d9b89 100644
--- a/client/package.json
+++ b/client/package.json
@@ -17,6 +17,7 @@
"react-markdown": "^10.1.0",
"react-router-dom": "^6.28.1",
"react-scripts": "5.0.1",
+ "react-speech-recognition": "^4.0.0",
"rehype-highlight": "^7.0.2",
"rehype-katex": "^7.0.1",
"rehype-raw": "^7.0.0",
diff --git a/client/src/components/layout/index.tsx b/client/src/components/layout/index.tsx
index a30d217..e5eae19 100644
--- a/client/src/components/layout/index.tsx
+++ b/client/src/components/layout/index.tsx
@@ -3,6 +3,7 @@ import './index.css';
import { Outlet } from 'react-router-dom';
import SideBarNav from '../main/sideBarNav';
import Header from '../header';
+import VoiceNavigator from '../main/voiceRecognition';
/**
* Main component represents the layout of the main page, including a sidebar and the main content area.
@@ -13,6 +14,7 @@ const Layout = () => (
diff --git a/client/src/components/main/voiceRecognition/index.tsx b/client/src/components/main/voiceRecognition/index.tsx
new file mode 100644
index 0000000..5b5c2c3
--- /dev/null
+++ b/client/src/components/main/voiceRecognition/index.tsx
@@ -0,0 +1,26 @@
+import useVoiceRecognition from '../../../hooks/useVoiceRecognition';
+
+const VoiceNavigator = () => {
+ const { transcript, listening, browserSupportsSpeechRecognition, startL, stopL } =
+ useVoiceRecognition();
+
+ if (!browserSupportsSpeechRecognition) {
+ return Your browser doesn't support speech recognition.
;
+ }
+
+ return (
+
+
Status: {listening ? '🎙️ Listening...' : '🛑 Not listening'}
+
+
+
+
+ Transcript: {transcript}
+
+
+ );
+};
+
+export default VoiceNavigator;
diff --git a/client/src/hooks/useVoiceRecognition.ts b/client/src/hooks/useVoiceRecognition.ts
new file mode 100644
index 0000000..03c2360
--- /dev/null
+++ b/client/src/hooks/useVoiceRecognition.ts
@@ -0,0 +1,76 @@
+import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition';
+import { useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+
+const useVoiceRecognition = () => {
+ const navigate = useNavigate();
+ const startL = () => SpeechRecognition.startListening({ continuous: true });
+ const stopL = () => SpeechRecognition.stopListening();
+
+ const commands = [
+ {
+ command: ['Go to home', 'Open home', 'Home page'],
+ callback: () => navigate('/home'),
+ },
+ {
+ command: [
+ 'Open chats',
+ 'Go to chats',
+ 'Chat page',
+ 'Chats',
+ 'Messages',
+ 'Go to messages',
+ 'Messages page',
+ ],
+ callback: () => navigate('/messages'),
+ },
+ {
+ command: ['Open questions', 'Go to questions', 'Questions', 'Question page'],
+ callback: () => navigate(`/questionPage`),
+ },
+ {
+ command: ['Open tags', 'Go to tags', 'Tags', 'Tags page'],
+ callback: () => navigate(`/tags`),
+ },
+ {
+ command: ['Open users', 'Go to users', 'Users', 'Users page'],
+ callback: () => navigate(`/users`),
+ },
+ {
+ command: ['Open games', 'Go to games', 'Games', 'Games page'],
+ callback: () => navigate(`/games`),
+ },
+ {
+ command: ['Open communities', 'Go to communities', 'Communities', 'Communities page'],
+ callback: () => navigate(`/communities/all`),
+ },
+ {
+ command: ['Go back', 'Navigate back'],
+ callback: () => navigate(-1),
+ },
+ {
+ command: 'Stop listening',
+ callback: () => SpeechRecognition.stopListening(),
+ },
+ ];
+
+ const { transcript, listening, browserSupportsSpeechRecognition } = useSpeechRecognition({
+ commands,
+ });
+
+ useEffect(() => {
+ if (browserSupportsSpeechRecognition) {
+ SpeechRecognition.startListening({ continuous: true });
+ }
+ }, [browserSupportsSpeechRecognition]);
+
+ return {
+ transcript,
+ listening,
+ browserSupportsSpeechRecognition,
+ startL,
+ stopL,
+ };
+};
+
+export default useVoiceRecognition;
diff --git a/package-lock.json b/package-lock.json
index c11a6aa..e4e4158 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,7 @@
"react-hotkeys-hook": "^4.6.1",
"react-icons": "^5.5.0",
"react-markdown": "^10.1.0",
+ "react-speech-recognition": "^4.0.0",
"rehype-highlight": "^7.0.2",
"rehype-katex": "^7.0.1",
"rehype-raw": "^7.0.0",
@@ -29,6 +30,9 @@
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"ts-node": "^10.9.2"
+ },
+ "devDependencies": {
+ "@types/react-speech-recognition": "^3.9.6"
}
},
"client": {
@@ -49,6 +53,7 @@
"react-markdown": "^10.1.0",
"react-router-dom": "^6.28.1",
"react-scripts": "5.0.1",
+ "react-speech-recognition": "^4.0.0",
"rehype-highlight": "^7.0.2",
"rehype-katex": "^7.0.1",
"rehype-raw": "^7.0.0",
@@ -4820,6 +4825,13 @@
"@types/ms": "*"
}
},
+ "node_modules/@types/dom-speech-recognition": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@types/dom-speech-recognition/-/dom-speech-recognition-0.0.6.tgz",
+ "integrity": "sha512-o7pAVq9UQPJL5RDjO1f/fcpfFHdgiMnR4PoIU2N/ZQrYOS3C5rzdOJMsrpqeBCbii2EE9mERXgqspQqPDdPahw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/eslint": {
"version": "8.56.12",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz",
@@ -5083,6 +5095,16 @@
"@types/react": "^18.0.0"
}
},
+ "node_modules/@types/react-speech-recognition": {
+ "version": "3.9.6",
+ "resolved": "https://registry.npmjs.org/@types/react-speech-recognition/-/react-speech-recognition-3.9.6.tgz",
+ "integrity": "sha512-cdzwXIZXWyp8zfM2XI7APDW1rZf4Nz73T4SIS2y+cC7zHnZluCdumYKH6HacxgxJH+zemAq2oXbHWXcyW0eT3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/dom-speech-recognition": "*"
+ }
+ },
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -24782,6 +24804,15 @@
"node": ">=10"
}
},
+ "node_modules/react-speech-recognition": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/react-speech-recognition/-/react-speech-recognition-4.0.0.tgz",
+ "integrity": "sha512-hz1OsRhjAW70rOMVXN84PR+1L2I1j8xS1TXpwpd4vlDaRY9i/LbAaxEklqscgObECTTuyxNeGBdVdcq/pX3bqQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
diff --git a/package.json b/package.json
index fea9aa6..b81d940 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"react-hotkeys-hook": "^4.6.1",
"react-icons": "^5.5.0",
"react-markdown": "^10.1.0",
+ "react-speech-recognition": "^4.0.0",
"rehype-highlight": "^7.0.2",
"rehype-katex": "^7.0.1",
"rehype-raw": "^7.0.0",
@@ -24,5 +25,8 @@
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"ts-node": "^10.9.2"
+ },
+ "devDependencies": {
+ "@types/react-speech-recognition": "^3.9.6"
}
}