fix: skip speech when the text is empty at the end of some chapters, closes #1231 (#1243)

This commit is contained in:
Huang Xin
2025-05-26 22:03:43 +08:00
committed by GitHub
parent 699a01c78f
commit 35735cd931
3 changed files with 13 additions and 3 deletions
@@ -1,5 +1,6 @@
import { FoliateView, TTSGranularity } from '@/types/view';
import { TTSClient, TTSMessageCode, TTSVoice } from './TTSClient';
import { parseSSMLMarks } from '@/utils/ssml';
import { WebSpeechClient } from './WebSpeechClient';
import { EdgeTTSClient } from './EdgeTTSClient';
import { TTSUtils } from './TTSUtils';
@@ -106,7 +107,7 @@ export class TTSController extends EventTarget {
// FIXME: in case we are at the end of the book, need a better way to handle this
if (this.#nossmlCnt < 10 && this.state === 'playing') {
resolve();
await this.view.next(1);
await this.view.next();
await this.forward();
}
return;
@@ -114,6 +115,11 @@ export class TTSController extends EventTarget {
this.#nossmlCnt = 0;
}
const { plainText, marks } = parseSSMLMarks(ssml);
if (!plainText || marks.length === 0) {
resolve();
return await this.forward();
}
const iter = await this.ttsClient.speak(ssml, signal);
let lastCode: TTSMessageCode = 'boundary';
for await (const { code, mark } of iter) {
+2 -2
View File
@@ -10,8 +10,8 @@ export interface FoliateView extends HTMLElement {
init: (options: { lastLocation: string }) => void;
goTo: (href: string) => void;
goToFraction: (fraction: number) => void;
prev: (distance: number) => void;
next: (distance: number) => void;
prev: (distance?: number) => void;
next: (distance?: number) => void;
goLeft: () => void;
goRight: () => void;
getCFI: (index: number, range: Range) => string;
+4
View File
@@ -248,6 +248,10 @@ const getLayoutStyles = (
hanging-punctuation: allow-end last;
widows: 2;
}
p:has(> img:only-child) {
text-indent: unset !important;
text-align: unset !important;
}
p, div {
${vertical ? `margin-left: ${paragraphMargin}em ${overrideLayout ? '!important' : ''};` : ''}
${vertical ? `margin-right: ${paragraphMargin}em ${overrideLayout ? '!important' : ''};` : ''}