Fix TTS
This commit is contained in:
@@ -76,15 +76,21 @@ export class AccessibilityManager extends EventEmitter {
|
|||||||
* Speak text using text-to-speech
|
* Speak text using text-to-speech
|
||||||
*/
|
*/
|
||||||
public speak(text: string): void {
|
public speak(text: string): void {
|
||||||
|
console.log('AccessibilityManager.speak() called with text:', text.substring(0, 50) + (text.length > 50 ? '...' : ''));
|
||||||
|
|
||||||
// Skip if speech is disabled
|
// Skip if speech is disabled
|
||||||
if (!this.isSpeechEnabled || !this.speechSynthesis) {
|
if (!this.isSpeechEnabled || !this.speechSynthesis) {
|
||||||
// console.log('Speech is disabled, not speaking');
|
console.log('Speech is disabled or speechSynthesis is null:', {
|
||||||
|
isSpeechEnabled: this.isSpeechEnabled,
|
||||||
|
speechSynthesis: !!this.speechSynthesis
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Clean and truncate text to prevent issues with large blocks
|
// Clean and truncate text to prevent issues with large blocks
|
||||||
const cleanText = this.cleanTextForSpeech(text);
|
const cleanText = this.cleanTextForSpeech(text);
|
||||||
|
console.log('Cleaned text for speech:', cleanText.substring(0, 50) + (cleanText.length > 50 ? '...' : ''));
|
||||||
|
|
||||||
// Only speak if there's meaningful text after cleaning
|
// Only speak if there's meaningful text after cleaning
|
||||||
if (cleanText && cleanText.trim().length > 0) {
|
if (cleanText && cleanText.trim().length > 0) {
|
||||||
@@ -117,10 +123,12 @@ export class AccessibilityManager extends EventEmitter {
|
|||||||
utterance.voice = this.speechOptions.voice;
|
utterance.voice = this.speechOptions.voice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Speak the text
|
// Speak the text
|
||||||
|
console.log('Calling speechSynthesis.speak()');
|
||||||
this.speechSynthesis.speak(utterance);
|
this.speechSynthesis.speak(utterance);
|
||||||
|
console.log('speechSynthesis.speak() called successfully');
|
||||||
|
} else {
|
||||||
|
console.log('Not speaking - cleaned text is empty');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in speak:', error);
|
console.error('Error in speak:', error);
|
||||||
|
|||||||
@@ -59,6 +59,27 @@
|
|||||||
// Set up keyboard listener for speech control
|
// Set up keyboard listener for speech control
|
||||||
document.addEventListener('keydown', handleKeyDown, true);
|
document.addEventListener('keydown', handleKeyDown, true);
|
||||||
|
|
||||||
|
// Subscribe to accessibility settings changes to update speech settings
|
||||||
|
const unsubAccessibility = accessibilitySettings.subscribe(settings => {
|
||||||
|
console.log(`AccessibilitySettings changed for ${profileId}`, settings);
|
||||||
|
|
||||||
|
if (accessibilityManager) {
|
||||||
|
// Update speech enabled state
|
||||||
|
accessibilityManager.setSpeechEnabled(settings.textToSpeech);
|
||||||
|
|
||||||
|
// Update speech options
|
||||||
|
accessibilityManager.updateSpeechOptions({
|
||||||
|
rate: settings.speechRate,
|
||||||
|
pitch: settings.speechPitch,
|
||||||
|
volume: settings.speechVolume
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Updated AccessibilityManager settings for ${profileId}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
unsubscribeFunctions.push(unsubAccessibility);
|
||||||
|
|
||||||
// Auto-connect if enabled
|
// Auto-connect if enabled
|
||||||
if (autoConnect) {
|
if (autoConnect) {
|
||||||
console.log('Auto-connecting profile:', profileId);
|
console.log('Auto-connecting profile:', profileId);
|
||||||
@@ -98,7 +119,20 @@
|
|||||||
|
|
||||||
// Initialize accessibility manager
|
// Initialize accessibility manager
|
||||||
accessibilityManager = new AccessibilityManager();
|
accessibilityManager = new AccessibilityManager();
|
||||||
console.log('Accessibility manager created');
|
console.log('Accessibility manager created for profile:', profileId);
|
||||||
|
|
||||||
|
// Ensure TTS is enabled if the setting is on
|
||||||
|
if ($accessibilitySettings.textToSpeech) {
|
||||||
|
console.log(`Setting TTS enabled for profile ${profileId}`);
|
||||||
|
accessibilityManager.setSpeechEnabled(true);
|
||||||
|
|
||||||
|
// Update speech options from settings
|
||||||
|
accessibilityManager.updateSpeechOptions({
|
||||||
|
rate: $accessibilitySettings.speechRate,
|
||||||
|
pitch: $accessibilitySettings.speechPitch,
|
||||||
|
volume: $accessibilitySettings.speechVolume
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Set up connection from manager if it exists
|
// Set up connection from manager if it exists
|
||||||
const existingConnection = connectionManager.getConnection(profileId);
|
const existingConnection = connectionManager.getConnection(profileId);
|
||||||
@@ -312,16 +346,12 @@
|
|||||||
console.log(`Profile ${profileId} received data`);
|
console.log(`Profile ${profileId} received data`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// First check if this is the active profile - only handle messages for the active profile
|
const isActiveProfile = get(activeProfileId) === profileId;
|
||||||
if (get(activeProfileId) !== profileId) {
|
|
||||||
console.log(`Ignoring received data for inactive profile ${profileId}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to output history
|
// Always add to output history for this profile
|
||||||
addToOutputHistory(text);
|
addToOutputHistory(text);
|
||||||
|
|
||||||
// Process triggers if available
|
// Process triggers if available for this profile
|
||||||
if (triggerSystem) {
|
if (triggerSystem) {
|
||||||
try {
|
try {
|
||||||
triggerSystem.processTriggers(text);
|
triggerSystem.processTriggers(text);
|
||||||
@@ -330,16 +360,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to use text-to-speech if enabled
|
// Handle text-to-speech
|
||||||
|
console.log(`TTS check for ${profileId}: isTTS=${$accessibilitySettings.textToSpeech}, isActive=${isActiveProfile}, speakAll=${$accessibilitySettings.speakAllProfiles}`);
|
||||||
if (accessibilityManager && $accessibilitySettings.textToSpeech) {
|
if (accessibilityManager && $accessibilitySettings.textToSpeech) {
|
||||||
|
// Speak if this is active profile OR speakAllProfiles is enabled
|
||||||
|
if (isActiveProfile || $accessibilitySettings.speakAllProfiles) {
|
||||||
|
console.log(`TTS condition satisfied, will attempt to speak for ${profileId}`);
|
||||||
// Use a small timeout to avoid UI blocking
|
// Use a small timeout to avoid UI blocking
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
try {
|
try {
|
||||||
accessibilityManager.speak(text);
|
// If not active profile, add profile name prefix for context
|
||||||
|
const speechText = isActiveProfile ? text : `From ${getProfileName(profileId)}: ${text}`;
|
||||||
|
console.log(`Speaking text for ${profileId}:`, speechText.substring(0, 50) + (speechText.length > 50 ? '...' : ''));
|
||||||
|
accessibilityManager.speak(speechText);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error using text-to-speech:', error);
|
console.error('Error using text-to-speech:', error);
|
||||||
}
|
}
|
||||||
}, 10);
|
}, 10);
|
||||||
|
} else {
|
||||||
|
console.log(`TTS skipped: profile ${profileId} is not active and speakAll is disabled`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`TTS not enabled for profile ${profileId} or accessibilityManager is null`);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch('received', { text });
|
dispatch('received', { text });
|
||||||
@@ -348,6 +390,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to get profile name for speech announcements
|
||||||
|
*/
|
||||||
|
function getProfileName(id) {
|
||||||
|
const allProfiles = get(profiles);
|
||||||
|
const profile = allProfiles.find(p => p.id === id);
|
||||||
|
return profile ? profile.name : id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle sent data
|
* Handle sent data
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -208,6 +208,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="setting-item">
|
||||||
|
<span class="setting-name">Speak All Profiles</span>
|
||||||
|
<label class="switch">
|
||||||
|
<input type="checkbox" bind:checked={$accessibilitySettings.speakAllProfiles}>
|
||||||
|
<span class="slider round"></span>
|
||||||
|
</label>
|
||||||
|
<div class="setting-description">
|
||||||
|
Announce text from all tabs, even when they're not active
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<span class="setting-name">Speech Rate</span>
|
<span class="setting-name">Speech Rate</span>
|
||||||
<div class="range-control">
|
<div class="range-control">
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface Settings {
|
|||||||
speechPitch: number;
|
speechPitch: number;
|
||||||
speechVolume: number;
|
speechVolume: number;
|
||||||
interruptSpeechOnEnter: boolean;
|
interruptSpeechOnEnter: boolean;
|
||||||
|
speakAllProfiles: boolean;
|
||||||
};
|
};
|
||||||
ui: {
|
ui: {
|
||||||
isDarkMode: boolean;
|
isDarkMode: boolean;
|
||||||
@@ -48,7 +49,8 @@ export class SettingsManager extends EventEmitter {
|
|||||||
speechRate: 1,
|
speechRate: 1,
|
||||||
speechPitch: 1,
|
speechPitch: 1,
|
||||||
speechVolume: 1,
|
speechVolume: 1,
|
||||||
interruptSpeechOnEnter: true
|
interruptSpeechOnEnter: true,
|
||||||
|
speakAllProfiles: true
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
isDarkMode: true,
|
isDarkMode: true,
|
||||||
@@ -186,7 +188,8 @@ export class SettingsManager extends EventEmitter {
|
|||||||
speechRate: 1,
|
speechRate: 1,
|
||||||
speechPitch: 1,
|
speechPitch: 1,
|
||||||
speechVolume: 1,
|
speechVolume: 1,
|
||||||
interruptSpeechOnEnter: true
|
interruptSpeechOnEnter: true,
|
||||||
|
speakAllProfiles: true
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
isDarkMode: true,
|
isDarkMode: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user