Files
agent-desktop/console/src/tauri/BackendReadyGate.tsx
T
Pine 123ba0d0fa feat: 桌面端认证/通信/tauri 后端更新 + README
- auth/jwt/header 认证流程更新,会话与令牌处理增强
- 通信(ChatWindow/ConversationList/Network)更新
- tauri backend.rs/remote.rs、tauri.conf.json 更新
- pineagents app 路由(agent_gate/opc)与配置更新
2026-09-11 21:17:48 +08:00

65 lines
2.0 KiB
TypeScript

import { type ReactNode, useCallback, useEffect, useRef } from "react";
import BackendLoadingPage from "./BackendLoadingPage";
import useBackendReadyPolling from "./useBackendReadyPolling";
import { withCacheBuster, withDesktopMarker } from "./backendRuntime";
interface Props {
children: ReactNode;
}
export default function BackendReadyGate({ children }: Props) {
const {
shouldGate,
status,
elapsed,
totalSec,
errorMessage,
readyUrl,
retry,
} = useBackendReadyPolling();
const navigateFiredRef = useRef(false);
// 进度条走到100%后的回调:延迟跳转,避免黑屏
const handleProgressComplete = useCallback(() => {
if (navigateFiredRef.current) return;
if (!shouldGate || status !== "ready" || !readyUrl) return;
navigateFiredRef.current = true;
// 再等待短暂时间,让用户看到100%的完成状态,然后跳转
setTimeout(() => {
window.location.replace(withCacheBuster(withDesktopMarker(readyUrl)));
}, 200);
}, [readyUrl, shouldGate, status]);
// 备用:如果进度回调没有触发(比如组件被强制卸载),仍然要跳转
useEffect(() => {
if (shouldGate && status === "ready" && readyUrl && !navigateFiredRef.current) {
// 设置一个最大等待时间,确保即使进度回调失败也能跳转
const fallbackTimer = setTimeout(() => {
if (!navigateFiredRef.current) {
navigateFiredRef.current = true;
window.location.replace(withCacheBuster(withDesktopMarker(readyUrl)));
}
}, 2000); // 最多等待2秒
return () => clearTimeout(fallbackTimer);
}
}, [readyUrl, shouldGate, status]);
// Browser mode, or Tauri after it has navigated to the backend-hosted console.
if (!shouldGate) {
return <>{children}</>;
}
return (
<BackendLoadingPage
status={status}
elapsed={elapsed}
totalSec={totalSec}
errorMessage={errorMessage}
onRetry={retry}
onProgressComplete={handleProgressComplete}
/>
);
}