refactor: scope providers by route and use XState selectors

This commit is contained in:
2026-07-13 19:07:53 +08:00
parent f9b5f22ee9
commit 37ae152abb
24 changed files with 512 additions and 336 deletions
+13 -2
View File
@@ -2,13 +2,24 @@
import { useEffect } from "react";
import { usePathname, useRouter } from "next/navigation";
import { shallowEqual } from "@xstate/react";
import { useAuthState } from "@/stores/auth/auth-context";
import {
selectAuthIsLoading,
useAuthSelector,
} from "@/stores/auth/auth-context";
import { resolveRouteGuardRedirect } from "./navigation-resolver";
export function AppNavigationGuard() {
const authState = useAuthState();
const authState = useAuthSelector(
(state) => ({
hasInitialized: state.context.hasInitialized,
isLoading: selectAuthIsLoading(state),
loginStatus: state.context.loginStatus,
}),
shallowEqual,
);
const pathname = usePathname();
const router = useRouter();
+11 -9
View File
@@ -10,8 +10,8 @@ import {
peekSubscriptionExplicitExitUrl,
} from "@/lib/navigation/subscription_exit";
import { getDefaultPayChannelForCountryCode } from "@/lib/payment/default_pay_channel";
import { useAuthState } from "@/stores/auth/auth-context";
import { useUserState } from "@/stores/user/user-context";
import { useAuthSelector } from "@/stores/auth/auth-context";
import { useUserSelector } from "@/stores/user/user-context";
import {
ROUTE_BUILDERS,
@@ -47,9 +47,11 @@ export interface AppNavigator {
export function useAppNavigator(): AppNavigator {
const router = useRouter();
const authState = useAuthState();
const userState = useUserState();
const isAuthenticatedUser = resolveIsAuthenticatedUser(authState.loginStatus);
const loginStatus = useAuthSelector((state) => state.context.loginStatus);
const countryCode = useUserSelector(
(state) => state.context.currentUser?.countryCode,
);
const isAuthenticatedUser = resolveIsAuthenticatedUser(loginStatus);
const push = useCallback((href: string, options?: { scroll?: boolean }): void => {
router.push(href, options);
@@ -77,8 +79,8 @@ export function useAppNavigator(): AppNavigator {
}, [router]);
const getDefaultPayChannel = useCallback(() => {
return getDefaultPayChannelForCountryCode(userState.currentUser?.countryCode);
}, [userState.currentUser?.countryCode]);
return getDefaultPayChannelForCountryCode(countryCode);
}, [countryCode]);
const openSubscription = useCallback(
({
@@ -93,7 +95,7 @@ export function useAppNavigator(): AppNavigator {
});
const nextUrl = resolveAuthenticatedNavigation({
loginStatus: authState.loginStatus,
loginStatus,
targetUrl: target,
});
@@ -103,7 +105,7 @@ export function useAppNavigator(): AppNavigator {
}
router.push(nextUrl);
},
[authState.loginStatus, getDefaultPayChannel, router],
[getDefaultPayChannel, loginStatus, router],
);
const startMessageUnlock = useCallback(