* fix(css): allow overriding the padding of the root html * fix(translation): reduce initial layout shift in the translation view, closes #3078
This commit is contained in:
@@ -1107,5 +1107,6 @@
|
||||
"System Screen Brightness": "سطوع شاشة النظام",
|
||||
"Page:": "صفحة:",
|
||||
"Page: {{number}}": "صفحة: {{number}}",
|
||||
"Annotation page number": "رقم صفحة التعליق"
|
||||
"Annotation page number": "رقم صفحة التعליق",
|
||||
"Translating...": "جارٍ الترجمة..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "সিস্টেম স্ক্রিন উজ্জ্বলতা",
|
||||
"Page:": "পৃষ্ঠা:",
|
||||
"Page: {{number}}": "পৃষ্ঠা: {{number}}",
|
||||
"Annotation page number": "টীকা পৃষ্ঠা নম্বর"
|
||||
"Annotation page number": "টীকা পৃষ্ঠা নম্বর",
|
||||
"Translating...": "অনুবাদ করা হচ্ছে..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "མ་ལག་ཤེལ་སྒོའི་གསལ་ཚད།",
|
||||
"Page:": "ཤོག་ལྷེ།:",
|
||||
"Page: {{number}}": "ཤོག་ལྷེ།: {{number}}",
|
||||
"Annotation page number": "མཆན་འགྲེལ་ཤོག་ཨང་།"
|
||||
"Annotation page number": "མཆན་འགྲེལ་ཤོག་ཨང་།",
|
||||
"Translating...": "ཡིག་བསྒྱུར་བྱེད་བཞིན་པ།..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "System-Bildschirmhelligkeit",
|
||||
"Page:": "Seite:",
|
||||
"Page: {{number}}": "Seite: {{number}}",
|
||||
"Annotation page number": "Seitenzahl der Anmerkung"
|
||||
"Annotation page number": "Seitenzahl der Anmerkung",
|
||||
"Translating...": "Übersetzen..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "Φωτεινότητα οθόνης συστήματος",
|
||||
"Page:": "Σελίδα:",
|
||||
"Page: {{number}}": "Σελίδα: {{number}}",
|
||||
"Annotation page number": "Αριθμός σελίδας σχολίου"
|
||||
"Annotation page number": "Αριθμός σελίδας σχολίου",
|
||||
"Translating...": "Μετάφραση..."
|
||||
}
|
||||
|
||||
@@ -1071,5 +1071,6 @@
|
||||
"System Screen Brightness": "Brillo de pantalla del sistema",
|
||||
"Page:": "Página:",
|
||||
"Page: {{number}}": "Página: {{number}}",
|
||||
"Annotation page number": "Número de página de la anotación"
|
||||
"Annotation page number": "Número de página de la anotación",
|
||||
"Translating...": "Traduciendo..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "روشنایی صفحه نمایش سیستم",
|
||||
"Page:": "صفحه:",
|
||||
"Page: {{number}}": "صفحه: {{number}}",
|
||||
"Annotation page number": "شماره صفحه یادداشت"
|
||||
"Annotation page number": "شماره صفحه یادداشت",
|
||||
"Translating...": "در حال ترجمه..."
|
||||
}
|
||||
|
||||
@@ -1071,5 +1071,6 @@
|
||||
"System Screen Brightness": "Luminosité de l'écran système",
|
||||
"Page:": "Page :",
|
||||
"Page: {{number}}": "Page : {{number}}",
|
||||
"Annotation page number": "Numéro de page de l'annotation"
|
||||
"Annotation page number": "Numéro de page de l'annotation",
|
||||
"Translating...": "Traduction en cours..."
|
||||
}
|
||||
|
||||
@@ -1071,5 +1071,6 @@
|
||||
"System Screen Brightness": "בהירות מסך המערכת",
|
||||
"Page:": "עמוד:",
|
||||
"Page: {{number}}": "עמוד: {{number}}",
|
||||
"Annotation page number": "מספר עמוד הערה"
|
||||
"Annotation page number": "מספר עמוד הערה",
|
||||
"Translating...": "מתרגם..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "सिस्टम स्क्रीन चमक",
|
||||
"Page:": "पृष्ठ:",
|
||||
"Page: {{number}}": "पृष्ठ: {{number}}",
|
||||
"Annotation page number": "व्याख्या पृष्ठ संख्या"
|
||||
"Annotation page number": "व्याख्या पृष्ठ संख्या",
|
||||
"Translating...": "अनुवाद हो रहा है..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "Kecerahan Layar Sistem",
|
||||
"Page:": "Halaman:",
|
||||
"Page: {{number}}": "Halaman: {{number}}",
|
||||
"Annotation page number": "Nomor halaman anotasi"
|
||||
"Annotation page number": "Nomor halaman anotasi",
|
||||
"Translating...": "Menerjemahkan..."
|
||||
}
|
||||
|
||||
@@ -1071,5 +1071,6 @@
|
||||
"System Screen Brightness": "Luminosità dello schermo del sistema",
|
||||
"Page:": "Pagina:",
|
||||
"Page: {{number}}": "Pagina: {{number}}",
|
||||
"Annotation page number": "Numero di pagina dell'annotazione"
|
||||
"Annotation page number": "Numero di pagina dell'annotazione",
|
||||
"Translating...": "Traduzione..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "システムの画面の明るさ",
|
||||
"Page:": "ページ:",
|
||||
"Page: {{number}}": "ページ: {{number}}",
|
||||
"Annotation page number": "注釈のページ番号"
|
||||
"Annotation page number": "注釈のページ番号",
|
||||
"Translating...": "翻訳中..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "시스템 화면 밝기",
|
||||
"Page:": "페이지:",
|
||||
"Page: {{number}}": "페이지: {{number}}",
|
||||
"Annotation page number": "주석 페이지 번호"
|
||||
"Annotation page number": "주석 페이지 번호",
|
||||
"Translating...": "번역 중..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "Kecerahan Skrin Sistem",
|
||||
"Page:": "Halaman:",
|
||||
"Page: {{number}}": "Halaman: {{number}}",
|
||||
"Annotation page number": "Nombor halaman anotasi"
|
||||
"Annotation page number": "Nombor halaman anotasi",
|
||||
"Translating...": "Menterjemah..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "Systeemhelderheid van het scherm",
|
||||
"Page:": "Pagina:",
|
||||
"Page: {{number}}": "Pagina: {{number}}",
|
||||
"Annotation page number": "Annotatiepaginanummer"
|
||||
"Annotation page number": "Annotatiepaginanummer",
|
||||
"Translating...": "Vertalen..."
|
||||
}
|
||||
|
||||
@@ -1083,5 +1083,6 @@
|
||||
"System Screen Brightness": "Jasność ekranu systemowego",
|
||||
"Page:": "Strona:",
|
||||
"Page: {{number}}": "Strona: {{number}}",
|
||||
"Annotation page number": "Numer strony adnotacji"
|
||||
"Annotation page number": "Numer strony adnotacji",
|
||||
"Translating...": "Tłumaczenie..."
|
||||
}
|
||||
|
||||
@@ -1071,5 +1071,6 @@
|
||||
"System Screen Brightness": "Brilho da tela do sistema",
|
||||
"Page:": "Página:",
|
||||
"Page: {{number}}": "Página: {{number}}",
|
||||
"Annotation page number": "Número de página da anotação"
|
||||
"Annotation page number": "Número de página da anotação",
|
||||
"Translating...": "Traduzindo..."
|
||||
}
|
||||
|
||||
@@ -1083,5 +1083,6 @@
|
||||
"System Screen Brightness": "Систেমная яркость экрана",
|
||||
"Page:": "Страница:",
|
||||
"Page: {{number}}": "Страница: {{number}}",
|
||||
"Annotation page number": "Номер страницы аннотации"
|
||||
"Annotation page number": "Номер страницы аннотации",
|
||||
"Translating...": "Перевод..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "පද්ධති තිර දීප්තිය",
|
||||
"Page:": "පිටුව:",
|
||||
"Page: {{number}}": "පිටුව: {{number}}",
|
||||
"Annotation page number": "විවරණ පිටු අංකය"
|
||||
"Annotation page number": "විවරණ පිටු අංකය",
|
||||
"Translating...": "පරිවර්තනය වෙමින් පවතී..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "Systemets skärmljusstyrka",
|
||||
"Page:": "Sida:",
|
||||
"Page: {{number}}": "Sida: {{number}}",
|
||||
"Annotation page number": "Annoteringssidnummer"
|
||||
"Annotation page number": "Annoteringssidnummer",
|
||||
"Translating...": "Översätter..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "கணினித் திரை பிரகாசம்",
|
||||
"Page:": "பக்கம்:",
|
||||
"Page: {{number}}": "பக்கம்: {{number}}",
|
||||
"Annotation page number": "சிறுகுறிப்புப் பக்க எண்"
|
||||
"Annotation page number": "சிறுகுறிப்புப் பக்க எண்",
|
||||
"Translating...": "மொழிபெயர்க்கிறது..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "ความสว่างหน้าจอระบบ",
|
||||
"Page:": "หน้า:",
|
||||
"Page: {{number}}": "หน้า: {{number}}",
|
||||
"Annotation page number": "หมายเลขหน้าคำอธิบายประกอบ"
|
||||
"Annotation page number": "หมายเลขหน้าคำอธิบายประกอบ",
|
||||
"Translating...": "กำลังแปล..."
|
||||
}
|
||||
|
||||
@@ -1059,5 +1059,6 @@
|
||||
"System Screen Brightness": "Sistem Ekran Parlaklığı",
|
||||
"Page:": "Sayfa:",
|
||||
"Page: {{number}}": "Sayfa: {{number}}",
|
||||
"Annotation page number": "Açıklama sayfa numarası"
|
||||
"Annotation page number": "Açıklama sayfa numarası",
|
||||
"Translating...": "Çevriliyor..."
|
||||
}
|
||||
|
||||
@@ -1083,5 +1083,6 @@
|
||||
"System Screen Brightness": "Системна яскравість екрана",
|
||||
"Page:": "Сторінка:",
|
||||
"Page: {{number}}": "Сторінка: {{number}}",
|
||||
"Annotation page number": "Номер сторінки анотації"
|
||||
"Annotation page number": "Номер сторінки анотації",
|
||||
"Translating...": "Переклад..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "Độ sáng màn hình hệ thống",
|
||||
"Page:": "Trang:",
|
||||
"Page: {{number}}": "Trang: {{number}}",
|
||||
"Annotation page number": "Số trang chú thích"
|
||||
"Annotation page number": "Số trang chú thích",
|
||||
"Translating...": "Đang dịch..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "系统屏幕亮度",
|
||||
"Page:": "页面:",
|
||||
"Page: {{number}}": "页面: {{number}}",
|
||||
"Annotation page number": "批注页码"
|
||||
"Annotation page number": "批注页码",
|
||||
"Translating...": "翻译中..."
|
||||
}
|
||||
|
||||
@@ -1047,5 +1047,6 @@
|
||||
"System Screen Brightness": "系統螢幕亮度",
|
||||
"Page:": "頁面:",
|
||||
"Page: {{number}}": "頁面: {{number}}",
|
||||
"Annotation page number": "註解頁碼"
|
||||
"Annotation page number": "註解頁碼",
|
||||
"Translating...": "翻譯中..."
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import { convertBlobUrlToDataUrl, BookDoc, getDirection } from '@/libs/document';
|
||||
import { BookConfig, PageInfo } from '@/types/book';
|
||||
@@ -611,7 +612,10 @@ const FoliateViewer: React.FC<{
|
||||
tabIndex={-1}
|
||||
role='document'
|
||||
aria-label={_('Book Content')}
|
||||
className='foliate-viewer h-[100%] w-[100%] focus:outline-none'
|
||||
className={clsx(
|
||||
'foliate-viewer h-[100%] w-[100%] focus:outline-none',
|
||||
viewState?.loading && 'bg-base-100',
|
||||
)}
|
||||
style={{
|
||||
paddingTop: showViewMargins ? insets.top : 0,
|
||||
paddingBottom: showViewMargins ? insets.bottom : 0,
|
||||
@@ -620,7 +624,11 @@ const FoliateViewer: React.FC<{
|
||||
{...touchHandlers}
|
||||
/>
|
||||
<ParagraphControl bookKey={bookKey} viewRef={viewRef} gridInsets={gridInsets} />
|
||||
{!docLoaded.current && loading && <Spinner loading={true} />}
|
||||
{((!docLoaded.current && loading) || viewState?.loading) && (
|
||||
<div className='bg-base-100/85 absolute left-0 top-0 z-10 flex h-full w-full items-center justify-center'>
|
||||
<Spinner loading={true} />
|
||||
</div>
|
||||
)}
|
||||
{syncState === 'conflict' && conflictDetails && (
|
||||
<KOSyncConflictResolver
|
||||
details={conflictDetails}
|
||||
|
||||
@@ -3,6 +3,8 @@ import { FoliateView } from '@/types/view';
|
||||
import { UseTranslatorOptions } from '@/services/translators';
|
||||
import { useReaderStore } from '@/store/readerStore';
|
||||
import { useTranslator } from '@/hooks/useTranslator';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { eventDispatcher } from '@/utils/event';
|
||||
import { walkTextNodes } from '@/utils/walk';
|
||||
import { debounce } from '@/utils/debounce';
|
||||
import { getLocale } from '@/utils/misc';
|
||||
@@ -13,7 +15,8 @@ export function useTextTranslation(
|
||||
widthLineBreak = false,
|
||||
targetBlockClassName = 'translation-target-block',
|
||||
) {
|
||||
const { getViewSettings, getProgress } = useReaderStore();
|
||||
const _ = useTranslation();
|
||||
const { getViewSettings, getProgress, setIsLoading } = useReaderStore();
|
||||
const viewSettings = getViewSettings(bookKey);
|
||||
const progress = getProgress(bookKey);
|
||||
|
||||
@@ -31,6 +34,12 @@ export function useTextTranslation(
|
||||
const observerRef = useRef<IntersectionObserver | null>(null);
|
||||
const translatedElements = useRef<HTMLElement[]>([]);
|
||||
const allTextNodes = useRef<HTMLElement[]>([]);
|
||||
const translationQueue = useRef<HTMLElement[]>([]);
|
||||
const activeTranslations = useRef(0);
|
||||
const MAX_CONCURRENT_TRANSLATIONS = 5;
|
||||
const pendingDOMUpdates = useRef<Array<() => void>>([]);
|
||||
const batchTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const hintTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
|
||||
const toggleTranslationVisibility = (visible: boolean) => {
|
||||
translatedElements.current.forEach((element) => {
|
||||
@@ -49,8 +58,21 @@ export function useTextTranslation(
|
||||
translateRef.current = translate;
|
||||
}, [translate]);
|
||||
|
||||
const hintInitialTranslating = () => {
|
||||
setIsLoading(bookKey, true);
|
||||
eventDispatcher.dispatch('hint', {
|
||||
bookKey,
|
||||
message: _('Translating...'),
|
||||
});
|
||||
hintTimerRef.current = setTimeout(() => {
|
||||
hintTimerRef.current = null;
|
||||
setIsLoading(bookKey, false);
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
const observeTextNodes = () => {
|
||||
if (!view || !enabled.current) return;
|
||||
|
||||
const observer = createTranslationObserver();
|
||||
observerRef.current = observer;
|
||||
const nodes = walkTextNodes(view, ['pre', 'code', 'math']);
|
||||
@@ -64,6 +86,13 @@ export function useTextTranslation(
|
||||
};
|
||||
|
||||
const updateTranslation = () => {
|
||||
translationQueue.current = [];
|
||||
activeTranslations.current = 0;
|
||||
if (batchTimerRef.current) {
|
||||
clearTimeout(batchTimerRef.current);
|
||||
batchTimerRef.current = null;
|
||||
}
|
||||
pendingDOMUpdates.current = [];
|
||||
translatedElements.current.forEach((element) => {
|
||||
const translationTargets = element.querySelectorAll('.translation-target');
|
||||
translationTargets.forEach((target) => target.remove());
|
||||
@@ -76,48 +105,86 @@ export function useTextTranslation(
|
||||
};
|
||||
|
||||
const createTranslationObserver = () => {
|
||||
const visibleElements = new Set<HTMLElement>();
|
||||
return new IntersectionObserver(
|
||||
(entries) => {
|
||||
let beforeIntersectedElement: HTMLElement | null = null;
|
||||
let lastIntersectedElement: HTMLElement | null = null;
|
||||
for (const entry of entries) {
|
||||
if (!entry.isIntersecting) {
|
||||
if (!lastIntersectedElement) {
|
||||
beforeIntersectedElement = entry.target as HTMLElement;
|
||||
}
|
||||
continue;
|
||||
if (entry.isIntersecting) {
|
||||
visibleElements.add(entry.target as HTMLElement);
|
||||
} else {
|
||||
visibleElements.delete(entry.target as HTMLElement);
|
||||
}
|
||||
const currentElement = entry.target as HTMLElement;
|
||||
translateElement(currentElement);
|
||||
lastIntersectedElement = currentElement;
|
||||
}
|
||||
if (beforeIntersectedElement) {
|
||||
translateElement(beforeIntersectedElement);
|
||||
|
||||
if (visibleElements.size === 0) return;
|
||||
|
||||
const nodes = allTextNodes.current;
|
||||
if (nodes.length === 0) return;
|
||||
|
||||
let firstIdx = nodes.length;
|
||||
let lastIdx = -1;
|
||||
for (const el of visibleElements) {
|
||||
const idx = nodes.indexOf(el);
|
||||
if (idx !== -1) {
|
||||
if (idx < firstIdx) firstIdx = idx;
|
||||
if (idx > lastIdx) lastIdx = idx;
|
||||
}
|
||||
}
|
||||
if (lastIntersectedElement) {
|
||||
preTranslateNextElements(lastIntersectedElement, 2);
|
||||
|
||||
if (lastIdx === -1) return;
|
||||
|
||||
const startIdx = Math.max(0, firstIdx - 1);
|
||||
const endIdx = Math.min(nodes.length - 1, lastIdx + 2);
|
||||
|
||||
for (let i = startIdx; i <= endIdx; i++) {
|
||||
const node = nodes[i];
|
||||
if (node) {
|
||||
scheduleTranslation(node);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
rootMargin: '1280px',
|
||||
threshold: 0,
|
||||
},
|
||||
{ threshold: 0 },
|
||||
);
|
||||
};
|
||||
|
||||
const preTranslateNextElements = (currentElement: HTMLElement, count: number) => {
|
||||
if (!allTextNodes.current || count <= 0) return;
|
||||
const currentIndex = allTextNodes.current.indexOf(currentElement);
|
||||
if (currentIndex === -1) {
|
||||
return;
|
||||
}
|
||||
const scheduleTranslation = (el: HTMLElement) => {
|
||||
if (!enabled.current) return;
|
||||
if (el.classList.contains('translation-target')) return;
|
||||
if (el.querySelector('.translation-target')) return;
|
||||
if (translationQueue.current.indexOf(el) !== -1) return;
|
||||
translationQueue.current.push(el);
|
||||
drainTranslationQueue();
|
||||
};
|
||||
|
||||
const nextElements = allTextNodes.current.slice(currentIndex + 1, currentIndex + 1 + count);
|
||||
nextElements.forEach((element, index) => {
|
||||
const drainTranslationQueue = () => {
|
||||
while (
|
||||
activeTranslations.current < MAX_CONCURRENT_TRANSLATIONS &&
|
||||
translationQueue.current.length > 0
|
||||
) {
|
||||
const el = translationQueue.current.shift()!;
|
||||
if (el.querySelector('.translation-target') || !enabled.current) continue;
|
||||
activeTranslations.current++;
|
||||
translateElement(el).finally(() => {
|
||||
activeTranslations.current--;
|
||||
drainTranslationQueue();
|
||||
});
|
||||
}
|
||||
if (translationQueue.current.length === 0 && activeTranslations.current === 0) {
|
||||
setTimeout(() => {
|
||||
translateElement(element);
|
||||
}, index * 500);
|
||||
});
|
||||
setIsLoading(bookKey, false);
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
const batchDOMUpdate = (update: () => void) => {
|
||||
pendingDOMUpdates.current.push(update);
|
||||
if (!batchTimerRef.current) {
|
||||
batchTimerRef.current = setTimeout(() => {
|
||||
batchTimerRef.current = null;
|
||||
const updates = pendingDOMUpdates.current.splice(0);
|
||||
updates.forEach((fn) => fn());
|
||||
}, 50);
|
||||
}
|
||||
};
|
||||
|
||||
const recreateTranslationObserver = () => {
|
||||
@@ -183,8 +250,6 @@ export function useTextTranslation(
|
||||
}
|
||||
};
|
||||
|
||||
updateSourceNodes(el);
|
||||
|
||||
try {
|
||||
const translated = await translateRef.current([text]);
|
||||
const translatedText = translated[0];
|
||||
@@ -211,8 +276,12 @@ export function useTextTranslation(
|
||||
if (el.querySelector('.translation-target')) {
|
||||
return;
|
||||
}
|
||||
el.appendChild(wrapper);
|
||||
translatedElements.current.push(el);
|
||||
batchDOMUpdate(() => {
|
||||
if (!enabled.current || el.querySelector('.translation-target')) return;
|
||||
updateSourceNodes(el);
|
||||
el.appendChild(wrapper);
|
||||
translatedElements.current.push(el);
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn('Translation failed:', err);
|
||||
}
|
||||
@@ -260,11 +329,11 @@ export function useTextTranslation(
|
||||
for (let i = beforeStart; i <= afterEnd; i++) {
|
||||
const node = nodes[i];
|
||||
if (node) {
|
||||
translateElement(node);
|
||||
scheduleTranslation(node);
|
||||
}
|
||||
}
|
||||
}, 500),
|
||||
[translateElement],
|
||||
[scheduleTranslation],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -316,15 +385,29 @@ export function useTextTranslation(
|
||||
|
||||
if ('renderer' in view) {
|
||||
view.addEventListener('load', observeTextNodes);
|
||||
view.addEventListener('load', hintInitialTranslating);
|
||||
} else {
|
||||
observeTextNodes();
|
||||
}
|
||||
return () => {
|
||||
if ('renderer' in view) {
|
||||
view.removeEventListener('load', observeTextNodes);
|
||||
view.removeEventListener('load', hintInitialTranslating);
|
||||
}
|
||||
observerRef.current?.disconnect();
|
||||
translatedElements.current = [];
|
||||
translationQueue.current = [];
|
||||
activeTranslations.current = 0;
|
||||
if (batchTimerRef.current) {
|
||||
clearTimeout(batchTimerRef.current);
|
||||
batchTimerRef.current = null;
|
||||
}
|
||||
if (hintTimerRef.current) {
|
||||
clearTimeout(hintTimerRef.current);
|
||||
hintTimerRef.current = null;
|
||||
}
|
||||
pendingDOMUpdates.current = [];
|
||||
setIsLoading(bookKey, false);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [view]);
|
||||
|
||||
@@ -51,6 +51,7 @@ interface ReaderStore {
|
||||
setHoveredBookKey: (key: string | null) => void;
|
||||
setBookmarkRibbonVisibility: (key: string, visible: boolean) => void;
|
||||
setTTSEnabled: (key: string, enabled: boolean) => void;
|
||||
setIsLoading: (key: string, loading: boolean) => void;
|
||||
setIsSyncing: (key: string, syncing: boolean) => void;
|
||||
setProgress: (
|
||||
key: string,
|
||||
@@ -393,6 +394,17 @@ export const useReaderStore = create<ReaderStore>((set, get) => ({
|
||||
},
|
||||
})),
|
||||
|
||||
setIsLoading: (key: string, loading: boolean) =>
|
||||
set((state) => ({
|
||||
viewStates: {
|
||||
...state.viewStates,
|
||||
[key]: {
|
||||
...state.viewStates[key]!,
|
||||
loading,
|
||||
},
|
||||
},
|
||||
})),
|
||||
|
||||
setIsSyncing: (key: string, syncing: boolean) =>
|
||||
set((state) => ({
|
||||
viewStates: {
|
||||
|
||||
+1
-1
Submodule packages/foliate-js updated: 8b931a7805...423edcb3a8
Reference in New Issue
Block a user