From 2af05c166c3f9010ceafe55a404400640eb918e6 Mon Sep 17 00:00:00 2001 From: "1808837298@qq.com" <1808837298@qq.com> Date: Tue, 11 Mar 2025 14:55:48 +0800 Subject: [PATCH] feat: Improve route handling and dynamic chat navigation in SiderBar --- web/src/App.js | 52 +++++++-------- web/src/components/SiderBar.js | 117 ++++++++++++++++++--------------- web/src/i18n/locales/en.json | 1 + 3 files changed, 89 insertions(+), 81 deletions(-) diff --git a/web/src/App.js b/web/src/App.js index 9e9407c0..a4d08d71 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -1,5 +1,5 @@ import React, { lazy, Suspense, useContext, useEffect } from 'react'; -import { Route, Routes } from 'react-router-dom'; +import { Route, Routes, useLocation } from 'react-router-dom'; import Loading from './components/Loading'; import User from './pages/User'; import { PrivateRoute } from './components/PrivateRoute'; @@ -8,10 +8,8 @@ import LoginForm from './components/LoginForm'; import NotFound from './pages/NotFound'; import Setting from './pages/Setting'; import EditUser from './pages/User/EditUser'; -import { getLogo, getSystemName } from './helpers'; import PasswordResetForm from './components/PasswordResetForm'; import PasswordResetConfirm from './components/PasswordResetConfirm'; -import { UserContext } from './context/User'; import Channel from './pages/Channel'; import Token from './pages/Token'; import EditChannel from './pages/Channel/EditChannel'; @@ -26,10 +24,6 @@ import Pricing from './pages/Pricing/index.js'; import Task from "./pages/Task/index.js"; import Playground from './pages/Playground/Playground.js'; import OAuth2Callback from "./components/OAuth2Callback.js"; -import { useTranslation } from 'react-i18next'; -import { StatusContext } from './context/Status'; -import { setStatusData } from './helpers/data.js'; -import { API, showError } from './helpers'; import PersonalSetting from './components/PersonalSetting.js'; const Home = lazy(() => import('./pages/Home')); @@ -37,13 +31,15 @@ const Detail = lazy(() => import('./pages/Detail')); const About = lazy(() => import('./pages/About')); function App() { + const location = useLocation(); + return ( <> }> + } key={location.pathname}> } @@ -59,7 +55,7 @@ function App() { }> + } key={location.pathname}> } @@ -67,7 +63,7 @@ function App() { }> + } key={location.pathname}> } @@ -107,7 +103,7 @@ function App() { }> + } key={location.pathname}> } @@ -115,7 +111,7 @@ function App() { }> + } key={location.pathname}> } @@ -123,7 +119,7 @@ function App() { }> + } key={location.pathname}> } @@ -131,7 +127,7 @@ function App() { }> + } key={location.pathname}> } @@ -139,7 +135,7 @@ function App() { }> + } key={location.pathname}> } @@ -147,7 +143,7 @@ function App() { }> + } key={location.pathname}> } @@ -155,7 +151,7 @@ function App() { }> + } key={location.pathname}> } @@ -163,7 +159,7 @@ function App() { }> + } key={location.pathname}> } @@ -172,7 +168,7 @@ function App() { path='/setting' element={ - }> + } key={location.pathname}> @@ -182,7 +178,7 @@ function App() { path='/personal' element={ - }> + } key={location.pathname}> @@ -192,7 +188,7 @@ function App() { path='/topup' element={ - }> + } key={location.pathname}> @@ -210,7 +206,7 @@ function App() { path='/detail' element={ - }> + } key={location.pathname}> @@ -220,7 +216,7 @@ function App() { path='/midjourney' element={ - }> + } key={location.pathname}> @@ -230,7 +226,7 @@ function App() { path='/task' element={ - }> + } key={location.pathname}> @@ -239,7 +235,7 @@ function App() { }> + } key={location.pathname}> } @@ -247,7 +243,7 @@ function App() { }> + } key={location.pathname}> } @@ -255,7 +251,7 @@ function App() { }> + } key={location.pathname}> } @@ -265,7 +261,7 @@ function App() { path='/chat2link' element={ - }> + } key={location.pathname}> diff --git a/web/src/components/SiderBar.js b/web/src/components/SiderBar.js index 60f60507..45c8c571 100644 --- a/web/src/components/SiderBar.js +++ b/web/src/components/SiderBar.js @@ -62,6 +62,25 @@ const iconStyle = (itemKey, selectedKeys) => { }; }; +// Define routerMap as a constant outside the component +const routerMap = { + home: '/', + channel: '/channel', + token: '/token', + redemption: '/redemption', + topup: '/topup', + user: '/user', + log: '/log', + midjourney: '/midjourney', + setting: '/setting', + about: '/about', + detail: '/detail', + pricing: '/pricing', + task: '/task', + playground: '/playground', + personal: '/personal', +}; + const SiderBar = () => { const { t } = useTranslation(); const [styleState, styleDispatch] = useContext(StyleContext); @@ -76,6 +95,7 @@ const SiderBar = () => { const theme = useTheme(); const setTheme = useSetTheme(); const location = useLocation(); + const [routerMapState, setRouterMapState] = useState(routerMap); // 预先计算所有可能的图标样式 const allItemKeys = useMemo(() => { @@ -97,25 +117,6 @@ const SiderBar = () => { return styles; }, [allItemKeys, selectedKeys]); - const routerMap = { - home: '/', - channel: '/channel', - token: '/token', - redemption: '/redemption', - topup: '/topup', - user: '/user', - log: '/log', - midjourney: '/midjourney', - setting: '/setting', - about: '/about', - chat: '/chat', - detail: '/detail', - pricing: '/pricing', - task: '/task', - playground: '/playground', - personal: '/personal', - }; - const workspaceItems = useMemo( () => [ { @@ -237,21 +238,24 @@ const SiderBar = () => { [chatItems, t], ); - useEffect(() => { - const currentPath = location.pathname; - const matchingKey = Object.keys(routerMap).find(key => routerMap[key] === currentPath); - - if (matchingKey) { - setSelectedKeys([matchingKey]); - } else if (currentPath.startsWith('/chat/')) { - setSelectedKeys(['chat']); + // Function to update router map with chat routes + const updateRouterMapWithChats = (chats) => { + const newRouterMap = { ...routerMap }; + + if (Array.isArray(chats) && chats.length > 0) { + for (let i = 0; i < chats.length; i++) { + newRouterMap['chat' + i] = '/chat/' + i; + } } - }, [location.pathname]); + + setRouterMapState(newRouterMap); + return newRouterMap; + }; + // Update the useEffect for chat items useEffect(() => { let chats = localStorage.getItem('chats'); if (chats) { - // console.log(chats); try { chats = JSON.parse(chats); if (Array.isArray(chats)) { @@ -263,19 +267,44 @@ const SiderBar = () => { chat.itemKey = 'chat' + i; chat.to = '/chat/' + i; } - // setRouterMap({ ...routerMap, chat: '/chat/' + i }) chatItems.push(chat); } setChatItems(chatItems); + + // Update router map with chat routes + updateRouterMapWithChats(chats); } } catch (e) { console.error(e); showError('聊天数据解析失败') } } + }, []); + // Update the useEffect for route selection + useEffect(() => { + const currentPath = location.pathname; + let matchingKey = Object.keys(routerMapState).find(key => routerMapState[key] === currentPath); + + // Handle chat routes + if (!matchingKey && currentPath.startsWith('/chat/')) { + const chatIndex = currentPath.split('/').pop(); + if (!isNaN(chatIndex)) { + matchingKey = 'chat' + chatIndex; + } else { + matchingKey = 'chat'; + } + } + + // If we found a matching key, update the selected keys + if (matchingKey) { + setSelectedKeys([matchingKey]); + } + }, [location.pathname, routerMapState]); + + useEffect(() => { setIsCollapsed(styleState.siderCollapsed); - }) + }, [styleState.siderCollapsed]); // Custom divider style const dividerStyle = { @@ -322,14 +351,14 @@ const SiderBar = () => { // 确保在收起侧边栏时有选中的项目,避免不必要的计算 if (selectedKeys.length === 0) { const currentPath = location.pathname; - const matchingKey = Object.keys(routerMap).find(key => routerMap[key] === currentPath); + const matchingKey = Object.keys(routerMapState).find(key => routerMapState[key] === currentPath); if (matchingKey) { setSelectedKeys([matchingKey]); } else if (currentPath.startsWith('/chat/')) { setSelectedKeys(['chat']); } else { - setSelectedKeys([]); // 默认选中首页 + setSelectedKeys(['detail']); // 默认选中首页 } } }} @@ -338,28 +367,10 @@ const SiderBar = () => { hoverStyle={navItemHoverStyle} selectedStyle={navItemSelectedStyle} renderWrapper={({ itemElement, isSubNav, isInSubNav, props }) => { - let chats = localStorage.getItem('chats'); - if (chats) { - chats = JSON.parse(chats); - if (Array.isArray(chats) && chats.length > 0) { - for (let i = 0; i < chats.length; i++) { - routerMap['chat' + i] = '/chat/' + i; - } - if (chats.length > 1) { - // delete /chat - if (routerMap['chat']) { - delete routerMap['chat']; - } - } else { - // rename /chat to /chat/0 - routerMap['chat'] = '/chat/0'; - } - } - } return ( {itemElement} @@ -466,7 +477,7 @@ const SiderBar = () => { diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index 9951534e..97efbf8f 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -1,5 +1,6 @@ { "主页": "Home", + "文档": "Docs", "控制台": "Console", "$%.6f 额度": "$%.6f quota", "%d 点额度": "%d point quota",