Skip to content

Commit 961b775

Browse files
authored
Update fast-search-card.js
1 parent 2f33801 commit 961b775

File tree

1 file changed

+97
-1
lines changed

1 file changed

+97
-1
lines changed

dist/fast-search-card.js

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10839,6 +10839,102 @@ class FastSearchCard extends HTMLElement {
1083910839
this.updateTTSButtonState('error');
1084010840
}
1084110841
}
10842+
10843+
updateTTSButtonState(state) {
10844+
// Finde den aktuell aktiven TTS Button
10845+
const activeTTSContainer = this.shadowRoot?.querySelector('.device-control-presets.tts-presets.visible') ||
10846+
document.querySelector('.device-control-presets.tts-presets.visible');
10847+
10848+
if (!activeTTSContainer) return;
10849+
10850+
const speakBtn = activeTTSContainer.querySelector('.tts-speak-btn');
10851+
const btnIcon = speakBtn?.querySelector('.tts-btn-icon');
10852+
const btnText = speakBtn?.querySelector('.tts-btn-text');
10853+
10854+
if (!speakBtn || !btnIcon || !btnText) return;
10855+
10856+
switch (state) {
10857+
case 'speaking':
10858+
speakBtn.disabled = true;
10859+
speakBtn.style.background = '#4CAF50'; // Grün
10860+
btnIcon.textContent = '🔊';
10861+
btnText.textContent = 'Spreche...';
10862+
10863+
// Auto-Reset nach geschätzter Zeit (150 Wörter/min)
10864+
const textarea = activeTTSContainer.querySelector('.tts-textarea');
10865+
if (textarea) {
10866+
const wordCount = textarea.value.trim().split(/\s+/).length;
10867+
const estimatedDuration = Math.max(3000, (wordCount / 150) * 60 * 1000); // Min 3 Sekunden
10868+
10869+
setTimeout(() => {
10870+
this.updateTTSButtonState('ready');
10871+
}, estimatedDuration);
10872+
}
10873+
break;
10874+
10875+
case 'error':
10876+
speakBtn.disabled = false;
10877+
speakBtn.style.background = '#f44336'; // Rot
10878+
btnIcon.textContent = '❌';
10879+
btnText.textContent = 'Fehler - Erneut versuchen';
10880+
10881+
// Reset nach 3 Sekunden
10882+
setTimeout(() => {
10883+
this.updateTTSButtonState('ready');
10884+
}, 3000);
10885+
break;
10886+
10887+
case 'ready':
10888+
default:
10889+
speakBtn.disabled = false;
10890+
speakBtn.style.background = 'var(--accent)'; // Standard Blau
10891+
btnIcon.textContent = '▶️';
10892+
btnText.textContent = 'Sprechen';
10893+
break;
10894+
}
10895+
}
10896+
10897+
setupTTSEventListeners(item, container) {
10898+
const textarea = container.querySelector('.tts-textarea');
10899+
const speakBtn = container.querySelector('.tts-speak-btn');
10900+
const counter = container.querySelector('.tts-counter');
10901+
10902+
if (!textarea || !speakBtn || !counter) {
10903+
console.warn('⚠️ TTS elements not found in container');
10904+
return;
10905+
}
10906+
10907+
// Verhindere doppelte Event Listener
10908+
if (container.dataset.ttsListenersAttached === 'true') return;
10909+
container.dataset.ttsListenersAttached = 'true';
10910+
10911+
// Zeichenzähler Update
10912+
textarea.addEventListener('input', () => {
10913+
const length = textarea.value.length;
10914+
counter.textContent = `${length}/300`;
10915+
10916+
// Warnung bei >250 Zeichen
10917+
if (length > 250) {
10918+
counter.classList.add('warning');
10919+
} else {
10920+
counter.classList.remove('warning');
10921+
}
10922+
10923+
// Button aktivieren/deaktivieren
10924+
speakBtn.disabled = length === 0;
10925+
});
10926+
10927+
// Sprechen Button
10928+
speakBtn.addEventListener('click', () => {
10929+
const text = textarea.value.trim();
10930+
if (text && !speakBtn.disabled) {
10931+
this.speakTTS(text, item.id);
10932+
}
10933+
});
10934+
10935+
console.log('✅ TTS Event Listeners attached for', item.id);
10936+
}
10937+
1084210938

1084310939
getMediaPlayerControlsHTML(item) {
1084410940
const state = this._hass.states[item.id];
@@ -10894,7 +10990,7 @@ class FastSearchCard extends HTMLElement {
1089410990
</div>
1089510991

1089610992
<div class="device-control-presets tts-presets" data-is-open="false">
10897-
TTS coming soon
10993+
${this.getTTSHTML()}
1089810994
</div>
1089910995
</div>
1090010996

0 commit comments

Comments
 (0)