/* eslint-disable react-refresh/only-export-components */ import { type ComponentType, lazy, type LazyExoticComponent } from 'react'; import type { PresetEditorTab } from '../components/PresetEditor'; type AppRouteComponent = LazyExoticComponent< ComponentType> >; export type AppRouteMatch = | { kind: 'game'; } | { kind: 'preset-editor'; initialTab: PresetEditorTab; } | { kind: 'qwen-sprite-tool'; }; export type ResolvedAppRoute = { kind: AppRouteMatch['kind']; loadingEyebrow: string; loadingText: string; Component: AppRouteComponent; componentProps?: Record; }; const GameApp = lazy(() => import('../App')) as AppRouteComponent; const PresetEditorApp = lazy(async () => { const module = await import('../components/PresetEditor'); return { default: module.PresetEditor, }; }) as AppRouteComponent; const QwenSpriteToolApp = lazy( () => import('../tools/QwenSpriteSheetTool'), ) as AppRouteComponent; const PRESET_EDITOR_ROUTES: Array<{ prefixes: string[]; initialTab: PresetEditorTab; }> = [ { prefixes: ['/character-asset-studio', '/asset-studio'], initialTab: 'assets', }, { prefixes: ['/function-editor', '/behavior-editor'], initialTab: 'functions', }, { prefixes: ['/item-editor'], initialTab: 'items', }, { prefixes: ['/npc-editor'], initialTab: 'npcs', }, { prefixes: ['/preset-editor'], initialTab: 'characters', }, ]; const QWEN_SPRITE_TOOL_PREFIXES = [ '/qwen-sprite-tool', '/sprite-tool', '/pixelmotion-qwen', ]; function normalizeRoutePath(pathname: string) { const trimmedPathname = pathname.trim().toLowerCase(); if (!trimmedPathname || trimmedPathname === '/') { return '/'; } return trimmedPathname.replace(/\/+$/u, ''); } function matchesRoutePrefix(pathname: string, prefix: string) { const normalizedPrefix = normalizeRoutePath(prefix); return ( pathname === normalizedPrefix || pathname.startsWith(`${normalizedPrefix}/`) ); } export function matchAppRoute(pathname: string): AppRouteMatch { const normalizedPathname = normalizeRoutePath(pathname); const isQwenSpriteToolRoute = QWEN_SPRITE_TOOL_PREFIXES.some((prefix) => matchesRoutePrefix(normalizedPathname, prefix), ); if (isQwenSpriteToolRoute) { return { kind: 'qwen-sprite-tool', }; } const presetRoute = PRESET_EDITOR_ROUTES.find((route) => route.prefixes.some((prefix) => matchesRoutePrefix(normalizedPathname, prefix), ), ); if (presetRoute) { return { kind: 'preset-editor', initialTab: presetRoute.initialTab, }; } return { kind: 'game', }; } export function resolveAppRoute(pathname: string): ResolvedAppRoute { const matchedRoute = matchAppRoute(pathname); if (matchedRoute.kind === 'qwen-sprite-tool') { return { kind: matchedRoute.kind, loadingEyebrow: '正在载入精灵表工坊', loadingText: '正在载入 Qwen 精灵表工具...', Component: QwenSpriteToolApp, }; } if (matchedRoute.kind === 'preset-editor') { return { kind: matchedRoute.kind, loadingEyebrow: '正在载入编辑器', loadingText: '正在载入编辑器...', Component: PresetEditorApp, componentProps: { initialTab: matchedRoute.initialTab, }, }; } return { kind: 'game', loadingEyebrow: '正在载入游戏', loadingText: '正在载入冒险...', Component: GameApp, }; }