Merge pull request #12 from router-for-me/main
sync: merge upstream router-for-me/Cli-Proxy-API-Management-Center 主要更新: - 登录页面重新设计(分屏布局 + 自动登录 UI) - AI 提供商编辑改为独立页面(替代弹窗模式) - 新增浮动导航侧边栏,支持快速跳转 - OAuth 模型别名和排除模型编辑页面 - 新增多个模型图标(Codex、DeepSeek、GLM、Grok、Kimi、MiniMax) - 页面过渡动画优化,防止空白闪烁 - 日志页面新增原始日志显示开关 - 移动端响应式布局优化 - 配额管理新增认证类型统计 冲突解决: - src/stores/index.ts: 保留本地 useDisabledModelsStore 和 PR 的 useOpenAIEditDraftStore - src/pages/AiProvidersPage.tsx: 采用 PR 版本(页面导航重构) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -378,6 +378,31 @@ export function MainLayout() {
|
||||
const trimmedPath =
|
||||
pathname.length > 1 && pathname.endsWith('/') ? pathname.slice(0, -1) : pathname;
|
||||
const normalizedPath = trimmedPath === '/dashboard' ? '/' : trimmedPath;
|
||||
|
||||
const aiProvidersIndex = navOrder.indexOf('/ai-providers');
|
||||
if (aiProvidersIndex !== -1) {
|
||||
if (normalizedPath === '/ai-providers') return aiProvidersIndex;
|
||||
if (normalizedPath.startsWith('/ai-providers/')) {
|
||||
if (normalizedPath.startsWith('/ai-providers/gemini')) return aiProvidersIndex + 0.1;
|
||||
if (normalizedPath.startsWith('/ai-providers/codex')) return aiProvidersIndex + 0.2;
|
||||
if (normalizedPath.startsWith('/ai-providers/claude')) return aiProvidersIndex + 0.3;
|
||||
if (normalizedPath.startsWith('/ai-providers/vertex')) return aiProvidersIndex + 0.4;
|
||||
if (normalizedPath.startsWith('/ai-providers/ampcode')) return aiProvidersIndex + 0.5;
|
||||
if (normalizedPath.startsWith('/ai-providers/openai')) return aiProvidersIndex + 0.6;
|
||||
return aiProvidersIndex + 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
const authFilesIndex = navOrder.indexOf('/auth-files');
|
||||
if (authFilesIndex !== -1) {
|
||||
if (normalizedPath === '/auth-files') return authFilesIndex;
|
||||
if (normalizedPath.startsWith('/auth-files/')) {
|
||||
if (normalizedPath.startsWith('/auth-files/oauth-excluded')) return authFilesIndex + 0.1;
|
||||
if (normalizedPath.startsWith('/auth-files/oauth-model-alias')) return authFilesIndex + 0.2;
|
||||
return authFilesIndex + 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
const exactIndex = navOrder.indexOf(normalizedPath);
|
||||
if (exactIndex !== -1) return exactIndex;
|
||||
const nestedIndex = navOrder.findIndex(
|
||||
@@ -386,6 +411,24 @@ export function MainLayout() {
|
||||
return nestedIndex === -1 ? null : nestedIndex;
|
||||
};
|
||||
|
||||
const getTransitionVariant = useCallback((fromPathname: string, toPathname: string) => {
|
||||
const normalize = (pathname: string) => {
|
||||
const trimmed =
|
||||
pathname.length > 1 && pathname.endsWith('/') ? pathname.slice(0, -1) : pathname;
|
||||
return trimmed === '/dashboard' ? '/' : trimmed;
|
||||
};
|
||||
|
||||
const from = normalize(fromPathname);
|
||||
const to = normalize(toPathname);
|
||||
const isAuthFiles = (pathname: string) =>
|
||||
pathname === '/auth-files' || pathname.startsWith('/auth-files/');
|
||||
const isAiProviders = (pathname: string) =>
|
||||
pathname === '/ai-providers' || pathname.startsWith('/ai-providers/');
|
||||
if (isAuthFiles(from) && isAuthFiles(to)) return 'ios';
|
||||
if (isAiProviders(from) && isAiProviders(to)) return 'ios';
|
||||
return 'vertical';
|
||||
}, []);
|
||||
|
||||
const handleRefreshAll = async () => {
|
||||
clearCache();
|
||||
const results = await Promise.allSettled([
|
||||
@@ -543,6 +586,7 @@ export function MainLayout() {
|
||||
<PageTransition
|
||||
render={(location) => <MainRoutes location={location} />}
|
||||
getRouteOrder={getRouteOrder}
|
||||
getTransitionVariant={getTransitionVariant}
|
||||
scrollContainerRef={contentRef}
|
||||
/>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user