diff --git a/apps/readest-app/src/app/library/page.tsx b/apps/readest-app/src/app/library/page.tsx index 109c85cd..1fe322f7 100644 --- a/apps/readest-app/src/app/library/page.tsx +++ b/apps/readest-app/src/app/library/page.tsx @@ -78,6 +78,7 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP const [booksTransferProgress, setBooksTransferProgress] = useState<{ [key: string]: number | null; }>({}); + const [pendingNavigationBookIds, setPendingNavigationBookIds] = useState(null); const [isDragging, setIsDragging] = useState(false); const demoBooks = useDemoBooks(); const containerRef = useRef(null); @@ -231,10 +232,10 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP console.log('Opening books:', bookIds); if (bookIds.length > 0) { - setTimeout(() => { - navigateToReader(router, bookIds); - }, 0); + setPendingNavigationBookIds(bookIds); + return true; } + return false; }, // eslint-disable-next-line react-hooks/exhaustive-deps [], @@ -245,21 +246,31 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP lastBookIds: string[], libraryBooks: Book[], ) => { - if (lastBookIds.length === 0) return; + if (lastBookIds.length === 0) return false; const bookIds: string[] = []; for (const bookId of lastBookIds) { const book = libraryBooks.find((b) => b.hash === bookId); if (book && (await appService.isBookAvailable(book))) { bookIds.push(book.hash); } - console.log('Opening last books:', bookIds); + } + console.log('Opening last books:', bookIds); + if (bookIds.length > 0) { + setPendingNavigationBookIds(bookIds); + return true; + } + return false; + }; + + useEffect(() => { + if (pendingNavigationBookIds) { + const bookIds = pendingNavigationBookIds; + setPendingNavigationBookIds(null); if (bookIds.length > 0) { - setTimeout(() => { - navigateToReader(router, bookIds); - }, 0); + navigateToReader(router, bookIds); } } - }; + }, [pendingNavigationBookIds, router]); useEffect(() => { if (isInitiating.current) return; @@ -287,19 +298,14 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP // Reuse the library from the store when we return from the reader const library = libraryBooks.length > 0 ? libraryBooks : await appService.loadLibraryBooks(); - if (checkOpenWithBooks) { - await handleOpenWithBooks(appService, library); - } else { - setCheckOpenWithBooks(false); - setLibrary(library); - } - - if (checkLastOpenBooks && settings.openLastBooks) { - await handleOpenLastBooks(appService, settings.lastOpenBooks, library); - } else { - setCheckLastOpenBooks(false); - } + setCheckOpenWithBooks(checkOpenWithBooks && (await handleOpenWithBooks(appService, library))); + setCheckLastOpenBooks( + checkLastOpenBooks && + settings.openLastBooks && + (await handleOpenLastBooks(appService, settings.lastOpenBooks, library)), + ); + setLibrary(library); setLibraryLoaded(true); if (loadingTimeout) clearTimeout(loadingTimeout); setLoading(false); @@ -309,11 +315,9 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP const openWithFiles = (await parseOpenWithFiles()) || []; if (openWithFiles.length > 0) { - await processOpenWithFiles(appService, openWithFiles, library); - } else { - setCheckOpenWithBooks(false); - setLibrary(library); + return await processOpenWithFiles(appService, openWithFiles, library); } + return false; }; initLogin(); diff --git a/apps/readest-app/src/app/page.tsx b/apps/readest-app/src/app/page.tsx index 128aad48..82db8283 100644 --- a/apps/readest-app/src/app/page.tsx +++ b/apps/readest-app/src/app/page.tsx @@ -1,7 +1,14 @@ -import { redirectToLibrary } from '@/utils/nav'; +'use client'; -const HomePage = () => { - redirectToLibrary(); -}; +import { useEffect } from 'react'; +import { useRouter } from 'next/navigation'; -export default HomePage; +export default function HomePage() { + const router = useRouter(); + + useEffect(() => { + router.replace('/library'); + }, [router]); + + return null; +} diff --git a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx index bab066d8..42168840 100644 --- a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx +++ b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx @@ -72,7 +72,7 @@ const FoliateViewer: React.FC<{ bookKey, viewSettings, content: data, - transformers: ['punctuation'], + transformers: ['punctuation', 'footnote'], }; return Promise.resolve(transformContent(ctx)); } diff --git a/apps/readest-app/src/hooks/useResponsiveSize.ts b/apps/readest-app/src/hooks/useResponsiveSize.ts index 1eb45cb9..7290987f 100644 --- a/apps/readest-app/src/hooks/useResponsiveSize.ts +++ b/apps/readest-app/src/hooks/useResponsiveSize.ts @@ -1,11 +1,17 @@ +import { getOSPlatform } from '@/utils/misc'; import { useMediaQuery } from 'react-responsive'; // use desktop size as base size export const useResponsiveSize = (baseSize: number) => { const isPhone = useMediaQuery({ maxWidth: 480 }); const isTablet = useMediaQuery({ minWidth: 481, maxWidth: 1024 }); - if (isPhone) return baseSize * 1.25; - if (isTablet) return baseSize * 1.15; + if (typeof window === 'undefined') { + return baseSize; + } + const pixelRatio = window.devicePixelRatio || 2.4; + const isMobile = ['android', 'ios'].includes(getOSPlatform()); + if (isPhone && isMobile) return baseSize * (pixelRatio / 3) * 1.25; + if (isTablet && isMobile) return baseSize * (pixelRatio / 3) * 1.25; return baseSize; }; diff --git a/apps/readest-app/src/services/transformers/footnote.ts b/apps/readest-app/src/services/transformers/footnote.ts new file mode 100644 index 00000000..fb2c47a2 --- /dev/null +++ b/apps/readest-app/src/services/transformers/footnote.ts @@ -0,0 +1,14 @@ +import type { Transformer } from './types'; + +export const footnoteTransformer: Transformer = { + name: 'footnote', + + transform: async (ctx) => { + let result = ctx.content; + result = result.replace( + /]*)>/gi, + '