fix(core): stabilize runtime status and separate service readiness

This commit is contained in:
lzt404 committed 2026-09-19 00:36:18 +08:00
1 parent e9805b395d
commit 9ff9a6c317
11 files changed
+82 -20

No files matched your search

+6 -6
View File
@@ -135,7 +135,7 @@ function AppContent() {
const languageMenuRef = useRef<HTMLDivElement>(null);
const languageButtonRef = useRef<HTMLButtonElement>(null);
const { status } = useCoreRuntime();
const coreRunning = Boolean(status?.running);
const coreReady = Boolean(status?.ready);
const activePage = pages.find((page) => page.id === active) ?? pages[0];
const ActivePage = activePage.component;
const selectedLanguage = languageOptions.find((option) => option.value === locale)
@@ -149,10 +149,10 @@ function AppContent() {
: '',
].filter(Boolean).join(' · ');
useEffect(() => {
if (!canOpenAppPage(active, coreRunning)) {
if (!canOpenAppPage(active, coreReady)) {
setActive('home');
}
}, [active, coreRunning]);
}, [active, coreReady]);
useEffect(() => {
if (!languageMenuOpen) return undefined;
@@ -230,7 +230,7 @@ function AppContent() {
}, [windowsClosePrompt]);
const select = (pageId: PageId) => {
if (!canOpenAppPage(pageId, coreRunning)) {
if (!canOpenAppPage(pageId, coreReady)) {
return;
}
setActive(pageId);
@@ -294,7 +294,7 @@ function AppContent() {
<nav className="nav-section" aria-label={t('app.navigation')}>
{pages.filter((page) => page.id !== 'easy').map((page) => {
const Icon = page.icon;
const locked = !canOpenAppPage(page.id, coreRunning);
const locked = !canOpenAppPage(page.id, coreReady);
const updateIndicator = page.id === 'versions'
? appUpdateIndicatorState(hasUpdate, coreHasUpdate, appUpdateProcessing)
: null;
@@ -437,7 +437,7 @@ function AppContent() {
<div className="workspace">
<main className="content">
{isAlwaysAvailablePage(activePage.id) || coreRunning ? (
{isAlwaysAvailablePage(activePage.id) || coreReady ? (
activePage.id === 'easy' ? (
<EasyModePage
onExit={() => select('home')}
+1
View File
@@ -5,6 +5,7 @@ import { listen } from '@tauri-apps/api/event';
export type CoreStatus = {
installed: boolean;
running: boolean;
ready: boolean;
starting: boolean;
managed: boolean;
processId: number | null;
+2 -2
View File
@@ -4,6 +4,6 @@ export function isAlwaysAvailablePage(pageId: string) {
return alwaysAvailablePages.has(pageId);
}
export function canOpenAppPage(pageId: string, coreRunning: boolean) {
return coreRunning || isAlwaysAvailablePage(pageId);
export function canOpenAppPage(pageId: string, coreReady: boolean) {
return coreReady || isAlwaysAvailablePage(pageId);
}
+3 -2
View File
@@ -180,6 +180,7 @@ export function KernelPage({ view = 'home' }: { view?: KernelView }) {
const currentVersion = coreStatus?.currentVersion ?? '';
const coreInstalled = Boolean(coreStatus?.installed);
const coreRunning = Boolean(coreStatus?.running);
const coreReady = Boolean(coreStatus?.ready);
const coreProcessBusy = processBusy || Boolean(coreStatus?.starting);
const statusTone = statusError ? 'error' : coreRunning ? 'success' : 'neutral';
@@ -326,8 +327,8 @@ export function KernelPage({ view = 'home' }: { view?: KernelView }) {
)}
</div>
</div>
<span className={`state-pill ${coreRunning ? 'success' : 'neutral'}`}>
{coreRunning ? t('kernel.access.connectable') : t('kernel.access.waiting')}
<span className={`state-pill ${coreReady ? 'success' : 'neutral'}`}>
{coreReady ? t('kernel.access.connectable') : t('kernel.access.waiting')}
</span>
</div>
+4 -1
View File
@@ -465,7 +465,10 @@ export function UsageRecordsPage() {
let disposed = false;
let unlisten: (() => void) | null = null;
const refresh = () => {
if (!disposed && !document.hidden) void loadData(true, true);
// WebView2 may classify an unfocused or occluded window on another monitor
// as hidden. Keep usage refreshes independent of Page Visibility so both
// record events and the fallback poll continue to update the current view.
if (!disposed) void loadData(true, true);
};
listen('usage-records-updated', refresh)
.then((stop) => {