83 lines
2.6 KiB
TypeScript
83 lines
2.6 KiB
TypeScript
"use client";
|
|
/**
|
|
* Auth 屏
|
|
*
|
|
*
|
|
*/
|
|
import { useEffect, useSyncExternalStore } from "react";
|
|
|
|
import { MobileShell } from "@/app/_components/core";
|
|
import { useAuthState } from "@/stores/auth/auth-context";
|
|
import { isAuthenticatedUser } from "@/router/navigation-resolver";
|
|
import { ROUTES } from "@/router/routes";
|
|
import { useAppNavigator } from "@/router/use-app-navigator";
|
|
|
|
import { AuthBackground, AuthPanel } from "./components";
|
|
import { Logger } from "@/utils/logger";
|
|
|
|
const log = new Logger("AppAuthAuthScreen");
|
|
|
|
export function AuthScreen() {
|
|
const state = useAuthState();
|
|
const navigator = useAppNavigator();
|
|
const redirectTo = useSyncExternalStore(
|
|
subscribeLocationSnapshot,
|
|
readRedirectFromLocation,
|
|
() => null,
|
|
);
|
|
const safeRedirectTo = getSafeRedirectPath(redirectTo) ?? ROUTES.chat;
|
|
|
|
// 真实用户登录成功 → 跳转;User hydrate 由根级 <UserAuthSync /> 监听 loginStatus 变化处理。
|
|
// 游客态不触发跳转,避免自动游客登录打断 auth 页面。
|
|
useEffect(() => {
|
|
const shouldRedirect = isAuthenticatedUser(state.loginStatus);
|
|
log.debug("[auth-screen] useEffect (loginStatus)", {
|
|
loginStatus: state.loginStatus,
|
|
willRedirect: shouldRedirect,
|
|
});
|
|
|
|
if (shouldRedirect) {
|
|
log.debug("[auth-screen] useEffect → navigator.replace", {
|
|
redirectTo: safeRedirectTo,
|
|
});
|
|
navigator.replace(safeRedirectTo);
|
|
}
|
|
}, [
|
|
state.loginStatus,
|
|
navigator,
|
|
safeRedirectTo,
|
|
]);
|
|
|
|
return (
|
|
<MobileShell>
|
|
<div className="relative flex min-h-(--app-viewport-height,100dvh) w-full flex-1 flex-col overflow-hidden bg-[#fbf1f2]">
|
|
<AuthBackground />
|
|
<div
|
|
className="relative z-2 flex flex-auto flex-col justify-center"
|
|
style={{
|
|
padding:
|
|
"calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-top, 0px)) calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-right, 0px)) calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-bottom, 0px)) calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-left, 0px))",
|
|
}}
|
|
>
|
|
<AuthPanel />
|
|
</div>
|
|
</div>
|
|
</MobileShell>
|
|
);
|
|
}
|
|
|
|
function getSafeRedirectPath(redirectTo: string | null | undefined): string | null {
|
|
if (!redirectTo) return null;
|
|
if (!redirectTo.startsWith("/") || redirectTo.startsWith("//")) return null;
|
|
return redirectTo;
|
|
}
|
|
|
|
function readRedirectFromLocation(): string | null {
|
|
if (typeof window === "undefined") return null;
|
|
return new URLSearchParams(window.location.search).get("redirect");
|
|
}
|
|
|
|
function subscribeLocationSnapshot(): () => void {
|
|
return () => {};
|
|
}
|