fix(logs): preserve log data and eliminate blank flash on page navigation

Preserve SWR cache in onConnected to avoid replacing accumulated logs
with kernel buffer on reconnect. Add KeepAlive for the logs page so
its DOM stays mounted across route changes, removing the visible blank
window when navigating back.
This commit is contained in:
Tunglies 2026-04-03 13:13:57 +08:00
parent 51578c03b0
commit 36624aff49
No known key found for this signature in database
GPG Key ID: B9B01B389469B3E8
3 changed files with 27 additions and 4 deletions

View File

@ -101,7 +101,12 @@ export const useLogData = () => {
async onConnected() {
const logs = await getClashLogs()
if (isMounted()) {
next(null, clampLogs(filterLogsByLevel(logs, allowedTypes)))
next(null, (current) => {
if (!current || current.length === 0) {
return clampLogs(filterLogsByLevel(logs, allowedTypes))
}
return current
})
}
},
cleanup: clearFlushTimer,

View File

@ -26,7 +26,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'
import type { CSSProperties } from 'react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Outlet, useNavigate } from 'react-router'
import { Outlet, useLocation, useNavigate } from 'react-router'
import { SWRConfig } from 'swr'
import iconDark from '@/assets/image/icon_dark.svg?react'
@ -53,6 +53,7 @@ import {
} from './_layout/hooks'
import { handleNoticeMessage } from './_layout/utils'
import { navItems } from './_routers'
import LogsPage from './logs'
import 'dayjs/locale/ru'
import 'dayjs/locale/zh-cn'
@ -120,6 +121,10 @@ const Layout = () => {
const navCollapsed = verge?.collapse_navbar ?? false
const { switchLanguage } = useI18n()
const navigate = useNavigate()
const { pathname } = useLocation()
const isLogsPage = pathname === '/logs'
const logsPageMountedRef = useRef(false)
if (isLogsPage) logsPageMountedRef.current = true
const themeReady = useMemo(() => Boolean(theme), [theme])
const [menuUnlocked, setMenuUnlocked] = useState(false)
@ -477,6 +482,20 @@ const Layout = () => {
<BaseErrorBoundary>
<Outlet />
</BaseErrorBoundary>
{logsPageMountedRef.current && (
<div
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
display: isLogsPage ? undefined : 'none',
}}
>
<LogsPage />
</div>
)}
</div>
</div>
</div>

View File

@ -20,7 +20,6 @@ import UnlockSvg from '@/assets/image/itemicon/unlock.svg?react'
import Layout from './_layout'
import ConnectionsPage from './connections'
import HomePage from './home'
import LogsPage from './logs'
import ProfilesPage from './profiles'
import ProxiesPage from './proxies'
import RulesPage from './rules'
@ -62,7 +61,7 @@ export const navItems = [
label: 'layout.components.navigation.tabs.logs',
path: '/logs',
icon: [<SubjectRoundedIcon key="mui" />, <LogsSvg key="svg" />],
Component: LogsPage,
Component: () => null /* KeepAlive: real LogsPage rendered in Layout */,
},
{
label: 'layout.components.navigation.tabs.unlock',