mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-20 23:22:05 +08:00
feat(navigation): migrate to TanStack Router and enhance navigation structure
- Replaced react-router with TanStack Router for improved routing capabilities. - Updated navigation logic across various components to utilize the new navigation API. - Refactored App.tsx to integrate AppShell as the main routing component, removing the deprecated Router. - Enhanced navigation methods to support search parameters, improving URL handling for settings and provider navigation. These changes streamline the routing architecture, enhancing the overall user experience and maintainability of the application.
This commit is contained in:
parent
5ad5bd537b
commit
b9a56fcec1
@ -7,15 +7,13 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { Provider } from 'react-redux'
|
||||
import { PersistGate } from 'redux-persist/integration/react'
|
||||
|
||||
// TODO: 新路由系统入口,迁移完成后启用
|
||||
// import { AppShell } from './components/layout/AppShell'
|
||||
import { AppShell } from './components/layout/AppShell'
|
||||
import TopViewContainer from './components/TopView'
|
||||
import AntdProvider from './context/AntdProvider'
|
||||
import { CodeStyleProvider } from './context/CodeStyleProvider'
|
||||
import { NotificationProvider } from './context/NotificationProvider'
|
||||
import StyleSheetManager from './context/StyleSheetManager'
|
||||
import { ThemeProvider } from './context/ThemeProvider'
|
||||
import Router from './Router'
|
||||
|
||||
const logger = loggerService.withContext('App.tsx')
|
||||
|
||||
@ -44,8 +42,7 @@ function App(): React.ReactElement {
|
||||
<CodeStyleProvider>
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<TopViewContainer>
|
||||
{/* TODO: 迁移完成后切换到 <AppShell /> */}
|
||||
<Router />
|
||||
<AppShell />
|
||||
</TopViewContainer>
|
||||
</PersistGate>
|
||||
</CodeStyleProvider>
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
import '@renderer/databases'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { HashRouter, Route, Routes } from 'react-router-dom'
|
||||
|
||||
import Sidebar from './components/app/Sidebar'
|
||||
import { ErrorBoundary } from './components/ErrorBoundary'
|
||||
import TabsContainer from './components/Tab/TabContainer'
|
||||
import NavigationHandler from './handler/NavigationHandler'
|
||||
import { useNavbarPosition } from './hooks/useNavbar'
|
||||
import CodeToolsPage from './pages/code/CodeToolsPage'
|
||||
import FilesPage from './pages/files/FilesPage'
|
||||
import HomePage from './pages/home/HomePage'
|
||||
import KnowledgePage from './pages/knowledge/KnowledgePage'
|
||||
import LaunchpadPage from './pages/launchpad/LaunchpadPage'
|
||||
import MinAppPage from './pages/minapps/MinAppPage'
|
||||
import MinAppsPage from './pages/minapps/MinAppsPage'
|
||||
import NotesPage from './pages/notes/NotesPage'
|
||||
import PaintingsRoutePage from './pages/paintings/PaintingsRoutePage'
|
||||
import SettingsPage from './pages/settings/SettingsPage'
|
||||
import AssistantPresetsPage from './pages/store/assistants/presets/AssistantPresetsPage'
|
||||
import TranslatePage from './pages/translate/TranslatePage'
|
||||
|
||||
const Router: FC = () => {
|
||||
const { navbarPosition } = useNavbarPosition()
|
||||
|
||||
const routes = useMemo(() => {
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/store" element={<AssistantPresetsPage />} />
|
||||
<Route path="/paintings/*" element={<PaintingsRoutePage />} />
|
||||
<Route path="/translate" element={<TranslatePage />} />
|
||||
<Route path="/files" element={<FilesPage />} />
|
||||
<Route path="/notes" element={<NotesPage />} />
|
||||
<Route path="/knowledge" element={<KnowledgePage />} />
|
||||
<Route path="/apps/:appId" element={<MinAppPage />} />
|
||||
<Route path="/apps" element={<MinAppsPage />} />
|
||||
<Route path="/code" element={<CodeToolsPage />} />
|
||||
<Route path="/settings/*" element={<SettingsPage />} />
|
||||
<Route path="/launchpad" element={<LaunchpadPage />} />
|
||||
</Routes>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
}, [])
|
||||
|
||||
if (navbarPosition === 'left') {
|
||||
return (
|
||||
<HashRouter>
|
||||
<Sidebar />
|
||||
{routes}
|
||||
<NavigationHandler />
|
||||
</HashRouter>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<HashRouter>
|
||||
<NavigationHandler />
|
||||
<TabsContainer>{routes}</TabsContainer>
|
||||
</HashRouter>
|
||||
)
|
||||
}
|
||||
|
||||
export default Router
|
||||
@ -30,13 +30,13 @@ export const FreeTrialModelTag: FC<Props> = ({ model, showLabel = true }) => {
|
||||
}
|
||||
|
||||
const onSelectProvider = () => {
|
||||
NavigationService.navigate!(`/settings/provider?id=${providerId}`)
|
||||
NavigationService.navigate!({ to: `/settings/provider`, search: { id: providerId } })
|
||||
}
|
||||
|
||||
const onNavigateProvider = (e: MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
SelectModelPopup.hide()
|
||||
NavigationService.navigate!(`/settings/provider?id=${providerId}`)
|
||||
NavigationService.navigate?.({ to: '/settings/provider', search: { id: providerId } })
|
||||
}
|
||||
|
||||
if (!showLabel) {
|
||||
|
||||
@ -6,11 +6,11 @@ import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
|
||||
import { useMinapps } from '@renderer/hooks/useMinapps'
|
||||
import { useNavbarPosition } from '@renderer/hooks/useNavbar'
|
||||
import type { MinAppType } from '@renderer/types'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import type { MenuProps } from 'antd'
|
||||
import { Dropdown } from 'antd'
|
||||
import type { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
interface Props {
|
||||
@ -47,7 +47,7 @@ const MinApp: FC<Props> = ({ app, onClick, size = 60, isLast }) => {
|
||||
const handleClick = () => {
|
||||
if (isTopNavbar) {
|
||||
// 顶部导航栏:导航到小程序页面
|
||||
navigate(`/apps/${app.id}`)
|
||||
navigate({ to: `/apps/${app.id}` })
|
||||
} else {
|
||||
// 侧边导航栏:保持原有弹窗行为
|
||||
openMinappKeepAlive(app)
|
||||
|
||||
@ -3,9 +3,9 @@ import WebviewContainer from '@renderer/components/MinApp/WebviewContainer'
|
||||
import { useMinapps } from '@renderer/hooks/useMinapps'
|
||||
import { useNavbarPosition } from '@renderer/hooks/useNavbar'
|
||||
import { getWebviewLoaded, setWebviewLoaded } from '@renderer/utils/webviewStateManager'
|
||||
import { useLocation } from '@tanstack/react-router'
|
||||
import type { WebviewTag } from 'electron'
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
/**
|
||||
|
||||
@ -193,7 +193,7 @@ const PopupContainer: React.FC<Props> = ({ model, filter: baseFilter, showTagFil
|
||||
e.stopPropagation()
|
||||
setOpen(false)
|
||||
resolve(undefined)
|
||||
window.navigate(`/settings/provider?id=${p.id}`)
|
||||
window.navigate({ to: '/settings/provider', search: { id: p.id } })
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
@ -17,6 +17,7 @@ import { addTab, removeTab, setActiveTab, setTabs } from '@renderer/store/tabs'
|
||||
import type { MinAppType } from '@renderer/types'
|
||||
import { classNames } from '@renderer/utils'
|
||||
import { ThemeMode } from '@shared/data/preference/preferenceTypes'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import type { LRUCache } from 'lru-cache'
|
||||
import {
|
||||
FileSearch,
|
||||
@ -37,7 +38,6 @@ import {
|
||||
} from 'lucide-react'
|
||||
import { useCallback, useEffect, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import MinAppIcon from '../Icons/MinAppIcon'
|
||||
@ -203,17 +203,17 @@ const TabsContainer: React.FC<TabsContainerProps> = ({ children }) => {
|
||||
|
||||
const handleAddTab = () => {
|
||||
hideMinappPopup()
|
||||
navigate('/launchpad')
|
||||
navigate({ to: '/launchpad' })
|
||||
}
|
||||
|
||||
const handleSettingsClick = () => {
|
||||
hideMinappPopup()
|
||||
navigate(lastSettingsPath)
|
||||
navigate({ to: lastSettingsPath })
|
||||
}
|
||||
|
||||
const handleTabClick = (tab: Tab) => {
|
||||
hideMinappPopup()
|
||||
navigate(tab.path)
|
||||
navigate({ to: tab.path })
|
||||
}
|
||||
|
||||
const visibleTabs = useMemo(() => tabs.filter((tab) => !specialTabs.includes(tab.id)), [tabs])
|
||||
|
||||
@ -30,9 +30,9 @@ import {
|
||||
} from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { useTabs } from '../../hooks/useTabs'
|
||||
import UserPopup from '../Popups/UserPopup'
|
||||
import { SidebarOpenedMinappTabs, SidebarPinnedApps } from './PinnedMinapps'
|
||||
|
||||
@ -40,9 +40,11 @@ const Sidebar: FC = () => {
|
||||
const { hideMinappPopup } = useMinappPopup()
|
||||
const { pinned, minappShow } = useMinapps()
|
||||
const [visibleSidebarIcons] = usePreference('ui.sidebar.icons.visible')
|
||||
const { tabs, activeTabId, updateTab } = useTabs()
|
||||
|
||||
const { pathname } = useLocation()
|
||||
const navigate = useNavigate()
|
||||
// 获取当前 Tab 的 URL 作为 pathname
|
||||
const activeTab = tabs.find((t) => t.id === activeTabId)
|
||||
const pathname = activeTab?.url || '/'
|
||||
|
||||
const { theme, settedTheme, toggleTheme } = useTheme()
|
||||
const avatar = useAvatar()
|
||||
@ -54,9 +56,12 @@ const Sidebar: FC = () => {
|
||||
|
||||
const showPinnedApps = pinned.length > 0 && visibleSidebarIcons.includes('minapp')
|
||||
|
||||
// 在当前 Tab 内跳转
|
||||
const to = async (path: string) => {
|
||||
await modelGenerating()
|
||||
navigate(path)
|
||||
if (activeTabId) {
|
||||
updateTab(activeTabId, { url: path })
|
||||
}
|
||||
}
|
||||
|
||||
const isFullscreen = useFullscreen()
|
||||
@ -121,14 +126,16 @@ const Sidebar: FC = () => {
|
||||
const MainMenus: FC = () => {
|
||||
const { hideMinappPopup } = useMinappPopup()
|
||||
const { minappShow } = useMinapps()
|
||||
const { tabs, activeTabId, updateTab } = useTabs()
|
||||
|
||||
// 获取当前 Tab 的 URL 作为 pathname
|
||||
const activeTab = tabs.find((t) => t.id === activeTabId)
|
||||
const pathname = activeTab?.url || '/'
|
||||
|
||||
const { pathname } = useLocation()
|
||||
const [visibleSidebarIcons] = usePreference('ui.sidebar.icons.visible')
|
||||
const { defaultPaintingProvider } = useSettings()
|
||||
const navigate = useNavigate()
|
||||
const { theme } = useTheme()
|
||||
|
||||
const isRoute = (path: string): string => (pathname === path && !minappShow ? 'active' : '')
|
||||
const isRoutes = (path: string): string => (pathname.startsWith(path) && !minappShow ? 'active' : '')
|
||||
|
||||
const iconMap = {
|
||||
@ -144,7 +151,7 @@ const MainMenus: FC = () => {
|
||||
}
|
||||
|
||||
const pathMap = {
|
||||
assistants: '/',
|
||||
assistants: '/chat',
|
||||
store: '/store',
|
||||
paintings: `/paintings/${defaultPaintingProvider}`,
|
||||
translate: '/translate',
|
||||
@ -155,17 +162,24 @@ const MainMenus: FC = () => {
|
||||
notes: '/notes'
|
||||
}
|
||||
|
||||
// 在当前 Tab 内跳转
|
||||
const to = async (path: string) => {
|
||||
await modelGenerating()
|
||||
if (activeTabId) {
|
||||
updateTab(activeTabId, { url: path })
|
||||
}
|
||||
}
|
||||
|
||||
return visibleSidebarIcons.map((icon) => {
|
||||
const path = pathMap[icon]
|
||||
const isActive = path === '/' ? isRoute(path) : isRoutes(path)
|
||||
const isActive = isRoutes(path)
|
||||
|
||||
return (
|
||||
<Tooltip key={icon} placement="right" content={getSidebarIconLabel(icon)} delay={800}>
|
||||
<StyledLink
|
||||
onClick={async () => {
|
||||
hideMinappPopup()
|
||||
await modelGenerating()
|
||||
navigate(path)
|
||||
await to(path)
|
||||
}}>
|
||||
<Icon theme={theme} className={isActive}>
|
||||
{iconMap[icon]}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import '@renderer/databases'
|
||||
|
||||
import { cn, Tabs, TabsList, TabsTrigger } from '@cherrystudio/ui'
|
||||
import { Plus, X } from 'lucide-react'
|
||||
import { Activity } from 'react'
|
||||
@ -31,7 +33,7 @@ export const AppShell = () => {
|
||||
id: uuid(),
|
||||
type: 'route',
|
||||
url: '/',
|
||||
title: 'New Tab',
|
||||
title: 'New Tab'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
4
src/renderer/src/env.d.ts
vendored
4
src/renderer/src/env.d.ts
vendored
@ -2,8 +2,8 @@
|
||||
|
||||
import type { PermissionUpdate } from '@anthropic-ai/claude-agent-sdk'
|
||||
import type { ToastUtilities } from '@cherrystudio/ui'
|
||||
import type { UseNavigateResult } from '@tanstack/react-router'
|
||||
import type { HookAPI } from 'antd/es/modal/useModal'
|
||||
import type { NavigateFunction } from 'react-router-dom'
|
||||
|
||||
interface ImportMetaEnv {
|
||||
VITE_RENDERER_INTEGRATED_MODEL: string
|
||||
@ -18,7 +18,7 @@ declare global {
|
||||
root: HTMLElement
|
||||
modal: HookAPI
|
||||
store: any
|
||||
navigate: NavigateFunction
|
||||
navigate: UseNavigateResult<string>
|
||||
toast: ToastUtilities
|
||||
agentTools: {
|
||||
respondToPermission: (payload: {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { useAppSelector } from '@renderer/store'
|
||||
import { IpcChannel } from '@shared/IpcChannel'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import { useEffect } from 'react'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
|
||||
const NavigationHandler: React.FC = () => {
|
||||
const location = useLocation()
|
||||
@ -17,7 +17,7 @@ const NavigationHandler: React.FC = () => {
|
||||
if (location.pathname.startsWith('/settings')) {
|
||||
return
|
||||
}
|
||||
navigate('/settings/provider')
|
||||
navigate({ to: '/settings/provider' })
|
||||
},
|
||||
{
|
||||
splitKey: '!',
|
||||
@ -30,7 +30,7 @@ const NavigationHandler: React.FC = () => {
|
||||
// Listen for navigate to About page event from macOS menu
|
||||
useEffect(() => {
|
||||
const handleNavigateToAbout = () => {
|
||||
navigate('/settings/about')
|
||||
navigate({ to: '/settings/about' })
|
||||
}
|
||||
|
||||
const removeListener = window.electron.ipcRenderer.on(IpcChannel.Windows_NavigateToAbout, handleNavigateToAbout)
|
||||
|
||||
@ -64,7 +64,7 @@ export function useAppInit() {
|
||||
useEffect(() => {
|
||||
window.api.getDataPathFromArgs().then((dataPath) => {
|
||||
if (dataPath) {
|
||||
window.navigate('/settings/data', { replace: true })
|
||||
window.navigate({ to: '/settings/data', replace: true })
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
@ -13,8 +13,8 @@ window.electron.ipcRenderer.on(IpcChannel.Mcp_ServersChanged, (_event, servers)
|
||||
|
||||
window.electron.ipcRenderer.on(IpcChannel.Mcp_AddServer, (_event, server: MCPServer) => {
|
||||
store.dispatch(addMCPServer(server))
|
||||
NavigationService.navigate?.('/settings/mcp')
|
||||
NavigationService.navigate?.(`/settings/mcp/settings/${encodeURIComponent(server.id)}`)
|
||||
NavigationService.navigate?.({ to: '/settings/mcp' })
|
||||
NavigationService.navigate?.({ to: `/settings/mcp/settings/${encodeURIComponent(server.id)}` })
|
||||
})
|
||||
|
||||
const selectMcpServers = (state: RootState) => state.mcp.servers
|
||||
|
||||
@ -186,7 +186,7 @@ export const useMinappPopup = () => {
|
||||
|
||||
// Then navigate to the app tab using NavigationService
|
||||
if (NavigationService.navigate) {
|
||||
NavigationService.navigate(`/apps/${config.id}`)
|
||||
NavigationService.navigate({ to: `/apps/${config.id}` })
|
||||
}
|
||||
} else {
|
||||
// For side navbar, use the traditional popup system
|
||||
|
||||
@ -19,12 +19,12 @@ import { getClaudeSupportedProviders } from '@renderer/utils/provider'
|
||||
import type { TerminalConfig } from '@shared/config/constant'
|
||||
import { codeTools, terminalApps } from '@shared/config/constant'
|
||||
import { isSiliconAnthropicCompatibleModel } from '@shared/config/providers'
|
||||
import { Link } from '@tanstack/react-router'
|
||||
import { Alert, Checkbox, Input, Popover, Select, Space } from 'antd'
|
||||
import { ArrowUpRight, Download, FolderOpen, HelpCircle, Terminal, X } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import {
|
||||
|
||||
@ -11,9 +11,9 @@ import { getTopicById } from '@renderer/hooks/useTopic'
|
||||
import { getAssistantById } from '@renderer/services/AssistantService'
|
||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
||||
import { locateToMessage } from '@renderer/services/MessagesService'
|
||||
import NavigationService from '@renderer/services/NavigationService'
|
||||
import type { Topic } from '@renderer/types'
|
||||
import { classNames, runAsyncFunction } from '@renderer/utils'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { Divider, Empty } from 'antd'
|
||||
import { t } from 'i18next'
|
||||
import { Forward } from 'lucide-react'
|
||||
@ -27,7 +27,8 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||
}
|
||||
|
||||
const TopicMessages: FC<Props> = ({ topic: _topic, ...props }) => {
|
||||
const navigate = NavigationService.navigate!
|
||||
const navigate = useNavigate()
|
||||
|
||||
const { handleScroll, containerRef } = useScrollPosition('TopicMessages')
|
||||
const [messageStyle] = usePreference('chat.message.style')
|
||||
const { setTimeoutTimer } = useTimer()
|
||||
@ -53,7 +54,7 @@ const TopicMessages: FC<Props> = ({ topic: _topic, ...props }) => {
|
||||
await modelGenerating()
|
||||
SearchPopup.hide()
|
||||
const assistant = getAssistantById(topic.assistantId)
|
||||
navigate('/', { state: { assistant, topic } })
|
||||
navigate({ to: '/chat', search: { assistantId: assistant?.id, topicId: topic.id } })
|
||||
setTimeoutTimer('onContinueChat', () => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 100)
|
||||
}
|
||||
|
||||
|
||||
@ -10,11 +10,11 @@ import { newMessagesActions } from '@renderer/store/newMessage'
|
||||
import { setActiveAgentId, setActiveTopicOrSessionAction } from '@renderer/store/runtime'
|
||||
import type { Assistant, Topic } from '@renderer/types'
|
||||
import { MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH, SECOND_MIN_WINDOW_WIDTH } from '@shared/config/constant'
|
||||
import { useNavigate, useSearch } from '@tanstack/react-router'
|
||||
import { AnimatePresence, motion } from 'motion/react'
|
||||
import type { FC } from 'react'
|
||||
import { startTransition, useCallback, useEffect, useState } from 'react'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import Chat from './Chat'
|
||||
@ -31,13 +31,23 @@ const HomePage: FC = () => {
|
||||
// Initialize agent session hook
|
||||
useAgentSessionInitializer()
|
||||
|
||||
const location = useLocation()
|
||||
const state = location.state
|
||||
const search = useSearch({ strict: false }) as { assistantId?: string; topicId?: string }
|
||||
|
||||
// 根据 search params 中的 ID 查找对应的 assistant
|
||||
const assistantFromSearch = search.assistantId
|
||||
? assistants.find((a) => a.id === search.assistantId)
|
||||
: undefined
|
||||
|
||||
const [activeAssistant, _setActiveAssistant] = useState<Assistant>(
|
||||
state?.assistant || _activeAssistant || assistants[0]
|
||||
assistantFromSearch || _activeAssistant || assistants[0]
|
||||
)
|
||||
const { activeTopic, setActiveTopic: _setActiveTopic } = useActiveTopic(activeAssistant?.id ?? '', state?.topic)
|
||||
|
||||
// 根据 search params 中的 topicId 查找对应的 topic
|
||||
const topicFromSearch = search.topicId
|
||||
? activeAssistant?.topics?.find((t) => t.id === search.topicId)
|
||||
: undefined
|
||||
|
||||
const { activeTopic, setActiveTopic: _setActiveTopic } = useActiveTopic(activeAssistant?.id ?? '', topicFromSearch)
|
||||
const [showAssistants] = usePreference('assistant.tab.show')
|
||||
const [showTopics] = usePreference('topic.tab.show')
|
||||
const [topicPosition] = usePreference('topic.position')
|
||||
@ -80,10 +90,10 @@ const HomePage: FC = () => {
|
||||
}, [navigate])
|
||||
|
||||
useEffect(() => {
|
||||
state?.assistant && setActiveAssistant(state?.assistant)
|
||||
state?.topic && setActiveTopic(state?.topic)
|
||||
assistantFromSearch && setActiveAssistant(assistantFromSearch)
|
||||
topicFromSearch && setActiveTopic(topicFromSearch)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [state])
|
||||
}, [search.assistantId, search.topicId])
|
||||
|
||||
useEffect(() => {
|
||||
const canMinimize = topicPosition == 'left' ? !showAssistants : !showAssistants && !showTopics
|
||||
|
||||
@ -5,11 +5,11 @@ import { QuickPanelReservedSymbol, useQuickPanel } from '@renderer/components/Qu
|
||||
import type { ToolQuickPanelApi } from '@renderer/pages/home/Inputbar/types'
|
||||
import { useAppSelector } from '@renderer/store'
|
||||
import type { KnowledgeBase } from '@renderer/types'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { CircleX, FileSearch, Plus } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
interface Props {
|
||||
quickPanel: ToolQuickPanelApi
|
||||
@ -54,7 +54,7 @@ const KnowledgeBaseButton: FC<Props> = ({ quickPanel, selectedBases, onSelect, d
|
||||
items.push({
|
||||
label: t('knowledge.add.title') + '...',
|
||||
icon: <Plus />,
|
||||
action: () => navigate('/knowledge'),
|
||||
action: () => navigate({ to: '/knowledge' }),
|
||||
isSelected: false
|
||||
})
|
||||
|
||||
|
||||
@ -12,12 +12,12 @@ import { EventEmitter } from '@renderer/services/EventService'
|
||||
import type { MCPPrompt, MCPResource, MCPServer } from '@renderer/types'
|
||||
import { isToolUseModeFunction } from '@renderer/utils/assistant'
|
||||
import { isGeminiWebSearchProvider, isSupportUrlContextProvider } from '@renderer/utils/provider'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { Form, Input } from 'antd'
|
||||
import { CircleX, Hammer, Plus } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
interface Props {
|
||||
assistantId: string
|
||||
@ -205,7 +205,7 @@ const MCPToolsButton: FC<Props> = ({ quickPanel, setInputValue, resizeTextArea,
|
||||
newList.push({
|
||||
label: t('settings.mcp.addServer.label') + '...',
|
||||
icon: <Plus />,
|
||||
action: () => navigate('/settings/mcp')
|
||||
action: () => navigate({ to: '/settings/mcp' })
|
||||
})
|
||||
|
||||
newList.unshift({
|
||||
|
||||
@ -9,6 +9,7 @@ import { getModelUniqId } from '@renderer/services/ModelService'
|
||||
import type { FileType, Model } from '@renderer/types'
|
||||
import { FileTypes } from '@renderer/types'
|
||||
import { getFancyProviderName } from '@renderer/utils'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { Avatar } from 'antd'
|
||||
import { useLiveQuery } from 'dexie-react-hooks'
|
||||
import { first, sortBy } from 'lodash'
|
||||
@ -16,7 +17,6 @@ import { AtSign, CircleX, Plus } from 'lucide-react'
|
||||
import type React from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router'
|
||||
import styled from 'styled-components'
|
||||
|
||||
export type MentionTriggerInfo = { type: 'input' | 'button'; position?: number; originalText?: string }
|
||||
@ -194,7 +194,7 @@ export const useMentionModelsPanel = (params: Params, role: 'button' | 'manager'
|
||||
items.push({
|
||||
label: t('settings.models.add.add_model') + '...',
|
||||
icon: <Plus />,
|
||||
action: () => navigate('/settings/provider'),
|
||||
action: () => navigate({ to: '/settings/provider' }),
|
||||
isSelected: false
|
||||
})
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ import CodeViewer from '@renderer/components/CodeViewer'
|
||||
import { useCodeStyle } from '@renderer/context/CodeStyleProvider'
|
||||
import { useTimer } from '@renderer/hooks/useTimer'
|
||||
import { getHttpMessageLabel, getProviderLabel } from '@renderer/i18n/label'
|
||||
import { getProviderById } from '@renderer/services/ProviderService'
|
||||
import { useAppDispatch } from '@renderer/store'
|
||||
import { removeBlocksThunk } from '@renderer/store/thunk/messageThunk'
|
||||
import type { SerializedAiSdkError, SerializedAiSdkErrorUnion, SerializedError } from '@renderer/types/error'
|
||||
@ -33,10 +32,10 @@ import {
|
||||
} from '@renderer/types/error'
|
||||
import type { ErrorMessageBlock, Message } from '@renderer/types/newMessage'
|
||||
import { formatAiSdkError, formatError, safeToString } from '@renderer/utils/error'
|
||||
import { Link } from '@tanstack/react-router'
|
||||
import { Alert as AntdAlert, Modal } from 'antd'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const HTTP_ERROR_CODES = [400, 401, 403, 404, 429, 500, 502, 503, 504]
|
||||
@ -71,8 +70,8 @@ const ErrorMessage: React.FC<{ block: ErrorMessageBlock }> = ({ block }) => {
|
||||
provider: (
|
||||
<Link
|
||||
style={{ color: 'var(--color-link)' }}
|
||||
to={`/settings/provider`}
|
||||
state={{ provider: getProviderById(providerId) }}
|
||||
to="/settings/provider"
|
||||
search={{ id: providerId }}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
|
||||
@ -16,6 +16,7 @@ import styled from 'styled-components'
|
||||
|
||||
import AssistantsDrawer from './components/AssistantsDrawer'
|
||||
import UpdateAppButton from './components/UpdateAppButton'
|
||||
|
||||
interface Props {
|
||||
activeAssistant: Assistant
|
||||
activeTopic: Topic
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import App from '@renderer/components/MinApp/MinApp'
|
||||
import { useMinapps } from '@renderer/hooks/useMinapps'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { Code, FileSearch, Folder, Languages, LayoutGrid, NotepadText, Palette, Sparkle } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const LaunchpadPage: FC = () => {
|
||||
@ -87,7 +87,7 @@ const LaunchpadPage: FC = () => {
|
||||
<SectionTitle>{t('launchpad.apps')}</SectionTitle>
|
||||
<Grid>
|
||||
{appMenuItems.map((item) => (
|
||||
<AppIcon key={item.path} onClick={() => navigate(item.path)}>
|
||||
<AppIcon key={item.path} onClick={() => navigate({ to: item.path })}>
|
||||
<IconContainer>
|
||||
<IconWrapper bgColor={item.bgColor}>{item.icon}</IconWrapper>
|
||||
</IconContainer>
|
||||
|
||||
@ -6,10 +6,10 @@ import { useMinapps } from '@renderer/hooks/useMinapps'
|
||||
import { useNavbarPosition } from '@renderer/hooks/useNavbar'
|
||||
import TabsService from '@renderer/services/TabsService'
|
||||
import { getWebviewLoaded, onWebviewStateChange, setWebviewLoaded } from '@renderer/utils/webviewStateManager'
|
||||
import { useNavigate, useParams } from '@tanstack/react-router'
|
||||
import type { WebviewTag } from 'electron'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import BeatLoader from 'react-spinners/BeatLoader'
|
||||
import styled from 'styled-components'
|
||||
|
||||
@ -20,7 +20,7 @@ import WebviewSearch from './components/WebviewSearch'
|
||||
const logger = loggerService.withContext('MinAppPage')
|
||||
|
||||
const MinAppPage: FC = () => {
|
||||
const { appId } = useParams<{ appId: string }>()
|
||||
const { appId } = useParams({ strict: false }) as { appId: string }
|
||||
const { isTopNavbar } = useNavbarPosition()
|
||||
const { openMinappKeepAlive, minAppsCache } = useMinappPopup()
|
||||
const { minapps } = useMinapps()
|
||||
@ -64,7 +64,7 @@ const MinAppPage: FC = () => {
|
||||
useEffect(() => {
|
||||
// If app not found, redirect to apps list
|
||||
if (!app) {
|
||||
navigate('/apps')
|
||||
navigate({ to: '/apps' })
|
||||
return
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ const MinAppPage: FC = () => {
|
||||
// Only check once and only if we haven't already redirected
|
||||
if (!initialIsTopNavbar.current && !hasRedirected.current) {
|
||||
hasRedirected.current = true
|
||||
navigate('/apps')
|
||||
navigate({ to: '/apps' })
|
||||
// Open popup after navigation
|
||||
setTimeout(() => {
|
||||
openMinappKeepAlive(app)
|
||||
|
||||
@ -15,11 +15,11 @@ import { isDev } from '@renderer/config/constant'
|
||||
import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
|
||||
import { useMinapps } from '@renderer/hooks/useMinapps'
|
||||
import type { MinAppType } from '@renderer/types'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import type { WebviewTag } from 'electron'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const logger = loggerService.withContext('MinimalToolbar')
|
||||
@ -213,7 +213,7 @@ const MinimalToolbar: FC<Props> = ({ app, webviewRef, currentUrl, onReload, onOp
|
||||
}, [app.id, webviewRef, scheduleNavigationUpdate])
|
||||
|
||||
const handleMinimize = useCallback(() => {
|
||||
navigate('/apps')
|
||||
navigate({ to: '/apps' })
|
||||
}, [navigate])
|
||||
|
||||
const handleTogglePin = useCallback(() => {
|
||||
|
||||
@ -19,12 +19,12 @@ import { translateText } from '@renderer/services/TranslateService'
|
||||
import type { FileMetadata } from '@renderer/types'
|
||||
import type { PaintingAction, PaintingsState } from '@renderer/types'
|
||||
import { getErrorMessage, uuid } from '@renderer/utils'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import { Input, InputNumber, Radio, Segmented, Select, Slider, Upload } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import SendMessageButton from '../home/Inputbar/SendMessageButton'
|
||||
@ -667,7 +667,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const handleProviderChange = (providerId: string) => {
|
||||
const routeName = location.pathname.split('/').pop()
|
||||
if (providerId !== routeName) {
|
||||
navigate('../' + providerId, { replace: true })
|
||||
navigate({ to: '../' + providerId, replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,13 +11,13 @@ import { useAllProviders } from '@renderer/hooks/useProvider'
|
||||
import FileManager from '@renderer/services/FileManager'
|
||||
import type { FileMetadata } from '@renderer/types'
|
||||
import { convertToBase64, uuid } from '@renderer/utils'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import type { DmxapiPainting } from '@types'
|
||||
import { Input, InputNumber, Segmented, Select } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import type { FC } from 'react'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { generationModeType } from '../../types'
|
||||
@ -640,7 +640,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const handleProviderChange = (providerId: string) => {
|
||||
const routeName = location.pathname.split('/').pop()
|
||||
if (providerId !== routeName) {
|
||||
navigate('../' + providerId, { replace: true })
|
||||
navigate({ to: '../' + providerId, replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,13 +29,13 @@ import type { PaintingAction, PaintingsState } from '@renderer/types'
|
||||
import type { FileMetadata } from '@renderer/types'
|
||||
import { getErrorMessage, uuid } from '@renderer/utils'
|
||||
import { isNewApiProvider } from '@renderer/utils/provider'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import { Empty, InputNumber, Segmented, Select, Upload } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import SendMessageButton from '../home/Inputbar/SendMessageButton'
|
||||
@ -436,7 +436,7 @@ const NewApiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const handleProviderChange = (providerId: string) => {
|
||||
const routeName = location.pathname.split('/').pop()
|
||||
if (providerId !== routeName) {
|
||||
navigate('../' + providerId, { replace: true })
|
||||
navigate({ to: '../' + providerId, replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,7 +463,7 @@ const NewApiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
|
||||
// 当 modelOptions 为空时,引导用户跳转到 Provider 设置页面,新增 image-generation 端点模型
|
||||
const handleShowAddModelPopup = () => {
|
||||
navigate(`/settings/provider?id=${newApiProvider.id}`)
|
||||
navigate({ to: `/settings/provider?id=${newApiProvider.id}` })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -15,13 +15,13 @@ import FileManager from '@renderer/services/FileManager'
|
||||
import { translateText } from '@renderer/services/TranslateService'
|
||||
import type { FileMetadata, OvmsPainting } from '@renderer/types'
|
||||
import { getErrorMessage, uuid } from '@renderer/utils'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import { Avatar, Input, InputNumber, Select, Slider } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { Info } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import SendMessageButton from '../home/Inputbar/SendMessageButton'
|
||||
@ -330,7 +330,7 @@ const OvmsPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const handleProviderChange = (providerId: string) => {
|
||||
const routeName = location.pathname.split('/').pop()
|
||||
if (providerId !== routeName) {
|
||||
navigate('../' + providerId, { replace: true })
|
||||
navigate({ to: '../' + providerId, replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,9 +5,9 @@ import { setDefaultPaintingProvider } from '@renderer/store/settings'
|
||||
import { updateTab } from '@renderer/store/tabs'
|
||||
import type { PaintingProvider, SystemProviderId } from '@renderer/types'
|
||||
import { isNewApiProvider } from '@renderer/utils/provider'
|
||||
import { useParams } from '@tanstack/react-router'
|
||||
import type { FC } from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { Route, Routes, useParams } from 'react-router-dom'
|
||||
|
||||
import AihubmixPage from './AihubmixPage'
|
||||
import DmxapiPage from './DmxapiPage'
|
||||
@ -22,8 +22,8 @@ const logger = loggerService.withContext('PaintingsRoutePage')
|
||||
const BASE_OPTIONS: SystemProviderId[] = ['zhipu', 'aihubmix', 'silicon', 'dmxapi', 'tokenflux', 'ovms']
|
||||
|
||||
const PaintingsRoutePage: FC = () => {
|
||||
const params = useParams()
|
||||
const provider = params['*']
|
||||
const params = useParams({ strict: false }) as { _splat?: string }
|
||||
const provider = params._splat
|
||||
const dispatch = useAppDispatch()
|
||||
const providers = useAllProviders()
|
||||
const [ovmsStatus, setOvmsStatus] = useState<'not-installed' | 'not-running' | 'running'>('not-running')
|
||||
@ -49,22 +49,34 @@ const PaintingsRoutePage: FC = () => {
|
||||
}
|
||||
}, [provider, dispatch, validOptions])
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="*" element={<NewApiPage Options={validOptions} />} />
|
||||
<Route path="/zhipu" element={<ZhipuPage Options={validOptions} />} />
|
||||
<Route path="/aihubmix" element={<AihubmixPage Options={validOptions} />} />
|
||||
<Route path="/silicon" element={<SiliconPage Options={validOptions} />} />
|
||||
<Route path="/dmxapi" element={<DmxapiPage Options={validOptions} />} />
|
||||
<Route path="/tokenflux" element={<TokenFluxPage Options={validOptions} />} />
|
||||
<Route path="/ovms" element={<OvmsPage Options={validOptions} />} />
|
||||
<Route path="/new-api" element={<NewApiPage Options={validOptions} />} />
|
||||
{/* new-api family providers are mounted dynamically below */}
|
||||
{newApiProviders.map((p) => (
|
||||
<Route key={p.id} path={`/${p.id}`} element={<NewApiPage Options={validOptions} />} />
|
||||
))}
|
||||
</Routes>
|
||||
)
|
||||
// 根据 provider 渲染对应的页面
|
||||
const renderPage = () => {
|
||||
switch (provider) {
|
||||
case 'zhipu':
|
||||
return <ZhipuPage Options={validOptions} />
|
||||
case 'aihubmix':
|
||||
return <AihubmixPage Options={validOptions} />
|
||||
case 'silicon':
|
||||
return <SiliconPage Options={validOptions} />
|
||||
case 'dmxapi':
|
||||
return <DmxapiPage Options={validOptions} />
|
||||
case 'tokenflux':
|
||||
return <TokenFluxPage Options={validOptions} />
|
||||
case 'ovms':
|
||||
return <OvmsPage Options={validOptions} />
|
||||
case 'new-api':
|
||||
return <NewApiPage Options={validOptions} />
|
||||
default:
|
||||
// 检查是否是 new-api 家族的 provider
|
||||
if (provider && newApiProviders.some((p) => p.id === provider)) {
|
||||
return <NewApiPage Options={validOptions} />
|
||||
}
|
||||
// 默认页面
|
||||
return <NewApiPage Options={validOptions} />
|
||||
}
|
||||
}
|
||||
|
||||
return renderPage()
|
||||
}
|
||||
|
||||
export default PaintingsRoutePage
|
||||
|
||||
@ -23,12 +23,12 @@ import FileManager from '@renderer/services/FileManager'
|
||||
import { translateText } from '@renderer/services/TranslateService'
|
||||
import type { FileMetadata, Painting } from '@renderer/types'
|
||||
import { getErrorMessage, uuid } from '@renderer/utils'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import { Input, InputNumber, Radio, Select, Slider } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import type { FC } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import SendMessageButton from '../home/Inputbar/SendMessageButton'
|
||||
@ -333,7 +333,7 @@ const SiliconPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const handleProviderChange = (providerId: string) => {
|
||||
const routeName = location.pathname.split('/').pop()
|
||||
if (providerId !== routeName) {
|
||||
navigate('../' + providerId, { replace: true })
|
||||
navigate({ to: '../' + providerId, replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,12 +15,12 @@ import FileManager from '@renderer/services/FileManager'
|
||||
import { translateText } from '@renderer/services/TranslateService'
|
||||
import type { TokenFluxPainting } from '@renderer/types'
|
||||
import { getErrorMessage, uuid } from '@renderer/utils'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import { Select } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import SendMessageButton from '../home/Inputbar/SendMessageButton'
|
||||
@ -268,7 +268,7 @@ const TokenFluxPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const handleProviderChange = (providerId: string) => {
|
||||
const routeName = location.pathname.split('/').pop()
|
||||
if (providerId !== routeName) {
|
||||
navigate('../' + providerId, { replace: true })
|
||||
navigate({ to: '../' + providerId, replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,12 +12,12 @@ import { usePaintings } from '@renderer/hooks/usePaintings'
|
||||
import { useAllProviders } from '@renderer/hooks/useProvider'
|
||||
import FileManager from '@renderer/services/FileManager'
|
||||
import { getErrorMessage, uuid } from '@renderer/utils'
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import { InputNumber, Radio, Select } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import type { FC } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import SendMessageButton from '../home/Inputbar/SendMessageButton'
|
||||
@ -260,7 +260,7 @@ const ZhipuPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const handleProviderChange = (providerId: string) => {
|
||||
const routeName = location.pathname.split('/').pop()
|
||||
if (providerId !== routeName) {
|
||||
navigate('../' + providerId, { replace: true })
|
||||
navigate({ to: '../' + providerId, replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ export function checkProviderEnabled(provider: Provider, t: TFunction): Promise<
|
||||
closable: true,
|
||||
okText: t('common.go_to_settings'),
|
||||
onOk: () => {
|
||||
window.navigate?.(`/settings/provider?id=${provider.id}`)
|
||||
window.navigate?.({ to: `/settings/provider`, search: { id: provider.id } })
|
||||
reject('Provider disabled')
|
||||
},
|
||||
onCancel: () => reject('Provider disabled')
|
||||
|
||||
@ -13,6 +13,7 @@ import i18n from '@renderer/i18n'
|
||||
// import { setUpdateState as setAppUpdateState } from '@renderer/store/runtime'
|
||||
import { runAsyncFunction } from '@renderer/utils'
|
||||
import { ThemeMode, UpgradeChannel } from '@shared/data/preference/preferenceTypes'
|
||||
import { Link } from '@tanstack/react-router'
|
||||
import { Avatar, Progress, Radio, Row, Tag } from 'antd'
|
||||
import { debounce } from 'lodash'
|
||||
import { Bug, Building2, Github, Globe, Mail, Rss } from 'lucide-react'
|
||||
@ -21,7 +22,6 @@ import type { FC } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Markdown from 'react-markdown'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingTitle } from '.'
|
||||
|
||||
@ -3,11 +3,11 @@ import { Center, ColFlex } from '@cherrystudio/ui'
|
||||
import { Button } from '@cherrystudio/ui'
|
||||
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||
import { setIsBunInstalled, setIsUvInstalled } from '@renderer/store/mcp'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { Alert } from 'antd'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { SettingDescription, SettingRow, SettingSubtitle } from '..'
|
||||
@ -87,7 +87,7 @@ const InstallNpxUv: FC<Props> = ({ mini = false }) => {
|
||||
<Button
|
||||
className="nodrag rounded-full"
|
||||
variant={installed ? 'default' : 'destructive'}
|
||||
onClick={() => navigate('/settings/mcp/mcp-install')}
|
||||
onClick={() => navigate({ to: '/settings/mcp/mcp-install' })}
|
||||
size="icon">
|
||||
{installed ? <CheckCircleOutlined /> : <WarningOutlined />}
|
||||
</Button>
|
||||
|
||||
@ -9,12 +9,12 @@ import { useMCPServerTrust } from '@renderer/hooks/useMCPServerTrust'
|
||||
import type { MCPServer } from '@renderer/types'
|
||||
import { formatMcpError } from '@renderer/utils/error'
|
||||
import { matchKeywordsInString } from '@renderer/utils/match'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { Button, Dropdown, Empty } from 'antd'
|
||||
import { Plus } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { startTransition, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { SettingTitle } from '..'
|
||||
@ -115,7 +115,7 @@ const McpServersList: FC = () => {
|
||||
isActive: false
|
||||
}
|
||||
addMCPServer(newServer)
|
||||
navigate(`/settings/mcp/settings/${encodeURIComponent(newServer.id)}`)
|
||||
navigate({ to: `/settings/mcp/settings/${encodeURIComponent(newServer.id)}` })
|
||||
window.toast.success(t('settings.mcp.addSuccess'))
|
||||
}, [addMCPServer, navigate, t])
|
||||
|
||||
@ -260,7 +260,7 @@ const McpServersList: FC = () => {
|
||||
isLoading={loadingServerIds.has(server.id)}
|
||||
onToggle={async (active) => await handleToggleActive(server, active)}
|
||||
onDelete={() => onDeleteMcpServer(server)}
|
||||
onEdit={() => navigate(`/settings/mcp/settings/${encodeURIComponent(server.id)}`)}
|
||||
onEdit={() => navigate({ to: `/settings/mcp/settings/${encodeURIComponent(server.id)}` })}
|
||||
onOpenUrl={(url) => window.open(url, '_blank')}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -11,13 +11,13 @@ import MCPDescription from '@renderer/pages/settings/MCPSettings/McpDescription'
|
||||
import type { MCPPrompt, MCPResource, MCPServer, MCPTool } from '@renderer/types'
|
||||
import { parseKeyValueString } from '@renderer/utils/env'
|
||||
import { formatMcpError } from '@renderer/utils/error'
|
||||
import { useNavigate, useParams } from '@tanstack/react-router'
|
||||
import type { TabsProps } from 'antd'
|
||||
import { Badge, Form, Input, Radio, Select, Tabs } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { ChevronDown, SaveIcon } from 'lucide-react'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate, useParams } from 'react-router'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { SettingContainer, SettingDivider, SettingGroup, SettingTitle } from '..'
|
||||
@ -68,7 +68,8 @@ type TabKey = 'settings' | 'description' | 'tools' | 'prompts' | 'resources'
|
||||
|
||||
const McpSettings: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const { serverId } = useParams<{ serverId: string }>()
|
||||
const params = useParams({ strict: false }) as { serverId?: string }
|
||||
const serverId = params.serverId
|
||||
const decodedServerId = serverId ? decodeURIComponent(serverId) : ''
|
||||
const server = useMCPServer(decodedServerId).server as MCPServer
|
||||
const { deleteMCPServer, updateMCPServer } = useMCPServers()
|
||||
@ -376,7 +377,7 @@ const McpSettings: React.FC = () => {
|
||||
await window.api.mcp.removeServer(server)
|
||||
deleteMCPServer(server.id)
|
||||
window.toast.success(t('settings.mcp.deleteSuccess'))
|
||||
navigate('/settings/mcp')
|
||||
navigate({ to: '/settings/mcp' })
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
|
||||
@ -8,30 +8,17 @@ import TokenFluxProviderLogo from '@renderer/assets/images/providers/tokenflux.p
|
||||
import DividerWithText from '@renderer/components/DividerWithText'
|
||||
import ListItem from '@renderer/components/ListItem'
|
||||
import Scrollbar from '@renderer/components/Scrollbar'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useMCPServers } from '@renderer/hooks/useMCPServers'
|
||||
import { Link, Outlet, useLocation, useNavigate } from '@tanstack/react-router'
|
||||
import { Button, Flex } from 'antd'
|
||||
import { FolderCog, Package, ShoppingBag } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { SettingContainer } from '..'
|
||||
import BuiltinMCPServerList from './BuiltinMCPServerList'
|
||||
import InstallNpxUv from './InstallNpxUv'
|
||||
import McpMarketList from './McpMarketList'
|
||||
import ProviderDetail from './McpProviderSettings'
|
||||
import McpServersList from './McpServersList'
|
||||
import McpSettings from './McpSettings'
|
||||
import NpxSearch from './NpxSearch'
|
||||
import { providers } from './providers/config'
|
||||
|
||||
const MCPSettings: FC = () => {
|
||||
const { theme } = useTheme()
|
||||
const { t } = useTranslation()
|
||||
const { mcpServers } = useMCPServers()
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
|
||||
@ -84,7 +71,7 @@ const MCPSettings: FC = () => {
|
||||
<ListItem
|
||||
title={t('settings.mcp.servers', 'MCP Servers')}
|
||||
active={activeView === 'servers'}
|
||||
onClick={() => navigate('/settings/mcp/servers')}
|
||||
onClick={() => navigate({ to: '/settings/mcp/servers' })}
|
||||
icon={<FolderCog size={18} />}
|
||||
titleStyle={{ fontWeight: 500 }}
|
||||
/>
|
||||
@ -92,14 +79,14 @@ const MCPSettings: FC = () => {
|
||||
<ListItem
|
||||
title={t('settings.mcp.builtinServers', 'Built-in Servers')}
|
||||
active={activeView === 'builtin'}
|
||||
onClick={() => navigate('/settings/mcp/builtin')}
|
||||
onClick={() => navigate({ to: '/settings/mcp/builtin' })}
|
||||
icon={<Package size={18} />}
|
||||
titleStyle={{ fontWeight: 500 }}
|
||||
/>
|
||||
<ListItem
|
||||
title={t('settings.mcp.marketplaces', 'Marketplaces')}
|
||||
active={activeView === 'marketplaces'}
|
||||
onClick={() => navigate('/settings/mcp/marketplaces')}
|
||||
onClick={() => navigate({ to: '/settings/mcp/marketplaces' })}
|
||||
icon={<ShoppingBag size={18} />}
|
||||
titleStyle={{ fontWeight: 500 }}
|
||||
/>
|
||||
@ -109,7 +96,7 @@ const MCPSettings: FC = () => {
|
||||
key={provider.key}
|
||||
title={provider.name}
|
||||
active={activeView === provider.key}
|
||||
onClick={() => navigate(`/settings/mcp/${provider.key}`)}
|
||||
onClick={() => navigate({ to: `/settings/mcp/${provider.key}` })}
|
||||
icon={providerIcons[provider.key] || <FolderCog size={16} />}
|
||||
titleStyle={{ fontWeight: 500 }}
|
||||
/>
|
||||
@ -125,50 +112,7 @@ const MCPSettings: FC = () => {
|
||||
</Link>
|
||||
</BackButtonContainer>
|
||||
)}
|
||||
<Routes>
|
||||
<Route index element={<Navigate to="servers" replace />} />
|
||||
<Route path="servers" element={<McpServersList />} />
|
||||
<Route path="settings/:serverId" element={<McpSettings />} />
|
||||
<Route
|
||||
path="npx-search"
|
||||
element={
|
||||
<SettingContainer theme={theme}>
|
||||
<NpxSearch />
|
||||
</SettingContainer>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="mcp-install"
|
||||
element={
|
||||
<SettingContainer style={{ backgroundColor: 'inherit' }}>
|
||||
<InstallNpxUv />
|
||||
</SettingContainer>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="builtin"
|
||||
element={
|
||||
<ContentWrapper>
|
||||
<BuiltinMCPServerList />
|
||||
</ContentWrapper>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="marketplaces"
|
||||
element={
|
||||
<ContentWrapper>
|
||||
<McpMarketList />
|
||||
</ContentWrapper>
|
||||
}
|
||||
/>
|
||||
{providers.map((provider) => (
|
||||
<Route
|
||||
key={provider.key}
|
||||
path={provider.key}
|
||||
element={<ProviderDetail provider={provider} existingServers={mcpServers} />}
|
||||
/>
|
||||
))}
|
||||
</Routes>
|
||||
<Outlet />
|
||||
</RightContainer>
|
||||
</MainContainer>
|
||||
</Container>
|
||||
@ -212,12 +156,6 @@ const ProviderIcon = styled.img`
|
||||
background-color: var(--color-background-soft);
|
||||
`
|
||||
|
||||
const ContentWrapper = styled.div`
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
`
|
||||
|
||||
const BackButtonContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -14,13 +14,13 @@ import ImageStorage from '@renderer/services/ImageStorage'
|
||||
import type { Provider, ProviderType } from '@renderer/types'
|
||||
import { isSystemProvider } from '@renderer/types'
|
||||
import { getFancyProviderName, matchKeywordsInModel, matchKeywordsInProvider, uuid } from '@renderer/utils'
|
||||
import { useLocation, useNavigate, useSearch } from '@tanstack/react-router'
|
||||
import type { MenuProps } from 'antd'
|
||||
import { Dropdown, Input, Tag } from 'antd'
|
||||
import { GripVertical, PlusIcon, Search, UserPen } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { startTransition, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import AddProviderPopup from './AddProviderPopup'
|
||||
@ -35,7 +35,9 @@ const systemType = await window.api.system.getDeviceType()
|
||||
const cpuName = await window.api.system.getCpuName()
|
||||
|
||||
const ProviderList: FC = () => {
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const search = useSearch({ strict: false }) as Record<string, string | undefined>
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const providers = useAllProviders()
|
||||
const { updateProviders, addProvider, removeProvider, updateProvider } = useProviders()
|
||||
const { setTimeoutTimer } = useTimer()
|
||||
@ -72,8 +74,8 @@ const ProviderList: FC = () => {
|
||||
}, [providers])
|
||||
|
||||
useEffect(() => {
|
||||
if (searchParams.get('id')) {
|
||||
const providerId = searchParams.get('id')
|
||||
if (search.id) {
|
||||
const providerId = search.id
|
||||
const provider = providers.find((p) => p.id === providerId)
|
||||
if (provider) {
|
||||
setSelectedProvider(provider)
|
||||
@ -89,10 +91,17 @@ const ProviderList: FC = () => {
|
||||
} else {
|
||||
setSelectedProvider(providers[0])
|
||||
}
|
||||
searchParams.delete('id')
|
||||
setSearchParams(searchParams)
|
||||
// 清除 id 参数
|
||||
navigate({
|
||||
to: location.pathname,
|
||||
search: (prev) => {
|
||||
const { id: _, ...rest } = prev as Record<string, unknown>
|
||||
return rest
|
||||
},
|
||||
replace: true
|
||||
})
|
||||
}
|
||||
}, [providers, searchParams, setSearchParams, setSelectedProvider, setTimeoutTimer])
|
||||
}, [providers, search.id, navigate, location.pathname, setSelectedProvider, setTimeoutTimer])
|
||||
|
||||
// Handle provider add key from URL schema
|
||||
useEffect(() => {
|
||||
@ -106,7 +115,7 @@ const ProviderList: FC = () => {
|
||||
const { id } = data
|
||||
|
||||
const { updatedProvider, isNew, displayName } = await UrlSchemaInfoPopup.show(data)
|
||||
window.navigate(`/settings/provider?id=${id}`)
|
||||
navigate({ to: '/settings/provider', search: { id } })
|
||||
|
||||
if (!updatedProvider) {
|
||||
return
|
||||
@ -123,7 +132,7 @@ const ProviderList: FC = () => {
|
||||
}
|
||||
|
||||
// 检查 URL 参数
|
||||
const addProviderData = searchParams.get('addProviderData')
|
||||
const addProviderData = search.addProviderData
|
||||
if (!addProviderData) {
|
||||
return
|
||||
}
|
||||
@ -132,17 +141,17 @@ const ProviderList: FC = () => {
|
||||
const { id, apiKey: newApiKey, baseUrl, type, name } = JSON.parse(addProviderData)
|
||||
if (!id || !newApiKey || !baseUrl) {
|
||||
window.toast.error(t('settings.models.provider_key_add_failed_by_invalid_data'))
|
||||
window.navigate('/settings/provider')
|
||||
navigate({ to: '/settings/provider' })
|
||||
return
|
||||
}
|
||||
|
||||
handleProviderAddKey({ id, apiKey: newApiKey, baseUrl, type, name })
|
||||
} catch (error) {
|
||||
window.toast.error(t('settings.models.provider_key_add_failed_by_invalid_data'))
|
||||
window.navigate('/settings/provider')
|
||||
navigate({ to: '/settings/provider' })
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [searchParams])
|
||||
}, [search.addProviderData])
|
||||
|
||||
const onAddProvider = async () => {
|
||||
const { name: providerName, type, logo } = await AddProviderPopup.show()
|
||||
|
||||
@ -6,12 +6,12 @@ import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { getSelectionDescriptionLabel } from '@renderer/i18n/label'
|
||||
import SelectionToolbar from '@renderer/windows/selection/toolbar/SelectionToolbar'
|
||||
import type { SelectionFilterMode, SelectionTriggerMode } from '@shared/data/preference/preferenceTypes'
|
||||
import { Link } from '@tanstack/react-router'
|
||||
import { Row, Slider } from 'antd'
|
||||
import { CircleHelp, Edit2 } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { GlobalOutlined } from '@ant-design/icons'
|
||||
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
|
||||
import Scrollbar from '@renderer/components/Scrollbar'
|
||||
import ModelSettings from '@renderer/pages/settings/ModelSettings/ModelSettings'
|
||||
import { Link, Outlet, useLocation } from '@tanstack/react-router'
|
||||
import { Divider as AntDivider } from 'antd'
|
||||
import {
|
||||
Brain,
|
||||
@ -22,27 +22,11 @@ import {
|
||||
} from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Link, Route, Routes, useLocation } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import AboutSettings from './AboutSettings'
|
||||
import DataSettings from './DataSettings/DataSettings'
|
||||
import DisplaySettings from './DisplaySettings/DisplaySettings'
|
||||
import DocProcessSettings from './DocProcessSettings'
|
||||
import GeneralSettings from './GeneralSettings'
|
||||
import MCPSettings from './MCPSettings'
|
||||
import MemorySettings from './MemorySettings'
|
||||
import NotesSettings from './NotesSettings'
|
||||
import { ProviderList } from './ProviderSettings'
|
||||
import QuickAssistantSettings from './QuickAssistantSettings'
|
||||
import QuickPhraseSettings from './QuickPhraseSettings'
|
||||
import SelectionAssistantSettings from './SelectionAssistantSettings/SelectionAssistantSettings'
|
||||
import ShortcutSettings from './ShortcutSettings'
|
||||
import { ApiServerSettings } from './ToolSettings/ApiServerSettings'
|
||||
import WebSearchSettings from './WebSearchSettings'
|
||||
|
||||
const SettingsPage: FC = () => {
|
||||
const { pathname } = useLocation()
|
||||
const location = useLocation()
|
||||
const { pathname } = location
|
||||
const { t } = useTranslation()
|
||||
|
||||
const isRoute = (path: string): string => (pathname.startsWith(path) ? 'active' : '')
|
||||
@ -156,24 +140,7 @@ const SettingsPage: FC = () => {
|
||||
</MenuItemLink>
|
||||
</SettingMenus>
|
||||
<SettingContent>
|
||||
<Routes>
|
||||
<Route path="provider" element={<ProviderList />} />
|
||||
<Route path="model" element={<ModelSettings />} />
|
||||
<Route path="websearch" element={<WebSearchSettings />} />
|
||||
<Route path="api-server" element={<ApiServerSettings />} />
|
||||
<Route path="docprocess" element={<DocProcessSettings />} />
|
||||
<Route path="quickphrase" element={<QuickPhraseSettings />} />
|
||||
<Route path="mcp/*" element={<MCPSettings />} />
|
||||
<Route path="memory" element={<MemorySettings />} />
|
||||
<Route path="general/*" element={<GeneralSettings />} />
|
||||
<Route path="display" element={<DisplaySettings />} />
|
||||
<Route path="shortcut" element={<ShortcutSettings />} />
|
||||
<Route path="quickAssistant" element={<QuickAssistantSettings />} />
|
||||
<Route path="selectionAssistant" element={<SelectionAssistantSettings />} />
|
||||
<Route path="data" element={<DataSettings />} />
|
||||
<Route path="notes" element={<NotesSettings />} />
|
||||
<Route path="about" element={<AboutSettings />} />
|
||||
</Routes>
|
||||
<Outlet />
|
||||
</SettingContent>
|
||||
</ContentContainer>
|
||||
</Container>
|
||||
|
||||
@ -9,48 +9,510 @@
|
||||
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
||||
|
||||
import { Route as rootRouteImport } from './routes/__root'
|
||||
import { Route as TranslateRouteImport } from './routes/translate'
|
||||
import { Route as StoreRouteImport } from './routes/store'
|
||||
import { Route as SettingsRouteImport } from './routes/settings'
|
||||
import { Route as NotesRouteImport } from './routes/notes'
|
||||
import { Route as KnowledgeRouteImport } from './routes/knowledge'
|
||||
import { Route as FilesRouteImport } from './routes/files'
|
||||
import { Route as CodeRouteImport } from './routes/code'
|
||||
import { Route as ChatRouteImport } from './routes/chat'
|
||||
import { Route as IndexRouteImport } from './routes/index'
|
||||
import { Route as SettingsIndexRouteImport } from './routes/settings/index'
|
||||
import { Route as PaintingsIndexRouteImport } from './routes/paintings/index'
|
||||
import { Route as AppsIndexRouteImport } from './routes/apps/index'
|
||||
import { Route as SettingsWebsearchRouteImport } from './routes/settings/websearch'
|
||||
import { Route as SettingsShortcutRouteImport } from './routes/settings/shortcut'
|
||||
import { Route as SettingsSelectionAssistantRouteImport } from './routes/settings/selectionAssistant'
|
||||
import { Route as SettingsQuickphraseRouteImport } from './routes/settings/quickphrase'
|
||||
import { Route as SettingsQuickAssistantRouteImport } from './routes/settings/quickAssistant'
|
||||
import { Route as SettingsProviderRouteImport } from './routes/settings/provider'
|
||||
import { Route as SettingsNotesRouteImport } from './routes/settings/notes'
|
||||
import { Route as SettingsModelRouteImport } from './routes/settings/model'
|
||||
import { Route as SettingsMemoryRouteImport } from './routes/settings/memory'
|
||||
import { Route as SettingsMcpRouteImport } from './routes/settings/mcp'
|
||||
import { Route as SettingsGeneralRouteImport } from './routes/settings/general'
|
||||
import { Route as SettingsDocprocessRouteImport } from './routes/settings/docprocess'
|
||||
import { Route as SettingsDisplayRouteImport } from './routes/settings/display'
|
||||
import { Route as SettingsDataRouteImport } from './routes/settings/data'
|
||||
import { Route as SettingsApiServerRouteImport } from './routes/settings/api-server'
|
||||
import { Route as SettingsAboutRouteImport } from './routes/settings/about'
|
||||
import { Route as PaintingsSplatRouteImport } from './routes/paintings/$'
|
||||
import { Route as AppsAppIdRouteImport } from './routes/apps/$appId'
|
||||
import { Route as SettingsMcpIndexRouteImport } from './routes/settings/mcp/index'
|
||||
import { Route as SettingsMcpServersRouteImport } from './routes/settings/mcp/servers'
|
||||
import { Route as SettingsMcpNpxSearchRouteImport } from './routes/settings/mcp/npx-search'
|
||||
import { Route as SettingsMcpMcpInstallRouteImport } from './routes/settings/mcp/mcp-install'
|
||||
import { Route as SettingsMcpMarketplacesRouteImport } from './routes/settings/mcp/marketplaces'
|
||||
import { Route as SettingsMcpBuiltinRouteImport } from './routes/settings/mcp/builtin'
|
||||
import { Route as SettingsMcpSplatRouteImport } from './routes/settings/mcp/$'
|
||||
import { Route as SettingsMcpSettingsServerIdRouteImport } from './routes/settings/mcp/settings.$serverId'
|
||||
|
||||
const TranslateRoute = TranslateRouteImport.update({
|
||||
id: '/translate',
|
||||
path: '/translate',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const StoreRoute = StoreRouteImport.update({
|
||||
id: '/store',
|
||||
path: '/store',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const SettingsRoute = SettingsRouteImport.update({
|
||||
id: '/settings',
|
||||
path: '/settings',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const NotesRoute = NotesRouteImport.update({
|
||||
id: '/notes',
|
||||
path: '/notes',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const KnowledgeRoute = KnowledgeRouteImport.update({
|
||||
id: '/knowledge',
|
||||
path: '/knowledge',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const FilesRoute = FilesRouteImport.update({
|
||||
id: '/files',
|
||||
path: '/files',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const CodeRoute = CodeRouteImport.update({
|
||||
id: '/code',
|
||||
path: '/code',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const ChatRoute = ChatRouteImport.update({
|
||||
id: '/chat',
|
||||
path: '/chat',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const IndexRoute = IndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const SettingsIndexRoute = SettingsIndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const PaintingsIndexRoute = PaintingsIndexRouteImport.update({
|
||||
id: '/paintings/',
|
||||
path: '/paintings/',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const AppsIndexRoute = AppsIndexRouteImport.update({
|
||||
id: '/apps/',
|
||||
path: '/apps/',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const SettingsWebsearchRoute = SettingsWebsearchRouteImport.update({
|
||||
id: '/websearch',
|
||||
path: '/websearch',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsShortcutRoute = SettingsShortcutRouteImport.update({
|
||||
id: '/shortcut',
|
||||
path: '/shortcut',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsSelectionAssistantRoute =
|
||||
SettingsSelectionAssistantRouteImport.update({
|
||||
id: '/selectionAssistant',
|
||||
path: '/selectionAssistant',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsQuickphraseRoute = SettingsQuickphraseRouteImport.update({
|
||||
id: '/quickphrase',
|
||||
path: '/quickphrase',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsQuickAssistantRoute = SettingsQuickAssistantRouteImport.update({
|
||||
id: '/quickAssistant',
|
||||
path: '/quickAssistant',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsProviderRoute = SettingsProviderRouteImport.update({
|
||||
id: '/provider',
|
||||
path: '/provider',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsNotesRoute = SettingsNotesRouteImport.update({
|
||||
id: '/notes',
|
||||
path: '/notes',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsModelRoute = SettingsModelRouteImport.update({
|
||||
id: '/model',
|
||||
path: '/model',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsMemoryRoute = SettingsMemoryRouteImport.update({
|
||||
id: '/memory',
|
||||
path: '/memory',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsMcpRoute = SettingsMcpRouteImport.update({
|
||||
id: '/mcp',
|
||||
path: '/mcp',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsGeneralRoute = SettingsGeneralRouteImport.update({
|
||||
id: '/general',
|
||||
path: '/general',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsDocprocessRoute = SettingsDocprocessRouteImport.update({
|
||||
id: '/docprocess',
|
||||
path: '/docprocess',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsDisplayRoute = SettingsDisplayRouteImport.update({
|
||||
id: '/display',
|
||||
path: '/display',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsDataRoute = SettingsDataRouteImport.update({
|
||||
id: '/data',
|
||||
path: '/data',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsApiServerRoute = SettingsApiServerRouteImport.update({
|
||||
id: '/api-server',
|
||||
path: '/api-server',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const SettingsAboutRoute = SettingsAboutRouteImport.update({
|
||||
id: '/about',
|
||||
path: '/about',
|
||||
getParentRoute: () => SettingsRoute,
|
||||
} as any)
|
||||
const PaintingsSplatRoute = PaintingsSplatRouteImport.update({
|
||||
id: '/paintings/$',
|
||||
path: '/paintings/$',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const AppsAppIdRoute = AppsAppIdRouteImport.update({
|
||||
id: '/apps/$appId',
|
||||
path: '/apps/$appId',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const SettingsMcpIndexRoute = SettingsMcpIndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () => SettingsMcpRoute,
|
||||
} as any)
|
||||
const SettingsMcpServersRoute = SettingsMcpServersRouteImport.update({
|
||||
id: '/servers',
|
||||
path: '/servers',
|
||||
getParentRoute: () => SettingsMcpRoute,
|
||||
} as any)
|
||||
const SettingsMcpNpxSearchRoute = SettingsMcpNpxSearchRouteImport.update({
|
||||
id: '/npx-search',
|
||||
path: '/npx-search',
|
||||
getParentRoute: () => SettingsMcpRoute,
|
||||
} as any)
|
||||
const SettingsMcpMcpInstallRoute = SettingsMcpMcpInstallRouteImport.update({
|
||||
id: '/mcp-install',
|
||||
path: '/mcp-install',
|
||||
getParentRoute: () => SettingsMcpRoute,
|
||||
} as any)
|
||||
const SettingsMcpMarketplacesRoute = SettingsMcpMarketplacesRouteImport.update({
|
||||
id: '/marketplaces',
|
||||
path: '/marketplaces',
|
||||
getParentRoute: () => SettingsMcpRoute,
|
||||
} as any)
|
||||
const SettingsMcpBuiltinRoute = SettingsMcpBuiltinRouteImport.update({
|
||||
id: '/builtin',
|
||||
path: '/builtin',
|
||||
getParentRoute: () => SettingsMcpRoute,
|
||||
} as any)
|
||||
const SettingsMcpSplatRoute = SettingsMcpSplatRouteImport.update({
|
||||
id: '/$',
|
||||
path: '/$',
|
||||
getParentRoute: () => SettingsMcpRoute,
|
||||
} as any)
|
||||
const SettingsMcpSettingsServerIdRoute =
|
||||
SettingsMcpSettingsServerIdRouteImport.update({
|
||||
id: '/settings/$serverId',
|
||||
path: '/settings/$serverId',
|
||||
getParentRoute: () => SettingsMcpRoute,
|
||||
} as any)
|
||||
|
||||
export interface FileRoutesByFullPath {
|
||||
'/': typeof IndexRoute
|
||||
'/settings': typeof SettingsRoute
|
||||
'/chat': typeof ChatRoute
|
||||
'/code': typeof CodeRoute
|
||||
'/files': typeof FilesRoute
|
||||
'/knowledge': typeof KnowledgeRoute
|
||||
'/notes': typeof NotesRoute
|
||||
'/settings': typeof SettingsRouteWithChildren
|
||||
'/store': typeof StoreRoute
|
||||
'/translate': typeof TranslateRoute
|
||||
'/apps/$appId': typeof AppsAppIdRoute
|
||||
'/paintings/$': typeof PaintingsSplatRoute
|
||||
'/settings/about': typeof SettingsAboutRoute
|
||||
'/settings/api-server': typeof SettingsApiServerRoute
|
||||
'/settings/data': typeof SettingsDataRoute
|
||||
'/settings/display': typeof SettingsDisplayRoute
|
||||
'/settings/docprocess': typeof SettingsDocprocessRoute
|
||||
'/settings/general': typeof SettingsGeneralRoute
|
||||
'/settings/mcp': typeof SettingsMcpRouteWithChildren
|
||||
'/settings/memory': typeof SettingsMemoryRoute
|
||||
'/settings/model': typeof SettingsModelRoute
|
||||
'/settings/notes': typeof SettingsNotesRoute
|
||||
'/settings/provider': typeof SettingsProviderRoute
|
||||
'/settings/quickAssistant': typeof SettingsQuickAssistantRoute
|
||||
'/settings/quickphrase': typeof SettingsQuickphraseRoute
|
||||
'/settings/selectionAssistant': typeof SettingsSelectionAssistantRoute
|
||||
'/settings/shortcut': typeof SettingsShortcutRoute
|
||||
'/settings/websearch': typeof SettingsWebsearchRoute
|
||||
'/apps': typeof AppsIndexRoute
|
||||
'/paintings': typeof PaintingsIndexRoute
|
||||
'/settings/': typeof SettingsIndexRoute
|
||||
'/settings/mcp/$': typeof SettingsMcpSplatRoute
|
||||
'/settings/mcp/builtin': typeof SettingsMcpBuiltinRoute
|
||||
'/settings/mcp/marketplaces': typeof SettingsMcpMarketplacesRoute
|
||||
'/settings/mcp/mcp-install': typeof SettingsMcpMcpInstallRoute
|
||||
'/settings/mcp/npx-search': typeof SettingsMcpNpxSearchRoute
|
||||
'/settings/mcp/servers': typeof SettingsMcpServersRoute
|
||||
'/settings/mcp/': typeof SettingsMcpIndexRoute
|
||||
'/settings/mcp/settings/$serverId': typeof SettingsMcpSettingsServerIdRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof IndexRoute
|
||||
'/settings': typeof SettingsRoute
|
||||
'/chat': typeof ChatRoute
|
||||
'/code': typeof CodeRoute
|
||||
'/files': typeof FilesRoute
|
||||
'/knowledge': typeof KnowledgeRoute
|
||||
'/notes': typeof NotesRoute
|
||||
'/store': typeof StoreRoute
|
||||
'/translate': typeof TranslateRoute
|
||||
'/apps/$appId': typeof AppsAppIdRoute
|
||||
'/paintings/$': typeof PaintingsSplatRoute
|
||||
'/settings/about': typeof SettingsAboutRoute
|
||||
'/settings/api-server': typeof SettingsApiServerRoute
|
||||
'/settings/data': typeof SettingsDataRoute
|
||||
'/settings/display': typeof SettingsDisplayRoute
|
||||
'/settings/docprocess': typeof SettingsDocprocessRoute
|
||||
'/settings/general': typeof SettingsGeneralRoute
|
||||
'/settings/memory': typeof SettingsMemoryRoute
|
||||
'/settings/model': typeof SettingsModelRoute
|
||||
'/settings/notes': typeof SettingsNotesRoute
|
||||
'/settings/provider': typeof SettingsProviderRoute
|
||||
'/settings/quickAssistant': typeof SettingsQuickAssistantRoute
|
||||
'/settings/quickphrase': typeof SettingsQuickphraseRoute
|
||||
'/settings/selectionAssistant': typeof SettingsSelectionAssistantRoute
|
||||
'/settings/shortcut': typeof SettingsShortcutRoute
|
||||
'/settings/websearch': typeof SettingsWebsearchRoute
|
||||
'/apps': typeof AppsIndexRoute
|
||||
'/paintings': typeof PaintingsIndexRoute
|
||||
'/settings': typeof SettingsIndexRoute
|
||||
'/settings/mcp/$': typeof SettingsMcpSplatRoute
|
||||
'/settings/mcp/builtin': typeof SettingsMcpBuiltinRoute
|
||||
'/settings/mcp/marketplaces': typeof SettingsMcpMarketplacesRoute
|
||||
'/settings/mcp/mcp-install': typeof SettingsMcpMcpInstallRoute
|
||||
'/settings/mcp/npx-search': typeof SettingsMcpNpxSearchRoute
|
||||
'/settings/mcp/servers': typeof SettingsMcpServersRoute
|
||||
'/settings/mcp': typeof SettingsMcpIndexRoute
|
||||
'/settings/mcp/settings/$serverId': typeof SettingsMcpSettingsServerIdRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
'/': typeof IndexRoute
|
||||
'/settings': typeof SettingsRoute
|
||||
'/chat': typeof ChatRoute
|
||||
'/code': typeof CodeRoute
|
||||
'/files': typeof FilesRoute
|
||||
'/knowledge': typeof KnowledgeRoute
|
||||
'/notes': typeof NotesRoute
|
||||
'/settings': typeof SettingsRouteWithChildren
|
||||
'/store': typeof StoreRoute
|
||||
'/translate': typeof TranslateRoute
|
||||
'/apps/$appId': typeof AppsAppIdRoute
|
||||
'/paintings/$': typeof PaintingsSplatRoute
|
||||
'/settings/about': typeof SettingsAboutRoute
|
||||
'/settings/api-server': typeof SettingsApiServerRoute
|
||||
'/settings/data': typeof SettingsDataRoute
|
||||
'/settings/display': typeof SettingsDisplayRoute
|
||||
'/settings/docprocess': typeof SettingsDocprocessRoute
|
||||
'/settings/general': typeof SettingsGeneralRoute
|
||||
'/settings/mcp': typeof SettingsMcpRouteWithChildren
|
||||
'/settings/memory': typeof SettingsMemoryRoute
|
||||
'/settings/model': typeof SettingsModelRoute
|
||||
'/settings/notes': typeof SettingsNotesRoute
|
||||
'/settings/provider': typeof SettingsProviderRoute
|
||||
'/settings/quickAssistant': typeof SettingsQuickAssistantRoute
|
||||
'/settings/quickphrase': typeof SettingsQuickphraseRoute
|
||||
'/settings/selectionAssistant': typeof SettingsSelectionAssistantRoute
|
||||
'/settings/shortcut': typeof SettingsShortcutRoute
|
||||
'/settings/websearch': typeof SettingsWebsearchRoute
|
||||
'/apps/': typeof AppsIndexRoute
|
||||
'/paintings/': typeof PaintingsIndexRoute
|
||||
'/settings/': typeof SettingsIndexRoute
|
||||
'/settings/mcp/$': typeof SettingsMcpSplatRoute
|
||||
'/settings/mcp/builtin': typeof SettingsMcpBuiltinRoute
|
||||
'/settings/mcp/marketplaces': typeof SettingsMcpMarketplacesRoute
|
||||
'/settings/mcp/mcp-install': typeof SettingsMcpMcpInstallRoute
|
||||
'/settings/mcp/npx-search': typeof SettingsMcpNpxSearchRoute
|
||||
'/settings/mcp/servers': typeof SettingsMcpServersRoute
|
||||
'/settings/mcp/': typeof SettingsMcpIndexRoute
|
||||
'/settings/mcp/settings/$serverId': typeof SettingsMcpSettingsServerIdRoute
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths: '/' | '/settings'
|
||||
fullPaths:
|
||||
| '/'
|
||||
| '/chat'
|
||||
| '/code'
|
||||
| '/files'
|
||||
| '/knowledge'
|
||||
| '/notes'
|
||||
| '/settings'
|
||||
| '/store'
|
||||
| '/translate'
|
||||
| '/apps/$appId'
|
||||
| '/paintings/$'
|
||||
| '/settings/about'
|
||||
| '/settings/api-server'
|
||||
| '/settings/data'
|
||||
| '/settings/display'
|
||||
| '/settings/docprocess'
|
||||
| '/settings/general'
|
||||
| '/settings/mcp'
|
||||
| '/settings/memory'
|
||||
| '/settings/model'
|
||||
| '/settings/notes'
|
||||
| '/settings/provider'
|
||||
| '/settings/quickAssistant'
|
||||
| '/settings/quickphrase'
|
||||
| '/settings/selectionAssistant'
|
||||
| '/settings/shortcut'
|
||||
| '/settings/websearch'
|
||||
| '/apps'
|
||||
| '/paintings'
|
||||
| '/settings/'
|
||||
| '/settings/mcp/$'
|
||||
| '/settings/mcp/builtin'
|
||||
| '/settings/mcp/marketplaces'
|
||||
| '/settings/mcp/mcp-install'
|
||||
| '/settings/mcp/npx-search'
|
||||
| '/settings/mcp/servers'
|
||||
| '/settings/mcp/'
|
||||
| '/settings/mcp/settings/$serverId'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to: '/' | '/settings'
|
||||
id: '__root__' | '/' | '/settings'
|
||||
to:
|
||||
| '/'
|
||||
| '/chat'
|
||||
| '/code'
|
||||
| '/files'
|
||||
| '/knowledge'
|
||||
| '/notes'
|
||||
| '/store'
|
||||
| '/translate'
|
||||
| '/apps/$appId'
|
||||
| '/paintings/$'
|
||||
| '/settings/about'
|
||||
| '/settings/api-server'
|
||||
| '/settings/data'
|
||||
| '/settings/display'
|
||||
| '/settings/docprocess'
|
||||
| '/settings/general'
|
||||
| '/settings/memory'
|
||||
| '/settings/model'
|
||||
| '/settings/notes'
|
||||
| '/settings/provider'
|
||||
| '/settings/quickAssistant'
|
||||
| '/settings/quickphrase'
|
||||
| '/settings/selectionAssistant'
|
||||
| '/settings/shortcut'
|
||||
| '/settings/websearch'
|
||||
| '/apps'
|
||||
| '/paintings'
|
||||
| '/settings'
|
||||
| '/settings/mcp/$'
|
||||
| '/settings/mcp/builtin'
|
||||
| '/settings/mcp/marketplaces'
|
||||
| '/settings/mcp/mcp-install'
|
||||
| '/settings/mcp/npx-search'
|
||||
| '/settings/mcp/servers'
|
||||
| '/settings/mcp'
|
||||
| '/settings/mcp/settings/$serverId'
|
||||
id:
|
||||
| '__root__'
|
||||
| '/'
|
||||
| '/chat'
|
||||
| '/code'
|
||||
| '/files'
|
||||
| '/knowledge'
|
||||
| '/notes'
|
||||
| '/settings'
|
||||
| '/store'
|
||||
| '/translate'
|
||||
| '/apps/$appId'
|
||||
| '/paintings/$'
|
||||
| '/settings/about'
|
||||
| '/settings/api-server'
|
||||
| '/settings/data'
|
||||
| '/settings/display'
|
||||
| '/settings/docprocess'
|
||||
| '/settings/general'
|
||||
| '/settings/mcp'
|
||||
| '/settings/memory'
|
||||
| '/settings/model'
|
||||
| '/settings/notes'
|
||||
| '/settings/provider'
|
||||
| '/settings/quickAssistant'
|
||||
| '/settings/quickphrase'
|
||||
| '/settings/selectionAssistant'
|
||||
| '/settings/shortcut'
|
||||
| '/settings/websearch'
|
||||
| '/apps/'
|
||||
| '/paintings/'
|
||||
| '/settings/'
|
||||
| '/settings/mcp/$'
|
||||
| '/settings/mcp/builtin'
|
||||
| '/settings/mcp/marketplaces'
|
||||
| '/settings/mcp/mcp-install'
|
||||
| '/settings/mcp/npx-search'
|
||||
| '/settings/mcp/servers'
|
||||
| '/settings/mcp/'
|
||||
| '/settings/mcp/settings/$serverId'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
SettingsRoute: typeof SettingsRoute
|
||||
ChatRoute: typeof ChatRoute
|
||||
CodeRoute: typeof CodeRoute
|
||||
FilesRoute: typeof FilesRoute
|
||||
KnowledgeRoute: typeof KnowledgeRoute
|
||||
NotesRoute: typeof NotesRoute
|
||||
SettingsRoute: typeof SettingsRouteWithChildren
|
||||
StoreRoute: typeof StoreRoute
|
||||
TranslateRoute: typeof TranslateRoute
|
||||
AppsAppIdRoute: typeof AppsAppIdRoute
|
||||
PaintingsSplatRoute: typeof PaintingsSplatRoute
|
||||
AppsIndexRoute: typeof AppsIndexRoute
|
||||
PaintingsIndexRoute: typeof PaintingsIndexRoute
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface FileRoutesByPath {
|
||||
'/translate': {
|
||||
id: '/translate'
|
||||
path: '/translate'
|
||||
fullPath: '/translate'
|
||||
preLoaderRoute: typeof TranslateRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/store': {
|
||||
id: '/store'
|
||||
path: '/store'
|
||||
fullPath: '/store'
|
||||
preLoaderRoute: typeof StoreRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/settings': {
|
||||
id: '/settings'
|
||||
path: '/settings'
|
||||
@ -58,6 +520,41 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof SettingsRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/notes': {
|
||||
id: '/notes'
|
||||
path: '/notes'
|
||||
fullPath: '/notes'
|
||||
preLoaderRoute: typeof NotesRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/knowledge': {
|
||||
id: '/knowledge'
|
||||
path: '/knowledge'
|
||||
fullPath: '/knowledge'
|
||||
preLoaderRoute: typeof KnowledgeRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/files': {
|
||||
id: '/files'
|
||||
path: '/files'
|
||||
fullPath: '/files'
|
||||
preLoaderRoute: typeof FilesRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/code': {
|
||||
id: '/code'
|
||||
path: '/code'
|
||||
fullPath: '/code'
|
||||
preLoaderRoute: typeof CodeRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/chat': {
|
||||
id: '/chat'
|
||||
path: '/chat'
|
||||
fullPath: '/chat'
|
||||
preLoaderRoute: typeof ChatRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/': {
|
||||
id: '/'
|
||||
path: '/'
|
||||
@ -65,12 +562,296 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof IndexRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/settings/': {
|
||||
id: '/settings/'
|
||||
path: '/'
|
||||
fullPath: '/settings/'
|
||||
preLoaderRoute: typeof SettingsIndexRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/paintings/': {
|
||||
id: '/paintings/'
|
||||
path: '/paintings'
|
||||
fullPath: '/paintings'
|
||||
preLoaderRoute: typeof PaintingsIndexRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/apps/': {
|
||||
id: '/apps/'
|
||||
path: '/apps'
|
||||
fullPath: '/apps'
|
||||
preLoaderRoute: typeof AppsIndexRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/settings/websearch': {
|
||||
id: '/settings/websearch'
|
||||
path: '/websearch'
|
||||
fullPath: '/settings/websearch'
|
||||
preLoaderRoute: typeof SettingsWebsearchRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/shortcut': {
|
||||
id: '/settings/shortcut'
|
||||
path: '/shortcut'
|
||||
fullPath: '/settings/shortcut'
|
||||
preLoaderRoute: typeof SettingsShortcutRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/selectionAssistant': {
|
||||
id: '/settings/selectionAssistant'
|
||||
path: '/selectionAssistant'
|
||||
fullPath: '/settings/selectionAssistant'
|
||||
preLoaderRoute: typeof SettingsSelectionAssistantRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/quickphrase': {
|
||||
id: '/settings/quickphrase'
|
||||
path: '/quickphrase'
|
||||
fullPath: '/settings/quickphrase'
|
||||
preLoaderRoute: typeof SettingsQuickphraseRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/quickAssistant': {
|
||||
id: '/settings/quickAssistant'
|
||||
path: '/quickAssistant'
|
||||
fullPath: '/settings/quickAssistant'
|
||||
preLoaderRoute: typeof SettingsQuickAssistantRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/provider': {
|
||||
id: '/settings/provider'
|
||||
path: '/provider'
|
||||
fullPath: '/settings/provider'
|
||||
preLoaderRoute: typeof SettingsProviderRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/notes': {
|
||||
id: '/settings/notes'
|
||||
path: '/notes'
|
||||
fullPath: '/settings/notes'
|
||||
preLoaderRoute: typeof SettingsNotesRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/model': {
|
||||
id: '/settings/model'
|
||||
path: '/model'
|
||||
fullPath: '/settings/model'
|
||||
preLoaderRoute: typeof SettingsModelRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/memory': {
|
||||
id: '/settings/memory'
|
||||
path: '/memory'
|
||||
fullPath: '/settings/memory'
|
||||
preLoaderRoute: typeof SettingsMemoryRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/mcp': {
|
||||
id: '/settings/mcp'
|
||||
path: '/mcp'
|
||||
fullPath: '/settings/mcp'
|
||||
preLoaderRoute: typeof SettingsMcpRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/general': {
|
||||
id: '/settings/general'
|
||||
path: '/general'
|
||||
fullPath: '/settings/general'
|
||||
preLoaderRoute: typeof SettingsGeneralRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/docprocess': {
|
||||
id: '/settings/docprocess'
|
||||
path: '/docprocess'
|
||||
fullPath: '/settings/docprocess'
|
||||
preLoaderRoute: typeof SettingsDocprocessRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/display': {
|
||||
id: '/settings/display'
|
||||
path: '/display'
|
||||
fullPath: '/settings/display'
|
||||
preLoaderRoute: typeof SettingsDisplayRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/data': {
|
||||
id: '/settings/data'
|
||||
path: '/data'
|
||||
fullPath: '/settings/data'
|
||||
preLoaderRoute: typeof SettingsDataRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/api-server': {
|
||||
id: '/settings/api-server'
|
||||
path: '/api-server'
|
||||
fullPath: '/settings/api-server'
|
||||
preLoaderRoute: typeof SettingsApiServerRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/settings/about': {
|
||||
id: '/settings/about'
|
||||
path: '/about'
|
||||
fullPath: '/settings/about'
|
||||
preLoaderRoute: typeof SettingsAboutRouteImport
|
||||
parentRoute: typeof SettingsRoute
|
||||
}
|
||||
'/paintings/$': {
|
||||
id: '/paintings/$'
|
||||
path: '/paintings/$'
|
||||
fullPath: '/paintings/$'
|
||||
preLoaderRoute: typeof PaintingsSplatRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/apps/$appId': {
|
||||
id: '/apps/$appId'
|
||||
path: '/apps/$appId'
|
||||
fullPath: '/apps/$appId'
|
||||
preLoaderRoute: typeof AppsAppIdRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/settings/mcp/': {
|
||||
id: '/settings/mcp/'
|
||||
path: '/'
|
||||
fullPath: '/settings/mcp/'
|
||||
preLoaderRoute: typeof SettingsMcpIndexRouteImport
|
||||
parentRoute: typeof SettingsMcpRoute
|
||||
}
|
||||
'/settings/mcp/servers': {
|
||||
id: '/settings/mcp/servers'
|
||||
path: '/servers'
|
||||
fullPath: '/settings/mcp/servers'
|
||||
preLoaderRoute: typeof SettingsMcpServersRouteImport
|
||||
parentRoute: typeof SettingsMcpRoute
|
||||
}
|
||||
'/settings/mcp/npx-search': {
|
||||
id: '/settings/mcp/npx-search'
|
||||
path: '/npx-search'
|
||||
fullPath: '/settings/mcp/npx-search'
|
||||
preLoaderRoute: typeof SettingsMcpNpxSearchRouteImport
|
||||
parentRoute: typeof SettingsMcpRoute
|
||||
}
|
||||
'/settings/mcp/mcp-install': {
|
||||
id: '/settings/mcp/mcp-install'
|
||||
path: '/mcp-install'
|
||||
fullPath: '/settings/mcp/mcp-install'
|
||||
preLoaderRoute: typeof SettingsMcpMcpInstallRouteImport
|
||||
parentRoute: typeof SettingsMcpRoute
|
||||
}
|
||||
'/settings/mcp/marketplaces': {
|
||||
id: '/settings/mcp/marketplaces'
|
||||
path: '/marketplaces'
|
||||
fullPath: '/settings/mcp/marketplaces'
|
||||
preLoaderRoute: typeof SettingsMcpMarketplacesRouteImport
|
||||
parentRoute: typeof SettingsMcpRoute
|
||||
}
|
||||
'/settings/mcp/builtin': {
|
||||
id: '/settings/mcp/builtin'
|
||||
path: '/builtin'
|
||||
fullPath: '/settings/mcp/builtin'
|
||||
preLoaderRoute: typeof SettingsMcpBuiltinRouteImport
|
||||
parentRoute: typeof SettingsMcpRoute
|
||||
}
|
||||
'/settings/mcp/$': {
|
||||
id: '/settings/mcp/$'
|
||||
path: '/$'
|
||||
fullPath: '/settings/mcp/$'
|
||||
preLoaderRoute: typeof SettingsMcpSplatRouteImport
|
||||
parentRoute: typeof SettingsMcpRoute
|
||||
}
|
||||
'/settings/mcp/settings/$serverId': {
|
||||
id: '/settings/mcp/settings/$serverId'
|
||||
path: '/settings/$serverId'
|
||||
fullPath: '/settings/mcp/settings/$serverId'
|
||||
preLoaderRoute: typeof SettingsMcpSettingsServerIdRouteImport
|
||||
parentRoute: typeof SettingsMcpRoute
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface SettingsMcpRouteChildren {
|
||||
SettingsMcpSplatRoute: typeof SettingsMcpSplatRoute
|
||||
SettingsMcpBuiltinRoute: typeof SettingsMcpBuiltinRoute
|
||||
SettingsMcpMarketplacesRoute: typeof SettingsMcpMarketplacesRoute
|
||||
SettingsMcpMcpInstallRoute: typeof SettingsMcpMcpInstallRoute
|
||||
SettingsMcpNpxSearchRoute: typeof SettingsMcpNpxSearchRoute
|
||||
SettingsMcpServersRoute: typeof SettingsMcpServersRoute
|
||||
SettingsMcpIndexRoute: typeof SettingsMcpIndexRoute
|
||||
SettingsMcpSettingsServerIdRoute: typeof SettingsMcpSettingsServerIdRoute
|
||||
}
|
||||
|
||||
const SettingsMcpRouteChildren: SettingsMcpRouteChildren = {
|
||||
SettingsMcpSplatRoute: SettingsMcpSplatRoute,
|
||||
SettingsMcpBuiltinRoute: SettingsMcpBuiltinRoute,
|
||||
SettingsMcpMarketplacesRoute: SettingsMcpMarketplacesRoute,
|
||||
SettingsMcpMcpInstallRoute: SettingsMcpMcpInstallRoute,
|
||||
SettingsMcpNpxSearchRoute: SettingsMcpNpxSearchRoute,
|
||||
SettingsMcpServersRoute: SettingsMcpServersRoute,
|
||||
SettingsMcpIndexRoute: SettingsMcpIndexRoute,
|
||||
SettingsMcpSettingsServerIdRoute: SettingsMcpSettingsServerIdRoute,
|
||||
}
|
||||
|
||||
const SettingsMcpRouteWithChildren = SettingsMcpRoute._addFileChildren(
|
||||
SettingsMcpRouteChildren,
|
||||
)
|
||||
|
||||
interface SettingsRouteChildren {
|
||||
SettingsAboutRoute: typeof SettingsAboutRoute
|
||||
SettingsApiServerRoute: typeof SettingsApiServerRoute
|
||||
SettingsDataRoute: typeof SettingsDataRoute
|
||||
SettingsDisplayRoute: typeof SettingsDisplayRoute
|
||||
SettingsDocprocessRoute: typeof SettingsDocprocessRoute
|
||||
SettingsGeneralRoute: typeof SettingsGeneralRoute
|
||||
SettingsMcpRoute: typeof SettingsMcpRouteWithChildren
|
||||
SettingsMemoryRoute: typeof SettingsMemoryRoute
|
||||
SettingsModelRoute: typeof SettingsModelRoute
|
||||
SettingsNotesRoute: typeof SettingsNotesRoute
|
||||
SettingsProviderRoute: typeof SettingsProviderRoute
|
||||
SettingsQuickAssistantRoute: typeof SettingsQuickAssistantRoute
|
||||
SettingsQuickphraseRoute: typeof SettingsQuickphraseRoute
|
||||
SettingsSelectionAssistantRoute: typeof SettingsSelectionAssistantRoute
|
||||
SettingsShortcutRoute: typeof SettingsShortcutRoute
|
||||
SettingsWebsearchRoute: typeof SettingsWebsearchRoute
|
||||
SettingsIndexRoute: typeof SettingsIndexRoute
|
||||
}
|
||||
|
||||
const SettingsRouteChildren: SettingsRouteChildren = {
|
||||
SettingsAboutRoute: SettingsAboutRoute,
|
||||
SettingsApiServerRoute: SettingsApiServerRoute,
|
||||
SettingsDataRoute: SettingsDataRoute,
|
||||
SettingsDisplayRoute: SettingsDisplayRoute,
|
||||
SettingsDocprocessRoute: SettingsDocprocessRoute,
|
||||
SettingsGeneralRoute: SettingsGeneralRoute,
|
||||
SettingsMcpRoute: SettingsMcpRouteWithChildren,
|
||||
SettingsMemoryRoute: SettingsMemoryRoute,
|
||||
SettingsModelRoute: SettingsModelRoute,
|
||||
SettingsNotesRoute: SettingsNotesRoute,
|
||||
SettingsProviderRoute: SettingsProviderRoute,
|
||||
SettingsQuickAssistantRoute: SettingsQuickAssistantRoute,
|
||||
SettingsQuickphraseRoute: SettingsQuickphraseRoute,
|
||||
SettingsSelectionAssistantRoute: SettingsSelectionAssistantRoute,
|
||||
SettingsShortcutRoute: SettingsShortcutRoute,
|
||||
SettingsWebsearchRoute: SettingsWebsearchRoute,
|
||||
SettingsIndexRoute: SettingsIndexRoute,
|
||||
}
|
||||
|
||||
const SettingsRouteWithChildren = SettingsRoute._addFileChildren(
|
||||
SettingsRouteChildren,
|
||||
)
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
SettingsRoute: SettingsRoute,
|
||||
ChatRoute: ChatRoute,
|
||||
CodeRoute: CodeRoute,
|
||||
FilesRoute: FilesRoute,
|
||||
KnowledgeRoute: KnowledgeRoute,
|
||||
NotesRoute: NotesRoute,
|
||||
SettingsRoute: SettingsRouteWithChildren,
|
||||
StoreRoute: StoreRoute,
|
||||
TranslateRoute: TranslateRoute,
|
||||
AppsAppIdRoute: AppsAppIdRoute,
|
||||
PaintingsSplatRoute: PaintingsSplatRoute,
|
||||
AppsIndexRoute: AppsIndexRoute,
|
||||
PaintingsIndexRoute: PaintingsIndexRoute,
|
||||
}
|
||||
export const routeTree = rootRouteImport
|
||||
._addFileChildren(rootRouteChildren)
|
||||
|
||||
@ -23,9 +23,9 @@ import {
|
||||
} from '@renderer/utils/messageUtils/create'
|
||||
import { filterContextMessages } from '@renderer/utils/messageUtils/filters'
|
||||
import { getMainTextContent } from '@renderer/utils/messageUtils/find'
|
||||
import type { UseNavigateResult } from '@tanstack/react-router'
|
||||
import dayjs from 'dayjs'
|
||||
import { t } from 'i18next'
|
||||
import type { NavigateFunction } from 'react-router'
|
||||
|
||||
import { getAssistantById, getAssistantProvider, getDefaultModel } from './AssistantService'
|
||||
import { EVENT_NAMES, EventEmitter } from './EventService'
|
||||
@ -68,14 +68,14 @@ export function deleteMessageFiles(message: Message) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function locateToMessage(navigate: NavigateFunction, message: Message) {
|
||||
export async function locateToMessage(navigate: UseNavigateResult<string>, message: Message) {
|
||||
await modelGenerating()
|
||||
|
||||
SearchPopup.hide()
|
||||
const assistant = getAssistantById(message.assistantId)
|
||||
const topic = await getTopicById(message.topicId)
|
||||
|
||||
navigate('/', { state: { assistant, topic } })
|
||||
navigate({ to: '/chat', search: { assistantId: assistant?.id, topicId: topic?.id } })
|
||||
|
||||
setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 0)
|
||||
setTimeout(() => EventEmitter.emit(EVENT_NAMES.LOCATE_MESSAGE + ':' + message.id), 300)
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
import type { NavigateFunction } from 'react-router-dom'
|
||||
import type { UseNavigateResult } from '@tanstack/react-router'
|
||||
|
||||
// Tab 导航服务 - 用于在非 React 组件中进行路由导航
|
||||
interface INavigationService {
|
||||
navigate: NavigateFunction | null
|
||||
setNavigate: (navigateFunc: NavigateFunction) => void
|
||||
navigate: UseNavigateResult<string> | null
|
||||
setNavigate: (navigateFunc: UseNavigateResult<string>) => void
|
||||
}
|
||||
|
||||
const NavigationService: INavigationService = {
|
||||
navigate: null,
|
||||
|
||||
setNavigate: (navigateFunc: NavigateFunction): void => {
|
||||
setNavigate: (navigateFunc: UseNavigateResult<string>): void => {
|
||||
NavigationService.navigate = navigateFunc
|
||||
window.navigate = NavigationService.navigate
|
||||
}
|
||||
|
||||
@ -55,12 +55,12 @@ class TabsService {
|
||||
|
||||
// 使用 NavigationService 导航到新的标签页
|
||||
if (NavigationService.navigate) {
|
||||
NavigationService.navigate(lastTab.path)
|
||||
NavigationService.navigate({ to: lastTab.path })
|
||||
} else {
|
||||
logger.warn('Navigation service not ready, will navigate on next render')
|
||||
setTimeout(() => {
|
||||
if (NavigationService.navigate) {
|
||||
NavigationService.navigate(lastTab.path)
|
||||
NavigationService.navigate({ to: lastTab.path })
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
@ -133,7 +133,7 @@ class TabsService {
|
||||
|
||||
// 导航到对应页面
|
||||
if (NavigationService.navigate) {
|
||||
NavigationService.navigate(tab.path)
|
||||
NavigationService.navigate({ to: tab.path })
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
Loading…
Reference in New Issue
Block a user