fix(core): stabilize runtime status and separate service readiness
This commit is contained in:
1 parent
e9805b395d
commit
9ff9a6c317
11 files changed
+82
-20
No files matched your search
+6
-6
@@ -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')}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in new issue
Block a user