141 lines
3.5 KiB
TypeScript
141 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import { useRouter } from "next/navigation";
|
|
|
|
import { NavigationStorage } from "@/data/storage/navigation";
|
|
import { getDefaultPayChannelForCountryCode } from "@/lib/payment/default_pay_channel";
|
|
import { useAuthState } from "@/stores/auth/auth-context";
|
|
import { useUserState } from "@/stores/user/user-context";
|
|
|
|
import {
|
|
ROUTE_BUILDERS,
|
|
ROUTES,
|
|
type Route,
|
|
} from "./routes";
|
|
import {
|
|
isAuthenticatedUser as resolveIsAuthenticatedUser,
|
|
resolveAuthenticatedNavigation,
|
|
} from "./navigation-resolver";
|
|
import type {
|
|
OpenSubscriptionForPendingUnlockInput,
|
|
OpenSubscriptionInput,
|
|
StartMessageUnlockInput,
|
|
} from "./navigation-types";
|
|
|
|
export interface AppNavigator {
|
|
push: (href: string, options?: { scroll?: boolean }) => void;
|
|
replace: (href: string, options?: { scroll?: boolean }) => void;
|
|
openAuth: (redirectTo?: string) => void;
|
|
openSubscription: (input: OpenSubscriptionInput) => void;
|
|
startMessageUnlock: (input: StartMessageUnlockInput) => void;
|
|
openSubscriptionForPendingUnlock: (
|
|
input: OpenSubscriptionForPendingUnlockInput,
|
|
) => void;
|
|
getDefaultPayChannel: () => ReturnType<typeof getDefaultPayChannelForCountryCode>;
|
|
isAuthenticatedUser: boolean;
|
|
}
|
|
|
|
export function useAppNavigator(): AppNavigator {
|
|
const router = useRouter();
|
|
const authState = useAuthState();
|
|
const userState = useUserState();
|
|
const isAuthenticatedUser = resolveIsAuthenticatedUser(authState.loginStatus);
|
|
|
|
function push(href: string, options?: { scroll?: boolean }): void {
|
|
router.push(href, options);
|
|
}
|
|
|
|
function replace(href: string, options?: { scroll?: boolean }): void {
|
|
router.replace(href, options);
|
|
}
|
|
|
|
function openAuth(redirectTo: string = ROUTES.chat): void {
|
|
router.push(ROUTE_BUILDERS.authWithRedirect(redirectTo));
|
|
}
|
|
|
|
function getDefaultPayChannel() {
|
|
return getDefaultPayChannelForCountryCode(userState.currentUser?.countryCode);
|
|
}
|
|
|
|
function openSubscription({
|
|
type,
|
|
payChannel = getDefaultPayChannel(),
|
|
returnTo = null,
|
|
replace: shouldReplace = false,
|
|
}: OpenSubscriptionInput): void {
|
|
const target = ROUTE_BUILDERS.subscription(type, {
|
|
payChannel,
|
|
returnTo: returnTo ?? undefined,
|
|
});
|
|
|
|
const nextUrl = resolveAuthenticatedNavigation({
|
|
loginStatus: authState.loginStatus,
|
|
targetUrl: target,
|
|
});
|
|
|
|
if (shouldReplace) {
|
|
router.replace(nextUrl);
|
|
return;
|
|
}
|
|
router.push(nextUrl);
|
|
}
|
|
|
|
function startMessageUnlock({
|
|
messageId,
|
|
kind,
|
|
returnUrl,
|
|
stage = "auth",
|
|
onAuthenticated,
|
|
}: StartMessageUnlockInput): void {
|
|
if (isAuthenticatedUser) {
|
|
onAuthenticated();
|
|
return;
|
|
}
|
|
|
|
void (async () => {
|
|
await NavigationStorage.savePendingChatUnlock({
|
|
messageId,
|
|
kind,
|
|
returnUrl,
|
|
stage,
|
|
});
|
|
router.push(ROUTE_BUILDERS.authWithRedirect(returnUrl));
|
|
})();
|
|
}
|
|
|
|
function openSubscriptionForPendingUnlock({
|
|
messageId,
|
|
kind,
|
|
returnUrl,
|
|
type,
|
|
payChannel = getDefaultPayChannel(),
|
|
}: OpenSubscriptionForPendingUnlockInput): void {
|
|
void (async () => {
|
|
await NavigationStorage.savePendingChatUnlock({
|
|
messageId,
|
|
kind,
|
|
returnUrl,
|
|
stage: "payment",
|
|
});
|
|
openSubscription({
|
|
type,
|
|
payChannel,
|
|
returnTo: "chat",
|
|
});
|
|
})();
|
|
}
|
|
|
|
return {
|
|
push,
|
|
replace,
|
|
openAuth,
|
|
openSubscription,
|
|
startMessageUnlock,
|
|
openSubscriptionForPendingUnlock,
|
|
getDefaultPayChannel,
|
|
isAuthenticatedUser,
|
|
};
|
|
}
|
|
|
|
export type { Route };
|