From cdc1950c3afb921f2362df4efe458d0422f31f33 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Fri, 31 Oct 2025 02:34:55 +0800 Subject: [PATCH] fix(layout): various fixes on the book and reader styles and layouts, closes #2368 (#2369) --- .../src/app/library/components/GroupingModal.tsx | 8 ++++---- .../components/footerbar/DesktopFooterBar.tsx | 15 +++++++++++++-- apps/readest-app/src/components/Popup.tsx | 6 +++++- .../src/services/transformers/sanitizer.ts | 11 ++++++++++- apps/readest-app/src/utils/style.ts | 11 ++++++++++- packages/foliate-js | 2 +- 6 files changed, 43 insertions(+), 10 deletions(-) diff --git a/apps/readest-app/src/app/library/components/GroupingModal.tsx b/apps/readest-app/src/app/library/components/GroupingModal.tsx index b4c0583a..5a86749f 100644 --- a/apps/readest-app/src/app/library/components/GroupingModal.tsx +++ b/apps/readest-app/src/app/library/components/GroupingModal.tsx @@ -65,7 +65,7 @@ const GroupingModal: React.FC = ({ } } }); - setLibrary(libraryBooks); + setLibrary([...libraryBooks]); appService?.saveLibraryBooks(libraryBooks); onConfirm(); }; @@ -118,7 +118,7 @@ const GroupingModal: React.FC = ({ } } }); - setLibrary(libraryBooks); + setLibrary([...libraryBooks]); appService?.saveLibraryBooks(libraryBooks); onConfirm(); }; @@ -155,7 +155,7 @@ const GroupingModal: React.FC = ({ className='flex items-center space-x-2 p-2 text-blue-500' > - {_('Remove From Group')} + {_('Remove From Group')} )} {showInput && ( diff --git a/apps/readest-app/src/app/reader/components/footerbar/DesktopFooterBar.tsx b/apps/readest-app/src/app/reader/components/footerbar/DesktopFooterBar.tsx index b6b04c1a..cda89b13 100644 --- a/apps/readest-app/src/app/reader/components/footerbar/DesktopFooterBar.tsx +++ b/apps/readest-app/src/app/reader/components/footerbar/DesktopFooterBar.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback, useEffect, useRef } from 'react'; import { FaHeadphones } from 'react-icons/fa6'; import { RiArrowLeftSLine, RiArrowRightSLine } from 'react-icons/ri'; import { RiArrowGoBackLine, RiArrowGoForwardLine } from 'react-icons/ri'; @@ -18,7 +18,7 @@ const DesktopFooterBar: React.FC = ({ onSpeakText, }) => { const _ = useTranslation(); - const { getView, getViewState, getViewSettings } = useReaderStore(); + const { hoveredBookKey, getView, getViewState, getViewSettings } = useReaderStore(); const view = getView(bookKey); const viewState = getViewState(bookKey); const viewSettings = getViewSettings(bookKey); @@ -27,6 +27,16 @@ const DesktopFooterBar: React.FC = ({ progressValid ? progressFraction * 100 : 0, ); + const rangeInputRef = useRef(null); + + useEffect(() => { + if (hoveredBookKey !== bookKey) { + if (rangeInputRef.current && document.activeElement === rangeInputRef.current) { + rangeInputRef.current.blur(); + } + } + }, [hoveredBookKey, bookKey]); + useEffect(() => { if (progressValid) { // eslint-disable-next-line react-hooks/set-state-in-effect @@ -93,6 +103,7 @@ const DesktopFooterBar: React.FC = ({ )} { + const attrWhitelist = [ + 'xmlns', + 'http-equiv', + 'content', + 'charset', + 'link', + 'vlink', + 'imt-state', // custom attribute generated by some translators + ]; return ( - ['xmlns', 'http-equiv', 'content', 'charset', 'link', 'vlink'].includes(attributeName) || + attrWhitelist.includes(attributeName) || attributeName.startsWith('xml:') || attributeName.startsWith('xmlns:') || attributeName.startsWith('epub:') diff --git a/apps/readest-app/src/utils/style.ts b/apps/readest-app/src/utils/style.ts index 8792b2ff..34d71002 100644 --- a/apps/readest-app/src/utils/style.ts +++ b/apps/readest-app/src/utils/style.ts @@ -121,6 +121,7 @@ const getColorStyles = ( --theme-bg-color: ${bg}; --theme-fg-color: ${fg}; --theme-primary-color: ${primary}; + --override-color: ${overrideColor}; color-scheme: ${isDarkMode ? 'dark' : 'light'}; } html, body { @@ -345,6 +346,11 @@ const getLayoutStyles = ( color: unset; } + /* some epubs set insane inline-block for p */ + p { + display: block; + } + /* inline images without dimension */ .ie6 img { width: unset; @@ -612,7 +618,10 @@ export const applyImageStyle = (document: Document) => { const hasTextSiblings = Array.from(parent.childNodes).some( (node) => node.nodeType === Node.TEXT_NODE && node.textContent?.trim(), ); - if (hasTextSiblings) { + const isInline = Array.from(parent.childNodes).every( + (node) => node.nodeType !== Node.ELEMENT_NODE || (node as Element).tagName !== 'BR', + ); + if (hasTextSiblings && isInline) { img.classList.add('has-text-siblings'); } }); diff --git a/packages/foliate-js b/packages/foliate-js index 3ffb3316..3981f577 160000 --- a/packages/foliate-js +++ b/packages/foliate-js @@ -1 +1 @@ -Subproject commit 3ffb3316203a8fed8978b268e1b76a53bf42136a +Subproject commit 3981f577dcd810cadfdfe15c8c03e151b08dfcdc