From 42f50af27bd2dfcf2d6c361659b33a478f34193a Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Wed, 18 Jun 2025 17:37:02 +0800 Subject: [PATCH] tts: each book view now has its own tts controller (#1411) --- .../src/app/reader/components/BooksGrid.tsx | 2 -- .../src/app/reader/components/FooterBar.tsx | 2 ++ .../src/app/reader/components/tts/TTSControl.tsx | 16 ++++++++++------ .../src/services/tts/TTSController.ts | 1 + 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/readest-app/src/app/reader/components/BooksGrid.tsx b/apps/readest-app/src/app/reader/components/BooksGrid.tsx index f7799532..86b09a9d 100644 --- a/apps/readest-app/src/app/reader/components/BooksGrid.tsx +++ b/apps/readest-app/src/app/reader/components/BooksGrid.tsx @@ -20,7 +20,6 @@ import Annotator from './annotator/Annotator'; import FootnotePopup from './FootnotePopup'; import HintInfo from './HintInfo'; import DoubleBorder from './DoubleBorder'; -import TTSControl from './tts/TTSControl'; interface BooksGridProps { bookKeys: string[]; @@ -188,7 +187,6 @@ const BooksGrid: React.FC = ({ bookKeys, onCloseBook }) => { ); })} - ); }; diff --git a/apps/readest-app/src/app/reader/components/FooterBar.tsx b/apps/readest-app/src/app/reader/components/FooterBar.tsx index e0fd18b6..55d4f629 100644 --- a/apps/readest-app/src/app/reader/components/FooterBar.tsx +++ b/apps/readest-app/src/app/reader/components/FooterBar.tsx @@ -23,6 +23,7 @@ import { saveViewSettings } from '../utils/viewSettingsHelper'; import { PageInfo } from '@/types/book'; import Button from '@/components/Button'; import Slider from '@/components/Slider'; +import TTSControl from './tts/TTSControl'; interface FooterBarProps { bookKey: string; @@ -376,6 +377,7 @@ const FooterBar: React.FC = ({ /> + ); }; diff --git a/apps/readest-app/src/app/reader/components/tts/TTSControl.tsx b/apps/readest-app/src/app/reader/components/tts/TTSControl.tsx index 9484aab0..576d1536 100644 --- a/apps/readest-app/src/app/reader/components/tts/TTSControl.tsx +++ b/apps/readest-app/src/app/reader/components/tts/TTSControl.tsx @@ -20,13 +20,16 @@ const POPUP_WIDTH = 282; const POPUP_HEIGHT = 160; const POPUP_PADDING = 10; -const TTSControl = () => { +interface TTSControlProps { + bookKey: string; +} + +const TTSControl: React.FC = ({ bookKey }) => { const _ = useTranslation(); const { appService } = useEnv(); const { getBookData } = useBookDataStore(); const { getView, getProgress, getViewSettings } = useReaderStore(); const { setViewSettings, setTTSEnabled } = useReaderStore(); - const [bookKey, setBookKey] = useState(''); const [ttsLang, setTtsLang] = useState('en'); const [isPlaying, setIsPlaying] = useState(false); const [isPaused, setIsPaused] = useState(false); @@ -152,7 +155,9 @@ const TTSControl = () => { }, [ttsController, bookKey]); const handleTTSSpeak = async (event: CustomEvent) => { - const { bookKey, range } = event.detail; + const { bookKey: ttsBookKey, range } = event.detail; + if (bookKey !== ttsBookKey) return; + const view = getView(bookKey); const progress = getProgress(bookKey); const viewSettings = getViewSettings(bookKey); @@ -182,7 +187,6 @@ const TTSControl = () => { } const primaryLang = bookData.book.primaryLanguage; - setBookKey(bookKey); if (ttsControllerRef.current) { ttsControllerRef.current.stop(); @@ -230,8 +234,8 @@ const TTSControl = () => { }; const handleTTSStop = async (event: CustomEvent) => { - const { bookKey } = event.detail; - if (ttsControllerRef.current) { + const { bookKey: ttsBookKey } = event.detail; + if (ttsControllerRef.current && bookKey === ttsBookKey) { handleStop(bookKey); } }; diff --git a/apps/readest-app/src/services/tts/TTSController.ts b/apps/readest-app/src/services/tts/TTSController.ts index 467528c4..ea0091a0 100644 --- a/apps/readest-app/src/services/tts/TTSController.ts +++ b/apps/readest-app/src/services/tts/TTSController.ts @@ -138,6 +138,7 @@ export class TTSController extends EventTarget { .replace('', ' ') .replace(/\.{3,}/g, ' ') .replace(/……/g, ' ') + .replace(/\*/g, ' ') .replace(/·/g, ' '); return ssml;