From 146b4be5494c95ece0e40ac88276c5bfbd87e197 Mon Sep 17 00:00:00 2001 From: balex Date: Sun, 1 Mar 2026 16:35:48 +0100 Subject: [PATCH] max words --- src/public/index.html | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/public/index.html b/src/public/index.html index af1a827..fd8eb09 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -323,7 +323,7 @@ font-size: 14px; } - .transcript-box.interim { color: var(--text-dim); } + .transcript-box[contenteditable="true"] { outline: none; cursor: text; border-color: var(--accent); } /* ── Actions ── */ .actions { @@ -830,6 +830,7 @@ function loadQuestion() { function resetPracticeUI() { state.transcript = ''; + transcriptBox.contentEditable = 'false'; updateTranscriptBox('', false); feedbackBox.classList.remove('visible'); feedbackContent.innerHTML = ''; @@ -866,8 +867,8 @@ speakBtn.addEventListener('click', () => { // ── Speech recognition ──────────────────────────────────────────────────────── const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; -const MAX_RECORD_SECONDS = 10; -const MAX_RECORD_WORDS = 30; +const MAX_RECORD_SECONDS = 20; +const MAX_RECORD_WORDS = 60; function initRecognition() { if (!SpeechRecognition) return null; @@ -875,7 +876,7 @@ function initRecognition() { const r = new SpeechRecognition(); r.lang = 'de-DE'; r.continuous = true; - r.interimResults = true; + r.interimResults = false; r.maxAlternatives = 1; let finalText = ''; @@ -888,32 +889,22 @@ function initRecognition() { }; r.onresult = (e) => { - let interim = ''; for (let i = e.resultIndex; i < e.results.length; i++) { - const t = e.results[i][0].transcript; if (e.results[i].isFinal) { - finalText += (finalText ? ' ' : '') + t; - } else { - interim = t; + finalText += (finalText ? ' ' : '') + e.results[i][0].transcript; } } if (finalText.trim().split(/\s+/).length >= MAX_RECORD_WORDS) { stopRecording(); return; } - const display = finalText + (interim ? ' ' + interim : ''); - updateTranscriptBox(display, !!interim); + updateTranscriptBox(finalText, false); state.transcript = finalText; checkBtn.disabled = !finalText.trim(); }; r.onend = () => { - if (state.isRecording) { - // create a fresh instance to avoid duplicate results on restart - const fresh = initRecognition(); - recognition = fresh; - try { fresh.start(); } catch (_) {} - } + if (state.isRecording) stopRecording(); }; r.onerror = (e) => { @@ -933,6 +924,7 @@ function startRecording() { return; } stopAudio(); + transcriptBox.contentEditable = 'false'; recognition = initRecognition(); state.isRecording = true; try { recognition.start(); } catch (_) {} @@ -950,6 +942,10 @@ function stopRecording() { } recordBtn.classList.remove('recording'); recordHint.textContent = 'Tippen zum Aufnehmen'; + if (state.transcript) { + transcriptBox.contentEditable = 'true'; + transcriptBox.focus(); + } } recordBtn.addEventListener('click', () => { @@ -972,10 +968,16 @@ function updateTranscriptBox(text, isInterim) { } } +transcriptBox.addEventListener('input', () => { + state.transcript = transcriptBox.textContent.trim(); + checkBtn.disabled = !state.transcript; +}); + // ── Clear ───────────────────────────────────────────────────────────────────── clearBtn.addEventListener('click', () => { stopRecording(); state.transcript = ''; + transcriptBox.contentEditable = 'false'; updateTranscriptBox('', false); checkBtn.disabled = true; feedbackBox.classList.remove('visible');