diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 6cfc2a1f..9d209d05 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -1906,5 +1906,6 @@ "biometrics": "البيومترية", "Show a short native-language hint above difficult words. Words above your level get a hint.": "أظهر تلميحًا قصيرًا بلغتك الأم فوق الكلمات الصعبة. الكلمات التي تفوق مستواك تحصل على تلميح.", "Level": "المستوى", - "CEFR level": "مستوى CEFR" + "CEFR level": "مستوى CEFR", + "Webtoon Mode": "وضع الويبتون" } diff --git a/apps/readest-app/public/locales/bn/translation.json b/apps/readest-app/public/locales/bn/translation.json index d7c72fb3..8ce3fe28 100644 --- a/apps/readest-app/public/locales/bn/translation.json +++ b/apps/readest-app/public/locales/bn/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "বায়োমেট্রিক্স", "Show a short native-language hint above difficult words. Words above your level get a hint.": "কঠিন শব্দের উপরে আপনার মাতৃভাষায় একটি সংক্ষিপ্ত ইঙ্গিত দেখান। আপনার স্তরের উপরের শব্দগুলো একটি ইঙ্গিত পায়।", "Level": "স্তর", - "CEFR level": "CEFR স্তর" + "CEFR level": "CEFR স্তর", + "Webtoon Mode": "ওয়েবটুন মোড" } diff --git a/apps/readest-app/public/locales/bo/translation.json b/apps/readest-app/public/locales/bo/translation.json index bc973b6b..53a5d584 100644 --- a/apps/readest-app/public/locales/bo/translation.json +++ b/apps/readest-app/public/locales/bo/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "ལུས་རྟགས་ངོ་སྤྲོད།", "Show a short native-language hint above difficult words. Words above your level get a hint.": "ཚིག་དཀའ་མོའི་སྟེང་དུ་རང་གི་སྐད་ཡིག་ཐོག་ནས་བརྡ་སྟོན་ཐུང་ངུ་ཞིག་སྟོན། ཁྱེད་ཀྱི་རིམ་པ་ལས་མཐོ་བའི་ཚིག་ལ་བརྡ་སྟོན་ཐོབ།", "Level": "རིམ་པ།", - "CEFR level": "CEFR རིམ་པ།" + "CEFR level": "CEFR རིམ་པ།", + "Webtoon Mode": "Webtoon སྤྱོད་ཚུལ།" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index 75482787..7d9b4091 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "Biometrie", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Zeigt einen kurzen Hinweis in deiner Muttersprache über schwierigen Wörtern an. Wörter über deinem Niveau erhalten einen Hinweis.", "Level": "Niveau", - "CEFR level": "CEFR-Niveau" + "CEFR level": "CEFR-Niveau", + "Webtoon Mode": "Webtoon-Modus" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index 29d046bc..d7b94874 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "βιομετρικά", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Εμφανίζει μια σύντομη υπόδειξη στη μητρική σου γλώσσα πάνω από δύσκολες λέξεις. Οι λέξεις πάνω από το επίπεδό σου λαμβάνουν υπόδειξη.", "Level": "Επίπεδο", - "CEFR level": "Επίπεδο CEFR" + "CEFR level": "Επίπεδο CEFR", + "Webtoon Mode": "Λειτουργία webtoon" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 9eb3ed2a..83a8254e 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -1807,5 +1807,6 @@ "biometrics": "biometría", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Muestra una breve pista en tu idioma nativo encima de las palabras difíciles. Las palabras por encima de tu nivel reciben una pista.", "Level": "Nivel", - "CEFR level": "Nivel CEFR" + "CEFR level": "Nivel CEFR", + "Webtoon Mode": "Modo webtoon" } diff --git a/apps/readest-app/public/locales/fa/translation.json b/apps/readest-app/public/locales/fa/translation.json index d30ba3b2..44af1480 100644 --- a/apps/readest-app/public/locales/fa/translation.json +++ b/apps/readest-app/public/locales/fa/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "بیومتریک", "Show a short native-language hint above difficult words. Words above your level get a hint.": "یک راهنمای کوتاه به زبان مادری‌تان بالای واژه‌های دشوار نشان می‌دهد. واژه‌های بالاتر از سطح شما راهنما می‌گیرند.", "Level": "سطح", - "CEFR level": "سطح CEFR" + "CEFR level": "سطح CEFR", + "Webtoon Mode": "حالت وب‌تون" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 4a1d532c..eb68e4e5 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -1807,5 +1807,6 @@ "biometrics": "biométrie", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Affiche une courte indication dans votre langue maternelle au-dessus des mots difficiles. Les mots au-dessus de votre niveau reçoivent une indication.", "Level": "Niveau", - "CEFR level": "Niveau CEFR" + "CEFR level": "Niveau CEFR", + "Webtoon Mode": "Mode webtoon" } diff --git a/apps/readest-app/public/locales/he/translation.json b/apps/readest-app/public/locales/he/translation.json index 6f7ca4a8..f2beae32 100644 --- a/apps/readest-app/public/locales/he/translation.json +++ b/apps/readest-app/public/locales/he/translation.json @@ -1807,5 +1807,6 @@ "biometrics": "ביומטריה", "Show a short native-language hint above difficult words. Words above your level get a hint.": "מציג רמז קצר בשפת האם שלך מעל מילים קשות. מילים מעל הרמה שלך מקבלות רמז.", "Level": "רמה", - "CEFR level": "רמת CEFR" + "CEFR level": "רמת CEFR", + "Webtoon Mode": "מצב ובטון" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index ec90e03f..d5b534cd 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "बायोमेट्रिक्स", "Show a short native-language hint above difficult words. Words above your level get a hint.": "कठिन शब्दों के ऊपर आपकी मातृभाषा में एक छोटा संकेत दिखाता है। आपके स्तर से ऊपर के शब्दों को संकेत मिलता है।", "Level": "स्तर", - "CEFR level": "CEFR स्तर" + "CEFR level": "CEFR स्तर", + "Webtoon Mode": "वेबटून मोड" } diff --git a/apps/readest-app/public/locales/hu/translation.json b/apps/readest-app/public/locales/hu/translation.json index 7e0c4854..e1b4bcac 100644 --- a/apps/readest-app/public/locales/hu/translation.json +++ b/apps/readest-app/public/locales/hu/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "biometria", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Rövid anyanyelvi tippet jelenít meg a nehéz szavak fölött. A szintednél nehezebb szavak kapnak tippet.", "Level": "Szint", - "CEFR level": "CEFR-szint" + "CEFR level": "CEFR-szint", + "Webtoon Mode": "Webtoon mód" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index 8540f679..36ac3b1c 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "biometrik", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Menampilkan petunjuk singkat dalam bahasa ibu Anda di atas kata-kata sulit. Kata-kata di atas level Anda mendapat petunjuk.", "Level": "Level", - "CEFR level": "Level CEFR" + "CEFR level": "Level CEFR", + "Webtoon Mode": "Mode webtoon" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index 0799502a..e2163e4c 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -1807,5 +1807,6 @@ "biometrics": "biometria", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Mostra un breve suggerimento nella tua lingua madre sopra le parole difficili. Le parole sopra il tuo livello ricevono un suggerimento.", "Level": "Livello", - "CEFR level": "Livello CEFR" + "CEFR level": "Livello CEFR", + "Webtoon Mode": "Modalità webtoon" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index c91f25bc..5bd5bb2f 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "生体認証", "Show a short native-language hint above difficult words. Words above your level get a hint.": "難しい単語の上に母語の短いヒントを表示します。あなたのレベルを超える単語にヒントが付きます。", "Level": "レベル", - "CEFR level": "CEFRレベル" + "CEFR level": "CEFRレベル", + "Webtoon Mode": "ウェブトゥーンモード" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index e459deb0..764d88db 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "생체 인증", "Show a short native-language hint above difficult words. Words above your level get a hint.": "어려운 단어 위에 모국어로 된 짧은 힌트를 표시합니다. 내 수준보다 높은 단어에 힌트가 표시됩니다.", "Level": "수준", - "CEFR level": "CEFR 수준" + "CEFR level": "CEFR 수준", + "Webtoon Mode": "웹툰 모드" } diff --git a/apps/readest-app/public/locales/ms/translation.json b/apps/readest-app/public/locales/ms/translation.json index 5e736ae5..3e804970 100644 --- a/apps/readest-app/public/locales/ms/translation.json +++ b/apps/readest-app/public/locales/ms/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "biometrik", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Menunjukkan petunjuk ringkas dalam bahasa ibunda anda di atas perkataan sukar. Perkataan melebihi tahap anda akan mendapat petunjuk.", "Level": "Tahap", - "CEFR level": "Tahap CEFR" + "CEFR level": "Tahap CEFR", + "Webtoon Mode": "Mode webtoon" } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index d2fca9fb..8adcc9a0 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "biometrie", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Toont een korte hint in je moedertaal boven moeilijke woorden. Woorden boven jouw niveau krijgen een hint.", "Level": "Niveau", - "CEFR level": "CEFR-niveau" + "CEFR level": "CEFR-niveau", + "Webtoon Mode": "Webtoon-modus" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index 5a117ab1..a7ffa6bb 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -1840,5 +1840,6 @@ "biometrics": "biometria", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Pokazuje krótką wskazówkę w Twoim języku ojczystym nad trudnymi słowami. Słowa powyżej Twojego poziomu otrzymują wskazówkę.", "Level": "Poziom", - "CEFR level": "Poziom CEFR" + "CEFR level": "Poziom CEFR", + "Webtoon Mode": "Tryb webtoon" } diff --git a/apps/readest-app/public/locales/pt-BR/translation.json b/apps/readest-app/public/locales/pt-BR/translation.json index 64e073b6..7bbc903b 100644 --- a/apps/readest-app/public/locales/pt-BR/translation.json +++ b/apps/readest-app/public/locales/pt-BR/translation.json @@ -1807,5 +1807,6 @@ "biometrics": "biometria", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Mostra uma breve dica no seu idioma nativo acima de palavras difíceis. Palavras acima do seu nível recebem uma dica.", "Level": "Nível", - "CEFR level": "Nível CEFR" + "CEFR level": "Nível CEFR", + "Webtoon Mode": "Modo webtoon" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index 3c18f93e..c3a675aa 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -1807,5 +1807,6 @@ "biometrics": "biometria", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Mostra uma breve dica na sua língua materna acima de palavras difíceis. Palavras acima do seu nível recebem uma dica.", "Level": "Nível", - "CEFR level": "Nível CEFR" + "CEFR level": "Nível CEFR", + "Webtoon Mode": "Modo webtoon" } diff --git a/apps/readest-app/public/locales/ro/translation.json b/apps/readest-app/public/locales/ro/translation.json index f43bb59f..85614f50 100644 --- a/apps/readest-app/public/locales/ro/translation.json +++ b/apps/readest-app/public/locales/ro/translation.json @@ -1807,5 +1807,6 @@ "biometrics": "biometrie", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Afișează un scurt indiciu în limba ta maternă deasupra cuvintelor dificile. Cuvintele peste nivelul tău primesc un indiciu.", "Level": "Nivel", - "CEFR level": "Nivel CEFR" + "CEFR level": "Nivel CEFR", + "Webtoon Mode": "Mod webtoon" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index 5fc106a1..68392e12 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -1840,5 +1840,6 @@ "biometrics": "биометрия", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Показывает короткую подсказку на вашем родном языке над сложными словами. Слова выше вашего уровня получают подсказку.", "Level": "Уровень", - "CEFR level": "Уровень CEFR" + "CEFR level": "Уровень CEFR", + "Webtoon Mode": "Режим вебтуна" } diff --git a/apps/readest-app/public/locales/si/translation.json b/apps/readest-app/public/locales/si/translation.json index 09e233e4..01a73d55 100644 --- a/apps/readest-app/public/locales/si/translation.json +++ b/apps/readest-app/public/locales/si/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "ජෛව මිතික", "Show a short native-language hint above difficult words. Words above your level get a hint.": "අසීරු වචන මත ඔබේ මව් භාෂාවෙන් කෙටි ඉඟියක් පෙන්වයි. ඔබේ මට්ටමට වඩා ඉහළ වචනවලට ඉඟියක් ලැබේ.", "Level": "මට්ටම", - "CEFR level": "CEFR මට්ටම" + "CEFR level": "CEFR මට්ටම", + "Webtoon Mode": "Webtoon ආකාරය" } diff --git a/apps/readest-app/public/locales/sl/translation.json b/apps/readest-app/public/locales/sl/translation.json index 89a76df5..8b480b1c 100644 --- a/apps/readest-app/public/locales/sl/translation.json +++ b/apps/readest-app/public/locales/sl/translation.json @@ -1840,5 +1840,6 @@ "biometrics": "biometrija", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Prikaže kratek namig v tvojem maternem jeziku nad težkimi besedami. Besede nad tvojo ravnjo dobijo namig.", "Level": "Raven", - "CEFR level": "Raven CEFR" + "CEFR level": "Raven CEFR", + "Webtoon Mode": "Tryb webtoon" } diff --git a/apps/readest-app/public/locales/sv/translation.json b/apps/readest-app/public/locales/sv/translation.json index 21b766f3..267d1522 100644 --- a/apps/readest-app/public/locales/sv/translation.json +++ b/apps/readest-app/public/locales/sv/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "biometri", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Visar en kort ledtråd på ditt modersmål ovanför svåra ord. Ord över din nivå får en ledtråd.", "Level": "Nivå", - "CEFR level": "CEFR-nivå" + "CEFR level": "CEFR-nivå", + "Webtoon Mode": "Webtoon-läge" } diff --git a/apps/readest-app/public/locales/ta/translation.json b/apps/readest-app/public/locales/ta/translation.json index c9d824ed..da2a70ff 100644 --- a/apps/readest-app/public/locales/ta/translation.json +++ b/apps/readest-app/public/locales/ta/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "உயிரியல் அடையாளம்", "Show a short native-language hint above difficult words. Words above your level get a hint.": "கடினமான சொற்களுக்கு மேலே உங்கள் தாய்மொழியில் ஒரு சிறு குறிப்பைக் காட்டும். உங்கள் நிலைக்கு மேலான சொற்களுக்கு குறிப்பு கிடைக்கும்.", "Level": "நிலை", - "CEFR level": "CEFR நிலை" + "CEFR level": "CEFR நிலை", + "Webtoon Mode": "வெப்டூன் பயன்முறை" } diff --git a/apps/readest-app/public/locales/th/translation.json b/apps/readest-app/public/locales/th/translation.json index 391d5efe..82df7318 100644 --- a/apps/readest-app/public/locales/th/translation.json +++ b/apps/readest-app/public/locales/th/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "ข้อมูลไบโอเมตริก", "Show a short native-language hint above difficult words. Words above your level get a hint.": "แสดงคำใบ้สั้น ๆ ในภาษาแม่ของคุณเหนือคำที่ยาก คำที่สูงกว่าระดับของคุณจะมีคำใบ้", "Level": "ระดับ", - "CEFR level": "ระดับ CEFR" + "CEFR level": "ระดับ CEFR", + "Webtoon Mode": "โหมดเว็บตูน" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index 9d1f0b89..e0429b07 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "biyometri", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Zor kelimelerin üzerinde ana dilinizde kısa bir ipucu gösterir. Seviyenizin üzerindeki kelimeler ipucu alır.", "Level": "Seviye", - "CEFR level": "CEFR seviyesi" + "CEFR level": "CEFR seviyesi", + "Webtoon Mode": "Webtoon modu" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index ffe323bf..6eeda7af 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -1840,5 +1840,6 @@ "biometrics": "біометрія", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Показує коротку підказку вашою рідною мовою над складними словами. Слова, вищі за ваш рівень, отримують підказку.", "Level": "Рівень", - "CEFR level": "Рівень CEFR" + "CEFR level": "Рівень CEFR", + "Webtoon Mode": "Режим вебтуна" } diff --git a/apps/readest-app/public/locales/uz/translation.json b/apps/readest-app/public/locales/uz/translation.json index 53b7ff11..4d79a954 100644 --- a/apps/readest-app/public/locales/uz/translation.json +++ b/apps/readest-app/public/locales/uz/translation.json @@ -1774,5 +1774,6 @@ "biometrics": "biometrik", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Qiyin so‘zlar ustida ona tilingizda qisqa maslahat ko‘rsatadi. Darajangizdan yuqori so‘zlarga maslahat beriladi.", "Level": "Daraja", - "CEFR level": "CEFR darajasi" + "CEFR level": "CEFR darajasi", + "Webtoon Mode": "Webtoon rejimi" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 3df9b093..374780da 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "sinh trắc học", "Show a short native-language hint above difficult words. Words above your level get a hint.": "Hiển thị gợi ý ngắn bằng tiếng mẹ đẻ của bạn phía trên những từ khó. Những từ trên trình độ của bạn sẽ có gợi ý.", "Level": "Cấp độ", - "CEFR level": "Cấp độ CEFR" + "CEFR level": "Cấp độ CEFR", + "Webtoon Mode": "Chế độ webtoon" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 581778c5..ca64090c 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "生物识别", "Show a short native-language hint above difficult words. Words above your level get a hint.": "在生词上方显示一条母语简短提示。高于你水平的单词会显示提示。", "Level": "级别", - "CEFR level": "CEFR 级别" + "CEFR level": "CEFR 级别", + "Webtoon Mode": "条漫模式" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 406e97da..b41a2d31 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -1741,5 +1741,6 @@ "biometrics": "生物辨識", "Show a short native-language hint above difficult words. Words above your level get a hint.": "在難詞上方顯示一則母語簡短提示。高於你程度的單字會顯示提示。", "Level": "等級", - "CEFR level": "CEFR 等級" + "CEFR level": "CEFR 等級", + "Webtoon Mode": "條漫模式" } diff --git a/apps/readest-app/src/__tests__/document/fixed-layout-scroll-gap.test.ts b/apps/readest-app/src/__tests__/document/fixed-layout-scroll-gap.test.ts new file mode 100644 index 00000000..58ce1841 --- /dev/null +++ b/apps/readest-app/src/__tests__/document/fixed-layout-scroll-gap.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from 'vitest'; + +import { scrollGapToCss } from 'foliate-js/fixed-layout.js'; + +describe('scrollGapToCss', () => { + it('maps a non-negative number string to a px length', () => { + expect(scrollGapToCss('0')).toBe('0px'); + expect(scrollGapToCss('4')).toBe('4px'); + expect(scrollGapToCss('12')).toBe('12px'); + }); + + it('returns null for empty / invalid / negative / null so the CSS fallback (4px) applies', () => { + expect(scrollGapToCss('')).toBeNull(); + expect(scrollGapToCss('abc')).toBeNull(); + expect(scrollGapToCss('-2')).toBeNull(); + expect(scrollGapToCss(null)).toBeNull(); + }); +}); diff --git a/apps/readest-app/src/__tests__/utils/webtoon.test.ts b/apps/readest-app/src/__tests__/utils/webtoon.test.ts new file mode 100644 index 00000000..57671639 --- /dev/null +++ b/apps/readest-app/src/__tests__/utils/webtoon.test.ts @@ -0,0 +1,13 @@ +import { describe, expect, it } from 'vitest'; + +import { getScrollGapAttr } from '@/utils/webtoon'; + +describe('getScrollGapAttr', () => { + it('returns 0 for Webtoon Mode (seamless, no gap)', () => { + expect(getScrollGapAttr(true)).toBe('0'); + }); + + it('returns the default 4 otherwise', () => { + expect(getScrollGapAttr(false)).toBe('4'); + }); +}); diff --git a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx index c6483835..7d32ac52 100644 --- a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx +++ b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx @@ -74,6 +74,7 @@ import { getLocale } from '@/utils/misc'; import { isMetered } from '@/utils/network'; import { eventDispatcher } from '@/utils/event'; import { isFontType } from '@/utils/font'; +import { getScrollGapAttr } from '@/utils/webtoon'; import { ParagraphControl } from './paragraph'; import Spinner from '@/components/Spinner'; import KOSyncConflictResolver from './KOSyncResolver'; @@ -702,6 +703,7 @@ const FoliateViewer: React.FC<{ view.renderer.setAttribute('zoom', viewSettings.zoomMode); view.renderer.setAttribute('spread', viewSettings.spreadMode); view.renderer.setAttribute('scale-factor', viewSettings.zoomLevel); + view.renderer.setAttribute('scroll-gap', getScrollGapAttr(viewSettings.webtoonMode)); } else { view.renderer.setAttribute('max-column-count', maxColumnCount); view.renderer.setAttribute('max-inline-size', `${maxInlineSize}px`); diff --git a/apps/readest-app/src/app/reader/components/ViewMenu.tsx b/apps/readest-app/src/app/reader/components/ViewMenu.tsx index 4ded805f..b1115fe2 100644 --- a/apps/readest-app/src/app/reader/components/ViewMenu.tsx +++ b/apps/readest-app/src/app/reader/components/ViewMenu.tsx @@ -21,6 +21,7 @@ import { useSettingsStore } from '@/store/settingsStore'; import { useTranslation } from '@/hooks/useTranslation'; import { getStyles } from '@/utils/style'; import { navigateToLogin } from '@/utils/nav'; +import { getScrollGapAttr } from '@/utils/webtoon'; import { eventDispatcher } from '@/utils/event'; import { getMaxInlineSize } from '@/utils/config'; import dayjs from 'dayjs'; @@ -54,6 +55,7 @@ const ViewMenu: React.FC = ({ const { themeMode, isDarkMode, setThemeMode } = useThemeStore(); const [isScrolledMode, setScrolledMode] = useState(viewSettings!.scrolled); + const [webtoonMode, setWebtoonMode] = useState(viewSettings!.webtoonMode ?? false); const [isParagraphMode, setParagraphMode] = useState( viewSettings?.paragraphMode?.enabled ?? false, ); @@ -70,6 +72,7 @@ const ViewMenu: React.FC = ({ const zoomOut = () => setZoomLevel((prev) => Math.max(prev - ZOOM_STEP, MIN_ZOOM_LEVEL)); const resetZoom = () => setZoomLevel(100); const toggleScrolledMode = () => setScrolledMode(!isScrolledMode); + const toggleWebtoonMode = () => setWebtoonMode(!webtoonMode); const toggleParagraphMode = () => { setParagraphMode(!isParagraphMode); eventDispatcher.dispatch('toggle-paragraph-mode', { bookKey }); @@ -119,6 +122,7 @@ const ViewMenu: React.FC = ({ useEffect(() => { if (isScrolledMode === viewSettings!.scrolled) return; viewSettings!.scrolled = isScrolledMode; + if (!isScrolledMode && webtoonMode) setWebtoonMode(false); getView(bookKey)?.renderer.setAttribute('flow', isScrolledMode ? 'scrolled' : 'paginated'); getView(bookKey)?.renderer.setAttribute( 'max-inline-size', @@ -129,6 +133,23 @@ const ViewMenu: React.FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [isScrolledMode]); + useEffect(() => { + if (webtoonMode === viewSettings.webtoonMode) return; + viewSettings.webtoonMode = webtoonMode; + getView(bookKey)?.renderer.setAttribute('scroll-gap', getScrollGapAttr(webtoonMode)); + if (webtoonMode) { + // Webtoon Mode implies scrolled flow + fit-width (scale-factor 100) so pages + // fill the width without horizontal overflow/clipping. Reuse the existing + // scrolled / zoomLevel effects rather than duplicating their renderer wiring. + if (!isScrolledMode) setScrolledMode(true); + if (zoomLevel !== 100) setZoomLevel(100); + saveViewSettings(envConfig, bookKey, 'scrolled', true, false, false); + } + setViewSettings(bookKey, viewSettings); + saveViewSettings(envConfig, bookKey, 'webtoonMode', webtoonMode, false, false); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [webtoonMode]); + useEffect(() => { if (zoomLevel === viewSettings.zoomLevel) return; saveViewSettings(envConfig, bookKey, 'zoomLevel', zoomLevel, true, true); @@ -290,6 +311,7 @@ const ViewMenu: React.FC = ({ onClick={() => setKeepCoverSpread(!keepCoverSpread)} disabled={spreadMode === 'none'} /> + diff --git a/apps/readest-app/src/app/reader/hooks/useBookShortcuts.ts b/apps/readest-app/src/app/reader/hooks/useBookShortcuts.ts index 62e1022b..ad8b076d 100644 --- a/apps/readest-app/src/app/reader/hooks/useBookShortcuts.ts +++ b/apps/readest-app/src/app/reader/hooks/useBookShortcuts.ts @@ -11,6 +11,7 @@ import { eventDispatcher } from '@/utils/event'; import { setShortcutsDialogVisible } from '@/components/KeyboardShortcutsHelp'; import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL, ZOOM_STEP } from '@/services/constants'; import { getParagraphActionForKey } from '@/utils/paragraphPresentation'; +import { getScrollGapAttr } from '@/utils/webtoon'; import { viewPagination } from './usePagination'; import useShortcuts from '@/hooks/useShortcuts'; import useBooksManager from './useBooksManager'; @@ -53,6 +54,12 @@ const useBookShortcuts = ({ sideBarBookKey, bookKeys }: UseBookShortcutsProps) = const viewSettings = getViewSettings(sideBarBookKey ?? ''); if (viewSettings && sideBarBookKey) { viewSettings.scrolled = !viewSettings.scrolled; + // Webtoon Mode requires scrolled flow; leaving scrolled exits Webtoon Mode + // and restores the default page gap (mirror the View menu's behavior). + if (!viewSettings.scrolled && viewSettings.webtoonMode) { + viewSettings.webtoonMode = false; + getView(sideBarBookKey)?.renderer.setAttribute('scroll-gap', getScrollGapAttr(false)); + } setViewSettings(sideBarBookKey, viewSettings!); const flowMode = viewSettings.scrolled ? 'scrolled' : 'paginated'; getView(sideBarBookKey)?.renderer.setAttribute('flow', flowMode); diff --git a/apps/readest-app/src/services/constants.ts b/apps/readest-app/src/services/constants.ts index a905dd5e..fd590ecc 100644 --- a/apps/readest-app/src/services/constants.ts +++ b/apps/readest-app/src/services/constants.ts @@ -241,6 +241,7 @@ export const DEFAULT_BOOK_LAYOUT: BookLayout = { compactMarginRightPx: 16, gapPercent: 5, scrolled: false, + webtoonMode: false, noContinuousScroll: false, disableClick: false, disableSwipe: false, diff --git a/apps/readest-app/src/types/book.ts b/apps/readest-app/src/types/book.ts index 2a23a2a8..654bff16 100644 --- a/apps/readest-app/src/types/book.ts +++ b/apps/readest-app/src/types/book.ts @@ -184,6 +184,7 @@ export interface BookLayout { compactMarginPx?: number; // deprecated gapPercent: number; scrolled: boolean; + webtoonMode: boolean; noContinuousScroll: boolean; disableClick: boolean; disableSwipe: boolean; diff --git a/apps/readest-app/src/utils/webtoon.ts b/apps/readest-app/src/utils/webtoon.ts new file mode 100644 index 00000000..9f51d43f --- /dev/null +++ b/apps/readest-app/src/utils/webtoon.ts @@ -0,0 +1,6 @@ +/** + * The `scroll-gap` attribute (px) a fixed-layout renderer should use for the + * current Webtoon Mode state. `0` = seamless webtoon strip; `4` = the default + * inter-page gap. The renderer maps this to the `--scroll-page-gap` CSS var. + */ +export const getScrollGapAttr = (webtoonMode: boolean): string => (webtoonMode ? '0' : '4'); diff --git a/packages/foliate-js b/packages/foliate-js index a7b5118c..1cb26e3f 160000 --- a/packages/foliate-js +++ b/packages/foliate-js @@ -1 +1 @@ -Subproject commit a7b5118c7832e65bba7a9f3e25a312559fad821d +Subproject commit 1cb26e3fe2c4b9612918b4d2fa66467a97bf3734