diff --git a/docs/chat-dialog.png b/docs/chat-dialog.png index 441de422..4fbb5d5f 100644 Binary files a/docs/chat-dialog.png and b/docs/chat-dialog.png differ diff --git a/src/main/resources/static/resources/css/chat.css b/src/main/resources/static/resources/css/chat.css index 4fcc4e91..43e29cb1 100644 --- a/src/main/resources/static/resources/css/chat.css +++ b/src/main/resources/static/resources/css/chat.css @@ -4,7 +4,7 @@ position: fixed; bottom: 10px; right: 10px; - width: 300px; + width: 400px; background-color: #f1f1f1; border-radius: 10px; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); @@ -52,7 +52,7 @@ /* Chat bubbles styling */ .chat-bubble { - max-width: 80%; + max-width: 85%; padding: 10px; border-radius: 20px; margin-bottom: 10px; @@ -113,3 +113,64 @@ .chatbox-footer button:hover { background-color: #128C7E; } + +#mic-button { + margin-left: 0; + border-radius: 50%; + width: 40px; + height: 40px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; +} + +#mic-button.active { + background-color: #dc3545; + border-color: #dc3545; + color: white; +} + +#mic-button.active:hover { + background-color: #bb2d3b; + border-color: #b02a37; +} + +#mic-button i { + font-size: 1.2em; +} + +/* Ajout du style pour le bouton d'envoi */ +#chatbox-input-container { + padding: 10px; + background-color: #f9f9f9; + display: flex; + align-items: center; + gap: 5px; +} + +#chatbox-input { + flex: 1; + padding: 8px; + border-radius: 20px; + border: 1px solid #ccc; + resize: none; + outline: none; + margin: 0; +} + +#chatbox-input-container button { + flex-shrink: 0; /* Empêche les boutons de rétrécir */ + border-radius: 50%; + width: 40px; + height: 40px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + margin: 0; +} + +#chatbox-input-container button i { + font-size: 1.2em; +} diff --git a/src/main/resources/static/resources/js/chat.js b/src/main/resources/static/resources/js/chat.js index 2e8e6612..131cbab4 100644 --- a/src/main/resources/static/resources/js/chat.js +++ b/src/main/resources/static/resources/js/chat.js @@ -104,10 +104,11 @@ async function displayBotReply(response) { } } -function handleKeyPress(event) { - if (event.key === "Enter") { - event.preventDefault(); // Prevents adding a newline - sendMessage(); // Send the message when Enter is pressed +function handleKeyDown(event) { + // If it's the Enter key without the Shift key + if (event.key === 'Enter' && !event.shiftKey) { + event.preventDefault(); // Prevents line feed + sendMessage(); } } @@ -134,3 +135,100 @@ function uuidv4() { return v.toString(16); }); } + +let recognition = null; +let isListening = false; + +function initializeSpeechRecognition() { + if ('webkitSpeechRecognition' in window) { + recognition = new webkitSpeechRecognition(); + recognition.continuous = false; + recognition.interimResults = true; + + const browserLang = navigator.language || navigator.userLanguage; + recognition.lang = browserLang || 'en-US'; + + let finalTranscript = ''; + + recognition.onresult = function(event) { + const input = document.getElementById('chatbox-input'); + const lastResult = event.results[event.results.length - 1]; + + if (lastResult.isFinal) { + finalTranscript = lastResult[0].transcript; + input.value = finalTranscript; + recognition.stop(); + } else { + input.value = finalTranscript + lastResult[0].transcript; + } + }; + + recognition.onend = function() { + const input = document.getElementById('chatbox-input'); + if (input.value.trim()) { + setTimeout(() => { + sendMessage(); + }, 100); + } + toggleMicrophoneButton(false); + isListening = false; + finalTranscript = ''; + }; + + recognition.onerror = function(event) { + const userElements = prepareMessage('bot'); + let errorMessage = 'Speech recognition error: '; + + switch(event.error) { + case 'network': + errorMessage += 'Network error occurred'; + break; + case 'no-speech': + errorMessage += 'No speech was detected'; + break; + case 'not-allowed': + errorMessage += 'Microphone access was denied'; + break; + default: + errorMessage += 'An unknown error occurred'; + } + + displayMessage(errorMessage, userElements); + toggleMicrophoneButton(false); + }; + } else { + const userElements = prepareMessage('bot'); + displayMessage('Speech recognition is not supported by your browser. Please try using a modern browser like Chrome.', userElements); + } +} + +function toggleSpeechRecognition() { + if (!recognition) { + initializeSpeechRecognition(); + } + + if (!isListening) { + try { + recognition.start(); + isListening = true; + toggleMicrophoneButton(true); + } catch (error) { + const userElements = prepareMessage('bot'); + displayMessage('Could not start speech recognition. Please make sure you have granted microphone permissions.', userElements); + toggleMicrophoneButton(false); + } + } else { + recognition.stop(); + isListening = false; + toggleMicrophoneButton(false); + } +} + +function toggleMicrophoneButton(isActive) { + const micButton = document.getElementById('mic-button'); + if (isActive) { + micButton.classList.add('active'); + } else { + micButton.classList.remove('active'); + } +} diff --git a/src/main/resources/templates/fragments/layout.html b/src/main/resources/templates/fragments/layout.html index 395cb024..1b084a08 100644 --- a/src/main/resources/templates/fragments/layout.html +++ b/src/main/resources/templates/fragments/layout.html @@ -95,9 +95,18 @@
-