From 48074f0f53f14bf7a0f444a4a30a937decbe6daa Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Mon, 17 Mar 2025 22:30:12 +0800 Subject: [PATCH] feat: add options to show/hide header and footer widgets in paginated and scrolled mode, also closes #602 (#620) --- .../public/locales/ar/translation.json | 5 +- .../public/locales/de/translation.json | 5 +- .../public/locales/el/translation.json | 5 +- .../public/locales/es/translation.json | 5 +- .../public/locales/fr/translation.json | 5 +- .../public/locales/hi/translation.json | 5 +- .../public/locales/id/translation.json | 5 +- .../public/locales/it/translation.json | 5 +- .../public/locales/ja/translation.json | 5 +- .../public/locales/ko/translation.json | 5 +- .../public/locales/pl/translation.json | 5 +- .../public/locales/pt/translation.json | 5 +- .../public/locales/ru/translation.json | 5 +- .../public/locales/tr/translation.json | 5 +- .../public/locales/uk/translation.json | 5 +- .../public/locales/vi/translation.json | 5 +- .../public/locales/zh-CN/translation.json | 7 +- .../public/locales/zh-TW/translation.json | 7 +- .../src/app/reader/components/BooksGrid.tsx | 74 +++++++------ .../app/reader/components/DoubleBorder.tsx | 66 +++++++----- .../app/reader/components/FoliateViewer.tsx | 4 +- .../src/app/reader/components/HintInfo.tsx | 16 +-- .../src/app/reader/components/PageInfo.tsx | 7 +- .../src/app/reader/components/SectionInfo.tsx | 19 ++-- .../reader/components/settings/FontPanel.tsx | 7 +- .../components/settings/LayoutPanel.tsx | 100 ++++++++++++------ .../reader/components/settings/MiscPanel.tsx | 6 +- apps/readest-app/src/services/constants.ts | 2 + apps/readest-app/src/store/themeStore.ts | 2 + apps/readest-app/src/styles/globals.css | 8 -- apps/readest-app/src/types/book.ts | 2 + packages/foliate-js | 2 +- 32 files changed, 257 insertions(+), 152 deletions(-) diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 013e2048..247218da 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -244,5 +244,8 @@ "Contrast": "التباين", "Sunset": "غروب الشمس", "Double Border": "حدود مزدوجة", - "Border Color": "لون الحدود" + "Border Color": "لون الحدود", + "Border Frame": "إطار الحدود", + "Show Header": "عرض الرأس", + "Show Footer": "عرض التذييل" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index b9963e11..ae358774 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -244,5 +244,8 @@ "Contrast": "Kontrast", "Sunset": "Sonnenuntergang", "Double Border": "Doppelter Rand", - "Border Color": "Randfarbe" + "Border Color": "Randfarbe", + "Border Frame": "Rahmenrand", + "Show Header": "Kopfzeile anzeigen", + "Show Footer": "Fußzeile anzeigen" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index 451bc92c..6c67d949 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -244,5 +244,8 @@ "Contrast": "Αντίθεση", "Sunset": "Ηλιοβασίλεμα", "Double Border": "Διπλό περιθώριο", - "Border Color": "Χρώμα περιγράμματος" + "Border Color": "Χρώμα περιγράμματος", + "Border Frame": "Πλαίσιο περιγράμματος", + "Show Header": "Εμφάνιση κεφαλίδας", + "Show Footer": "Εμφάνιση υποσέλιδου" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 57468799..02f5bda5 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -244,5 +244,8 @@ "Contrast": "Contraste", "Sunset": "Atardecer", "Double Border": "Doble borde", - "Border Color": "Color del borde" + "Border Color": "Color del borde", + "Border Frame": "Marco de borde", + "Show Header": "Mostrar encabezado", + "Show Footer": "Mostrar pie de página" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 9145db39..39f0146f 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -244,5 +244,8 @@ "Contrast": "Contraste", "Sunset": "Coucher de soleil", "Double Border": "Double bordure", - "Border Color": "Couleur de la bordure" + "Border Color": "Couleur de la bordure", + "Border Frame": "Cadre de bordure", + "Show Header": "Afficher l'en-tête", + "Show Footer": "Afficher le pied de page" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index d11c157b..1b95e672 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -244,5 +244,8 @@ "Contrast": "विरोधाभास", "Sunset": "सनसेट", "Double Border": "डबल बॉर्डर", - "Border Color": "बॉर्डर रंग" + "Border Color": "बॉर्डर रंग", + "Border Frame": "बॉर्डर फ्रेम", + "Show Header": "हेडर दिखाएं", + "Show Footer": "फ़ुटर दिखाएं" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index e76637f6..6707db12 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -244,5 +244,8 @@ "Contrast": "Kontras", "Sunset": "Senja", "Double Border": "Garis Ganda", - "Border Color": "Warna Garis" + "Border Color": "Warna Garis", + "Border Frame": "Bingkai Garis", + "Show Header": "Tampilkan Header", + "Show Footer": "Tampilkan Footer" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index b6f30b93..a5b2c026 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -244,5 +244,8 @@ "Contrast": "Contrasto", "Sunset": "Tramonto", "Double Border": "Doppio bordo", - "Border Color": "Colore bordo" + "Border Color": "Colore bordo", + "Border Frame": "Cornice bordo", + "Show Header": "Mostra intestazione", + "Show Footer": "Mostra piè di pagina" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index 3cd26fc3..ee5d1f55 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -244,5 +244,8 @@ "Contrast": "コントラスト", "Sunset": "サンセット", "Double Border": "二重枠", - "Border Color": "ボーダーカラー" + "Border Color": "ボーダーカラー", + "Border Frame": "ボーダーフレーム", + "Show Header": "ヘッダーを表示", + "Show Footer": "フッターを表示" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index 223cb8f5..0c5f7d7f 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -244,5 +244,8 @@ "Contrast": "대비", "Sunset": "일몰", "Double Border": "이중 테두리", - "Border Color": "테두리 색상" + "Border Color": "테두리 색상", + "Border Frame": "테두리 프레임", + "Show Header": "헤더 표시", + "Show Footer": "푸터 표시" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index d726b453..51daba94 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -244,5 +244,8 @@ "Contrast": "Kontrast", "Sunset": "Zachód słońca", "Double Border": "Podwójna ramka", - "Border Color": "Kolor ramki" + "Border Color": "Kolor ramki", + "Border Frame": "Ramka", + "Show Header": "Pokaż nagłówek", + "Show Footer": "Pokaż stopkę" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index cd5f81ce..a0149691 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -244,5 +244,8 @@ "Contrast": "Contraste", "Sunset": "Pôr do Sol", "Double Border": "Borda Dupla", - "Border Color": "Cor da Borda" + "Border Color": "Cor da Borda", + "Border Frame": "Moldura da Borda", + "Show Header": "Mostrar Cabeçalho", + "Show Footer": "Mostrar Rodapé" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index 4037e7b2..8627e5b8 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -244,5 +244,8 @@ "Contrast": "Контраст", "Sunset": "Закат", "Double Border": "Двойная граница", - "Border Color": "Цвет границы" + "Border Color": "Цвет границы", + "Border Frame": "Граница рамки", + "Show Header": "Показать заголовок", + "Show Footer": "Показать нижний колонтитул" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index 89d34914..8ee96f9b 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -244,5 +244,8 @@ "Contrast": "Kontrast", "Sunset": "Gün Batımı", "Double Border": "Çift Sınır", - "Border Color": "Sınır Rengi" + "Border Color": "Sınır Rengi", + "Border Frame": "Sınır Çerçevesi", + "Show Header": "Başlık Göster", + "Show Footer": "Altbilgi Göster" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index d7ec36fb..e4454804 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -244,5 +244,8 @@ "Contrast": "Контраст", "Sunset": "Захід сонця", "Double Border": "Подвійна рамка", - "Border Color": "Колір рамки" + "Border Color": "Колір рамки", + "Border Frame": "Рамка рамки", + "Show Header": "Показати заголовок", + "Show Footer": "Показати нижню частину" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 944d676b..447b88e5 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -244,5 +244,8 @@ "Contrast": "Tương phản", "Sunset": "Hoàng hôn", "Double Border": "Đôi viền", - "Border Color": "Màu viền" + "Border Color": "Màu viền", + "Border Frame": "Khung viền", + "Show Header": "Hiển thị tiêu đề", + "Show Footer": "Hiển thị chân trang" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 4997c180..687cd969 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -243,6 +243,9 @@ "Preview": "预览", "Contrast": "对比", "Sunset": "日落", - "Double Border": "页面版框", - "Border Color": "版框颜色" + "Double Border": "显示版框", + "Border Color": "版框颜色", + "Border Frame": "页面版框", + "Show Header": "显示页眉", + "Show Footer": "显示页脚" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 715b68f1..1891449e 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -243,6 +243,9 @@ "Preview": "預覽", "Contrast": "對比", "Sunset": "日落", - "Double Border": "頁面邊框", - "Border Color": "邊框顏色" + "Double Border": "顯示邊框", + "Border Color": "邊框顏色", + "Border Frame": "頁面邊框", + "Show Header": "顯示頁眉", + "Show Footer": "顯示頁腳" } diff --git a/apps/readest-app/src/app/reader/components/BooksGrid.tsx b/apps/readest-app/src/app/reader/components/BooksGrid.tsx index bd48c688..705f5944 100644 --- a/apps/readest-app/src/app/reader/components/BooksGrid.tsx +++ b/apps/readest-app/src/app/reader/components/BooksGrid.tsx @@ -81,36 +81,50 @@ const BooksGrid: React.FC = ({ bookKeys, onCloseBook }) => { /> - {viewSettings.scrolled ? null : ( - <> - {viewSettings.vertical && viewSettings.doubleBorder && ( - - )} - - - - +
+
+ {viewSettings.vertical && viewSettings.doubleBorder && ( + + )} + {viewSettings.showHeader && ( + + )} + + {viewSettings.showFooter && ( + )} = ({ borderColor, horizontalGap, verticalMargin, + showHeader, + showFooter, }) => { return ( <> + {/* outter frame */}
+ {/* inner frame */}
-
-
+ {/* footer */} + {showFooter && ( +
+ )} + {/* header */} + {showHeader && ( +
+ )} ); }; diff --git a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx index 316349e6..3a5c402e 100644 --- a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx +++ b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx @@ -35,7 +35,7 @@ const FoliateViewer: React.FC<{ const { getView, setView: setFoliateView, setProgress } = useReaderStore(); const { getViewSettings, setViewSettings } = useReaderStore(); const { getParallels } = useParallelViewStore(); - const { themeCode, isDarkMode } = useThemeStore(); + const { themeCode, isDarkMode, getIsDarkMode } = useThemeStore(); const viewSettings = getViewSettings(bookKey)!; const [toastMessage, setToastMessage] = useState(''); @@ -64,7 +64,7 @@ const FoliateViewer: React.FC<{ viewSettings.rtl = writingDir?.rtl || viewSettings.writingMode.includes('rl') || false; setViewSettings(bookKey, viewSettings); - applyColorScheme(detail.doc, isDarkMode); + applyColorScheme(detail.doc, getIsDarkMode()); mountAdditionalFonts(detail.doc); if (!detail.doc.isEventListenersAdded) { diff --git a/apps/readest-app/src/app/reader/components/HintInfo.tsx b/apps/readest-app/src/app/reader/components/HintInfo.tsx index 42dead76..7650c8b3 100644 --- a/apps/readest-app/src/app/reader/components/HintInfo.tsx +++ b/apps/readest-app/src/app/reader/components/HintInfo.tsx @@ -1,7 +1,5 @@ import clsx from 'clsx'; import React, { useEffect, useRef } from 'react'; -import { useSidebarStore } from '@/store/sidebarStore'; -import { useTrafficLightStore } from '@/store/trafficLightStore'; import { eventDispatcher } from '@/utils/event'; interface SectionInfoProps { @@ -17,8 +15,6 @@ const HintInfo: React.FC = ({ horizontalGap, verticalMargin, }) => { - const { isSideBarVisible } = useSidebarStore(); - const { isTrafficLightVisible } = useTrafficLightStore(); const [hintMessage, setHintMessage] = React.useState(null); const hintTimeout = useRef(2000); const dismissTimeout = useRef | null>(null); @@ -49,17 +45,15 @@ const HintInfo: React.FC = ({ return (
= ({
= ({ horizontalGap, verticalMargin, }) => { - const { isSideBarVisible } = useSidebarStore(); - const { isTrafficLightVisible } = useTrafficLightStore(); return (

diff --git a/apps/readest-app/src/app/reader/components/settings/FontPanel.tsx b/apps/readest-app/src/app/reader/components/settings/FontPanel.tsx index e66ecc7a..eea4e25e 100644 --- a/apps/readest-app/src/app/reader/components/settings/FontPanel.tsx +++ b/apps/readest-app/src/app/reader/components/settings/FontPanel.tsx @@ -225,7 +225,6 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
= ({ bookKey }) => { max={120} /> = ({ bookKey }) => {
= ({ bookKey }) => {

{_('Font Family')}

-
+
{_('Default Font')} = ({ bookKey }) => { />
-
+
{_('Override Book Font')} = ({ bookKey }) => { const [isScrolledMode, setScrolledMode] = useState(viewSettings.scrolled!); const [doubleBorder, setDoubleBorder] = useState(viewSettings.doubleBorder!); const [borderColor, setBorderColor] = useState(viewSettings.borderColor!); + const [showHeader, setShowHeader] = useState(viewSettings.showHeader!); + const [showFooter, setShowFooter] = useState(viewSettings.showFooter!); useEffect(() => { viewSettings.paragraphMargin = paragraphMargin; @@ -246,6 +248,26 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [borderColor]); + useEffect(() => { + viewSettings.showHeader = showHeader; + setViewSettings(bookKey, viewSettings); + if (isFontLayoutSettingsGlobal) { + settings.globalViewSettings.showHeader = showHeader; + setSettings(settings); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [showHeader]); + + useEffect(() => { + viewSettings.showFooter = showFooter; + setViewSettings(bookKey, viewSettings); + if (isFontLayoutSettingsGlobal) { + settings.globalViewSettings.showFooter = showFooter; + setSettings(settings); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [showFooter]); + const langCode = getBookLangCode(bookData.bookDoc?.metadata?.language); const mightBeRTLBook = MIGHT_BE_RTL_LANGS.includes(langCode) || isCJKEnv(); @@ -309,36 +331,37 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { )} {viewSettings.vertical && ( - <> -
-
-

{_('Double Border')}

- setDoubleBorder(!doubleBorder)} - /> -
-
+
+

{_('Border Frame')}

+
+
+
+ {_('Double Border')} + setDoubleBorder(!doubleBorder)} + /> +
-
-
-

{_('Border Color')}

-
- +
+ {_('Border Color')} +
+ - + +
- +
)}
@@ -346,7 +369,6 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
= ({ bookKey }) => { max={4} step={1} /> -
+
{_('Full Justification')} = ({ bookKey }) => { onChange={() => setFullJustification(!fullJustification)} />
-
+
{_('Hyphenation')} = ({ bookKey }) => { onChange={() => setHyphenation(!hyphenation)} />
-
+
{_('Override Book Layout')} = ({ bookKey }) => {

{_('Page')}

+
+ {_('Show Header')} + setShowHeader(!showHeader)} + /> +
+
+ {_('Show Footer')} + setShowFooter(!showFooter)} + /> +
= ({ bookKey }) => { onChange={setGapPercent} min={viewSettings.vertical ? 2 : 0} max={30} + step={0.5} /> = ({ bookKey }) => {

{_('Animation')}

-
+
{_('Paging Animation')} = ({ bookKey }) => {

{_('Behavior')}

-
+
{_('Continuous Scroll')} = ({ bookKey }) => { onChange={() => setIsContinuousScroll(!isContinuousScroll)} />
-
+
{_('Disable Click-to-Flip')} boolean; setThemeMode: (mode: ThemeMode) => void; setThemeColor: (color: string) => void; updateAppTheme: (color: keyof Palette) => void; @@ -61,6 +62,7 @@ export const useThemeStore = create((set, get) => { systemIsDarkMode, isDarkMode, themeCode, + getIsDarkMode: () => get().isDarkMode, setThemeMode: (mode) => { if (typeof window !== 'undefined' && localStorage) { localStorage.setItem('themeMode', mode); diff --git a/apps/readest-app/src/styles/globals.css b/apps/readest-app/src/styles/globals.css index f6334ea8..0a6a8b5e 100644 --- a/apps/readest-app/src/styles/globals.css +++ b/apps/readest-app/src/styles/globals.css @@ -191,14 +191,6 @@ foliate-view { @apply hover:bg-base-100/50; } -.config-item-top { - @apply rounded-t-2xl; -} - -.config-item-bottom { - @apply rounded-b-2xl; -} - .collapse-arrow > .collapse-title:after { top: var(--top-override, default-value); inset-inline-end: var(--end-override, default-value); diff --git a/apps/readest-app/src/types/book.ts b/apps/readest-app/src/types/book.ts index c50302c7..397551ae 100644 --- a/apps/readest-app/src/types/book.ts +++ b/apps/readest-app/src/types/book.ts @@ -70,6 +70,8 @@ export interface BookLayout { rtl: boolean; doubleBorder: boolean; borderColor: string; + showHeader: boolean; + showFooter: boolean; } export interface BookStyle { diff --git a/packages/foliate-js b/packages/foliate-js index c5096074..ed663c9e 160000 --- a/packages/foliate-js +++ b/packages/foliate-js @@ -1 +1 @@ -Subproject commit c50960743b9ea0ce4c0eef3edc156f553f2c562a +Subproject commit ed663c9ea59dd084360ce9ce3da1ee2a2804fc17