Compare commits

...

7 Commits

11 changed files with 51 additions and 14 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@readest/readest-app",
"version": "0.9.80",
"version": "0.9.81",
"private": true,
"scripts": {
"dev": "dotenv -e .env.tauri -- next dev",
@@ -113,7 +113,7 @@
"Apply to This Book": "Застосувати лише до цієї книги",
"Unable to fetch the translation. Try again later.": "Не вдалося отримати переклад. Спробуйте пізніше.",
"Check Update": "Перевірити оновлення",
"Already the latest version": "У вас вже встановлена остання версія",
"Already the latest version": "У вас вже встановлена найновіша версія",
"Book Details": "Деталі книги",
"From Local File": "З локального файлу",
"TOC": "Зміст",
@@ -499,7 +499,7 @@
"Sync Conflict": "Конфлікт синхронізації",
"Sync reading progress from \"{{deviceName}}\"?": "Синхронізувати прогрес читання із \"{{deviceName}}\"?",
"another device": "інший пристрій",
"Local Progress": "Локальний прогрес",
"Local Progress": "Локальний проґрес",
"Remote Progress": "Проґрес у хмарі",
"Page {{page}} of {{total}} ({{percentage}}%)": "Сторінка {{page}} з {{total}} ({{percentage}}%)",
"Current position": "Поточна позиція",
@@ -547,8 +547,8 @@
"Search Options": "Параметри пошуку",
"Close": "Закрити",
"Delete Book Options": "Параметри видалення книги",
"ON": "УВІМКНЕННЯ",
"OFF": "ВИМКНЕННЯ",
"ON": "УВІМКНЕННО",
"OFF": "ВИМКНЕНО",
"Reading Progress": "Проґрес читання",
"Page Margin": "Поля сторінки",
"Remove Bookmark": "Видалити закладку",
+10
View File
@@ -1,5 +1,15 @@
{
"releases": {
"0.9.81": {
"date": "2025-09-19",
"notes": [
"TTS: Added desktop common media control support when TTS is playing",
"PDF: Disabled swipe-up gesture for toggling the action bar when zoomed in",
"Fonts: Fixed an issue where embedded fonts in ebooks were occasionally not applied",
"Reader: Fixed an issue where newly created highlights sometimes would not appear",
"Reader: Enabled scrolling in the menu when the menu is too long"
]
},
"0.9.80": {
"date": "2025-09-19",
"notes": [
@@ -183,7 +183,6 @@ const TOCView: React.FC<{
(activeItem as HTMLElement).setAttribute('aria-current', 'page');
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [flatItems, activeHref]);
const virtualItemSize = useMemo(() => {
@@ -121,7 +121,7 @@ const TTSControl: React.FC<TTSControlProps> = ({ bookKey, gridInsets }) => {
const progress = getProgress(bookKey);
const { sectionLabel } = progress || {};
const mark = (e as CustomEvent<TTSMark>).detail;
if (appService?.isMobileApp && 'mediaSession' in navigator) {
if ('mediaSession' in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: mark?.text || '',
artist: sectionLabel || title,
@@ -439,10 +439,18 @@ const TTSControl: React.FC<TTSControlProps> = ({ bookKey, gridInsets }) => {
});
navigator.mediaSession.setActionHandler('seekforward', () => {
handleForward();
handleForward(true);
});
navigator.mediaSession.setActionHandler('seekbackward', () => {
handleBackward(true);
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
handleForward();
});
navigator.mediaSession.setActionHandler('previoustrack', () => {
handleBackward();
});
}
@@ -1,5 +1,6 @@
import { useEffect } from 'react';
import { useReaderStore } from '@/store/readerStore';
import { useBookDataStore } from '@/store/bookDataStore';
import { debounce } from '@/utils/debounce';
import { ScrollSource } from './usePagination';
@@ -61,6 +62,7 @@ export const useTouchEvent = (
handlePageFlip: (msg: CustomEvent) => void,
handleContinuousScroll: (source: ScrollSource, delta: number, threshold: number) => void,
) => {
const { getBookData } = useBookDataStore();
const { hoveredBookKey, setHoveredBookKey, getViewSettings } = useReaderStore();
let touchStart: IframeTouch | null = null;
@@ -104,6 +106,7 @@ export const useTouchEvent = (
const windowWidth = window.innerWidth;
if (touchEnd) {
const viewSettings = getViewSettings(bookKey)!;
const bookData = getBookData(bookKey)!;
const deltaY = touchEnd.screenY - touchStart.screenY;
const deltaX = touchEnd.screenX - touchStart.screenX;
// also check for deltaX to prevent swipe page turn from triggering the toggle
@@ -113,7 +116,11 @@ export const useTouchEvent = (
Math.abs(deltaX) < windowWidth * 0.3
) {
// swipe up to toggle the header bar and the footer bar, only for horizontal page mode
if (!viewSettings!.scrolled && !viewSettings!.vertical) {
if (
!viewSettings!.scrolled && // not scrolled
!viewSettings!.vertical && // not vertical
(!bookData.isFixedLayout || viewSettings.zoomLevel <= 100) // for fixed layout, not when zoomed in
) {
setHoveredBookKey(hoveredBookKey ? null : bookKey);
}
} else {
@@ -99,7 +99,7 @@ export const useProgressSync = (bookKey: string) => {
if (!progress?.location || !user) return;
handleAutoSync();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [progress]);
}, [progress?.location]);
// Pull: pull progress once when the book is opened
useEffect(() => {
+5 -1
View File
@@ -22,7 +22,11 @@ const Menu: React.FC<MenuProps> = ({ children, className }) => {
}, []);
return (
<div ref={menuRef} role='none' className={clsx(className)}>
<div
ref={menuRef}
role='none'
className={clsx('max-h-[calc(100vh-96px)] overflow-y-auto', className)}
>
{children}
</div>
);
+2 -1
View File
@@ -65,7 +65,8 @@ export function useSync(bookKey?: string) {
const { syncClient } = useSyncContext();
useEffect(() => {
setIsSyncing(bookKey || '', syncing);
if (!bookKey) return;
setIsSyncing(bookKey, syncing);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [bookKey, syncing]);
+1 -1
View File
@@ -98,7 +98,7 @@ export const useReaderStore = create<ReaderStore>((set, get) => ({
getViewsById: (id: string) => {
const { viewStates } = get();
return Object.values(viewStates)
.filter((state) => state.key.startsWith(id))
.filter((state) => state.key && state.key.startsWith(id))
.map((state) => state.view!);
},
+9 -1
View File
@@ -48,6 +48,7 @@ const getFontStyles = (
...FALLBACK_FONTS,
];
const monospaceFonts = [monospace, ...MONOSPACE_FONTS.filter((font) => font !== monospace)];
const defaultFontFamily = defaultFont.toLowerCase() === 'serif' ? '--serif' : '--sans-serif';
const fontStyles = `
html {
--serif: ${serifFonts.map((font) => `"${font}"`).join(', ')}, serif;
@@ -55,12 +56,19 @@ const getFontStyles = (
--monospace: ${monospaceFonts.map((font) => `"${font}"`).join(', ')}, monospace;
}
html, body {
font-family: var(${defaultFont.toLowerCase() === 'serif' ? '--serif' : '--sans-serif'}) ${overrideFont ? '!important' : ''};
font-size: ${fontSize}px !important;
font-weight: ${fontWeight};
-webkit-text-size-adjust: none;
text-size-adjust: none;
}
/* lower specificity than ebook built-in font styles */
html {
font-family: var(${defaultFontFamily}) ${overrideFont ? '!important' : ''};
}
/* higher specificity than ebook built-in font styles */
html body {
${overrideFont ? `font-family: var(${defaultFontFamily}) !important;` : ''}
}
font[size="1"] {
font-size: ${minFontSize}px;
}