diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 820c6ebb..4821d010 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -349,5 +349,8 @@ "Search notes and excerpts...": "بحث في الملاحظات والمقتطفات...", "Sign in to Sync": "سجّل للمزامنة", "Synced at {{time}}": "تمت عند {{time}}", - "Never synced": "لم تُزامَن" + "Never synced": "لم تُزامَن", + "Show Remaining Time": "إظهار الوقت المتبقي", + "Show Page Number": "إظهار رقم الصفحة", + "{{time}} min left in chapter": "{{time}} دقيقة متبقية في الفصل" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index 0a361714..7c764ed3 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -341,5 +341,8 @@ "Search notes and excerpts...": "Notizen und Auszüge suchen...", "Sign in to Sync": "Anmelden zum Synchronisieren", "Synced at {{time}}": "Synchronisiert um {{time}}", - "Never synced": "Nie synchronisiert" + "Never synced": "Nie synchronisiert", + "Show Remaining Time": "Verbleibende Zeit anzeigen", + "Show Page Number": "Seitenzahl anzeigen", + "{{time}} min left in chapter": "{{time}} min verbleibend im Kapitel" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index 367f1bef..9e19101a 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -341,5 +341,8 @@ "Search notes and excerpts...": "Αναζήτηση σημειώσεων...", "Sign in to Sync": "Σύνδεση για συγχρονισμό", "Synced at {{time}}": "Συγχρονίστηκε στις {{time}}", - "Never synced": "Ποτέ δεν συγχρονίστηκε" + "Never synced": "Ποτέ δεν συγχρονίστηκε", + "Show Remaining Time": "Εμφάνιση υπολειπόμενου χρόνου", + "Show Page Number": "Εμφάνιση αριθμού σελίδας", + "{{time}} min left in chapter": "{{time}} λεπτά απομένουν στο κεφάλαιο" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 935fac1b..67f418b9 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -343,5 +343,8 @@ "Search notes and excerpts...": "Buscar notas...", "Sign in to Sync": "Inicia sesión para sincronizar", "Synced at {{time}}": "Sincronizado a las {{time}}", - "Never synced": "Nunca sincronizado" + "Never synced": "Nunca sincronizado", + "Show Remaining Time": "Mostrar tiempo restante", + "Show Page Number": "Mostrar número de página", + "{{time}} min left in chapter": "{{time}} min restantes en el capítulo" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 9aff539c..9b800928 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -343,5 +343,8 @@ "Search notes and excerpts...": "Rechercher des notes...", "Sign in to Sync": "Connectez-vous pour synchroniser", "Synced at {{time}}": "Synchronisé à {{time}}", - "Never synced": "Jamais synchronisé" + "Never synced": "Jamais synchronisé", + "Show Remaining Time": "Afficher le temps restant", + "Show Page Number": "Afficher le numéro de page", + "{{time}} min left in chapter": "{{time}} min restant dans le chapitre" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 2d23a6f1..1fe40264 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -341,5 +341,8 @@ "Search notes and excerpts...": "नोट्स खोजें...", "Sign in to Sync": "सिंक करने के लिए साइन इन करें", "Synced at {{time}}": "{{time}} पर सिंक किया गया", - "Never synced": "कभी सिंक नहीं किया गया" + "Never synced": "कभी सिंक नहीं किया गया", + "Show Remaining Time": "शेष समय दिखाएं", + "Show Page Number": "पृष्ठ संख्या दिखाएं", + "{{time}} min left in chapter": "{{time}} मिनट शेष अध्याय में" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index 25aee966..7a72f484 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -339,5 +339,8 @@ "Search notes and excerpts...": "Cari catatan...", "Sign in to Sync": "Masuk untuk Sinkronisasi", "Synced at {{time}}": "Disinkronkan pada {{time}}", - "Never synced": "Belum pernah disinkronkan" + "Never synced": "Belum pernah disinkronkan", + "Show Remaining Time": "__STRING_NOT_TRANSLATED__", + "Show Page Number": "__STRING_NOT_TRANSLATED__", + "{{time}} min left in chapter": "{{time}} menit tersisa di bab" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index 92cbf62e..cf499844 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -343,5 +343,8 @@ "Search notes and excerpts...": "Cerca nelle note...", "Sign in to Sync": "Accedi per sincronizzare", "Synced at {{time}}": "Sincronizzato alle {{time}}", - "Never synced": "Mai sincronizzato" + "Never synced": "Mai sincronizzato", + "Show Remaining Time": "Mostra tempo rimanente", + "Show Page Number": "Mostra numero pagina", + "{{time}} min left in chapter": "{{time}} min rimasti nel capitolo" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index da568484..17160f04 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -339,5 +339,8 @@ "Search notes and excerpts...": "ノートを検索...", "Sign in to Sync": "同期するにはサインイン", "Synced at {{time}}": "{{time}} に同期済み", - "Never synced": "まだ同期されていません" + "Never synced": "まだ同期されていません", + "Show Remaining Time": "残り時間を表示", + "Show Page Number": "ページ番号を表示", + "{{time}} min left in chapter": "{{time}}分残り" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index 3ee94257..d77a5be5 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -339,5 +339,8 @@ "Search notes and excerpts...": "노트 검색...", "Sign in to Sync": "동기화를 위해 로그인하세요", "Synced at {{time}}": "{{time}}에 동기화됨", - "Never synced": "동기화된 적 없음" + "Never synced": "동기화된 적 없음", + "Show Remaining Time": "남은 시간 표시", + "Show Page Number": "페이지 번호 표시", + "{{time}} min left in chapter": "{{time}}분 남음" } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index f2e0f67a..f294584c 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -341,5 +341,8 @@ "Search notes and excerpts...": "Zoek notities...", "Sign in to Sync": "Meld je aan om te synchroniseren", "Synced at {{time}}": "Gesynchroniseerd om {{time}}", - "Never synced": "Nooit gesynchroniseerd" + "Never synced": "Nooit gesynchroniseerd", + "Show Remaining Time": "Toon resterende tijd", + "Show Page Number": "Toon paginanummer", + "{{time}} min left in chapter": "Nog {{time}} min in hoofdstuk" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index 63411db4..6c0d7d15 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -345,5 +345,8 @@ "Search notes and excerpts...": "Szukaj notatek...", "Sign in to Sync": "Zaloguj się", "Synced at {{time}}": "Sync: {{time}}", - "Never synced": "Brak synchronizacji" + "Never synced": "Brak synchronizacji", + "Show Remaining Time": "Pokazuj pozostały czas", + "Show Page Number": "Pokaż numer strony", + "{{time}} min left in chapter": "{{time}} min pozostało do końca rozdziału" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index 69305dfa..ab4719f9 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -343,5 +343,8 @@ "Search notes and excerpts...": "Buscar notas...", "Sign in to Sync": "Entrar", "Synced at {{time}}": "Sincronizado às {{time}}", - "Never synced": "Nunca sincronizado" + "Never synced": "Nunca sincronizado", + "Show Remaining Time": "Mostrar Tempo Restante", + "Show Page Number": "Mostrar Número da Página", + "{{time}} min left in chapter": "{{time}} min restantes no capítulo" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index dbed1603..fcde56d1 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -345,5 +345,8 @@ "Search notes and excerpts...": "Искать записи...", "Sign in to Sync": "Войти", "Synced at {{time}}": "Синхр. в {{time}}", - "Never synced": "Не синхр." + "Never synced": "Не синхр.", + "Show Remaining Time": "Показать оставшееся время", + "Show Page Number": "Показать номер страницы", + "{{time}} min left in chapter": "{{time}} мин осталось в главе" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index ce4c19bb..52d1a3c4 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -341,5 +341,8 @@ "Search notes and excerpts...": "Notlarda ara...", "Sign in to Sync": "Giriş yap", "Synced at {{time}}": "{{time}}'de eşzlendi", - "Never synced": "Hiç eşzlenmedi" + "Never synced": "Hiç eşzlenmedi", + "Show Remaining Time": "Kalan Süreyi Göster", + "Show Page Number": "Sayfa Numarasını Göster", + "{{time}} min left in chapter": "{{time}} dakika bölümde kaldı" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index e5a2fc47..2df90487 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -345,5 +345,8 @@ "Search notes and excerpts...": "Шукати нотатки...", "Sign in to Sync": "Увійти", "Synced at {{time}}": "Синхр. о {{time}}", - "Never synced": "Ніколи не синхр." + "Never synced": "Ніколи не синхр.", + "Show Remaining Time": "Показати залишок часу", + "Show Page Number": "Показати номер сторінки", + "{{time}} min left in chapter": "{{time}} хв до кінця розділу" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 835b42b2..15aec8c2 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -339,5 +339,8 @@ "Search notes and excerpts...": "Tìm ghi chú...", "Sign in to Sync": "Đăng nhập", "Synced at {{time}}": "Đã đồng bộ lúc {{time}}", - "Never synced": "Chưa từng đồng bộ" + "Never synced": "Chưa từng đồng bộ", + "Show Remaining Time": "Hiển thị thời gian còn lại", + "Show Page Number": "Hiển thị số trang", + "{{time}} min left in chapter": "{{time}} phút còn lại trong chương" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 07feebab..e6039467 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -339,5 +339,8 @@ "Search notes and excerpts...": "搜索笔记...", "Sign in to Sync": "登录后同步", "Synced at {{time}}": "同步于:{{time}}", - "Never synced": "从未同步" + "Never synced": "从未同步", + "Show Remaining Time": "显示剩余时间", + "Show Page Number": "显示页码", + "{{time}} min left in chapter": "本章剩余 {{time}} 分钟" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 53309b9f..a98ce032 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -339,5 +339,8 @@ "Search notes and excerpts...": "搜尋筆記...", "Sign in to Sync": "登入以同步", "Synced at {{time}}": "同步於:{{time}}", - "Never synced": "從未同步" + "Never synced": "從未同步", + "Show Remaining Time": "顯示剩餘時間", + "Show Page Number": "顯示頁碼", + "{{time}} min left in chapter": "本章剩餘 {{time}} 分鐘" } diff --git a/apps/readest-app/src/app/reader/components/BooksGrid.tsx b/apps/readest-app/src/app/reader/components/BooksGrid.tsx index 6b4b1b5b..c1708ac3 100644 --- a/apps/readest-app/src/app/reader/components/BooksGrid.tsx +++ b/apps/readest-app/src/app/reader/components/BooksGrid.tsx @@ -11,7 +11,7 @@ import getGridTemplate from '@/utils/grid'; import SectionInfo from './SectionInfo'; import HeaderBar from './HeaderBar'; import FooterBar from './FooterBar'; -import PageInfoView from './PageInfo'; +import ProgressInfoView from './ProgressInfo'; import Ribbon from './Ribbon'; import SettingsDialog from './settings/SettingsDialog'; import Annotator from './annotator/Annotator'; @@ -57,7 +57,7 @@ const BooksGrid: React.FC = ({ bookKeys, onCloseBook }) => { const { book, bookDoc } = bookData || {}; if (!book || !config || !bookDoc || !viewSettings) return null; - const { section, pageinfo, sectionLabel } = progress || {}; + const { section, pageinfo, timeinfo, sectionLabel } = progress || {}; const isBookmarked = getViewState(bookKey)?.ribbonVisible; const horizontalGapPercent = viewSettings.gapPercent; const verticalMarginPixels = viewSettings.marginPx; @@ -139,13 +139,12 @@ const BooksGrid: React.FC = ({ bookKeys, onCloseBook }) => { verticalMargin={verticalMarginPixels} /> {showFooter && ( - diff --git a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx index a0cff8f5..d5653373 100644 --- a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx +++ b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx @@ -61,7 +61,15 @@ const FoliateViewer: React.FC<{ const progressRelocateHandler = (event: Event) => { const detail = (event as CustomEvent).detail; - setProgress(bookKey, detail.cfi, detail.tocItem, detail.section, detail.location, detail.range); + setProgress( + bookKey, + detail.cfi, + detail.tocItem, + detail.section, + detail.location, + detail.time, + detail.range, + ); }; const getDocTransformHandler = ({ width, height }: { width: number; height: number }) => { diff --git a/apps/readest-app/src/app/reader/components/PageInfo.tsx b/apps/readest-app/src/app/reader/components/ProgressInfo.tsx similarity index 57% rename from apps/readest-app/src/app/reader/components/PageInfo.tsx rename to apps/readest-app/src/app/reader/components/ProgressInfo.tsx index b8f7668f..2db39f9e 100644 --- a/apps/readest-app/src/app/reader/components/PageInfo.tsx +++ b/apps/readest-app/src/app/reader/components/ProgressInfo.tsx @@ -1,32 +1,37 @@ import clsx from 'clsx'; import React from 'react'; import { useEnv } from '@/context/EnvContext'; +import { useReaderStore } from '@/store/readerStore'; import { useTranslation } from '@/hooks/useTranslation'; -import { PageInfo } from '@/types/book'; +import { PageInfo, TimeInfo } from '@/types/book'; interface PageInfoProps { + bookKey: string; bookFormat: string; section?: PageInfo; pageinfo?: PageInfo; - showDoubleBorder: boolean; - isScrolled: boolean; - isVertical: boolean; + timeinfo?: TimeInfo; horizontalGap: number; verticalMargin: number; } -const PageInfoView: React.FC = ({ +const ProgressInfoView: React.FC = ({ + bookKey, bookFormat, section, pageinfo, - showDoubleBorder, - isScrolled, - isVertical, + timeinfo, horizontalGap, verticalMargin, }) => { const _ = useTranslation(); const { appService } = useEnv(); + const { getViewSettings } = useReaderStore(); + const viewSettings = getViewSettings(bookKey)!; + + const showDoubleBorder = viewSettings.vertical && viewSettings.doubleBorder; + const isScrolled = viewSettings.scrolled; + const isVertical = viewSettings.vertical; const pageInfo = ['PDF', 'CBZ'].includes(bookFormat) ? section ? isVertical @@ -39,11 +44,15 @@ const PageInfoView: React.FC = ({ totalPage: pageinfo.total, }) : ''; + const timeInfo = timeinfo + ? _('{{time}} min left in chapter', { time: Math.round(timeinfo.section) }) + : ''; return (
= ({ bottom: `${verticalMargin * 1.5}px`, left: showDoubleBorder ? `calc(${horizontalGap}% - 32px)` : 0, width: showDoubleBorder ? '32px' : `${horizontalGap}%`, - height: `calc(100% - ${verticalMargin * 2}px)`, + height: `calc(100% - ${verticalMargin * 3}px)`, } : { - insetInlineEnd: `${horizontalGap}%`, + paddingInlineStart: `${horizontalGap}%`, + paddingInlineEnd: `${horizontalGap}%`, paddingBottom: appService?.hasSafeAreaInset ? 'calc(env(safe-area-inset-bottom)*0.67)' : 0, } } > -

- {pageInfo} -

+ {viewSettings.showRemainingTime && {timeInfo}} + {viewSettings.showPageNumber && {pageInfo}}
); }; -export default PageInfoView; +export default ProgressInfoView; diff --git a/apps/readest-app/src/app/reader/components/settings/LayoutPanel.tsx b/apps/readest-app/src/app/reader/components/settings/LayoutPanel.tsx index b80dabde..9f953036 100644 --- a/apps/readest-app/src/app/reader/components/settings/LayoutPanel.tsx +++ b/apps/readest-app/src/app/reader/components/settings/LayoutPanel.tsx @@ -45,6 +45,8 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { const [showHeader, setShowHeader] = useState(viewSettings.showHeader!); const [showFooter, setShowFooter] = useState(viewSettings.showFooter!); const [showBarsOnScroll, setShowBarsOnScroll] = useState(viewSettings.showBarsOnScroll!); + const [showRemainingTime, setShowRemainingTime] = useState(viewSettings.showRemainingTime!); + const [showPageNumber, setShowPageNumber] = useState(viewSettings.showPageNumber!); useEffect(() => { saveViewSettings(envConfig, bookKey, 'paragraphMargin', paragraphMargin); @@ -191,6 +193,16 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [showBarsOnScroll]); + useEffect(() => { + saveViewSettings(envConfig, bookKey, 'showRemainingTime', showRemainingTime, false, false); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [showRemainingTime]); + + useEffect(() => { + saveViewSettings(envConfig, bookKey, 'showPageNumber', showPageNumber, false, false); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [showPageNumber]); + const applyMarginAndGap = () => { const isCompact = !showHeader && !showFooter; const marginPx = isCompact ? viewSettings.compactMarginPx : viewSettings.marginPx; @@ -475,6 +487,26 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { onChange={() => setShowFooter(!showFooter)} /> +
+ {_('Show Remaining Time')} + setShowRemainingTime(!showRemainingTime)} + /> +
+
+ {_('Show Page Number')} + setShowPageNumber(!showPageNumber)} + /> +
{_('Apply also in Scrolled Mode')} void; getProgress: (key: string) => BookProgress | null; @@ -215,6 +223,7 @@ export const useReaderStore = create((set, get) => ({ tocItem: TOCItem, section: PageInfo, pageinfo: PageInfo, + timeinfo: TimeInfo, range: Range, ) => set((state) => { @@ -270,6 +279,7 @@ export const useReaderStore = create((set, get) => ({ sectionId: tocItem?.id, section, pageinfo, + timeinfo, range, }, }, diff --git a/apps/readest-app/src/types/book.ts b/apps/readest-app/src/types/book.ts index cc3e624a..34a17421 100644 --- a/apps/readest-app/src/types/book.ts +++ b/apps/readest-app/src/types/book.ts @@ -41,6 +41,12 @@ export interface PageInfo { total: number; } +// Remaining time of the book in minutes +export interface TimeInfo { + section: number; + total: number; +} + export interface BookNote { bookHash?: string; id: string; @@ -82,11 +88,6 @@ export interface BookLayout { writingMode: WritingMode; vertical: boolean; rtl: boolean; - doubleBorder: boolean; - borderColor: string; - showHeader: boolean; - showFooter: boolean; - showBarsOnScroll: boolean; scrollingOverlap: number; allowScript: boolean; } @@ -122,6 +123,15 @@ export interface ViewConfig { sideBarTab: string; uiLanguage: string; sortedTOC: boolean; + + doubleBorder: boolean; + borderColor: string; + + showHeader: boolean; + showFooter: boolean; + showRemainingTime: boolean; + showPageNumber: boolean; + showBarsOnScroll: boolean; } export interface TTSConfig { @@ -156,6 +166,7 @@ export interface BookProgress { sectionLabel: string; section: PageInfo; pageinfo: PageInfo; + timeinfo: TimeInfo; range: Range; }