fix(chat): redirect guests to auth before image paywall
This commit is contained in:
@@ -17,10 +17,15 @@ import { Logger } from "@/utils";
|
|||||||
|
|
||||||
const log = new Logger("AppAuthAuthScreen");
|
const log = new Logger("AppAuthAuthScreen");
|
||||||
|
|
||||||
export function AuthScreen() {
|
export interface AuthScreenProps {
|
||||||
|
redirectTo?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AuthScreen({ redirectTo = null }: AuthScreenProps) {
|
||||||
const state = useAuthState();
|
const state = useAuthState();
|
||||||
const authDispatch = useAuthDispatch();
|
const authDispatch = useAuthDispatch();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const safeRedirectTo = getSafeRedirectPath(redirectTo) ?? ROUTES.chat;
|
||||||
|
|
||||||
// 邮箱登录成功 → 跳转;User hydrate 由根级 <UserAuthSync /> 监听 loginStatus 变化处理。
|
// 邮箱登录成功 → 跳转;User hydrate 由根级 <UserAuthSync /> 监听 loginStatus 变化处理。
|
||||||
// 用 pendingRedirect flag(不是 useRef transition detection)——
|
// 用 pendingRedirect flag(不是 useRef transition detection)——
|
||||||
@@ -34,13 +39,19 @@ export function AuthScreen() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (state.pendingRedirect && state.loginStatus !== "notLoggedIn") {
|
if (state.pendingRedirect && state.loginStatus !== "notLoggedIn") {
|
||||||
log.debug(
|
log.debug("[auth-screen] useEffect → router.replace [via pendingRedirect flag]", {
|
||||||
"[auth-screen] useEffect → router.replace(/chat) [via pendingRedirect flag]",
|
redirectTo: safeRedirectTo,
|
||||||
);
|
});
|
||||||
authDispatch({ type: "AuthClearPendingRedirect" });
|
authDispatch({ type: "AuthClearPendingRedirect" });
|
||||||
router.replace(ROUTES.chat);
|
router.replace(safeRedirectTo);
|
||||||
}
|
}
|
||||||
}, [state.loginStatus, state.pendingRedirect, authDispatch, router]);
|
}, [
|
||||||
|
state.loginStatus,
|
||||||
|
state.pendingRedirect,
|
||||||
|
authDispatch,
|
||||||
|
router,
|
||||||
|
safeRedirectTo,
|
||||||
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MobileShell>
|
<MobileShell>
|
||||||
@@ -53,3 +64,9 @@ export function AuthScreen() {
|
|||||||
</MobileShell>
|
</MobileShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSafeRedirectPath(redirectTo: string | null | undefined): string | null {
|
||||||
|
if (!redirectTo) return null;
|
||||||
|
if (!redirectTo.startsWith("/") || redirectTo.startsWith("//")) return null;
|
||||||
|
return redirectTo;
|
||||||
|
}
|
||||||
|
|||||||
+13
-4
@@ -1,7 +1,16 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { AuthScreen } from "@/app/auth/auth-screen";
|
import { AuthScreen } from "@/app/auth/auth-screen";
|
||||||
|
|
||||||
export default function AuthPage() {
|
interface AuthPageProps {
|
||||||
return <AuthScreen />;
|
searchParams: Promise<{
|
||||||
|
redirect?: string | string[];
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function AuthPage({ searchParams }: AuthPageProps) {
|
||||||
|
const params = await searchParams;
|
||||||
|
const redirectTo = Array.isArray(params.redirect)
|
||||||
|
? params.redirect[0]
|
||||||
|
: params.redirect;
|
||||||
|
|
||||||
|
return <AuthScreen redirectTo={redirectTo ?? null} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,12 @@ export function ChatScreen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleUnlockImagePaywall(): void {
|
function handleUnlockImagePaywall(): void {
|
||||||
router.push(`${ROUTES.subscription}?type=vip`);
|
const subscriptionUrl = ROUTE_BUILDERS.subscription("vip");
|
||||||
|
if (isGuest) {
|
||||||
|
router.push(ROUTE_BUILDERS.authWithRedirect(subscriptionUrl));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
router.push(subscriptionUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMessageLimitUnlock(): void {
|
function handleMessageLimitUnlock(): void {
|
||||||
@@ -141,7 +146,7 @@ export function ChatScreen() {
|
|||||||
router.push(ROUTES.auth);
|
router.push(ROUTES.auth);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.push(`${ROUTES.subscription}?type=vip`);
|
router.push(ROUTE_BUILDERS.subscription("vip"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ export type StaticRoute = (typeof ROUTES)[keyof typeof ROUTES];
|
|||||||
export const ROUTE_BUILDERS = {
|
export const ROUTE_BUILDERS = {
|
||||||
chatDeviceId: (deviceId: string): `/chat/deviceid/${string}` =>
|
chatDeviceId: (deviceId: string): `/chat/deviceid/${string}` =>
|
||||||
`/chat/deviceid/${encodeURIComponent(deviceId)}` as const,
|
`/chat/deviceid/${encodeURIComponent(deviceId)}` as const,
|
||||||
|
subscription: (type: "vip" | "voice"): `/subscription?type=${string}` =>
|
||||||
|
`${ROUTES.subscription}?type=${encodeURIComponent(type)}` as const,
|
||||||
|
authWithRedirect: (redirectTo: string): `/auth?redirect=${string}` =>
|
||||||
|
`${ROUTES.auth}?redirect=${encodeURIComponent(redirectTo)}` as const,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
/** 仅未登录态可见的路由(命中后已登录用户应跳走) */
|
/** 仅未登录态可见的路由(命中后已登录用户应跳走) */
|
||||||
|
|||||||
Reference in New Issue
Block a user