diff --git a/apps/readest-app/src/app/reader/components/BooksGrid.tsx b/apps/readest-app/src/app/reader/components/BooksGrid.tsx index 11f2cdc8..c4ee4a62 100644 --- a/apps/readest-app/src/app/reader/components/BooksGrid.tsx +++ b/apps/readest-app/src/app/reader/components/BooksGrid.tsx @@ -81,7 +81,7 @@ const BooksGrid: React.FC = ({ bookKeys, onCloseBook }) => { /> - {viewSettings.vertical && ( + {viewSettings.vertical && viewSettings.scrolled && ( <>
= ({ bookKey }) => { viewSettings.gapPercent, Math.ceil(4800 / window.innerWidth), ); + setGapPercent(viewSettings.gapPercent); setViewSettings(bookKey, viewSettings); } saveViewSettings(envConfig, bookKey, 'doubleBorder', doubleBorder); @@ -176,11 +177,35 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { }, [borderColor]); useEffect(() => { + if (showHeader && !viewSettings.vertical) { + viewSettings.marginPx = Math.max(viewSettings.marginPx, 44); + setMarginPx(viewSettings.marginPx); + setViewSettings(bookKey, viewSettings); + } else if (showHeader && viewSettings.vertical) { + viewSettings.gapPercent = Math.max( + viewSettings.gapPercent, + Math.ceil(4800 / window.innerWidth), + ); + setGapPercent(viewSettings.gapPercent); + setViewSettings(bookKey, viewSettings); + } saveViewSettings(envConfig, bookKey, 'showHeader', showHeader); // eslint-disable-next-line react-hooks/exhaustive-deps }, [showHeader]); useEffect(() => { + if (showFooter && !viewSettings.vertical) { + viewSettings.marginPx = Math.max(viewSettings.marginPx, 44); + setMarginPx(viewSettings.marginPx); + setViewSettings(bookKey, viewSettings); + } else if (showFooter && viewSettings.vertical) { + viewSettings.gapPercent = Math.max( + viewSettings.gapPercent, + Math.ceil(4800 / window.innerWidth), + ); + setGapPercent(viewSettings.gapPercent); + setViewSettings(bookKey, viewSettings); + } saveViewSettings(envConfig, bookKey, 'showFooter', showFooter); // eslint-disable-next-line react-hooks/exhaustive-deps }, [showFooter]); @@ -382,7 +407,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { label={_('Vertical Margins (px)')} value={marginPx} onChange={setMarginPx} - min={0} + min={!viewSettings.vertical && (showFooter || showHeader) ? 44 : 0} max={88} step={4} /> diff --git a/apps/readest-app/src/app/reader/components/settings/NumberInput.tsx b/apps/readest-app/src/app/reader/components/settings/NumberInput.tsx index 6f20b0e5..27d1ebfa 100644 --- a/apps/readest-app/src/app/reader/components/settings/NumberInput.tsx +++ b/apps/readest-app/src/app/reader/components/settings/NumberInput.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { FiMinus, FiPlus } from 'react-icons/fi'; interface NumberInputProps { @@ -26,6 +26,10 @@ const NumberInput: React.FC = ({ const [localValue, setLocalValue] = useState(value); const numberStep = step || 1; + useEffect(() => { + setLocalValue(value); + }, [value]); + const handleChange = (e: React.ChangeEvent) => { const value = e.target.value; diff --git a/apps/readest-app/src/app/reader/hooks/useIframeEvents.ts b/apps/readest-app/src/app/reader/hooks/useIframeEvents.ts index c42bd773..a2984591 100644 --- a/apps/readest-app/src/app/reader/hooks/useIframeEvents.ts +++ b/apps/readest-app/src/app/reader/hooks/useIframeEvents.ts @@ -137,7 +137,11 @@ export const useTouchEvent = ( if (hoveredBookKey && touchEnd) { const deltaY = touchEnd.screenY - touchStart.screenY; const deltaX = touchEnd.screenX - touchStart.screenX; - if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) { + if (!viewSettings!.scrolled && !viewSettings!.vertical) { + if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) { + setHoveredBookKey(null); + } + } else { setHoveredBookKey(null); } } @@ -161,8 +165,10 @@ export const useTouchEvent = ( Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaX) < windowWidth * 0.3 ) { - // swipe up to toggle the header bar and the footer bar - setHoveredBookKey(hoveredBookKey ? null : bookKey); + // swipe up to toggle the header bar and the footer bar, only for horizontal page mode + if (!viewSettings!.scrolled && !viewSettings!.vertical) { + setHoveredBookKey(hoveredBookKey ? null : bookKey); + } } else { if (hoveredBookKey) { setHoveredBookKey(null); @@ -187,15 +193,10 @@ export const useTouchEvent = ( }; useEffect(() => { - // swipe touch is not compatible with scrolled mode, so only enable it in page mode - if (!viewSettings!.scrolled) { - window.addEventListener('message', handleTouch); - return () => { - window.removeEventListener('message', handleTouch); - }; - } else { - return () => {}; - } + window.addEventListener('message', handleTouch); + return () => { + window.removeEventListener('message', handleTouch); + }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [hoveredBookKey, viewRef]); }; diff --git a/apps/readest-app/src/hooks/useTheme.ts b/apps/readest-app/src/hooks/useTheme.ts index a1dee9e7..5592260e 100644 --- a/apps/readest-app/src/hooks/useTheme.ts +++ b/apps/readest-app/src/hooks/useTheme.ts @@ -2,7 +2,6 @@ import { useEffect } from 'react'; import { useThemeStore } from '@/store/themeStore'; import { useSettingsStore } from '@/store/settingsStore'; import { applyCustomTheme } from '@/styles/themes'; -import { applyColorScheme } from '@/utils/style'; export const useTheme = () => { const { settings } = useSettingsStore(); @@ -17,6 +16,6 @@ export const useTheme = () => { useEffect(() => { const colorScheme = isDarkMode ? 'dark' : 'light'; document.documentElement.setAttribute('data-theme', `${themeColor}-${colorScheme}`); - applyColorScheme(document, isDarkMode); + document.documentElement.style.setProperty('color-scheme', colorScheme); }, [themeColor, isDarkMode]); }; diff --git a/apps/readest-app/src/utils/style.ts b/apps/readest-app/src/utils/style.ts index c2bdc541..3a9903b6 100644 --- a/apps/readest-app/src/utils/style.ts +++ b/apps/readest-app/src/utils/style.ts @@ -137,10 +137,11 @@ const getLayoutStyles = ( bg: string, fg: string, primary: string, + isDarkMode: boolean, ) => ` @namespace epub "http://www.idpf.org/2007/ops"; html { - color-scheme: light dark; + color-scheme: ${isDarkMode ? 'dark' : 'light'}; color: ${fg}; } a:any-link { @@ -158,6 +159,8 @@ const getLayoutStyles = ( html { --theme-bg-color: ${bg}; + --theme-fg-color: ${fg}; + --theme-primary-color: ${primary}; --default-text-align: ${justify ? 'justify' : 'start'}; hanging-punctuation: allow-end last; orphans: 2; @@ -248,15 +251,19 @@ export const getFootnoteStyles = () => ` display: block !important; } + body { + padding: 1em !important; + } + + a:any-link { + text-decoration: none; + } + ol { margin: 0; padding: 0; } - body { - padding: 1em !important; - } - p, li, blockquote, dd { margin: unset; text-indent: unset; @@ -268,6 +275,7 @@ export interface ThemeCode { fg: string; primary: string; palette: Palette; + isDarkMode: boolean; } export const getThemeCode = () => { @@ -303,6 +311,7 @@ export const getThemeCode = () => { fg: defaultPalette['base-content'], primary: defaultPalette.primary, palette: defaultPalette, + isDarkMode, } as ThemeCode; }; @@ -325,6 +334,7 @@ export const getStyles = (viewSettings: ViewSettings, themeCode?: ThemeCode) => themeCode.bg, themeCode.fg, themeCode.primary, + themeCode.isDarkMode, ); // scale the font size on-the-fly so that we can sync the same font size on different devices const isMobile = ['ios', 'android'].includes(getOSPlatform()); @@ -364,8 +374,3 @@ export const mountAdditionalFonts = (document: Document) => { style.textContent = getAdditionalFontFaces(); document.head.appendChild(style); }; - -export const applyColorScheme = (document: Document, isDarkMode: boolean) => { - const colorScheme = isDarkMode ? 'dark' : 'light'; - document.documentElement.style.setProperty('color-scheme', colorScheme); -}; diff --git a/packages/foliate-js b/packages/foliate-js index b4a0bbca..5fb4a4b4 160000 --- a/packages/foliate-js +++ b/packages/foliate-js @@ -1 +1 @@ -Subproject commit b4a0bbca87935ba6d2d86a37162af2cc0a352483 +Subproject commit 5fb4a4b46ef69167d447834dc322fce2be8c1ed8