From bc0b43151d172ccbe29331cce2854c5ef48248ce Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 8 May 2026 07:54:08 +0200 Subject: [PATCH] convert settings helpers to modules --- public/index.html | 6 +- public/js/transcriptionSettings.js | 105 ++++------------------- public/js/ui-state.js | 32 ++++--- public/js/voicePreferences.js | 3 - test/module-entrypoints.test.js | 3 + test/transcription-memory-policy.test.js | 1 + 6 files changed, 38 insertions(+), 112 deletions(-) diff --git a/public/index.html b/public/index.html index 0e506af..a9a2292 100644 --- a/public/index.html +++ b/public/index.html @@ -477,10 +477,10 @@ - - + + - + diff --git a/public/js/transcriptionSettings.js b/public/js/transcriptionSettings.js index 5d920c0..7994dae 100644 --- a/public/js/transcriptionSettings.js +++ b/public/js/transcriptionSettings.js @@ -1,8 +1,7 @@ // ============================================================ -// TRANSCRIPTION SETTINGS — Browser Whisper + Web Speech API +// TRANSCRIPTION SETTINGS — Web Speech API // ============================================================ -(function() { var _inited = false; document.addEventListener('tabChanged', function(e) { @@ -15,7 +14,7 @@ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { setTimeout(function() { - if (!_inited && document.getElementById('browser-whisper-enabled')) { + if (!_inited && document.getElementById('web-speech-enabled')) { _inited = true; initTranscriptionSettings(); } @@ -23,7 +22,7 @@ }); } else { setTimeout(function() { - if (!_inited && document.getElementById('browser-whisper-enabled')) { + if (!_inited && document.getElementById('web-speech-enabled')) { _inited = true; initTranscriptionSettings(); } @@ -33,78 +32,6 @@ function initTranscriptionSettings() { console.log('[TranscriptionSettings] Initializing...'); - // ── Browser Whisper ────────────────────────────────────── - var whisperCheckbox = document.getElementById('browser-whisper-enabled'); - var whisperStatus = document.getElementById('browser-whisper-status'); - var whisperModel = document.getElementById('browser-whisper-model'); - var whisperPreload = document.getElementById('btn-whisper-preload'); - var whisperProgress = document.getElementById('browser-whisper-progress'); - var whisperProgressText = document.getElementById('browser-whisper-progress-text'); - - if (whisperCheckbox && window.BrowserWhisper) { - whisperCheckbox.checked = BrowserWhisper.isEnabled(); - whisperStatus.textContent = BrowserWhisper.isEnabled() ? 'On — audio stays on device' : 'Off'; - - if (whisperModel) { - whisperModel.value = BrowserWhisper.getModel(); - } - - whisperCheckbox.addEventListener('change', function() { - BrowserWhisper.setEnabled(whisperCheckbox.checked); - whisperStatus.textContent = whisperCheckbox.checked ? 'On — audio stays on device' : 'Off'; - - if (whisperCheckbox.checked) { - // Auto-preload on enable - BrowserWhisper.preload(function(file, pct) { - if (whisperProgress && whisperProgressText) { - if (pct >= 100) { - whisperProgress.style.display = 'none'; - return; - } - whisperProgress.style.display = 'block'; - whisperProgressText.textContent = file + (pct > 0 ? ' ' + pct + '%' : ''); - } - }); - } - }); - - if (whisperModel) { - whisperModel.addEventListener('change', function() { - BrowserWhisper.setModel(whisperModel.value); - }); - } - - if (whisperPreload) { - whisperPreload.addEventListener('click', function() { - if (!BrowserWhisper || !BrowserWhisper.isSupported()) { - showToast('Browser Whisper not supported', 'error'); - return; - } - - whisperPreload.disabled = true; - whisperPreload.innerHTML = ' Downloading...'; - whisperProgress.style.display = 'block'; - whisperProgressText.textContent = 'Initializing...'; - - BrowserWhisper.setEnabled(true); - whisperCheckbox.checked = true; - whisperStatus.textContent = 'On — audio stays on device'; - - BrowserWhisper.preload(function(file, pct) { - if (pct >= 100) { - whisperProgress.style.display = 'none'; - whisperPreload.disabled = false; - whisperPreload.innerHTML = ' Pre-download model'; - showToast('Whisper model ready!', 'success'); - return; - } - whisperProgress.style.display = 'block'; - whisperProgressText.textContent = file + (pct > 0 ? ' ' + pct + '%' : ''); - }); - }); - } - } - // ── Web Speech Recognition ─────────────────────────────── var speechCheckbox = document.getElementById('web-speech-enabled'); var speechStatus = document.getElementById('web-speech-status'); @@ -117,10 +44,10 @@ // Show privacy info if (speechBrowserInfo) { var privacyInfo = WebSpeechRecognition.getPrivacyInfo(); - speechBrowserInfo.innerHTML = - 'Provider: ' + privacyInfo.provider + '
' + - 'Privacy: ' + privacyInfo.privacy + '
' + - '⚠️ ' + privacyInfo.warning + ''; + speechBrowserInfo.textContent = ''; + appendPrivacyLine(speechBrowserInfo, 'Provider: ', privacyInfo.provider); + appendPrivacyLine(speechBrowserInfo, 'Privacy: ', privacyInfo.privacy); + appendPrivacyLine(speechBrowserInfo, 'Warning: ', privacyInfo.warning, true); } speechCheckbox.addEventListener('change', function() { @@ -132,13 +59,6 @@ 'This is NOT HIPAA-compliant. ' + 'Only enable if you understand and accept this privacy trade-off.', function() { - // Disable Browser Whisper if enabling Web Speech - if (whisperCheckbox && whisperCheckbox.checked) { - whisperCheckbox.checked = false; - BrowserWhisper.setEnabled(false); - whisperStatus.textContent = 'Off'; - showToast('Browser Whisper disabled (Web Speech takes priority)', 'info'); - } WebSpeechRecognition.setEnabled(true); speechStatus.textContent = 'On — real-time streaming'; }, @@ -158,7 +78,7 @@ speechCheckbox.disabled = true; speechStatus.textContent = 'Not supported in this browser'; if (speechBrowserInfo) { - speechBrowserInfo.innerHTML = 'Not supported - Web Speech API not available in this browser.'; + speechBrowserInfo.textContent = 'Not supported - Web Speech API not available in this browser.'; } } } @@ -166,4 +86,11 @@ console.log('✅ Transcription settings initialized'); } -})(); + function appendPrivacyLine(container, label, value, warning) { + var strong = document.createElement('strong'); + strong.textContent = label; + if (warning) strong.style.color = 'var(--orange)'; + container.appendChild(strong); + container.appendChild(document.createTextNode(value)); + container.appendChild(document.createElement('br')); + } diff --git a/public/js/ui-state.js b/public/js/ui-state.js index 9dc9d40..d0aa770 100644 --- a/public/js/ui-state.js +++ b/public/js/ui-state.js @@ -14,22 +14,20 @@ // the UI. // ============================================================ -(function () { - var PREFIX = 'ped_ui/'; +var PREFIX = 'ped_ui/'; - function get(key) { - try { return localStorage.getItem(PREFIX + key); } catch (e) { return null; } - } - function set(key, value) { - try { localStorage.setItem(PREFIX + key, value); } catch (e) {} - } - function del(key) { - try { localStorage.removeItem(PREFIX + key); } catch (e) {} - } +function get(key) { + try { return localStorage.getItem(PREFIX + key); } catch (e) { return null; } +} +function set(key, value) { + try { localStorage.setItem(PREFIX + key, value); } catch (e) {} +} +function del(key) { + try { localStorage.removeItem(PREFIX + key); } catch (e) {} +} - window.UIState = { - get: get, - set: set, - del: del, - }; -})(); +window.UIState = { + get: get, + set: set, + del: del, +}; diff --git a/public/js/voicePreferences.js b/public/js/voicePreferences.js index bdc24d5..1e7e203 100644 --- a/public/js/voicePreferences.js +++ b/public/js/voicePreferences.js @@ -2,7 +2,6 @@ // VOICE PREFERENCES — STT Model & TTS Voice selection // ============================================================ -(function() { var _inited = false; // Listen for tab changes (correct event name is 'tabChanged' not 'tab-loaded') @@ -205,5 +204,3 @@ } }); } - -})(); diff --git a/test/module-entrypoints.test.js b/test/module-entrypoints.test.js index 538074f..b0e4eed 100644 --- a/test/module-entrypoints.test.js +++ b/test/module-entrypoints.test.js @@ -20,7 +20,10 @@ const moduleEntrypoints = [ 'public/js/notes.js', 'public/js/sickVisit.js', 'public/js/soap.js', + 'public/js/transcriptionSettings.js', + 'public/js/ui-state.js', 'public/js/wellVisit.js', + 'public/js/voicePreferences.js', 'public/js/documents.js' ]; diff --git a/test/transcription-memory-policy.test.js b/test/transcription-memory-policy.test.js index 0d25d0c..b6ff599 100644 --- a/test/transcription-memory-policy.test.js +++ b/test/transcription-memory-policy.test.js @@ -44,6 +44,7 @@ test('browser Whisper is removed from public runtime and user settings', () => { const publicRuntimeFiles = [ 'public/index.html', 'public/js/app.js', + 'public/js/transcriptionSettings.js', 'public/components/settings.html', 'public/components/faq.html' ];