77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
import {
|
|
DEFAULT_CHARACTER,
|
|
getCharacterBySlug,
|
|
type CharacterProfile,
|
|
} from "@/data/constants/character";
|
|
|
|
import { getCharacterRoutes, ROUTES } from "./routes";
|
|
|
|
export const GLOBAL_RETURN_TO_PARAM = "returnTo";
|
|
|
|
export type GlobalPageRoute =
|
|
| typeof ROUTES.sidebar
|
|
| typeof ROUTES.feedback
|
|
| typeof ROUTES.coinsRules;
|
|
|
|
export interface GlobalRouteContext {
|
|
readonly characterSlug: CharacterProfile["slug"];
|
|
readonly chatUrl: string;
|
|
readonly splashUrl: string;
|
|
readonly sidebarUrl: string;
|
|
readonly feedbackUrl: string;
|
|
readonly coinsRulesUrl: string;
|
|
}
|
|
|
|
export type GlobalReturnToValue =
|
|
| string
|
|
| readonly string[]
|
|
| null
|
|
| undefined;
|
|
|
|
export function resolveGlobalRouteContext(
|
|
value?: GlobalReturnToValue,
|
|
): GlobalRouteContext {
|
|
const character = resolveReturnCharacter(getFirstValue(value));
|
|
const characterRoutes = getCharacterRoutes(character.slug);
|
|
const chatUrl = characterRoutes.chat;
|
|
|
|
return Object.freeze({
|
|
characterSlug: character.slug,
|
|
chatUrl,
|
|
splashUrl: characterRoutes.splash,
|
|
sidebarUrl: buildGlobalPageUrl(ROUTES.sidebar, chatUrl),
|
|
feedbackUrl: buildGlobalPageUrl(ROUTES.feedback, chatUrl),
|
|
coinsRulesUrl: buildGlobalPageUrl(ROUTES.coinsRules, chatUrl),
|
|
});
|
|
}
|
|
|
|
export function buildGlobalPageUrl(
|
|
route: GlobalPageRoute,
|
|
returnTo: string,
|
|
): string {
|
|
const safeReturnTo = resolveGlobalRouteContextValue(returnTo);
|
|
const params = new URLSearchParams({
|
|
[GLOBAL_RETURN_TO_PARAM]: safeReturnTo,
|
|
});
|
|
return `${route}?${params.toString()}`;
|
|
}
|
|
|
|
export function resolveGlobalRouteContextValue(
|
|
value?: GlobalReturnToValue,
|
|
): string {
|
|
const character = resolveReturnCharacter(getFirstValue(value));
|
|
return getCharacterRoutes(character.slug).chat;
|
|
}
|
|
|
|
function resolveReturnCharacter(value: string | null): CharacterProfile {
|
|
const match = value?.match(/^\/characters\/([^/?#]+)\/chat$/);
|
|
if (!match?.[1]) return DEFAULT_CHARACTER;
|
|
return getCharacterBySlug(match[1]) ?? DEFAULT_CHARACTER;
|
|
}
|
|
|
|
function getFirstValue(value: GlobalReturnToValue): string | null {
|
|
if (typeof value === "string") return value;
|
|
if (Array.isArray(value)) return value[0] ?? null;
|
|
return null;
|
|
}
|