From 434a44e62c595fcdef5639264ee09b90bf0fe1e3 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Tue, 13 Jan 2026 15:35:57 +0100 Subject: [PATCH] feat(proofread): add an option for whole word replacement, closes #2934 (#2938) --- .../public/locales/ar/translation.json | 6 +- .../public/locales/bn/translation.json | 6 +- .../public/locales/bo/translation.json | 6 +- .../public/locales/de/translation.json | 6 +- .../public/locales/el/translation.json | 6 +- .../public/locales/es/translation.json | 6 +- .../public/locales/fa/translation.json | 6 +- .../public/locales/fr/translation.json | 6 +- .../public/locales/hi/translation.json | 6 +- .../public/locales/id/translation.json | 6 +- .../public/locales/it/translation.json | 6 +- .../public/locales/ja/translation.json | 6 +- .../public/locales/ko/translation.json | 6 +- .../public/locales/ms/translation.json | 6 +- .../public/locales/nl/translation.json | 6 +- .../public/locales/pl/translation.json | 6 +- .../public/locales/pt/translation.json | 6 +- .../public/locales/ru/translation.json | 6 +- .../public/locales/si/translation.json | 6 +- .../public/locales/sv/translation.json | 6 +- .../public/locales/ta/translation.json | 6 +- .../public/locales/th/translation.json | 6 +- .../public/locales/tr/translation.json | 6 +- .../public/locales/uk/translation.json | 6 +- .../public/locales/vi/translation.json | 6 +- .../public/locales/zh-CN/translation.json | 6 +- .../public/locales/zh-TW/translation.json | 6 +- .../components/annotator/ProofreadPopup.tsx | 73 +++++++++++++------ .../components/annotator/TranslatorPopup.tsx | 12 +-- .../components/annotator/WikipediaPopup.tsx | 14 ++-- .../components/annotator/WiktionaryPopup.tsx | 14 ++-- apps/readest-app/src/styles/globals.css | 4 + apps/readest-app/src/utils/word.ts | 5 ++ 33 files changed, 217 insertions(+), 67 deletions(-) diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 5797109a..f463a036 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -880,5 +880,9 @@ "Exported successfully": "تم التصدير بنجاح", "Book exported successfully.": "تم تصدير الكتاب بنجاح.", "Failed to export the book.": "فشل تصدير الكتاب.", - "Export Book": "تصدير الكتاب" + "Export Book": "تصدير الكتاب", + "Whole word:": "كلمة كاملة:", + "Error": "خطأ", + "Unable to load the article. Try searching directly on {{link}}.": "تعذر تحميل المقال. حاول البحث مباشرة على {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "تعذر تحميل الكلمة. حاول البحث مباشرة على {{link}}." } diff --git a/apps/readest-app/public/locales/bn/translation.json b/apps/readest-app/public/locales/bn/translation.json index a92ee16e..4a9abd3c 100644 --- a/apps/readest-app/public/locales/bn/translation.json +++ b/apps/readest-app/public/locales/bn/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "সফলভাবে রপ্তানি হয়েছে", "Book exported successfully.": "বইটি সফলভাবে রপ্তানি হয়েছে।", "Failed to export the book.": "বই রপ্তানি করতে ব্যর্থ।", - "Export Book": "বই রপ্তানি করুন" + "Export Book": "বই রপ্তানি করুন", + "Whole word:": "সম্পূর্ণ শব্দ:", + "Error": "ত্রুটি", + "Unable to load the article. Try searching directly on {{link}}.": "নিবন্ধ লোড করতে অক্ষম। সরাসরি {{link}} এ অনুসন্ধান করার চেষ্টা করুন।", + "Unable to load the word. Try searching directly on {{link}}.": "শব্দ লোড করতে অক্ষম। সরাসরি {{link}} এ অনুসন্ধান করার চেষ্টা করুন।" } diff --git a/apps/readest-app/public/locales/bo/translation.json b/apps/readest-app/public/locales/bo/translation.json index 093e37a6..939a437b 100644 --- a/apps/readest-app/public/locales/bo/translation.json +++ b/apps/readest-app/public/locales/bo/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "ཕྱིར་འདོན་ལེགས་གྲུབ་བྱུང་།", "Book exported successfully.": "དཔེ་དེབ་ཕྱིར་འདོན་ལེགས་གྲུབ་བྱུང་།", "Failed to export the book.": "དཔེ་དེབ་ཕྱིར་འདོན་མི་ཐུབ།", - "Export Book": "དཔེ་དེབ་ཕྱིར་འདོན།" + "Export Book": "དཔེ་དེབ་ཕྱིར་འདོན།", + "Whole word:": "ཚིག་གྲུབ་ཆ་ཚང་:", + "Error": "ནོར་འཁྲུལ།", + "Unable to load the article. Try searching directly on {{link}}.": "རྩོམ་ཡིག་མངོན་མི་ཐུབ། {{link}} ཐད་ཀར་འཚོལ་བ་བྱོས།", + "Unable to load the word. Try searching directly on {{link}}.": "ཚིག་མངོན་མི་ཐུབ། {{link}} ཐད་ཀར་འཚོལ་བ་བྱོས།" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index b3761fae..91e50af4 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "Erfolgreich exportiert", "Book exported successfully.": "Buch erfolgreich exportiert.", "Failed to export the book.": "Buch konnte nicht exportiert werden.", - "Export Book": "Buch exportieren" + "Export Book": "Buch exportieren", + "Whole word:": "Ganzes Wort:", + "Error": "Fehler", + "Unable to load the article. Try searching directly on {{link}}.": "Artikel kann nicht geladen werden. Versuchen Sie die direkte Suche auf {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Wort kann nicht geladen werden. Versuchen Sie die direkte Suche auf {{link}}." } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index 5c73b78f..d0ee829f 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "Εξαγωγή επιτυχής", "Book exported successfully.": "Το βιβλίο εξήχθη επιτυχώς.", "Failed to export the book.": "Αποτυχία εξαγωγής του βιβλίου.", - "Export Book": "Εξαγωγή βιβλίου" + "Export Book": "Εξαγωγή βιβλίου", + "Whole word:": "Ολόκληρη λέξη:", + "Error": "Σφάλμα", + "Unable to load the article. Try searching directly on {{link}}.": "Αδυναμία φόρτωσης του άρθρου. Δοκιμάστε να αναζητήσετε απευθείας στο {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Αδυναμία φόρτωσης της λέξης. Δοκιμάστε να αναζητήσετε απευθείας στο {{link}}." } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 6ba481b3..c201bad6 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -850,5 +850,9 @@ "Exported successfully": "Exportado con éxito", "Book exported successfully.": "Libro exportado con éxito.", "Failed to export the book.": "Error al exportar el libro.", - "Export Book": "Exportar libro" + "Export Book": "Exportar libro", + "Whole word:": "Palabra completa:", + "Error": "Error", + "Unable to load the article. Try searching directly on {{link}}.": "No se puede cargar el artículo. Intenta buscar directamente en {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "No se puede cargar la palabra. Intenta buscar directamente en {{link}}." } diff --git a/apps/readest-app/public/locales/fa/translation.json b/apps/readest-app/public/locales/fa/translation.json index 80b8599b..7b5730c7 100644 --- a/apps/readest-app/public/locales/fa/translation.json +++ b/apps/readest-app/public/locales/fa/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "صادرات موفق", "Book exported successfully.": "کتاب با موفقیت صادر شد.", "Failed to export the book.": "صادر کردن کتاب ناموفق بود.", - "Export Book": "صادر کردن کتاب" + "Export Book": "صادر کردن کتاب", + "Whole word:": "کلمه کامل:", + "Error": "خطا", + "Unable to load the article. Try searching directly on {{link}}.": "بارگذاری مقاله امکان‌پذیر نیست. سعی کنید مستقیماً در {{link}} جستجو کنید.", + "Unable to load the word. Try searching directly on {{link}}.": "بارگذاری کلمه امکان‌پذیر نیست. سعی کنید مستقیماً در {{link}} جستجو کنید." } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 9314a476..b787cd27 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -850,5 +850,9 @@ "Exported successfully": "Exporté avec succès", "Book exported successfully.": "Livre exporté avec succès.", "Failed to export the book.": "Échec de l'exportation du livre.", - "Export Book": "Exporter le livre" + "Export Book": "Exporter le livre", + "Whole word:": "Mot entier :", + "Error": "Erreur", + "Unable to load the article. Try searching directly on {{link}}.": "Impossible de charger l'article. Essayez de rechercher directement sur {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Impossible de charger le mot. Essayez de rechercher directement sur {{link}}." } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 10fdcaa1..044e71fb 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "सफलतापूर्वक निर्यात किया गया", "Book exported successfully.": "पुस्तक सफलतापूर्वक निर्यात की गई।", "Failed to export the book.": "पुस्तक निर्यात करने में विफल।", - "Export Book": "पुस्तक निर्यात करें" + "Export Book": "पुस्तक निर्यात करें", + "Whole word:": "पूरा शब्द:", + "Error": "त्रुटि", + "Unable to load the article. Try searching directly on {{link}}.": "लेख लोड करने में असमर्थ। सीधे {{link}} पर खोजने का प्रयास करें।", + "Unable to load the word. Try searching directly on {{link}}.": "शब्द लोड करने में असमर्थ। सीधे {{link}} पर खोजने का प्रयास करें।" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index 6cb26e12..7bc78903 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "Berhasil diekspor", "Book exported successfully.": "Buku berhasil diekspor.", "Failed to export the book.": "Gagal mengekspor buku.", - "Export Book": "Ekspor Buku" + "Export Book": "Ekspor Buku", + "Whole word:": "Kata utuh:", + "Error": "Kesalahan", + "Unable to load the article. Try searching directly on {{link}}.": "Tidak dapat memuat artikel. Coba cari langsung di {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Tidak dapat memuat kata. Coba cari langsung di {{link}}." } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index 5f8e80c7..4fa30d1a 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -850,5 +850,9 @@ "Exported successfully": "Esportato con successo", "Book exported successfully.": "Libro esportato con successo.", "Failed to export the book.": "Impossibile esportare il libro.", - "Export Book": "Esporta libro" + "Export Book": "Esporta libro", + "Whole word:": "Parola intera:", + "Error": "Errore", + "Unable to load the article. Try searching directly on {{link}}.": "Impossibile caricare l'articolo. Prova a cercare direttamente su {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Impossibile caricare la parola. Prova a cercare direttamente su {{link}}." } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index 4e9a738f..aedb62eb 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "エクスポート成功", "Book exported successfully.": "書籍のエクスポートに成功しました。", "Failed to export the book.": "書籍のエクスポートに失敗しました。", - "Export Book": "書籍をエクスポート" + "Export Book": "書籍をエクスポート", + "Whole word:": "単語全体:", + "Error": "エラー", + "Unable to load the article. Try searching directly on {{link}}.": "記事を読み込めません。{{link}}で直接検索してみてください。", + "Unable to load the word. Try searching directly on {{link}}.": "単語を読み込めません。{{link}}で直接検索してみてください。" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index 6dd12635..4c04e8cc 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "내보내기 성공", "Book exported successfully.": "책을 성공적으로 내보냈습니다.", "Failed to export the book.": "책 내보내기에 실패했습니다.", - "Export Book": "책 내보내기" + "Export Book": "책 내보내기", + "Whole word:": "전체 단어:", + "Error": "오류", + "Unable to load the article. Try searching directly on {{link}}.": "문서를 로드할 수 없습니다. {{link}}에서 직접 검색해 보세요.", + "Unable to load the word. Try searching directly on {{link}}.": "단어를 로드할 수 없습니다. {{link}}에서 직접 검색해 보세요." } diff --git a/apps/readest-app/public/locales/ms/translation.json b/apps/readest-app/public/locales/ms/translation.json index d3f3dda9..17e35f0d 100644 --- a/apps/readest-app/public/locales/ms/translation.json +++ b/apps/readest-app/public/locales/ms/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "Berjaya dieksport", "Book exported successfully.": "Buku berjaya dieksport.", "Failed to export the book.": "Gagal mengeksport buku.", - "Export Book": "Eksport Buku" + "Export Book": "Eksport Buku", + "Whole word:": "Perkataan penuh:", + "Error": "Ralat", + "Unable to load the article. Try searching directly on {{link}}.": "Tidak dapat memuatkan artikel. Cuba cari terus di {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Tidak dapat memuatkan perkataan. Cuba cari terus di {{link}}." } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index f28acb43..36370a87 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "Succesvol geëxporteerd", "Book exported successfully.": "Boek succesvol geëxporteerd.", "Failed to export the book.": "Exporteren van het boek mislukt.", - "Export Book": "Boek exporteren" + "Export Book": "Boek exporteren", + "Whole word:": "Heel woord:", + "Error": "Fout", + "Unable to load the article. Try searching directly on {{link}}.": "Kan het artikel niet laden. Probeer direct te zoeken op {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Kan het woord niet laden. Probeer direct te zoeken op {{link}}." } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index aceebf8e..ee56c75e 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -860,5 +860,9 @@ "Exported successfully": "Wyeksportowano pomyślnie", "Book exported successfully.": "Książka została wyeksportowana pomyślnie.", "Failed to export the book.": "Nie udało się wyeksportować książki.", - "Export Book": "Eksportuj książkę" + "Export Book": "Eksportuj książkę", + "Whole word:": "Całe słowo:", + "Error": "Błąd", + "Unable to load the article. Try searching directly on {{link}}.": "Nie można załadować artykułu. Spróbuj wyszukać bezpośrednio na {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Nie można załadować słowa. Spróbuj wyszukać bezpośrednio na {{link}}." } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index ea227948..7ba6635b 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -850,5 +850,9 @@ "Exported successfully": "Exportado com sucesso", "Book exported successfully.": "Livro exportado com sucesso.", "Failed to export the book.": "Falha ao exportar o livro.", - "Export Book": "Exportar livro" + "Export Book": "Exportar livro", + "Whole word:": "Palavra inteira:", + "Error": "Erro", + "Unable to load the article. Try searching directly on {{link}}.": "Não foi possível carregar o artigo. Tente pesquisar diretamente em {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Não foi possível carregar a palavra. Tente pesquisar diretamente em {{link}}." } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index ef1de359..5b00c393 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -860,5 +860,9 @@ "Exported successfully": "Успешно экспортировано", "Book exported successfully.": "Книга успешно экспортирована.", "Failed to export the book.": "Не удалось экспортировать книгу.", - "Export Book": "Экспорт книги" + "Export Book": "Экспорт книги", + "Whole word:": "Слово целиком:", + "Error": "Ошибка", + "Unable to load the article. Try searching directly on {{link}}.": "Не удалось загрузить статью. Попробуйте искать напрямую на {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Не удалось загрузить слово. Попробуйте искать напрямую на {{link}}." } diff --git a/apps/readest-app/public/locales/si/translation.json b/apps/readest-app/public/locales/si/translation.json index 18f9f27f..3ed376ca 100644 --- a/apps/readest-app/public/locales/si/translation.json +++ b/apps/readest-app/public/locales/si/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "සාර්ථකව අපනයනය කරන ලදී", "Book exported successfully.": "පොත සාර්ථකව අපනයනය කරන ලදී.", "Failed to export the book.": "පොත අපනයනය කිරීමට අසමත් විය.", - "Export Book": "පොත අපනයනය කරන්න" + "Export Book": "පොත අපනයනය කරන්න", + "Whole word:": "සම්පූර්ණ වචනය:", + "Error": "දෝෂය", + "Unable to load the article. Try searching directly on {{link}}.": "ලිපිය පූරණය කළ නොහැක. {{link}} හි කෙලින්ම සෙවීමට උත්සාහ කරන්න.", + "Unable to load the word. Try searching directly on {{link}}.": "වචනය පූරණය කළ නොහැක. {{link}} හි කෙලින්ම සෙවීමට උත්සාහ කරන්න." } diff --git a/apps/readest-app/public/locales/sv/translation.json b/apps/readest-app/public/locales/sv/translation.json index 683d5828..d30ab803 100644 --- a/apps/readest-app/public/locales/sv/translation.json +++ b/apps/readest-app/public/locales/sv/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "Exporterad", "Book exported successfully.": "Boken har exporterats.", "Failed to export the book.": "Det gick inte att exportera boken.", - "Export Book": "Exportera bok" + "Export Book": "Exportera bok", + "Whole word:": "Hela ordet:", + "Error": "Fel", + "Unable to load the article. Try searching directly on {{link}}.": "Kan inte ladda artikeln. Försök söka direkt på {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Kan inte ladda ordet. Försök söka direkt på {{link}}." } diff --git a/apps/readest-app/public/locales/ta/translation.json b/apps/readest-app/public/locales/ta/translation.json index 36726067..41c1ddd5 100644 --- a/apps/readest-app/public/locales/ta/translation.json +++ b/apps/readest-app/public/locales/ta/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "ஏற்றுமதி வெற்றி", "Book exported successfully.": "புத்தகம் வெற்றிகரமாக ஏற்றுமதி செய்யப்பட்டது.", "Failed to export the book.": "புத்தகத்தை ஏற்றுமதி செய்ய இயலவில்லை.", - "Export Book": "புத்தகத்தை ஏற்றுமதி செய்" + "Export Book": "புத்தகத்தை ஏற்றுமதி செய்", + "Whole word:": "முழு சொல்:", + "Error": "பிழை", + "Unable to load the article. Try searching directly on {{link}}.": "கட்டுரையை ஏற்ற முடியவில்லை. நேரடியாக {{link}} இல் தேடவும்.", + "Unable to load the word. Try searching directly on {{link}}.": "சொல்லை ஏற்ற முடியவில்லை. நேரடியாக {{link}} இல் தேடவும்." } diff --git a/apps/readest-app/public/locales/th/translation.json b/apps/readest-app/public/locales/th/translation.json index 12b79ad4..99dfedce 100644 --- a/apps/readest-app/public/locales/th/translation.json +++ b/apps/readest-app/public/locales/th/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "ส่งออกสำเร็จ", "Book exported successfully.": "ส่งออกหนังสือสำเร็จ", "Failed to export the book.": "ส่งออกหนังสือล้มเหลว", - "Export Book": "ส่งออกหนังสือ" + "Export Book": "ส่งออกหนังสือ", + "Whole word:": "คำทั้งคำ:", + "Error": "ข้อผิดพลาด", + "Unable to load the article. Try searching directly on {{link}}.": "ไม่สามารถโหลดบทความได้ ลองค้นหาโดยตรงที่ {{link}}", + "Unable to load the word. Try searching directly on {{link}}.": "ไม่สามารถโหลดคำได้ ลองค้นหาโดยตรงที่ {{link}}" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index a2140be0..0ceb1b31 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -840,5 +840,9 @@ "Exported successfully": "Başarıyla dışa aktarıldı", "Book exported successfully.": "Kitap başarıyla dışa aktarıldı.", "Failed to export the book.": "Kitap dışa aktarılamadı.", - "Export Book": "Kitabı Dışa Aktar" + "Export Book": "Kitabı Dışa Aktar", + "Whole word:": "Tam kelime:", + "Error": "Hata", + "Unable to load the article. Try searching directly on {{link}}.": "Makale yüklenemiyor. Doğrudan {{link}} üzerinde arama yapmayı deneyin.", + "Unable to load the word. Try searching directly on {{link}}.": "Kelime yüklenemiyor. Doğrudan {{link}} üzerinde arama yapmayı deneyin." } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index da31aaed..60994464 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -860,5 +860,9 @@ "Exported successfully": "Успішно експортовано", "Book exported successfully.": "Книгу успішно експортовано.", "Failed to export the book.": "Не вдалося експортувати книгу.", - "Export Book": "Експортувати книгу" + "Export Book": "Експортувати книгу", + "Whole word:": "Ціле слово:", + "Error": "Помилка", + "Unable to load the article. Try searching directly on {{link}}.": "Не вдалося завантажити статтю. Спробуйте шукати безпосередньо на {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Не вдалося завантажити слово. Спробуйте шукати безпосередньо на {{link}}." } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 8ee38164..686e64f6 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "Xuất thành công", "Book exported successfully.": "Sách đã được xuất thành công.", "Failed to export the book.": "Xuất sách thất bại.", - "Export Book": "Xuất sách" + "Export Book": "Xuất sách", + "Whole word:": "Toàn bộ từ:", + "Error": "Lỗi", + "Unable to load the article. Try searching directly on {{link}}.": "Không thể tải bài viết. Hãy thử tìm kiếm trực tiếp trên {{link}}.", + "Unable to load the word. Try searching directly on {{link}}.": "Không thể tải từ. Hãy thử tìm kiếm trực tiếp trên {{link}}." } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index af9fc191..89827f6c 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "导出成功", "Book exported successfully.": "书籍导出成功。", "Failed to export the book.": "书籍导出失败。", - "Export Book": "导出书籍" + "Export Book": "导出书籍", + "Whole word:": "全词匹配:", + "Error": "错误", + "Unable to load the article. Try searching directly on {{link}}.": "无法加载文章。请直接在 {{link}} 上搜索。", + "Unable to load the word. Try searching directly on {{link}}.": "无法加载词汇。请直接在 {{link}} 上搜索。" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 3aa356cb..d72df3c2 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -830,5 +830,9 @@ "Exported successfully": "匯出成功", "Book exported successfully.": "書籍匯出成功。", "Failed to export the book.": "書籍匯出失敗。", - "Export Book": "匯出書籍" + "Export Book": "匯出書籍", + "Whole word:": "全詞匹配:", + "Error": "錯誤", + "Unable to load the article. Try searching directly on {{link}}.": "無法載入文章。請直接在 {{link}} 上搜尋。", + "Unable to load the word. Try searching directly on {{link}}.": "無法載入詞彙。請直接在 {{link}} 上搜尋。" } diff --git a/apps/readest-app/src/app/reader/components/annotator/ProofreadPopup.tsx b/apps/readest-app/src/app/reader/components/annotator/ProofreadPopup.tsx index 16856532..3b5bc01e 100644 --- a/apps/readest-app/src/app/reader/components/annotator/ProofreadPopup.tsx +++ b/apps/readest-app/src/app/reader/components/annotator/ProofreadPopup.tsx @@ -8,7 +8,7 @@ import { CreateProofreadRuleOptions, useProofreadStore } from '@/store/proofread import { ProofreadScope } from '@/types/book'; import { eventDispatcher } from '@/utils/event'; import { Position, TextSelection } from '@/utils/sel'; -import { isWholeWord } from '@/utils/word'; +import { isPunctuationOnly, isWholeWord } from '@/utils/word'; import Select from '@/components/Select'; import Popup from '@/components/Popup'; @@ -41,11 +41,17 @@ const ProofreadPopup: React.FC = ({ const [replacementText, setReplacementText] = useState(''); const [caseSensitive, setCaseSensitive] = useState(true); + const [wholeWord, setWholeWord] = useState(!isPunctuationOnly(selection?.text || '')); const [scope, setScope] = useState('selection'); const inputRef = useRef(null); useAutoFocus({ ref: inputRef }); + const handleInputChange = (e: React.ChangeEvent) => { + const text = e.target.value; + setReplacementText(text); + }; + const handleScopeChange = (event: React.ChangeEvent) => { setScope(event.target.value as ProofreadScope); }; @@ -58,10 +64,10 @@ const ProofreadPopup: React.FC = ({ if (range) { const isValidWholeWord = isWholeWord(range, selection?.text || ''); - if (!isValidWholeWord) { + if (wholeWord && !isValidWholeWord) { eventDispatcher.dispatch('toast', { type: 'warning', - message: `Cannot replace "${selection.text}" - please select a complete word. Partial word selections (like "and" in "England" or "errand") are not supported.`, + message: 'Please select a whole word or uncheck the "Whole word" option.', timeout: 5000, }); return; @@ -73,7 +79,7 @@ const ProofreadPopup: React.FC = ({ range.insertNode(textNode); } - const options = { + const options: CreateProofreadRuleOptions = { scope, pattern: selection.text, replacement: replacementText.trim(), @@ -82,7 +88,7 @@ const ProofreadPopup: React.FC = ({ isRegex: false, enabled: true, caseSensitive, - wholeWord: true, + wholeWord: wholeWord, }; onConfirm?.(options); @@ -111,14 +117,14 @@ const ProofreadPopup: React.FC = ({ width={popupWidth} minHeight={popupHeight} position={position} - className='flex flex-col justify-between rounded-lg bg-gray-700 text-gray-400' + className='not-eink:text-gray-400 flex flex-col justify-between rounded-lg bg-gray-700' triangleClassName='text-gray-700' onDismiss={onDismiss} >
-
+
{_('Selected text:')} - + "{selection?.text || ''}"
@@ -131,20 +137,23 @@ const ProofreadPopup: React.FC = ({ ref={inputRef} type='text' value={replacementText} - onChange={(e) => setReplacementText(e.target.value)} + onChange={handleInputChange} onKeyDown={(e) => { if (e.key === 'Enter' && replacementText.trim()) { handleApply(); } }} placeholder={_('Enter text...')} - className='w-full flex-1 rounded-md bg-gray-600 p-2 text-sm text-white placeholder-gray-400 focus:outline-none focus:ring-0' + className={clsx( + 'w-full flex-1 rounded-md p-2 text-sm placeholder-gray-400 focus:outline-none focus:ring-0', + 'not-eink:bg-gray-600 not-eink:text-white eink:border eink:border-base-content', + )} />
-
-
@@ -176,7 +176,7 @@ const TranslatorPopup: React.FC = ({

{_('Translated Text')}

({ value, label }))} diff --git a/apps/readest-app/src/app/reader/components/annotator/WikipediaPopup.tsx b/apps/readest-app/src/app/reader/components/annotator/WikipediaPopup.tsx index d9afd4ee..68d26725 100644 --- a/apps/readest-app/src/app/reader/components/annotator/WikipediaPopup.tsx +++ b/apps/readest-app/src/app/reader/components/annotator/WikipediaPopup.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useRef } from 'react'; import Popup from '@/components/Popup'; import { Position } from '@/utils/sel'; +import { useTranslation } from '@/hooks/useTranslation'; interface WikipediaPopupProps { text: string; @@ -21,6 +22,7 @@ const WikipediaPopup: React.FC = ({ popupHeight, onDismiss, }) => { + const _ = useTranslation(); const isLoading = useRef(false); useEffect(() => { @@ -85,12 +87,14 @@ const WikipediaPopup: React.FC = ({ const errorDiv = document.createElement('div'); const h1 = document.createElement('h1'); - h1.innerText = 'Error'; + h1.innerText = _('Error'); const errorMsg = document.createElement('p'); - errorMsg.innerHTML = `Unable to load the article. Try searching directly on Wikipedia.`; + errorMsg.innerHTML = _('Unable to load the article. Try searching directly on {{link}}.', { + link: `Wikipedia`, + }); errorDiv.append(h1, errorMsg); main.appendChild(errorDiv); @@ -101,7 +105,7 @@ const WikipediaPopup: React.FC = ({ const bookLang = typeof lang === 'string' ? lang : lang?.[0]; const langCode = bookLang ? bookLang.split('-')[0]! : 'en'; fetchSummary(text, langCode); - }, [text, lang]); + }, [_, text, lang]); return (
diff --git a/apps/readest-app/src/app/reader/components/annotator/WiktionaryPopup.tsx b/apps/readest-app/src/app/reader/components/annotator/WiktionaryPopup.tsx index e8f6753b..0a31c35f 100644 --- a/apps/readest-app/src/app/reader/components/annotator/WiktionaryPopup.tsx +++ b/apps/readest-app/src/app/reader/components/annotator/WiktionaryPopup.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; import { Position } from '@/utils/sel'; +import { useTranslation } from '@/hooks/useTranslation'; import Popup from '@/components/Popup'; type Definition = { @@ -32,6 +33,7 @@ const WiktionaryPopup: React.FC = ({ popupHeight, onDismiss, }) => { + const _ = useTranslation(); const [lookupWord, setLookupWord] = useState(word); const isLookingUp = useRef(false); @@ -141,13 +143,15 @@ const WiktionaryPopup: React.FC = ({ 'flex flex-col items-center justify-center w-full h-full text-center absolute inset-0'; const h1 = document.createElement('h1'); - h1.innerText = 'Error'; + h1.innerText = _('Error'); h1.className = 'text-lg font-bold'; const p = document.createElement('p'); - p.innerHTML = `Unable to load the word. Try searching directly on Wiktionary.`; + p.innerHTML = _('Unable to load the word. Try searching directly on {{link}}.', { + link: `Wiktionary`, + }); div.append(h1, p); main.append(div); @@ -156,7 +160,7 @@ const WiktionaryPopup: React.FC = ({ const langCode = typeof lang === 'string' ? lang : lang?.[0]; fetchDefinitions(lookupWord, langCode); - }, [lookupWord, lang]); + }, [_, lookupWord, lang]); return (
diff --git a/apps/readest-app/src/styles/globals.css b/apps/readest-app/src/styles/globals.css index 37cd7090..9f89bd2f 100644 --- a/apps/readest-app/src/styles/globals.css +++ b/apps/readest-app/src/styles/globals.css @@ -595,6 +595,10 @@ foliate-fxl { background-color: theme('colors.base-100') !important; } +[data-eink="true"] input[type="checkbox"] { + --tglbg: theme('colors.base-100') !important; +} + .no-transitions * { transition: none !important; } \ No newline at end of file diff --git a/apps/readest-app/src/utils/word.ts b/apps/readest-app/src/utils/word.ts index 6a2bfc2e..bb5bd7bc 100644 --- a/apps/readest-app/src/utils/word.ts +++ b/apps/readest-app/src/utils/word.ts @@ -30,6 +30,11 @@ export const isWholeWord = (range: Range, selectedText: string): boolean => { } }; +export const isPunctuationOnly = (text: string): boolean => { + const punctuationPattern = /^[\p{P}\p{S}\s]+$/u; + return punctuationPattern.test(text); +}; + // Helper to get characters before and after the selection const getBoundaryChars = (range: Range): { charBefore: string; charAfter: string } => { let charBefore = '';