fix(splash): reuse latest chat message preview

This commit is contained in:
2026-07-14 11:28:23 +08:00
parent b4904e738b
commit f9c15bd91f
13 changed files with 389 additions and 18 deletions
+10 -7
View File
@@ -3,12 +3,13 @@
/**
* 根级 Client Providers 包装
*
* 这里只保留跨路由的 Auth、User 和 viewport Provider。Chat、Payment、
* PrivateRoom 状态机由对应路由 layout 按需挂载。
* 这里只保留跨路由的 Auth、User、消息预览和 viewport Provider。Chat、
* Payment、PrivateRoom 状态机由对应路由 layout 按需挂载。
*/
import type { ReactNode } from "react";
import { SplashLatestMessageProvider } from "@/providers/splash-latest-message-provider";
import { ViewportCssVarsProvider } from "@/providers/viewport-css-vars-provider";
import { AppNavigationGuard } from "@/router/app-navigation-guard";
import { AuthProvider } from "@/stores/auth/auth-context";
@@ -28,11 +29,13 @@ export function RootProviders({ children }: RootProvidersProps) {
<AuthStatusChecker />
<OAuthSessionSync />
<AppNavigationGuard />
<UserProvider>
<UserAuthSync />
{children}
<div id="toast-portal" />
</UserProvider>
<SplashLatestMessageProvider>
<UserProvider>
<UserAuthSync />
{children}
<div id="toast-portal" />
</UserProvider>
</SplashLatestMessageProvider>
</AuthProvider>
</ViewportCssVarsProvider>
);
@@ -0,0 +1,73 @@
"use client";
import {
createContext,
type ReactNode,
useContext,
useEffect,
useRef,
useState,
} from "react";
import {
createSplashLatestMessageCache,
type SplashLatestMessageCache,
} from "@/lib/chat/splash_latest_message_cache";
import { useAuthState } from "@/stores/auth/auth-context";
const SplashLatestMessageCacheContext =
createContext<SplashLatestMessageCache | null>(null);
export function SplashLatestMessageProvider({
children,
}: {
children: ReactNode;
}) {
const [cache] = useState(createSplashLatestMessageCache);
return (
<SplashLatestMessageCacheContext.Provider value={cache}>
<SplashLatestMessageAuthSync cache={cache} />
{children}
</SplashLatestMessageCacheContext.Provider>
);
}
export function useSplashLatestMessageCache(): SplashLatestMessageCache {
const cache = useContext(SplashLatestMessageCacheContext);
if (!cache) {
throw new Error(
"useSplashLatestMessageCache must be used within SplashLatestMessageProvider.",
);
}
return cache;
}
function SplashLatestMessageAuthSync({
cache,
}: {
cache: SplashLatestMessageCache;
}) {
const authState = useAuthState();
const previousLoginStatusRef = useRef<string | null>(null);
useEffect(() => {
if (!authState.hasInitialized || authState.isLoading) return;
const previousLoginStatus = previousLoginStatusRef.current;
if (
previousLoginStatus !== null &&
previousLoginStatus !== authState.loginStatus
) {
cache.clear();
}
previousLoginStatusRef.current = authState.loginStatus;
}, [
authState.hasInitialized,
authState.isLoading,
authState.loginStatus,
cache,
]);
return null;
}