Document markup and improve choice tags

This commit is contained in:
2026-05-17 15:52:41 +02:00
parent c2fb27b6b8
commit 2c54498ee2
52 changed files with 3485 additions and 377 deletions
+78 -7
View File
@@ -10,6 +10,7 @@ class AudioManagerModule extends BaseModule {
this.sounds = new Map();
this.sfxCache = new Map();
this.currentAudio = null;
this.currentAudioRole = null;
this.currentLoop = null;
this.currentMusic = null;
this.queuedMusic = null;
@@ -17,6 +18,12 @@ class AudioManagerModule extends BaseModule {
this.musicVolume = 1.0;
this.sfxVolume = 1.0;
this.ttsVolume = 1.0;
this.masterVolumeEnabled = true;
this.musicVolumeEnabled = true;
this.sfxVolumeEnabled = true;
this.ttsVolumeEnabled = true;
this.musicDuckingAmount = 0.3;
this.musicDuckingEnabled = true;
this.musicDuckingFactor = 1.0;
this.musicFadeToken = 0;
this.activeTtsPlaybackCount = 0;
@@ -79,6 +86,12 @@ class AudioManagerModule extends BaseModule {
this.musicVolume = this.clampVolume(persistenceManager.getPreference('audio', 'musicVolume', this.musicVolume));
this.sfxVolume = this.clampVolume(persistenceManager.getPreference('audio', 'sfxVolume', this.sfxVolume));
this.ttsVolume = this.clampVolume(persistenceManager.getPreference('audio', 'ttsVolume', this.ttsVolume));
this.masterVolumeEnabled = persistenceManager.getPreference('audio', 'masterVolumeEnabled', this.masterVolumeEnabled) !== false;
this.musicVolumeEnabled = persistenceManager.getPreference('audio', 'musicVolumeEnabled', this.musicVolumeEnabled) !== false;
this.sfxVolumeEnabled = persistenceManager.getPreference('audio', 'sfxVolumeEnabled', this.sfxVolumeEnabled) !== false;
this.ttsVolumeEnabled = persistenceManager.getPreference('audio', 'ttsVolumeEnabled', this.ttsVolumeEnabled) !== false;
this.musicDuckingAmount = this.clampVolume(persistenceManager.getPreference('audio', 'musicDuckingAmount', this.musicDuckingAmount));
this.musicDuckingEnabled = persistenceManager.getPreference('audio', 'musicDuckingEnabled', this.musicDuckingEnabled) !== false;
}
setupEventListeners() {
@@ -108,6 +121,12 @@ class AudioManagerModule extends BaseModule {
if (key === 'musicVolume') this.setMusicVolume(value);
if (key === 'sfxVolume') this.setSfxVolume(value);
if (key === 'ttsVolume') this.setTtsVolume(value);
if (key === 'masterVolumeEnabled') this.setVolumeEnabled('master', value);
if (key === 'musicVolumeEnabled') this.setVolumeEnabled('music', value);
if (key === 'sfxVolumeEnabled') this.setVolumeEnabled('sfx', value);
if (key === 'ttsVolumeEnabled') this.setVolumeEnabled('tts', value);
if (key === 'musicDuckingAmount') this.setMusicDuckingAmount(value);
if (key === 'musicDuckingEnabled') this.setMusicDuckingEnabled(value);
});
this.addEventListener(document, 'tts:playback-start', () => {
@@ -204,6 +223,7 @@ class AudioManagerModule extends BaseModule {
this.currentLoop = audio;
} else {
this.currentAudio = audio.cloneNode(true);
this.currentAudioRole = 'sfx';
this.setMediaVolume(this.currentAudio, this.getSfxVolume());
this.currentAudio.play().catch(error => {
console.error('Error playing audio:', error);
@@ -241,6 +261,7 @@ class AudioManagerModule extends BaseModule {
return this.currentLoop;
} else {
this.currentAudio = new Audio(url);
this.currentAudioRole = 'sfx';
this.setMediaVolume(this.currentAudio, this.getSfxVolume());
this.currentAudio.play().catch(error => {
console.error('Error playing audio:', error);
@@ -269,6 +290,7 @@ class AudioManagerModule extends BaseModule {
this.currentAudio.pause();
this.currentAudio.currentTime = 0;
this.currentAudio = null;
this.currentAudioRole = null;
}
if (this.currentLoop) {
@@ -306,6 +328,7 @@ class AudioManagerModule extends BaseModule {
*/
setTtsVolume(volume) {
this.ttsVolume = this.clampVolume(volume);
this.updateVolumes();
}
/**
@@ -325,6 +348,33 @@ class AudioManagerModule extends BaseModule {
this.sfxVolume = this.clampVolume(volume);
this.updateVolumes();
}
setVolumeEnabled(kind, enabled) {
const value = enabled !== false;
if (kind === 'master') this.masterVolumeEnabled = value;
if (kind === 'music') this.musicVolumeEnabled = value;
if (kind === 'sfx') this.sfxVolumeEnabled = value;
if (kind === 'tts') this.ttsVolumeEnabled = value;
this.updateVolumes();
}
setMusicDuckingAmount(amount) {
this.musicDuckingAmount = this.clampVolume(amount);
if (this.musicDuckingFactor !== 1.0) {
this.duckMusicForSpeech();
} else {
this.updateVolumes();
}
}
setMusicDuckingEnabled(enabled) {
this.musicDuckingEnabled = enabled !== false;
if (this.musicDuckingFactor !== 1.0) {
this.duckMusicForSpeech();
} else {
this.updateVolumes();
}
}
/**
* Update all volume levels based on current settings
@@ -332,11 +382,11 @@ class AudioManagerModule extends BaseModule {
updateVolumes() {
this.sounds.forEach(audio => {
const isMusic = audio.loop;
this.setMediaVolume(audio, this.masterVolume * (isMusic ? this.musicVolume : this.sfxVolume));
this.setMediaVolume(audio, isMusic ? this.getMusicVolume() : this.getSfxVolume());
});
if (this.currentAudio) {
this.setMediaVolume(this.currentAudio, this.masterVolume * this.sfxVolume);
this.setMediaVolume(this.currentAudio, this.currentAudioRole === 'tts' ? this.getTtsVolume() : this.getSfxVolume());
}
if (this.currentLoop) {
@@ -358,20 +408,29 @@ class AudioManagerModule extends BaseModule {
}
getSfxVolume() {
return this.masterVolume * this.sfxVolume;
return this.getMasterVolume() * (this.sfxVolumeEnabled ? this.sfxVolume : 0);
}
getMusicVolume() {
return this.masterVolume * this.musicVolume * this.musicDuckingFactor;
return this.getUnduckedMusicVolume() * this.musicDuckingFactor;
}
getUnduckedMusicVolume() {
return this.masterVolume * this.musicVolume;
return this.getMasterVolume() * (this.musicVolumeEnabled ? this.musicVolume : 0);
}
getMasterVolume() {
return this.masterVolumeEnabled ? this.masterVolume : 0;
}
getTtsVolume() {
return this.getMasterVolume() * (this.ttsVolumeEnabled ? this.ttsVolume : 0);
}
duckMusicForSpeech() {
console.log('AudioManager: Ducking music for TTS playback');
this.fadeMusicTo(0.3, 500);
const factor = this.musicDuckingEnabled ? 1 - this.musicDuckingAmount : 1;
this.fadeMusicTo(factor, 500);
}
restoreMusicAfterSpeech() {
@@ -564,6 +623,7 @@ class AudioManagerModule extends BaseModule {
const audio = template.cloneNode(true);
this.setMediaVolume(audio, this.getSfxVolume());
this.currentAudio = audio;
this.currentAudioRole = 'sfx';
const maxDuration = Math.max(0, Number(options.maxDurationSeconds || options.maxDuration || 0)) * 1000;
const endMode = String(options.endMode || options.mode || 'stop').toLowerCase().startsWith('fade') ? 'fade' : 'stop';
const fadeDuration = Math.max(100, Number(options.fadeDurationSeconds || options.fadeDuration || 2) * 1000);
@@ -572,6 +632,7 @@ class AudioManagerModule extends BaseModule {
if (maxTimer) clearTimeout(maxTimer);
if (this.currentAudio === audio) {
this.currentAudio = null;
this.currentAudioRole = null;
}
}, { once: true });
await audio.play();
@@ -588,6 +649,7 @@ class AudioManagerModule extends BaseModule {
audio.pause();
audio.currentTime = 0;
if (this.currentAudio === audio) this.currentAudio = null;
if (this.currentAudio === null) this.currentAudioRole = null;
}
}, timeoutDuration);
}
@@ -614,6 +676,7 @@ class AudioManagerModule extends BaseModule {
audio.pause();
audio.currentTime = 0;
if (this.currentAudio === audio) this.currentAudio = null;
if (this.currentAudio === null) this.currentAudioRole = null;
resolve(true);
};
requestAnimationFrame(step);
@@ -832,6 +895,10 @@ class AudioManagerModule extends BaseModule {
audio.pause();
audio.currentTime = 0;
this.setMediaVolume(audio, initialVolume); // Reset volume for future use
if (this.currentAudio === audio) {
this.currentAudio = null;
this.currentAudioRole = null;
}
resolve();
} else {
this.setMediaVolume(audio, currentVolume);
@@ -860,6 +927,7 @@ class AudioManagerModule extends BaseModule {
if (this.currentAudio) {
this.currentAudio.pause();
this.currentAudio.currentTime = 0;
this.currentAudioRole = null;
}
// Create new audio element
@@ -880,13 +948,14 @@ class AudioManagerModule extends BaseModule {
}
// Apply master volume and speech volume
this.setMediaVolume(audio, this.masterVolume * speechVolume * this.ttsVolume);
this.setMediaVolume(audio, speechVolume * this.getTtsVolume());
// Set up cleanup
audio.onended = () => {
URL.revokeObjectURL(audioUrl);
if (this.currentAudio === audio) {
this.currentAudio = null;
this.currentAudioRole = null;
}
if (options.onComplete && typeof options.onComplete === 'function') {
options.onComplete();
@@ -902,6 +971,7 @@ class AudioManagerModule extends BaseModule {
URL.revokeObjectURL(audioUrl);
if (this.currentAudio === audio) {
this.currentAudio = null;
this.currentAudioRole = null;
}
if (options.onError && typeof options.onError === 'function') {
options.onError(error);
@@ -915,6 +985,7 @@ class AudioManagerModule extends BaseModule {
// Store as current audio
this.currentAudio = audio;
this.currentAudioRole = 'tts';
// Play the audio
await audio.play();