tts: tts now works when language codes are mistakenly set with language names (#1737)

This commit is contained in:
Huang Xin
2025-08-02 22:52:32 +08:00
committed by GitHub
parent 1ef126f820
commit 511093a6ef
26 changed files with 77 additions and 55 deletions
+2 -1
View File
@@ -38,7 +38,8 @@
"upload": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && opennextjs-cloudflare upload",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts",
"check:optional-chaining": "count=$(grep -rno '\\?\\.[a-zA-Z_$]' .next/static/chunks/* out/_next/static/chunks/* | wc -l); if [ \"$count\" -gt 0 ]; then echo '❌ Optional chaining found in output!'; exit 1; else echo '✅ No optional chaining found.'; fi",
"check:all": "pnpm check:optional-chaining",
"check:translations": "count=$(grep -rno '__STRING_NOT_TRANSLATED__' public/locales/* | wc -l); if [ \"$count\" -gt 0 ]; then echo '❌ Untranslated strings found!'; exit 1; else echo '✅ All strings translated.'; fi",
"check:all": "pnpm check:optional-chaining && pnpm check:translations",
"build-check": "pnpm build && pnpm build-web && pnpm check:all"
},
"dependencies": {
@@ -94,7 +94,6 @@
"Speak": "تحدث",
"Subjects": "المواضيع",
"System Fonts": "خطوط النظام",
"TTS not supported in this device": "القراءة الصوتية غير مدعومة في هذا الجهاز",
"Theme Color": "لون السمة",
"Theme Mode": "وضع السمة",
"Translate": "ترجمة",
@@ -477,5 +476,6 @@
"Storage": "التخزين",
"Terms of Service": "شروط الخدمة",
"Privacy Policy": "سياسة الخصوصية",
"Disable Double Click": "تعطيل النقر المزدوج"
"Disable Double Click": "تعطيل النقر المزدوج",
"TTS not supported for this document": "تكنولوجيا تحويل النص إلى كلام غير مدعومة لهذا المستند."
}
@@ -94,7 +94,6 @@
"Speak": "Sprechen",
"Subjects": "Themen",
"System Fonts": "System-Schriftarten",
"TTS not supported in this device": "TTS wird auf diesem Gerät nicht unterstützt",
"Theme Color": "Themenfarbe",
"Theme Mode": "Themenmodus",
"Translate": "Übersetzen",
@@ -461,5 +460,6 @@
"Storage": "Speicher",
"Terms of Service": "Allgemeine Geschäftsbedingungen",
"Privacy Policy": "Datenschutzbestimmungen",
"Disable Double Click": "Doppelklick deaktivieren"
"Disable Double Click": "Doppelklick deaktivieren",
"TTS not supported for this document": "TTS wird für dieses Dokument nicht unterstützt"
}
@@ -95,7 +95,6 @@
"Speak": "Ομιλία",
"Subjects": "Θέματα",
"System Fonts": "Γραμματοσειρές συστήματος",
"TTS not supported in this device": "Η μετατροπή κειμένου σε ομιλία δεν υποστηρίζεται σε αυτή τη συσκευή",
"Theme Color": "Χρώμα θέματος",
"Theme Mode": "Λειτουργία θέματος",
"Translate": "Μετάφραση",
@@ -461,5 +460,6 @@
"Storage": "Αποθήκευση",
"Terms of Service": "Όροι χρήσης",
"Privacy Policy": "Πολιτική απορρήτου",
"Disable Double Click": "Απενεργοποίηση διπλού κλικ"
"Disable Double Click": "Απενεργοποίηση διπλού κλικ",
"TTS not supported for this document": "Η τεχνολογία TTS δεν υποστηρίζεται για αυτό το έγγραφο."
}
@@ -95,7 +95,6 @@
"Speak": "Leer",
"Subjects": "Temas",
"System Fonts": "Fuentes del sistema",
"TTS not supported in this device": "TTS no es compatible con este dispositivo",
"Theme Color": "Color del tema",
"Theme Mode": "Modo del tema",
"Translate": "Traducir",
@@ -465,5 +464,6 @@
"Storage": "Almacenamiento",
"Terms of Service": "Condiciones del servicio",
"Privacy Policy": "Política de privacidad",
"Disable Double Click": "Deshabilitar Doble Clic"
"Disable Double Click": "Deshabilitar Doble Clic",
"TTS not supported for this document": "TTS no es compatible con este documento."
}
@@ -95,7 +95,6 @@
"Speak": "Lire",
"Subjects": "Sujets",
"System Fonts": "Polices système",
"TTS not supported in this device": "La synthèse vocale n'est pas prise en charge sur cet appareil",
"Theme Color": "Couleur du thème",
"Theme Mode": "Mode du thème",
"Translate": "Traduire",
@@ -465,5 +464,6 @@
"Storage": "Stockage",
"Terms of Service": "Conditions d'utilisation",
"Privacy Policy": "Politique de confidentialité",
"Disable Double Click": "Désactiver le double-clic"
"Disable Double Click": "Désactiver le double-clic",
"TTS not supported for this document": "TTS non pris en charge pour ce document"
}
@@ -95,7 +95,6 @@
"Speak": "बोलें",
"Subjects": "विषय",
"System Fonts": "सिस्टम फ़ॉन्ट्स",
"TTS not supported in this device": "यह डिवाइस TTS का समर्थन नहीं करता",
"Theme Color": "थीम रंग",
"Theme Mode": "थीम मोड",
"Translate": "अनुवाद करें",
@@ -461,5 +460,6 @@
"Storage": "भंडारण",
"Terms of Service": "सेवा की शर्तें",
"Privacy Policy": "गोपनीयता नीति",
"Disable Double Click": "डबल क्लिक अक्षम करें"
"Disable Double Click": "डबल क्लिक अक्षम करें",
"TTS not supported for this document": "TTS इस दस्तावेज़ के लिए समर्थित नहीं है"
}
@@ -95,7 +95,6 @@
"Speak": "Bicara",
"Subjects": "Subjek",
"System Fonts": "Font Sistem",
"TTS not supported in this device": "TTS tidak didukung di perangkat ini",
"Theme Color": "Warna Tema",
"Theme Mode": "Mode Tema",
"Translate": "Terjemahkan",
@@ -457,5 +456,6 @@
"Storage": "Penyimpanan",
"Terms of Service": "Ketentuan Layanan",
"Privacy Policy": "Kebijakan Privasi",
"Disable Double Click": "Nonaktifkan Klik Ganda"
"Disable Double Click": "Nonaktifkan Klik Ganda",
"TTS not supported for this document": "TTS tidak didukung untuk dokumen ini"
}
@@ -95,7 +95,6 @@
"Speak": "Leggi",
"Subjects": "Argomenti",
"System Fonts": "Font di sistema",
"TTS not supported in this device": "TTS non supportato su questo dispositivo",
"Theme Color": "Colore tema",
"Theme Mode": "Modalità tema",
"Translate": "Traduci",
@@ -465,5 +464,6 @@
"Storage": "Archiviazione",
"Terms of Service": "Termini di servizio",
"Privacy Policy": "Informativa sulla privacy",
"Disable Double Click": "Disabilita Doppio Clic"
"Disable Double Click": "Disabilita Doppio Clic",
"TTS not supported for this document": "TTS non supportato per questo documento"
}
@@ -95,7 +95,6 @@
"Speak": "読み上げ",
"Subjects": "主題",
"System Fonts": "システムフォント",
"TTS not supported in this device": "このデバイスではTTSがサポートされていません",
"Theme Color": "テーマカラー",
"Theme Mode": "テーマモード",
"Translate": "翻訳",
@@ -457,5 +456,6 @@
"Storage": "ストレージ",
"Terms of Service": "利用規約",
"Privacy Policy": "プライバシーポリシー",
"Disable Double Click": "ダブルクリック無効"
"Disable Double Click": "ダブルクリック無効",
"TTS not supported for this document": "TTSはこのドキュメントではサポートされていません"
}
@@ -95,7 +95,6 @@
"Speak": "말하기",
"Subjects": "주제",
"System Fonts": "시스템 글꼴",
"TTS not supported in this device": "이 장치에서 TTS가 지원되지 않음",
"Theme Color": "테마 색상",
"Theme Mode": "테마 모드",
"Translate": "번역",
@@ -457,5 +456,6 @@
"Storage": "저장소",
"Terms of Service": "서비스 약관",
"Privacy Policy": "개인정보 보호정책",
"Disable Double Click": "더블 클릭 비활성화"
"Disable Double Click": "더블 클릭 비활성화",
"TTS not supported for this document": "TTS가 이 문서에서 지원되지 않습니다"
}
@@ -213,7 +213,6 @@
"TOC": "Inhoudsopgave",
"Sidebar": "Zijbalk",
"TTS not supported for PDF": "TTS niet ondersteund voor PDF",
"TTS not supported in this device": "TTS niet ondersteund op dit apparaat",
"No Timeout": "Geen time-out",
"{{value}} minute": "{{value}} minuut",
"{{value}} minutes": "{{value}} minuten",
@@ -303,7 +302,7 @@
"Security": "Beveiliging",
"Allow JavaScript": "JavaScript toestaan",
"Enable only if you trust the file.": "Schakel alleen in als u het bestand vertrouwt.",
"Sort TOC by Page": "__STRING_NOT_TRANSLATED__",
"Sort TOC by Page": "TOC sorteren op pagina",
"Search in {{count}} Book(s)..._one": "Zoeken in {{count}} Boek...",
"Search in {{count}} Book(s)..._other": "Zoeken in {{count}} Boeken...",
"No notes match your search": "Geen notities gevonden",
@@ -461,5 +460,6 @@
"Storage": "Opslag",
"Terms of Service": "Gebruiksvoorwaarden",
"Privacy Policy": "Privacybeleid",
"Disable Double Click": "Dubbelklikken uitschakelen"
"Disable Double Click": "Dubbelklikken uitschakelen",
"TTS not supported for this document": "TTS niet ondersteund voor dit document"
}
@@ -95,7 +95,6 @@
"Speak": "Czytaj",
"Subjects": "Tematy",
"System Fonts": "Czcionki systemowe",
"TTS not supported in this device": "TTS nie jest obsługiwane na tym urządzeniu",
"Theme Color": "Kolor motywu",
"Theme Mode": "Tryb motywu",
"Translate": "Tłumacz",
@@ -469,5 +468,6 @@
"Storage": "Przechowywanie",
"Terms of Service": "Warunki korzystania z usługi",
"Privacy Policy": "Polityka prywatności",
"Disable Double Click": "Wyłącz podwójne kliknięcie"
"Disable Double Click": "Wyłącz podwójne kliknięcie",
"TTS not supported for this document": "TTS nie jest obsługiwane dla tego dokumentu"
}
@@ -95,7 +95,6 @@
"Speak": "Falar",
"Subjects": "Assuntos",
"System Fonts": "Fontes do Sistema",
"TTS not supported in this device": "TTS não suportado neste dispositivo",
"Theme Color": "Cor do Tema",
"Theme Mode": "Modo do Tema",
"Translate": "Traduzir",
@@ -465,5 +464,6 @@
"Storage": "Armazenamento",
"Terms of Service": "Termos de Serviço",
"Privacy Policy": "Política de Privacidade",
"Disable Double Click": "Desativar Clique Duplo"
"Disable Double Click": "Desativar Clique Duplo",
"TTS not supported for this document": "TTS não suportado para este documento"
}
@@ -95,7 +95,6 @@
"Speak": "Произнести",
"Subjects": "Темы",
"System Fonts": "Системные шрифты",
"TTS not supported in this device": "TTS не поддерживается на этом устройстве",
"Theme Color": "Цвет темы",
"Theme Mode": "Режим темы",
"Translate": "Перевести",
@@ -469,5 +468,6 @@
"Storage": "Хранилище",
"Terms of Service": "Условия использования",
"Privacy Policy": "Политика конфиденциальности",
"Disable Double Click": "Отключить двойной клик"
"Disable Double Click": "Отключить двойной клик",
"TTS not supported for this document": "TTS не поддерживается для этого документа"
}
@@ -280,7 +280,6 @@
"Disable Translation": "ปิดการแปล",
"Translation Not Available": "ไม่มีการแปล",
"TTS not supported for PDF": "ไม่รองรับ TTS สำหรับ PDF",
"TTS not supported in this device": "อุปกรณ์นี้ไม่รองรับ TTS",
"No Timeout": "ไม่จำกัดเวลา",
"{{value}} minute": "{{value}} นาที",
"{{value}} minutes": "{{value}} นาที",
@@ -457,5 +456,6 @@
"Storage": "พื้นที่เก็บข้อมูล",
"Terms of Service": "ข้อกำหนดในการให้บริการ",
"Privacy Policy": "นโยบายความเป็นส่วนตัว",
"Disable Double Click": "ปิดการคลิกสองครั้ง"
"Disable Double Click": "ปิดการคลิกสองครั้ง",
"TTS not supported for this document": "ไม่รองรับ TTS สำหรับเอกสารนี้"
}
@@ -95,7 +95,6 @@
"Speak": "Konuş",
"Subjects": "Konular",
"System Fonts": "Sistem Yazı Tipleri",
"TTS not supported in this device": "Bu cihazda TTS desteklenmiyor",
"Theme Color": "Tema Rengi",
"Theme Mode": "Tema Modu",
"Translate": "Çevir",
@@ -461,5 +460,6 @@
"Storage": "Depolama",
"Terms of Service": "Hizmet Şartları",
"Privacy Policy": "Gizlilik Politikası",
"Disable Double Click": "Çift Tıklamayı Devre Dışı Bırak"
"Disable Double Click": "Çift Tıklamayı Devre Dışı Bırak",
"TTS not supported for this document": "TTS bu belge için desteklenmiyor"
}
@@ -95,7 +95,6 @@
"Speak": "Озвучити",
"Subjects": "Теми",
"System Fonts": "Системні шрифти",
"TTS not supported in this device": "TTS не підтримується на цьому пристрої",
"Theme Color": "Колір теми",
"Theme Mode": "Режим теми",
"Translate": "Перекласти",
@@ -469,5 +468,6 @@
"Storage": "Сховище",
"Terms of Service": "Умови обслуговування",
"Privacy Policy": "Політика конфіденційності",
"Disable Double Click": "Вимкнути подвійне клацання"
"Disable Double Click": "Вимкнути подвійне клацання",
"TTS not supported for this document": "TTS не підтримується для цього документа"
}
@@ -95,7 +95,6 @@
"Speak": "Đọc",
"Subjects": "Chủ đề",
"System Fonts": "Phông chữ hệ thống",
"TTS not supported in this device": "TTS không được hỗ trợ trên thiết bị này",
"Theme Color": "Màu chủ đề",
"Theme Mode": "Chế độ chủ đề",
"Translate": "Dịch",
@@ -457,5 +456,6 @@
"Storage": "Lưu trữ",
"Terms of Service": "Điều khoản dịch vụ",
"Privacy Policy": "Chính sách bảo mật",
"Disable Double Click": "Tắt Nhấp Đôi"
"Disable Double Click": "Tắt Nhấp Đôi",
"TTS not supported for this document": "TTS không được hỗ trợ cho tài liệu này"
}
@@ -95,7 +95,6 @@
"Speak": "朗读",
"Subjects": "主题",
"System Fonts": "系统字体",
"TTS not supported in this device": "此设备不支持 TTS",
"Theme Color": "主题颜色",
"Theme Mode": "主题模式",
"Translate": "翻译",
@@ -457,5 +456,6 @@
"Storage": "云同步空间",
"Terms of Service": "服务条款",
"Privacy Policy": "隐私政策",
"Disable Double Click": "禁用双击"
"Disable Double Click": "禁用双击",
"TTS not supported for this document": "TTS 不支持此文档"
}
@@ -95,7 +95,6 @@
"Speak": "朗讀",
"Subjects": "主題",
"System Fonts": "系統字體",
"TTS not supported in this device": "此設備不支持 TTS",
"Theme Color": "主題顏色",
"Theme Mode": "主題模式",
"Translate": "翻譯",
@@ -457,5 +456,6 @@
"Storage": "雲同步空間",
"Terms of Service": "服務條款",
"Privacy Policy": "隱私政策",
"Disable Double Click": "禁用雙擊"
"Disable Double Click": "禁用雙擊",
"TTS not supported for this document": "TTS 不支援此文件"
}
@@ -196,9 +196,6 @@ const TTSControl: React.FC<TTSControlProps> = ({ bookKey }) => {
ttsControllerRef.current = null;
}
setTTSEnabled(bookKey, true);
setShowIndicator(true);
try {
if (appService?.isIOSApp) {
await invokeUseBackgroundAudio({ enabled: true });
@@ -223,9 +220,11 @@ const TTSControl: React.FC<TTSControlProps> = ({ bookKey }) => {
setTtsController(ttsController);
}
setTtsClientsInitialized(true);
setTTSEnabled(bookKey, true);
setShowIndicator(true);
} catch (error) {
eventDispatcher.dispatch('toast', {
message: _('TTS not supported in this device'),
message: _('TTS not supported for this document'),
type: 'error',
});
console.error(error);
@@ -659,3 +659,7 @@ export const TRANSLATED_LANGS = {
};
export const SUPPORTED_LANGS: Record<string, string> = { ...TRANSLATED_LANGS, zh: '中文' };
export const SUPPORTED_LANGNAMES: Record<string, string> = Object.fromEntries(
Object.entries(SUPPORTED_LANGS).map(([code, name]) => [name, code]),
);
+8 -1
View File
@@ -13,10 +13,11 @@ import { EnvConfigType } from '@/services/environment';
import { FoliateView } from '@/types/view';
import { DocumentLoader, TOCItem } from '@/libs/document';
import { updateToc } from '@/utils/toc';
import { formatTitle, getBaseFilename, getPrimaryLanguage } from '@/utils/book';
import { SUPPORTED_LANGNAMES } from '@/services/constants';
import { useSettingsStore } from './settingsStore';
import { useBookDataStore } from './bookDataStore';
import { useLibraryStore } from './libraryStore';
import { formatTitle, getBaseFilename, getPrimaryLanguage } from '@/utils/book';
interface ViewState {
/* Unique key for each book view */
@@ -137,6 +138,12 @@ export const useReaderStore = create<ReaderStore>((set, get) => ({
console.log('Loading book', key);
const { book: bookDoc } = await new DocumentLoader(file).open();
updateToc(bookDoc, config.viewSettings?.sortedTOC ?? false);
// Correct language codes mistakenly set with language names
if (typeof bookDoc.metadata?.language === 'string') {
if (bookDoc.metadata.language in SUPPORTED_LANGNAMES) {
bookDoc.metadata.language = SUPPORTED_LANGNAMES[bookDoc.metadata.language]!;
}
}
// Set the book's language for formerly imported books, newly imported books have this field set
if (!bookDoc.metadata.title) {
bookDoc.metadata.title = getBaseFilename(file.name);
+1
View File
@@ -11,6 +11,7 @@
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.9.1",
"@sindresorhus/tsconfig": "^6.0.0",
"caniuse-lite": "^1.0.30001731",
"eslint": "^9.28.0",
"eslint-config-prettier": "^9.1.0",
"husky": "^9.1.6",
+18 -8
View File
@@ -17,6 +17,9 @@ importers:
'@sindresorhus/tsconfig':
specifier: ^6.0.0
version: 6.0.0
caniuse-lite:
specifier: ^1.0.30001731
version: 1.0.30001731
eslint:
specifier: ^9.28.0
version: 9.28.0(jiti@1.21.6)
@@ -3117,6 +3120,9 @@ packages:
'@types/node@22.16.5':
resolution: {integrity: sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==}
'@types/node@22.17.0':
resolution: {integrity: sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ==}
'@types/phoenix@1.6.6':
resolution: {integrity: sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==}
@@ -3641,12 +3647,12 @@ packages:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
caniuse-lite@1.0.30001684:
resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==}
caniuse-lite@1.0.30001695:
resolution: {integrity: sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==}
caniuse-lite@1.0.30001731:
resolution: {integrity: sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==}
chai@5.2.1:
resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==}
engines: {node: '>=18'}
@@ -10800,6 +10806,10 @@ snapshots:
dependencies:
undici-types: 6.21.0
'@types/node@22.17.0':
dependencies:
undici-types: 6.21.0
'@types/phoenix@1.6.6': {}
'@types/prop-types@15.7.13': {}
@@ -11266,7 +11276,7 @@ snapshots:
autoprefixer@10.4.20(postcss@8.4.49):
dependencies:
browserslist: 4.24.2
caniuse-lite: 1.0.30001684
caniuse-lite: 1.0.30001695
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.1.1
@@ -11359,7 +11369,7 @@ snapshots:
browserslist@4.24.2:
dependencies:
caniuse-lite: 1.0.30001684
caniuse-lite: 1.0.30001695
electron-to-chromium: 1.5.67
node-releases: 2.0.18
update-browserslist-db: 1.1.1(browserslist@4.24.2)
@@ -11410,10 +11420,10 @@ snapshots:
camelcase@5.3.1: {}
caniuse-lite@1.0.30001684: {}
caniuse-lite@1.0.30001695: {}
caniuse-lite@1.0.30001731: {}
chai@5.2.1:
dependencies:
assertion-error: 2.0.1
@@ -12842,7 +12852,7 @@ snapshots:
jest-worker@27.5.1:
dependencies:
'@types/node': 22.16.5
'@types/node': 22.17.0
merge-stream: 2.0.0
supports-color: 8.1.1