Skip to content

Commit 06f1680

Browse files
authored
Update fast-search-card.js
1 parent 0d052e4 commit 06f1680

File tree

1 file changed

+128
-62
lines changed

1 file changed

+128
-62
lines changed

dist/fast-search-card.js

Lines changed: 128 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ class FastSearchCard extends HTMLElement {
355355
this.isTTSActive = false; // Verhindert überlappende TTS-Calls
356356
this.ttsAbortController = null; // Ermöglicht TTS-Abbruch
357357
this.ttsResumeTimeout = null;
358+
this.savedPlayerContext = null; // 🆕 Für Player-Kontext speichern
359+
this.ttsMonitorInterval = null; // 🆕 Für Event-Monitoring
358360

359361
}
360362

@@ -12331,6 +12333,21 @@ class FastSearchCard extends HTMLElement {
1233112333
// 💾 Status für Auto-Resume speichern
1233212334
this.ttsPlayerWasPlaying = wasPlaying ? entityId : null;
1233312335
this.ttsStartedAt = Date.now();
12336+
12337+
// 💾 VOLLSTÄNDIGEN Player-Zustand speichern
12338+
if (wasPlaying) {
12339+
const state = this._hass.states[entityId];
12340+
this.savedPlayerContext = {
12341+
entityId: entityId,
12342+
mediaContentId: state.attributes.media_content_id,
12343+
mediaContentType: state.attributes.media_content_type || 'music',
12344+
mediaPosition: state.attributes.media_position || 0,
12345+
volumeLevel: state.attributes.volume_level,
12346+
mediaTitle: state.attributes.media_title,
12347+
mediaArtist: state.attributes.media_artist
12348+
};
12349+
console.log('💾 Saved player context:', this.savedPlayerContext);
12350+
}
1233412351

1233512352
// ⏸️ Intelligentes Pausieren
1233612353
if (wasPlaying) {
@@ -12341,8 +12358,8 @@ class FastSearchCard extends HTMLElement {
1234112358
this.updateTTSButtonState('speaking');
1234212359
await this.executeSmartTTS(text, entityId);
1234312360

12344-
// ⏰ Intelligente Auto-Resume-Logik
12345-
await this.scheduleSmartResume(text, entityId);
12361+
// 🎧 Event-basierte TTS-Überwachung (ersetzt Timer)
12362+
await this.startTTSMonitoring(entityId);
1234612363

1234712364
return true;
1234812365

@@ -12354,24 +12371,6 @@ class FastSearchCard extends HTMLElement {
1235412371
}
1235512372
}
1235612373

12357-
// ⏰ INTELLIGENTE AUTO-RESUME-LOGIK
12358-
async scheduleSmartResume(text, entityId) {
12359-
if (!this.ttsPlayerWasPlaying) return;
12360-
12361-
// 🕒 Verbesserte Duration-Berechnung
12362-
const duration = this.calculateEnhancedTTSDuration(text);
12363-
12364-
console.log(`⏰ Scheduling auto-resume in ${duration}ms`);
12365-
12366-
// 🎯 Timer-basierte Resume-Logik
12367-
const resumeTimeout = setTimeout(async () => {
12368-
await this.attemptSmartResume(entityId);
12369-
}, duration);
12370-
12371-
// 🔄 Speichere Timeout für möglichen Abbruch
12372-
this.ttsResumeTimeout = resumeTimeout;
12373-
}
12374-
1237512374
// 🔍 ERWEITERTE PLAYER-STATE-ERKENNUNG
1237612375
async getEnhancedPlayerState(entityId) {
1237712376
const state = this._hass.states[entityId];
@@ -12494,16 +12493,7 @@ class FastSearchCard extends HTMLElement {
1249412493
message: text
1249512494
});
1249612495

12497-
console.log(`✅ TTS successful with: ${service}`);
12498-
12499-
// 🆕 HINZUFÜGEN: Expliziter Play-Befehl nach TTS
12500-
console.log(`▶️ Starting TTS playback...`);
12501-
await new Promise(resolve => setTimeout(resolve, 300)); // Kurz warten
12502-
await this._hass.callService('media_player', 'media_play', {
12503-
entity_id: entityId
12504-
});
12505-
console.log(`🎵 TTS playback started`);
12506-
12496+
console.log(`✅ TTS successful with: ${service}`);
1250712497
return service; // Return successful service
1250812498

1250912499
} catch (error) {
@@ -12517,47 +12507,123 @@ class FastSearchCard extends HTMLElement {
1251712507
}
1251812508
}
1251912509

12520-
// 🔄 SMART RESUME ATTEMPT
12521-
async attemptSmartResume(entityId) {
12522-
if (!this.ttsPlayerWasPlaying || this.ttsPlayerWasPlaying !== entityId) {
12523-
console.log('⏭️ No auto-resume needed');
12524-
await this.cleanupTTSState(); // 🆕 HINZUGEFÜGT
12525-
this.updateTTSButtonState('ready'); // 🆕 HINZUGEFÜGT
12526-
return;
12527-
}
12528-
12529-
const ttsAge = Date.now() - (this.ttsStartedAt || 0);
12530-
12531-
// 🚫 Sicherheits-Checks
12532-
if (ttsAge > 15000) { // 🆕 War: 60000 - GEÄNDERT zu 15 Sekunden
12533-
console.log('⏭️ Skipping auto-resume (too old)');
12534-
await this.cleanupTTSState();
12535-
this.updateTTSButtonState('ready');
12536-
return;
12510+
// 🔄 RESTORE PLAYER CONTEXT (Event-basierte Wiederherstellung)
12511+
async restorePlayerContext() {
12512+
if (!this.savedPlayerContext) {
12513+
console.log('⏭️ No saved player context to restore');
12514+
return false;
1253712515
}
1253812516

12539-
// 🔍 Player-Status Double-Check
12540-
const currentState = this._hass.states[entityId];
12541-
if (currentState?.state === 'playing') {
12542-
console.log('⏭️ Player already playing, no resume needed');
12543-
await this.cleanupTTSState(); // 🆕 HINZUGEFÜGT
12544-
this.updateTTSButtonState('ready'); // 🆕 HINZUGEFÜGT
12545-
return;
12546-
}
12517+
const context = this.savedPlayerContext;
12518+
console.log('🔄 Restoring player context:', context);
1254712519

1254812520
try {
12549-
// 🎯 Verwende smartPlayPause für Resume
12550-
console.log('🎵 Auto-resuming music...');
12551-
await this.smartPlayPause({ id: entityId });
12552-
console.log(`✅ Resumed using smartPlayPause`);
12521+
// 1️⃣ Originalinhalt wiederherstellen
12522+
console.log('🎵 Restoring original media...');
12523+
await this._hass.callService('media_player', 'play_media', {
12524+
entity_id: context.entityId,
12525+
media_content_id: context.mediaContentId,
12526+
media_content_type: context.mediaContentType
12527+
});
12528+
12529+
// 2️⃣ Kurz warten, damit Player den neuen Inhalt lädt
12530+
await new Promise(resolve => setTimeout(resolve, 800));
12531+
12532+
// 3️⃣ Zur gespeicherten Position springen
12533+
if (context.mediaPosition && context.mediaPosition > 0) {
12534+
console.log(`⏭️ Seeking to position: ${context.mediaPosition}s`);
12535+
await this._hass.callService('media_player', 'media_seek', {
12536+
entity_id: context.entityId,
12537+
seek_position: context.mediaPosition
12538+
});
12539+
}
12540+
12541+
// 4️⃣ Lautstärke wiederherstellen (falls geändert)
12542+
if (context.volumeLevel && context.volumeLevel > 0) {
12543+
await this._hass.callService('media_player', 'volume_set', {
12544+
entity_id: context.entityId,
12545+
volume_level: context.volumeLevel
12546+
});
12547+
}
12548+
12549+
console.log('✅ Player context successfully restored');
12550+
return true;
12551+
1255312552
} catch (error) {
12554-
console.error('❌ Auto-resume failed:', error);
12553+
console.error('❌ Failed to restore player context:', error);
12554+
return false;
1255512555
} finally {
12556-
await this.cleanupTTSState();
12557-
this.updateTTSButtonState('ready'); // 🆕 HINZUGEFÜGT
12556+
// 5️⃣ Aufräumen
12557+
this.savedPlayerContext = null;
12558+
console.log('🧹 Saved player context cleared');
1255812559
}
12560+
}
12561+
12562+
// 🎧 EVENT-BASIERTE TTS-ÜBERWACHUNG (ersetzt Timer-Logik)
12563+
async startTTSMonitoring(entityId) {
12564+
console.log('🎧 Starting TTS monitoring...');
12565+
12566+
let checkCount = 0;
12567+
const maxChecks = 60; // Max 60 Sekunden überwachen
12568+
12569+
const monitorInterval = setInterval(async () => {
12570+
checkCount++;
12571+
12572+
// 🚫 Abbruch-Bedingungen
12573+
if (!this.isTTSActive || checkCount > maxChecks) {
12574+
console.log('🛑 TTS monitoring stopped (timeout or inactive)');
12575+
clearInterval(monitorInterval);
12576+
await this.finalizeTTSProcess(entityId);
12577+
return;
12578+
}
12579+
12580+
// 🔍 Player-Status prüfen
12581+
const currentState = this._hass.states[entityId];
12582+
const playerState = currentState?.state;
12583+
12584+
console.log(`🔍 TTS Monitor check ${checkCount}: Player state = ${playerState}`);
12585+
12586+
// 🎯 TTS beendet erkennen: Player ist nicht mehr 'playing'
12587+
if (playerState !== 'playing') {
12588+
console.log('🎉 TTS completed! Player no longer playing');
12589+
clearInterval(monitorInterval);
12590+
12591+
// Kurz warten für sauberen Übergang
12592+
await new Promise(resolve => setTimeout(resolve, 500));
12593+
12594+
// Player-Kontext wiederherstellen
12595+
await this.restorePlayerContext();
12596+
12597+
// Button-Status zurücksetzen
12598+
await this.finalizeTTSProcess(entityId);
12599+
}
12600+
12601+
}, 1000); // Jede Sekunde prüfen
12602+
12603+
// Store interval for potential cleanup
12604+
this.ttsMonitorInterval = monitorInterval;
1255912605
}
1256012606

12607+
// 🏁 TTS-PROZESS FINALISIEREN
12608+
async finalizeTTSProcess(entityId) {
12609+
console.log('🏁 Finalizing TTS process...');
12610+
12611+
// Aufräumen
12612+
await this.cleanupTTSState();
12613+
12614+
// Button zurücksetzen
12615+
this.updateTTSButtonState('ready');
12616+
12617+
// Monitor-Interval löschen
12618+
if (this.ttsMonitorInterval) {
12619+
clearInterval(this.ttsMonitorInterval);
12620+
this.ttsMonitorInterval = null;
12621+
}
12622+
12623+
console.log('✅ TTS process finalized');
12624+
}
12625+
12626+
1256112627
// 🧹 CLEANUP STATE
1256212628
async cleanupTTSState() {
1256312629
this.isTTSActive = false;

0 commit comments

Comments
 (0)