diff --git a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx index 1cc6ea9c..c264f6df 100644 --- a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx +++ b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx @@ -12,6 +12,7 @@ import { useAutoHideScrollbar } from '../hooks/useAutoHideScrollbar'; import { getStyles, mountAdditionalFonts } from '@/utils/style'; import { getBookDirFromLanguage, getBookDirFromWritingMode } from '@/utils/book'; import { useTheme } from '@/hooks/useTheme'; +import { useUICSS } from '@/hooks/useUICSS'; import { handleKeydown, handleMousedown, @@ -36,6 +37,7 @@ const FoliateViewer: React.FC<{ const { getViewSettings, setViewSettings } = useReaderStore(); const { getParallels } = useParallelViewStore(); const { themeCode } = useTheme(); + const viewSettings = getViewSettings(bookKey)!; const [toastMessage, setToastMessage] = useState(''); useEffect(() => { @@ -43,6 +45,7 @@ const FoliateViewer: React.FC<{ return () => clearTimeout(timer); }, [toastMessage]); + useUICSS(viewSettings); useProgressSync(bookKey); useProgressAutoSave(bookKey); @@ -138,7 +141,6 @@ const FoliateViewer: React.FC<{ document.body.append(view); containerRef.current?.appendChild(view); - const viewSettings = getViewSettings(bookKey)!; const writingMode = viewSettings.writingMode; if (writingMode) { const settingsDir = getBookDirFromWritingMode(writingMode); diff --git a/apps/readest-app/src/app/reader/components/settings/MiscPanel.tsx b/apps/readest-app/src/app/reader/components/settings/MiscPanel.tsx index 03ca80d1..4b70ded9 100644 --- a/apps/readest-app/src/app/reader/components/settings/MiscPanel.tsx +++ b/apps/readest-app/src/app/reader/components/settings/MiscPanel.tsx @@ -52,7 +52,7 @@ const MiscPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { setDraftStylesheet(formattedCSS); setDraftStylesheetSaved(true); viewSettings.userStylesheet = formattedCSS; - setViewSettings(bookKey, viewSettings); + setViewSettings(bookKey, { ...viewSettings }); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.userStylesheet = formattedCSS; diff --git a/apps/readest-app/src/hooks/useUICSS.ts b/apps/readest-app/src/hooks/useUICSS.ts new file mode 100644 index 00000000..88e3bcca --- /dev/null +++ b/apps/readest-app/src/hooks/useUICSS.ts @@ -0,0 +1,25 @@ +import { ViewSettings } from '@/types/book'; +import { useEffect, useState } from 'react'; + +// This hook allows you to inject custom CSS into the reader UI. +// Note that the book content is rendered in an iframe, so UI CSS won't affect book rendering. +export const useUICSS = (viewSettings: ViewSettings) => { + const [styleElement, setStyleElement] = useState(null); + + useEffect(() => { + if (!viewSettings) return; + if (styleElement) { + styleElement.remove(); + } + + const newStyleEl = document.createElement('style'); + newStyleEl.textContent = viewSettings.userStylesheet; + document.head.appendChild(newStyleEl); + setStyleElement(newStyleEl); + + return () => { + newStyleEl.remove(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [viewSettings]); +}; diff --git a/packages/foliate-js b/packages/foliate-js index 568f404a..9c5be501 160000 --- a/packages/foliate-js +++ b/packages/foliate-js @@ -1 +1 @@ -Subproject commit 568f404aa67734ba7c68e645fbdb2af5f13f91dc +Subproject commit 9c5be5014b53a15fe144e2ea1be8163c5857f282