convert settings helpers to modules

This commit is contained in:
Daniel 2026-05-08 07:54:08 +02:00
parent b6ebca0e6f
commit bc0b43151d
6 changed files with 38 additions and 112 deletions

View file

@ -477,10 +477,10 @@
<script defer src="/js/milestonesData.js"></script>
<script defer src="/js/audioBackup.js"></script>
<script defer src="/js/speechRecognition.js"></script>
<script defer src="/js/transcriptionSettings.js"></script>
<script defer src="/js/voicePreferences.js"></script>
<script type="module" src="/js/transcriptionSettings.js"></script>
<script type="module" src="/js/voicePreferences.js"></script>
<script defer src="/js/app.js?v=7.1.3"></script>
<script defer src="/js/ui-state.js"></script>
<script type="module" src="/js/ui-state.js"></script>
<script defer src="/js/secureStorage.js"></script>
<script defer src="/js/authFetch.js"></script>
<script defer src="/js/auth.js"></script>

View file

@ -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 = '<i class="fas fa-spinner fa-spin"></i> 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 = '<i class="fas fa-download"></i> 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 =
'<strong>Provider:</strong> ' + privacyInfo.provider + '<br>' +
'<strong>Privacy:</strong> ' + privacyInfo.privacy + '<br>' +
'<strong style="color:var(--orange);">⚠️ ' + privacyInfo.warning + '</strong>';
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 = '<strong style="color:var(--red);">Not supported</strong> - 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'));
}

View file

@ -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,
};

View file

@ -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 @@
}
});
}
})();

View file

@ -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'
];

View file

@ -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'
];