diff --git a/apps/readest-app/src/app/library/page.tsx b/apps/readest-app/src/app/library/page.tsx
index b4c6ceec..bc4dc1da 100644
--- a/apps/readest-app/src/app/library/page.tsx
+++ b/apps/readest-app/src/app/library/page.tsx
@@ -21,7 +21,6 @@ import { getCurrentWebview } from '@tauri-apps/api/webview';
import { useEnv } from '@/context/EnvContext';
import { useAuth } from '@/context/AuthContext';
-import { useThemeStore } from '@/store/themeStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useLibraryStore } from '@/store/libraryStore';
import { useSettingsStore } from '@/store/settingsStore';
@@ -60,8 +59,7 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
setCheckOpenWithBooks,
} = useLibraryStore();
const _ = useTranslation();
- useTheme();
- const { updateAppTheme } = useThemeStore();
+ useTheme({ systemUIVisible: true, appThemeColor: 'base-200' });
const { settings, setSettings, saveSettings } = useSettingsStore();
const [loading, setLoading] = useState(false);
const isInitiating = useRef(false);
@@ -94,11 +92,6 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
},
});
- useEffect(() => {
- updateAppTheme('base-200');
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
useEffect(() => {
const doCheckAppUpdates = async () => {
if (appService?.hasUpdater && settings.autoCheckUpdates) {
@@ -533,11 +526,16 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
= ({
cleanupTrafficLightListeners,
} = useTrafficLightStore();
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
- const { bookKeys, hoveredBookKey, setHoveredBookKey } = useReaderStore();
+ const { bookKeys, hoveredBookKey, systemUIVisible, setHoveredBookKey } = useReaderStore();
const { isSideBarVisible } = useSidebarStore();
const iconSize16 = useResponsiveSize(16);
@@ -89,20 +89,27 @@ const HeaderBar: React.FC = ({
'bg-base-100 absolute left-0 right-0 top-0 z-10 h-[env(safe-area-inset-top)]',
isVisible ? 'visible' : 'hidden',
)}
+ style={{
+ height: systemUIVisible ? 'max(env(safe-area-inset-top), 24px)' : '',
+ }}
/>
!appService?.isMobile && setHoveredBookKey('')}
>
@@ -139,7 +146,10 @@ const HeaderBar: React.FC = ({
showMaximize={
bookKeys.length == 1 && !isTrafficLightVisible && appService?.appPlatform !== 'web'
}
- onClose={() => onCloseBook(bookKey)}
+ onClose={() => {
+ setHoveredBookKey(null);
+ onCloseBook(bookKey);
+ }}
/>
diff --git a/apps/readest-app/src/app/reader/components/Reader.tsx b/apps/readest-app/src/app/reader/components/Reader.tsx
index 3aa19523..7a863d3b 100644
--- a/apps/readest-app/src/app/reader/components/Reader.tsx
+++ b/apps/readest-app/src/app/reader/components/Reader.tsx
@@ -7,10 +7,12 @@ import { useEffect, Suspense, useRef } from 'react';
import { useEnv } from '@/context/EnvContext';
import { useTheme } from '@/hooks/useTheme';
import { useThemeStore } from '@/store/themeStore';
+import { useReaderStore } from '@/store/readerStore';
import { useLibraryStore } from '@/store/libraryStore';
import { useSidebarStore } from '@/store/sidebarStore';
import { useSettingsStore } from '@/store/settingsStore';
import { useScreenWakeLock } from '@/hooks/useScreenWakeLock';
+import { setSystemUIVisibility } from '@/utils/bridge';
import { AboutWindow } from '@/components/AboutWindow';
import { UpdaterWindow } from '@/components/UpdaterWindow';
import { Toast } from '@/components/Toast';
@@ -19,16 +21,16 @@ import ReaderContent from './ReaderContent';
const Reader: React.FC<{ ids?: string }> = ({ ids }) => {
const { envConfig, appService } = useEnv();
const { settings, setSettings } = useSettingsStore();
+ const { isDarkMode } = useThemeStore();
+ const { hoveredBookKey, showSystemUI, dismissSystemUI } = useReaderStore();
const { isSideBarVisible } = useSidebarStore();
const { getVisibleLibrary, setLibrary } = useLibraryStore();
const isInitiating = useRef(false);
- const { updateAppTheme } = useThemeStore();
- useTheme();
+ useTheme({ systemUIVisible: false, appThemeColor: 'base-100' });
useScreenWakeLock(settings.screenWakeLock);
useEffect(() => {
- updateAppTheme('base-100');
if (isInitiating.current) return;
isInitiating.current = true;
const initLibrary = async () => {
@@ -42,6 +44,18 @@ const Reader: React.FC<{ ids?: string }> = ({ ids }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
+ useEffect(() => {
+ if (!appService?.isMobile) return;
+ const systemUIVisible = !!hoveredBookKey;
+ setSystemUIVisibility({ visible: systemUIVisible, darkMode: isDarkMode });
+ if (systemUIVisible) {
+ showSystemUI();
+ } else {
+ dismissSystemUI();
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [hoveredBookKey]);
+
return (
getVisibleLibrary().length > 0 &&
settings.globalReadSettings && (
diff --git a/apps/readest-app/src/app/updater/page.tsx b/apps/readest-app/src/app/updater/page.tsx
index c36914b2..31a868d3 100644
--- a/apps/readest-app/src/app/updater/page.tsx
+++ b/apps/readest-app/src/app/updater/page.tsx
@@ -1,10 +1,13 @@
'use client';
import { Suspense } from 'react';
-import Spinner from '@/components/Spinner';
import { UpdaterContent } from '@/components/UpdaterWindow';
+import { useTheme } from '@/hooks/useTheme';
+import Spinner from '@/components/Spinner';
const UpdaterPage = () => {
+ useTheme();
+
return (
{
const headerRef = useRef(null);
- useTheme();
+ useTheme({ systemUIVisible: false });
useEffect(() => {
if (!user || !token) return;
diff --git a/apps/readest-app/src/components/UpdaterWindow.tsx b/apps/readest-app/src/components/UpdaterWindow.tsx
index 280f36bc..6869de40 100644
--- a/apps/readest-app/src/components/UpdaterWindow.tsx
+++ b/apps/readest-app/src/components/UpdaterWindow.tsx
@@ -9,7 +9,6 @@ import { relaunch } from '@tauri-apps/plugin-process';
import { fetch } from '@tauri-apps/plugin-http';
import { useTranslation } from '@/hooks/useTranslation';
import { useSearchParams } from 'next/navigation';
-import { useTheme } from '@/hooks/useTheme';
import { tauriDownload } from '@/utils/transfer';
import { READEST_UPDATER_FILE, READEST_CHANGELOG_FILE } from '@/services/constants';
import packageJson from '../../package.json';
@@ -201,8 +200,6 @@ export const UpdaterContent = ({ version }: { version?: string }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [update]);
- useTheme();
-
useEffect(() => {
setIsMounted(true);
}, []);
diff --git a/apps/readest-app/src/hooks/usePullToRefresh.ts b/apps/readest-app/src/hooks/usePullToRefresh.ts
index 50376693..b09099ac 100644
--- a/apps/readest-app/src/hooks/usePullToRefresh.ts
+++ b/apps/readest-app/src/hooks/usePullToRefresh.ts
@@ -62,7 +62,10 @@ export const usePullToRefresh = (ref: React.RefObject, onTrigger
return;
}
+ const headerbar = document.querySelector('.titlebar');
const pullIndicator = document.createElement('div');
+ const headerBottom = headerbar?.getBoundingClientRect().bottom || 0;
+ pullIndicator.style.top = `${headerBottom + 20}px`;
pullIndicator.className = 'pull-indicator text-gray-500';
pullIndicator.innerHTML = `