Fixed Ducking. Refined UI.

This commit is contained in:
2026-05-14 23:18:30 +02:00
parent b5829ed773
commit 9a6bb009f2
10 changed files with 224 additions and 74 deletions
+24 -6
View File
@@ -31,7 +31,8 @@ class SentenceQueueModule extends BaseModule {
'extractWords',
'getDropCapText',
'extractDropCapText',
'calculateAnimationTiming'
'calculateAnimationTiming',
'clear'
]);
}
@@ -266,7 +267,7 @@ class SentenceQueueModule extends BaseModule {
const metadata = typeof item === 'object' && item !== null ? item : {};
try {
if (metadata.type && metadata.type !== 'paragraph') {
if (metadata.type && !['paragraph', 'heading'].includes(metadata.type)) {
if (metadata.type === 'music') {
const audioManager = this.getModule('audio-manager');
if (audioManager && typeof audioManager.playMusic === 'function') {
@@ -306,10 +307,11 @@ class SentenceQueueModule extends BaseModule {
return {
id,
kind: metadata.type === 'heading' ? 'heading' : 'paragraph',
text,
paragraphIndex: metadata.paragraphIndex ?? null,
isFirstParagraphInChapter: Boolean(metadata.isFirstParagraphInChapter),
role: metadata.role || 'body',
role: metadata.role || (metadata.type === 'heading' ? 'chapter-heading' : 'body'),
dropCap: Boolean(metadata.dropCap),
addTopSpace: Boolean(metadata.addTopSpace),
cueMarkers: metadata.cueMarkers || [],
@@ -375,14 +377,17 @@ class SentenceQueueModule extends BaseModule {
// Standard book indentation: no indent on the first chapter paragraph,
// first-line indent on following paragraphs.
const isHeading = metadata.type === 'heading' || metadata.role === 'chapter-heading' || metadata.role === 'section-heading';
const dropCapLines = metadata.dropCap ? 2 : 0;
const dropCapWidth = metadata.dropCap ? lineHeight * 1.45 : 0;
const indentWidth = (metadata.isFirstParagraphInChapter || metadata.addTopSpace) ? 0 : lineHeight * 1.5;
const indentWidth = (isHeading || metadata.isFirstParagraphInChapter || metadata.addTopSpace) ? 0 : lineHeight * 1.5;
const layoutText = metadata.layoutText || text;
const layoutPlainText = metadata.dropCap ? this.extractDropCapText(layoutText) : layoutText;
// Measures are consumed in line order by the line breaker.
const measures = metadata.dropCap
const measures = isHeading
? [containerWidth]
: metadata.dropCap
? [
Math.max(120, containerWidth - dropCapWidth),
Math.max(120, containerWidth - dropCapWidth),
@@ -419,7 +424,8 @@ class SentenceQueueModule extends BaseModule {
dropCapText: metadata.dropCap ? this.getDropCapText(layoutText) : '',
dropCapLines,
addTopSpace: Boolean(metadata.addTopSpace),
role: metadata.role || 'body',
role: metadata.role || (isHeading ? 'chapter-heading' : 'body'),
align: isHeading ? 'center' : 'justify',
fontSize: layout.fontSize,
fontFamily: layout.fontFamily,
lineHeight: layout.lineHeight,
@@ -535,6 +541,18 @@ class SentenceQueueModule extends BaseModule {
this.processNextSentence();
}
}
clear() {
this.sentenceQueue = [];
this.isProcessing = false;
this.preparedCache.clear();
document.dispatchEvent(new CustomEvent('tts:queue-empty', {
detail: { reason: 'sentence-queue-cleared' }
}));
document.dispatchEvent(new CustomEvent('story:process-state', {
detail: { state: 'ready', reason: 'sentence-queue-cleared' }
}));
}
}
// Create the singleton instance