diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 6cda2658..e51c6fa3 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -1935,5 +1935,8 @@ "Sort descending": "ترتيب تنازلي", "Filter Annotations": "تصفية التعليقات التوضيحية", "Colors": "الألوان", - "Styles": "الأنماط" + "Styles": "الأنماط", + "Word": "كلمة", + "Sentence": "جملة", + "Granularity": "الدقة" } diff --git a/apps/readest-app/public/locales/bn/translation.json b/apps/readest-app/public/locales/bn/translation.json index 3ab70a28..91a9c29d 100644 --- a/apps/readest-app/public/locales/bn/translation.json +++ b/apps/readest-app/public/locales/bn/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "অধঃক্রমে সাজান", "Filter Annotations": "টীকা ফিল্টার করুন", "Colors": "রঙ", - "Styles": "শৈলী" + "Styles": "শৈলী", + "Word": "শব্দ", + "Sentence": "বাক্য", + "Granularity": "সূক্ষ্মতা" } diff --git a/apps/readest-app/public/locales/bo/translation.json b/apps/readest-app/public/locales/bo/translation.json index 5c96a8ac..76b44479 100644 --- a/apps/readest-app/public/locales/bo/translation.json +++ b/apps/readest-app/public/locales/bo/translation.json @@ -1764,5 +1764,8 @@ "Metadata updated": "གནད་སྨིན་གོ་དོན་གསར་བསྒྱུར་བྱས།", "Filter Annotations": "མཆན་འདེམས་སྒྲིག", "Colors": "ཁ་དོག", - "Styles": "རྣམ་པ" + "Styles": "རྣམ་པ", + "Word": "ཚིག", + "Sentence": "ཚིག་གྲུབ།", + "Granularity": "ཞིབ་ཕྲའི་ཚད" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index f83c2d34..20c35fda 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "Absteigend sortieren", "Filter Annotations": "Anmerkungen filtern", "Colors": "Farben", - "Styles": "Stile" + "Styles": "Stile", + "Word": "Wort", + "Sentence": "Satz", + "Granularity": "Granularität" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index b086e451..33a02835 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "Φθίνουσα ταξινόμηση", "Filter Annotations": "Φιλτράρισμα σχολιασμών", "Colors": "Χρώματα", - "Styles": "Στυλ" + "Styles": "Στυλ", + "Word": "Λέξη", + "Sentence": "Πρόταση", + "Granularity": "Διαβάθμιση" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 81f0c6e5..94e32f20 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -1836,5 +1836,8 @@ "Sort descending": "Orden descendente", "Filter Annotations": "Filtrar anotaciones", "Colors": "Colores", - "Styles": "Estilos" + "Styles": "Estilos", + "Word": "Palabra", + "Sentence": "Oración", + "Granularity": "Granularidad" } diff --git a/apps/readest-app/public/locales/fa/translation.json b/apps/readest-app/public/locales/fa/translation.json index c5387cc2..b68c14a4 100644 --- a/apps/readest-app/public/locales/fa/translation.json +++ b/apps/readest-app/public/locales/fa/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "مرتب‌سازی نزولی", "Filter Annotations": "فیلتر یادداشت‌ها", "Colors": "رنگ‌ها", - "Styles": "سبک‌ها" + "Styles": "سبک‌ها", + "Word": "کلمه", + "Sentence": "جمله", + "Granularity": "دانه‌بندی" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 6c035eb6..ece5d9f4 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -1836,5 +1836,8 @@ "Sort descending": "Tri décroissant", "Filter Annotations": "Filtrer les annotations", "Colors": "Couleurs", - "Styles": "Styles" + "Styles": "Styles", + "Word": "Mot", + "Sentence": "Phrase", + "Granularity": "Granularité" } diff --git a/apps/readest-app/public/locales/he/translation.json b/apps/readest-app/public/locales/he/translation.json index 0acdcfc8..12bdaa2b 100644 --- a/apps/readest-app/public/locales/he/translation.json +++ b/apps/readest-app/public/locales/he/translation.json @@ -1836,5 +1836,8 @@ "Sort descending": "מיון יורד", "Filter Annotations": "סינון הערות", "Colors": "צבעים", - "Styles": "סגנונות" + "Styles": "סגנונות", + "Word": "מילה", + "Sentence": "משפט", + "Granularity": "רמת פירוט" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 77545c39..54b2689f 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "अवरोही क्रम", "Filter Annotations": "टिप्पणियाँ फ़िल्टर करें", "Colors": "रंग", - "Styles": "शैलियाँ" + "Styles": "शैलियाँ", + "Word": "शब्द", + "Sentence": "वाक्य", + "Granularity": "सूक्ष्मता" } diff --git a/apps/readest-app/public/locales/hu/translation.json b/apps/readest-app/public/locales/hu/translation.json index 770ac1a9..8e83a072 100644 --- a/apps/readest-app/public/locales/hu/translation.json +++ b/apps/readest-app/public/locales/hu/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "Csökkenő sorrend", "Filter Annotations": "Jegyzetek szűrése", "Colors": "Színek", - "Styles": "Stílusok" + "Styles": "Stílusok", + "Word": "Szó", + "Sentence": "Mondat", + "Granularity": "Részletesség" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index c66db0f3..2b473ee5 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -1770,5 +1770,8 @@ "Sort descending": "Urutkan menurun", "Filter Annotations": "Filter Anotasi", "Colors": "Warna", - "Styles": "Gaya" + "Styles": "Gaya", + "Word": "Kata", + "Sentence": "Kalimat", + "Granularity": "Granularitas" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index cdcd2ffe..078b625e 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -1836,5 +1836,8 @@ "Sort descending": "Ordine decrescente", "Filter Annotations": "Filtra annotazioni", "Colors": "Colori", - "Styles": "Stili" + "Styles": "Stili", + "Word": "Parola", + "Sentence": "Frase", + "Granularity": "Granularità" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index 07c99168..849b58b8 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -1770,5 +1770,8 @@ "Sort descending": "降順で並べ替え", "Filter Annotations": "注釈をフィルター", "Colors": "色", - "Styles": "スタイル" + "Styles": "スタイル", + "Word": "単語", + "Sentence": "文", + "Granularity": "粒度" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index edbbc7bd..6a52ea9c 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -1770,5 +1770,8 @@ "Sort descending": "내림차순 정렬", "Filter Annotations": "주석 필터링", "Colors": "색상", - "Styles": "스타일" + "Styles": "스타일", + "Word": "단어", + "Sentence": "문장", + "Granularity": "단위" } diff --git a/apps/readest-app/public/locales/ms/translation.json b/apps/readest-app/public/locales/ms/translation.json index 28753d19..879076e3 100644 --- a/apps/readest-app/public/locales/ms/translation.json +++ b/apps/readest-app/public/locales/ms/translation.json @@ -1770,5 +1770,8 @@ "Sort descending": "Isih menurun", "Filter Annotations": "Tapis Anotasi", "Colors": "Warna", - "Styles": "Gaya" + "Styles": "Gaya", + "Word": "Perkataan", + "Sentence": "Ayat", + "Granularity": "Granulariti" } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index d5965afb..d0a1e282 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "Aflopend sorteren", "Filter Annotations": "Aantekeningen filteren", "Colors": "Kleuren", - "Styles": "Stijlen" + "Styles": "Stijlen", + "Word": "Woord", + "Sentence": "Zin", + "Granularity": "Granulariteit" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index fec2c7db..fae23d3e 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -1869,5 +1869,8 @@ "Sort descending": "Sortuj malejąco", "Filter Annotations": "Filtruj adnotacje", "Colors": "Kolory", - "Styles": "Style" + "Styles": "Style", + "Word": "Słowo", + "Sentence": "Zdanie", + "Granularity": "Ziarnistość" } diff --git a/apps/readest-app/public/locales/pt-BR/translation.json b/apps/readest-app/public/locales/pt-BR/translation.json index 764b56df..835d2f2b 100644 --- a/apps/readest-app/public/locales/pt-BR/translation.json +++ b/apps/readest-app/public/locales/pt-BR/translation.json @@ -1836,5 +1836,8 @@ "Sort descending": "Ordem decrescente", "Filter Annotations": "Filtrar anotações", "Colors": "Cores", - "Styles": "Estilos" + "Styles": "Estilos", + "Word": "Palavra", + "Sentence": "Frase", + "Granularity": "Granularidade" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index 4eb4eecd..c1c535bf 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -1836,5 +1836,8 @@ "Sort descending": "Ordem decrescente", "Filter Annotations": "Filtrar anotações", "Colors": "Cores", - "Styles": "Estilos" + "Styles": "Estilos", + "Word": "Palavra", + "Sentence": "Frase", + "Granularity": "Granularidade" } diff --git a/apps/readest-app/public/locales/ro/translation.json b/apps/readest-app/public/locales/ro/translation.json index 8e9787d2..f11547ca 100644 --- a/apps/readest-app/public/locales/ro/translation.json +++ b/apps/readest-app/public/locales/ro/translation.json @@ -1836,5 +1836,8 @@ "Sort descending": "Sortare descrescătoare", "Filter Annotations": "Filtrează adnotările", "Colors": "Culori", - "Styles": "Stiluri" + "Styles": "Stiluri", + "Word": "Cuvânt", + "Sentence": "Propoziție", + "Granularity": "Granularitate" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index 34a6df17..cbacb948 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -1869,5 +1869,8 @@ "Sort descending": "По убыванию", "Filter Annotations": "Фильтровать аннотации", "Colors": "Цвета", - "Styles": "Стили" + "Styles": "Стили", + "Word": "Слово", + "Sentence": "Предложение", + "Granularity": "Детализация" } diff --git a/apps/readest-app/public/locales/si/translation.json b/apps/readest-app/public/locales/si/translation.json index ff19bef1..cc3b8237 100644 --- a/apps/readest-app/public/locales/si/translation.json +++ b/apps/readest-app/public/locales/si/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "අවරෝහණව සකසන්න", "Filter Annotations": "සටහන් පෙරහන් කරන්න", "Colors": "වර්ණ", - "Styles": "මෝස්තර" + "Styles": "මෝස්තර", + "Word": "වචනය", + "Sentence": "වාක්‍යය", + "Granularity": "විස්තර මට්ටම" } diff --git a/apps/readest-app/public/locales/sl/translation.json b/apps/readest-app/public/locales/sl/translation.json index 1322239e..5ac5861f 100644 --- a/apps/readest-app/public/locales/sl/translation.json +++ b/apps/readest-app/public/locales/sl/translation.json @@ -1869,5 +1869,8 @@ "Sort descending": "Padajoče razvrščanje", "Filter Annotations": "Filtriraj opombe", "Colors": "Barve", - "Styles": "Slogi" + "Styles": "Slogi", + "Word": "Beseda", + "Sentence": "Stavek", + "Granularity": "Granularnost" } diff --git a/apps/readest-app/public/locales/sv/translation.json b/apps/readest-app/public/locales/sv/translation.json index 5ac61e7e..4f5c3ae3 100644 --- a/apps/readest-app/public/locales/sv/translation.json +++ b/apps/readest-app/public/locales/sv/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "Fallande sortering", "Filter Annotations": "Filtrera anteckningar", "Colors": "Färger", - "Styles": "Stilar" + "Styles": "Stilar", + "Word": "Ord", + "Sentence": "Mening", + "Granularity": "Detaljnivå" } diff --git a/apps/readest-app/public/locales/ta/translation.json b/apps/readest-app/public/locales/ta/translation.json index c3c7d2fd..bccf8c87 100644 --- a/apps/readest-app/public/locales/ta/translation.json +++ b/apps/readest-app/public/locales/ta/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "இறங்குவரிசை", "Filter Annotations": "சிறுகுறிப்புகளை வடிகட்டு", "Colors": "நிறங்கள்", - "Styles": "பாணிகள்" + "Styles": "பாணிகள்", + "Word": "சொல்", + "Sentence": "வாக்கியம்", + "Granularity": "நுண்மை" } diff --git a/apps/readest-app/public/locales/th/translation.json b/apps/readest-app/public/locales/th/translation.json index ec41949f..c566d8ce 100644 --- a/apps/readest-app/public/locales/th/translation.json +++ b/apps/readest-app/public/locales/th/translation.json @@ -1770,5 +1770,8 @@ "Sort descending": "เรียงจากมากไปน้อย", "Filter Annotations": "กรองคำอธิบายประกอบ", "Colors": "สี", - "Styles": "สไตล์" + "Styles": "สไตล์", + "Word": "คำ", + "Sentence": "ประโยค", + "Granularity": "ระดับความละเอียด" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index ea701f6f..a3f336dd 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "Azalan sıralama", "Filter Annotations": "Açıklamaları Filtrele", "Colors": "Renkler", - "Styles": "Stiller" + "Styles": "Stiller", + "Word": "Kelime", + "Sentence": "Cümle", + "Granularity": "Ayrıntı düzeyi" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index 9f2f7eb8..9ea11afb 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -1869,5 +1869,8 @@ "Sort descending": "За спаданням", "Filter Annotations": "Фільтрувати анотації", "Colors": "Кольори", - "Styles": "Стилі" + "Styles": "Стилі", + "Word": "Слово", + "Sentence": "Речення", + "Granularity": "Деталізація" } diff --git a/apps/readest-app/public/locales/uz/translation.json b/apps/readest-app/public/locales/uz/translation.json index cd9787ba..3eedb82c 100644 --- a/apps/readest-app/public/locales/uz/translation.json +++ b/apps/readest-app/public/locales/uz/translation.json @@ -1803,5 +1803,8 @@ "Sort descending": "Kamayish boʻyicha", "Filter Annotations": "Izohlarni filtrlash", "Colors": "Ranglar", - "Styles": "Uslublar" + "Styles": "Uslublar", + "Word": "So‘z", + "Sentence": "Gap", + "Granularity": "Tafsilot darajasi" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 33d4cab8..d219a0c2 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -1770,5 +1770,8 @@ "Sort descending": "Sắp xếp giảm dần", "Filter Annotations": "Lọc chú thích", "Colors": "Màu sắc", - "Styles": "Kiểu" + "Styles": "Kiểu", + "Word": "Từ", + "Sentence": "Câu", + "Granularity": "Mức độ chi tiết" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 856a958c..ce788dae 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -1770,5 +1770,8 @@ "Sort descending": "降序排列", "Filter Annotations": "筛选笔记", "Colors": "颜色", - "Styles": "样式" + "Styles": "样式", + "Word": "单词", + "Sentence": "句子", + "Granularity": "粒度" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index c04ad959..a026032e 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -1770,5 +1770,8 @@ "Sort descending": "降序排列", "Filter Annotations": "篩選筆記", "Colors": "顏色", - "Styles": "樣式" + "Styles": "樣式", + "Word": "單字", + "Sentence": "句子", + "Granularity": "粒度" } diff --git a/apps/readest-app/src/__tests__/hooks/useTTSControl.test.tsx b/apps/readest-app/src/__tests__/hooks/useTTSControl.test.tsx index 00a385f8..f9e02c7c 100644 --- a/apps/readest-app/src/__tests__/hooks/useTTSControl.test.tsx +++ b/apps/readest-app/src/__tests__/hooks/useTTSControl.test.tsx @@ -133,6 +133,7 @@ vi.mock('@/services/tts', () => ({ ), initViewTTS: vi.fn().mockResolvedValue(undefined), updateHighlightOptions: vi.fn(), + setHighlightGranularity: vi.fn(), setLang: vi.fn(), setRate: vi.fn(), setVoice: vi.fn(), diff --git a/apps/readest-app/src/__tests__/services/tts-controller.test.ts b/apps/readest-app/src/__tests__/services/tts-controller.test.ts index f9a0058d..05ec991b 100644 --- a/apps/readest-app/src/__tests__/services/tts-controller.test.ts +++ b/apps/readest-app/src/__tests__/services/tts-controller.test.ts @@ -744,6 +744,29 @@ describe('TTSController', () => { controller.prepareSpeakWords([]); expect(controller.getCurrentHighlightCfi()).toBeNull(); }); + + test('granularity "sentence" forces sentence highlighting (skips word-by-word)', async () => { + controller.setHighlightGranularity('sentence'); + await armWithSentence(makeSentenceRange()); + getOverlayer().add.mockClear(); + // Even when the client reports word boundaries and calls prepareSpeakWords, + // the user's "sentence" choice keeps highlighting at the sentence level: the + // sentence highlight was already drawn at mark dispatch (not suppressed), so + // prepareSpeakWords is a no-op and word mode never engages. + controller.prepareSpeakWords(['Hello', 'brave', 'world']); + expect(getOverlayer().add).not.toHaveBeenCalled(); + expect(controller.getCurrentHighlightCfi()).toBeNull(); + }); + + test('granularity "word" (default) still highlights word-by-word', async () => { + controller.setHighlightGranularity('word'); + await armWithSentence(makeSentenceRange()); + getOverlayer().add.mockClear(); + controller.prepareSpeakWords(['Hello', 'brave', 'world']); + // First word highlighted immediately and word mode engaged. + expect(getOverlayer().add).toHaveBeenCalledTimes(1); + expect(controller.getCurrentHighlightCfi()).not.toBeNull(); + }); }); describe('tts-position event', () => { diff --git a/apps/readest-app/src/app/reader/hooks/useTTSControl.ts b/apps/readest-app/src/app/reader/hooks/useTTSControl.ts index 134e3dc9..1b04330b 100644 --- a/apps/readest-app/src/app/reader/hooks/useTTSControl.ts +++ b/apps/readest-app/src/app/reader/hooks/useTTSControl.ts @@ -531,6 +531,12 @@ export const useTTSControl = ({ bookKey, onRequestHidePanel }: UseTTSControlProp // eslint-disable-next-line react-hooks/exhaustive-deps }, [viewSettings?.ttsHighlightOptions, viewSettings?.isEink, getTTSHighlightOptions]); + useEffect(() => { + if (ttsControllerRef.current && viewSettings?.ttsHighlightGranularity) { + ttsControllerRef.current.setHighlightGranularity(viewSettings.ttsHighlightGranularity); + } + }, [viewSettings?.ttsHighlightGranularity]); + // handleStop (defined before handleTTSSpeak/handleTTSStop which reference it) const handleStop = useCallback( async (bookKey: string) => { @@ -659,6 +665,7 @@ export const useTTSControl = ({ bookKey, onRequestHidePanel }: UseTTSControlProp ttsController.updateHighlightOptions( getTTSHighlightOptions(viewSettings.ttsHighlightOptions, viewSettings.isEink), ); + ttsController.setHighlightGranularity(viewSettings.ttsHighlightGranularity ?? 'word'); const ssml = oneTime && ttsSpeakRange ? genSSMLRaw(ttsSpeakRange.toString().trim()) diff --git a/apps/readest-app/src/components/settings/TTSPanel.tsx b/apps/readest-app/src/components/settings/TTSPanel.tsx index 9b0a5ab2..bf886ee4 100644 --- a/apps/readest-app/src/components/settings/TTSPanel.tsx +++ b/apps/readest-app/src/components/settings/TTSPanel.tsx @@ -6,7 +6,7 @@ import { useResetViewSettings } from '@/hooks/useResetSettings'; import { useTranslation } from '@/hooks/useTranslation'; import { saveViewSettings } from '@/helpers/settings'; import { SettingsPanelPanelProp } from './SettingsDialog'; -import { TTSMediaMetadataMode } from '@/services/tts/types'; +import { TTSHighlightGranularity, TTSMediaMetadataMode } from '@/services/tts/types'; import { BoxedList, SettingsRow, SettingsSelect } from './primitives'; import TTSHighlightStyleEditor, { TTSHighlightStyle } from './color/TTSHighlightStyleEditor'; @@ -20,6 +20,9 @@ const TTSPanel: React.FC = ({ bookKey, onRegisterReset } const [ttsMediaMetadata, setTtsMediaMetadata] = useState( viewSettings.ttsMediaMetadata ?? 'sentence', ); + const [ttsHighlightGranularity, setTtsHighlightGranularity] = useState( + viewSettings.ttsHighlightGranularity ?? 'word', + ); const [ttsHighlightStyle, setTtsHighlightStyle] = useState( viewSettings.ttsHighlightOptions.style, ); @@ -35,6 +38,9 @@ const TTSPanel: React.FC = ({ bookKey, onRegisterReset } const handleReset = () => { resetToDefaults({ ttsMediaMetadata: setTtsMediaMetadata as React.Dispatch>, + ttsHighlightGranularity: setTtsHighlightGranularity as React.Dispatch< + React.SetStateAction + >, }); }; @@ -49,6 +55,19 @@ const TTSPanel: React.FC = ({ bookKey, onRegisterReset } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ttsMediaMetadata]); + useEffect(() => { + if (ttsHighlightGranularity === viewSettings.ttsHighlightGranularity) return; + saveViewSettings( + envConfig, + bookKey, + 'ttsHighlightGranularity', + ttsHighlightGranularity, + false, + false, + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ttsHighlightGranularity]); + const handleTTSStyleChange = (style: TTSHighlightStyle) => { setTtsHighlightStyle(style); saveViewSettings(envConfig, bookKey, 'ttsHighlightOptions', { @@ -76,12 +95,18 @@ const TTSPanel: React.FC = ({ bookKey, onRegisterReset } setTtsMediaMetadata(event.target.value as TTSMediaMetadataMode); }; + const handleTTSGranularityChange = (granularity: TTSHighlightGranularity) => { + setTtsHighlightGranularity(granularity); + }; + return (
void; onStyleChange: (style: TTSHighlightStyle) => void; onColorChange: (color: string) => void; onCustomColorsChange: (colors: string[]) => void; } const TTSHighlightStyleEditor: React.FC = ({ + granularity, style, color, customColors, + onGranularityChange, onStyleChange, onColorChange, onCustomColorsChange, @@ -60,6 +65,18 @@ const TTSHighlightStyleEditor: React.FC = ({ return ( + + onGranularityChange(e.target.value as TTSHighlightGranularity)} + ariaLabel={_('Granularity')} + options={[ + { value: 'word', label: _('Word') }, + { value: 'sentence', label: _('Sentence') }, + ]} + /> + +