Show Piper model download progress
Build and publish frontend / publish (push) Successful in 47s

This commit is contained in:
Ein Anderssono
2026-10-16 07:49:58 +02:00
parent ccaa14896c
commit 846bfec04d
4 changed files with 61 additions and 6 deletions
+39 -2
View File
@@ -20,6 +20,8 @@
#message { width: 100%; min-height: 3.5rem; box-sizing: border-box; }
#message-tools { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
#voice-status { min-height: 1.5em; }
#speech-progress { width: min(100%, 32rem); height: 1.25rem; }
#speech-progress-value { margin-inline-start: .5rem; font-variant-numeric: tabular-nums; }
#dialogue li[data-role="voice-controls"] { border: 1px solid currentColor; border-radius: .35rem; padding: .75rem; }
#dialogue li[data-role="voice-controls"] fieldset { display: grid; gap: .5rem; margin-block: .5rem; }
#admin-content { display: grid; gap: 1rem; }
@@ -56,6 +58,11 @@
<span id="message-help" class="sr-only">Tryck Enter för att skicka. Tryck Skift och Enter för ny rad.</span>
</form>
<p id="voice-status" role="status" aria-live="polite"></p>
<div id="speech-progress-container" hidden>
<label for="speech-progress">Hämtar svensk röstmodell till enheten</label>
<progress id="speech-progress" aria-label="Nedladdning av svensk röstmodell"></progress>
<output id="speech-progress-value" for="speech-progress">Väntar på nedladdning</output>
</div>
</section>
<section id="admin-view" aria-labelledby="admin-heading" hidden>
<h1 id="admin-heading">Administration</h1>
@@ -157,6 +164,29 @@
const authVoiceStatus = document.querySelector('#auth-voice-status');
if (authVoiceStatus && !auth.hidden && message) authVoiceStatus.textContent = message;
}
function updateSpeechProgress(message = '') {
const container = document.querySelector('#speech-progress-container');
const progress = document.querySelector('#speech-progress');
const value = document.querySelector('#speech-progress-value');
const preparing = message.startsWith('Förbereder svensk uppläsning.');
const match = message.match(/^Hämtar svensk röstmodell till enheten: (\d+) procent\.$/);
if (!preparing && !match) {
container.hidden = true;
progress.removeAttribute('value');
value.textContent = 'Väntar på nedladdning';
return false;
}
container.hidden = false;
if (match) {
const percent = Math.max(0, Math.min(100, Number(match[1])));
progress.value = percent;
value.textContent = `${percent}%`;
return true;
}
progress.removeAttribute('value');
value.textContent = 'Förbereder…';
return true;
}
function clearSpeechRecovery() {
speechRecoveryElement?.remove();
speechRecoveryElement = null;
@@ -218,8 +248,15 @@
microphone.setAttribute('aria-pressed', String(listening));
microphone.textContent = listening ? 'Avsluta mikrofon' : 'Starta mikrofon';
refreshMicrophone();
if (message) setVoiceStatus(message);
else if (state === 'IDLE') setVoiceStatus('');
if (message) {
const downloading = updateSpeechProgress(message);
setVoiceStatus(downloading && message.startsWith('Hämtar svensk röstmodell')
? 'Hämtar svensk röstmodell till enheten.'
: message);
} else if (state === 'IDLE') {
updateSpeechProgress('');
setVoiceStatus('');
}
if (/Läs senaste repliken/.test(message)) showSpeechRecovery(message);
playVoiceSignal(state === 'IDLE' && /Mikrofonen är avstängd/.test(message) ? 'STOPPED' : state);
},