From 09e36649a560f1a002aa435e824c37510d5df528 Mon Sep 17 00:00:00 2001 From: saifxyzyz Date: Fri, 31 Oct 2025 18:42:12 +0530 Subject: [PATCH] adding speech-to-text func --- app/static/js/speech.js | 91 ++++++++++++++++++++++++++++ app/templates/header.html | 123 +++++++++++++++++++++++--------------- app/templates/index.html | 59 ++++++++++++------ app/templates/search.html | 5 +- 4 files changed, 210 insertions(+), 68 deletions(-) create mode 100644 app/static/js/speech.js diff --git a/app/static/js/speech.js b/app/static/js/speech.js new file mode 100644 index 0000000000..e9f63f404c --- /dev/null +++ b/app/static/js/speech.js @@ -0,0 +1,91 @@ +document.addEventListener('DOMContentLoaded', () => { + const speechToTextBtns = document.querySelectorAll('.speech-to-text-btn'); + + if (speechToTextBtns.length === 0) { + console.warn('Speech-to-text buttons not found.'); + return; + } + + const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; + + if (!SpeechRecognition) { + console.warn('Web Speech API is not supported in this browser.'); + speechToTextBtns.forEach(btn => btn.style.display = 'none'); // Hide all buttons if API not supported + return; + } + + const recognition = new SpeechRecognition(); + recognition.continuous = false; + recognition.lang = 'en-US'; + recognition.interimResults = false; + recognition.maxAlternatives = 1; + + let activeBtn = null; + let activeSearchInput = null; + let activeSearchForm = null; + + speechToTextBtns.forEach(btn => { + btn.addEventListener('click', () => { + activeBtn = btn; + activeSearchForm = btn.closest('form'); + if (activeSearchForm) { + activeSearchInput = activeSearchForm.querySelector('input[name="q"]'); + } + + if (!activeSearchInput) { + console.error('Could not find search input associated with the button.'); + return; + } + + activeBtn.disabled = true; + activeBtn.textContent = '🔴'; // Indicate listening + activeSearchInput.placeholder = 'Listening...'; + recognition.start(); + }); + }); + + recognition.onresult = (event) => { + if (!activeSearchInput) return; + const speechResult = event.results[0][0].transcript; + activeSearchInput.value = speechResult; + console.log('Speech result: ' + speechResult); + console.log('Confidence: ' + event.results[0][0].confidence); + }; + + recognition.onspeechend = () => { + recognition.stop(); + if (activeBtn) { + activeBtn.disabled = false; + activeBtn.textContent = '🎙️'; // Reset button text + } + if (activeSearchInput) { + activeSearchInput.placeholder = 'Whoogle Search'; + } + if (activeSearchForm) { + activeSearchForm.submit(); // Automatically submit the form + } + }; + + recognition.onerror = (event) => { + if (activeBtn) { + activeBtn.disabled = false; + activeBtn.textContent = '🎙️'; // Reset button text + } + if (activeSearchInput) { + activeSearchInput.placeholder = 'Whoogle Search'; + } + console.error('Speech recognition error: ' + event.error); + if (event.error === 'no-speech') { + alert('No speech was detected. Please try again.'); + } else if (event.error === 'not-allowed') { + alert('Microphone access was denied. Please allow access to use speech-to-text.'); + } else { + alert('An error occurred during speech recognition: ' + event.error); + } + }; + + recognition.onnomatch = () => { + console.log('Speech not recognized.'); + alert('Could not understand speech. Please try again.'); + }; +}); diff --git a/app/templates/header.html b/app/templates/header.html index 5d0b85707d..2e306faf27 100644 --- a/app/templates/header.html +++ b/app/templates/header.html @@ -9,31 +9,31 @@ {{ logo|safe }} -
-
- {% if config.preferences %} - - {% endif %} - - - - - -
-
-
- +
+
+ {% if config.preferences %} + + {% endif %} + + + + + + +
+
+
@@ -71,30 +71,30 @@ class="search-form" id="sf" method="{{ 'GET' if config.get_only else 'POST' }}"> -
-
- {% if config.preferences %} - - {% endif %} - - - - - -
-
-
- +
+
+ {% if config.preferences %} + + {% endif %} + + + + + + +
+
+
@@ -160,3 +160,28 @@ {% else %} {% endif %} + + diff --git a/app/templates/index.html b/app/templates/index.html index aa26dcd31b..87b84fd4ad 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -25,6 +25,7 @@ {% endif %} {% endif %} + {% if bundle_static() %} @@ -66,6 +67,30 @@ + Whoogle Search @@ -75,23 +100,23 @@
-
- {% if config.preferences %} - - {% endif %} - -
- +
+ {% if config.preferences %} + + {% endif %} + + +
{% if not config_disabled %} diff --git a/app/templates/search.html b/app/templates/search.html index 073b7edca7..27d6371b88 100644 --- a/app/templates/search.html +++ b/app/templates/search.html @@ -2,7 +2,7 @@ - + +