From 42c970f9d1773a71bdbfd0a95750e7e79b244cdb Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 14:02:02 +0800 Subject: [PATCH 01/26] Rename MainFramework to HomeFramework. Move tools to independent path. --- src/pages/Home.tsx | 4 +- .../{MainFramework.tsx => HomeFramework.tsx} | 10 ++--- src/router/index.tsx | 45 +++++++++++++------ 3 files changed, 38 insertions(+), 21 deletions(-) rename src/pages/{MainFramework.tsx => HomeFramework.tsx} (97%) diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 3091de0..25ca34d 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,7 +1,7 @@ import React from 'react' import '@/assets/css/components/home/home.scss' import FitFullScreen from '@/components/common/FitFullScreen' -import { MainFrameworkContext } from '@/pages/MainFramework' +import { HomeFrameworkContext } from '@/pages/HomeFramework' import Slogan from '@/components/home/Slogan' import OxygenToolbox from '@/components/home/OxygenToolbox' import Indicator from '@/components/common/Indicator' @@ -13,7 +13,7 @@ const Home: React.FC = () => { navbarHiddenState: { navbarHidden, setNavbarHidden }, showDropdownMenuState: { setShowDropdownMenu }, preventScrollState: { setPreventScroll } - } = useContext(MainFrameworkContext) + } = useContext(HomeFrameworkContext) const fitFullScreenRef = useRef(null) const scrollTimeout = useRef(0) diff --git a/src/pages/MainFramework.tsx b/src/pages/HomeFramework.tsx similarity index 97% rename from src/pages/MainFramework.tsx rename to src/pages/HomeFramework.tsx index c867634..4d77fb9 100644 --- a/src/pages/MainFramework.tsx +++ b/src/pages/HomeFramework.tsx @@ -7,7 +7,7 @@ import Icon from '@ant-design/icons' import { COLOR_FONT_SECONDARY } from '@/constants/Common.constants.ts' import { NavLink } from 'react-router-dom' -export const MainFrameworkContext = createContext<{ +export const HomeFrameworkContext = createContext<{ navbarHiddenState: { navbarHidden: boolean setNavbarHidden: (newValue: boolean) => void @@ -53,7 +53,7 @@ export const MainFrameworkContext = createContext<{ hideScrollbarRef: createRef() }) -const MainFramework: React.FC = () => { +const HomeFramework: React.FC = () => { const routeId = useMatches()[1].id const routeChildren = router.routes[0].children?.find((value) => value.id === routeId)?.children @@ -187,7 +187,7 @@ const MainFramework: React.FC = () => { - { > - + ) } -export default MainFramework +export default HomeFramework diff --git a/src/router/index.tsx b/src/router/index.tsx index 580eaf6..18df163 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -15,10 +15,32 @@ const routes: RouteObject[] = [ id: 'loading', Component: React.lazy(() => import('@/components/common/LoadingMask')) }, + { + path: '/tools', + id: 'tools', + Component: React.lazy(() => import('@/pages/Tools')), + children: [ + { + path: 'translation', + id: 'tools-translation', + Component: React.lazy(() => import('@/pages/tools/Translation')), + handle: { + name: '翻译', + menu: true, + auth: true + } + } + ], + handle: { + name: '工具', + title: '工具', + auth: false + } + }, { path: '', - id: 'mainFramework', - Component: React.lazy(() => import('@/pages/MainFramework')), + id: 'homeFramework', + Component: React.lazy(() => import('@/pages/HomeFramework')), children: [ { path: '', @@ -32,33 +54,28 @@ const routes: RouteObject[] = [ }, { path: 'https://blog.fatweb.top', - id: 'blog', + id: 'url-blog', handle: { name: '博客', - menu: true, - auth: false + menu: true } }, { - path: 'tools', - id: 'tools', - Component: React.lazy(() => import('@/pages/Tools')), + path: '/tools', + id: 'url-tools', children: [ { path: 'translation', - id: 'tools-translation', - Component: React.lazy(() => import('@/pages/tools/Translation')), + id: 'url-tools-translation', handle: { name: '翻译', - menu: true, - auth: false + menu: true } } ], handle: { name: '工具', - menu: true, - auth: false + menu: true } } ] -- 2.49.1 From 3d84a8eed48b692c19e02c595133e20503410940 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 14:03:32 +0800 Subject: [PATCH 02/26] Fix AuthRoute --- src/AuthRoute.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/AuthRoute.tsx b/src/AuthRoute.tsx index 788ba52..57948cb 100644 --- a/src/AuthRoute.tsx +++ b/src/AuthRoute.tsx @@ -1,8 +1,9 @@ import { getLoginStatus } from '@/utils/auth.ts' const AuthRoute = () => { - const match = useMatches()[1] - const handle = match.handle as RouteHandle + const matches = useMatches() + const lastMatch = matches.reduce((_, second) => second) + const handle = lastMatch.handle as RouteHandle const outlet = useOutlet() const isLogin = getLoginStatus() @@ -10,11 +11,11 @@ const AuthRoute = () => { if (handle?.auth && !isLogin) { return } - if (isLogin && match.pathname === '/login') { + if (isLogin && lastMatch.pathname === '/login') { return } return outlet - }, [handle?.auth, isLogin, match.pathname, outlet]) + }, [handle?.auth, isLogin, lastMatch.pathname, outlet]) } export default AuthRoute -- 2.49.1 From 885a097e7ff7f82261d88bac0f846a73a3e1ae0d Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 14:04:33 +0800 Subject: [PATCH 03/26] Add auto set title to AuthRoute --- src/AuthRoute.tsx | 14 +++++++++++++- src/vite-env.d.ts | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/AuthRoute.tsx b/src/AuthRoute.tsx index 57948cb..a70354f 100644 --- a/src/AuthRoute.tsx +++ b/src/AuthRoute.tsx @@ -1,4 +1,5 @@ import { getLoginStatus } from '@/utils/auth.ts' +import { PRODUCTION_NAME } from '@/constants/Common.constants.ts' const AuthRoute = () => { const matches = useMatches() @@ -8,6 +9,9 @@ const AuthRoute = () => { const isLogin = getLoginStatus() return useMemo(() => { + document.title = `${handle?.titlePrefix ?? ''}${ + handle?.title ? handle?.title : PRODUCTION_NAME + }${handle?.titlePostfix ?? ''}` if (handle?.auth && !isLogin) { return } @@ -15,7 +19,15 @@ const AuthRoute = () => { return } return outlet - }, [handle?.auth, isLogin, lastMatch.pathname, outlet]) + }, [ + handle?.auth, + handle?.title, + handle?.titlePostfix, + handle?.titlePrefix, + isLogin, + lastMatch.pathname, + outlet + ]) } export default AuthRoute diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 324bb5f..1311793 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -13,6 +13,9 @@ type RouteHandle = { name?: string menu?: boolean auth?: boolean + titlePrefix?: string + title?: string + titlePostfix?: string } type _Response = { -- 2.49.1 From bd1e69954302f270e0cc25380b0d38c637fdd471 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 14:41:27 +0800 Subject: [PATCH 04/26] Add redirect after login --- src/AuthRoute.tsx | 10 +++++++++- src/pages/Login.tsx | 7 ++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/AuthRoute.tsx b/src/AuthRoute.tsx index a70354f..725136c 100644 --- a/src/AuthRoute.tsx +++ b/src/AuthRoute.tsx @@ -5,6 +5,7 @@ const AuthRoute = () => { const matches = useMatches() const lastMatch = matches.reduce((_, second) => second) const handle = lastMatch.handle as RouteHandle + const location = useLocation() const outlet = useOutlet() const isLogin = getLoginStatus() @@ -13,7 +14,13 @@ const AuthRoute = () => { handle?.title ? handle?.title : PRODUCTION_NAME }${handle?.titlePostfix ?? ''}` if (handle?.auth && !isLogin) { - return + return ( + @@ -26,6 +33,7 @@ const AuthRoute = () => { handle?.titlePrefix, isLogin, lastMatch.pathname, + location.search, outlet ]) } diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 02ff4d2..92a8bac 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -12,6 +12,7 @@ import '@/assets/css/pages/login.scss' const Login: React.FC = () => { const [messageApi, contextHolder] = message.useMessage() const navigate = useNavigate() + const [searchParams] = useSearchParams() const [isLoggingIn, setIsLoggingIn] = useState(false) const onFinish = (values: LoginForm) => { @@ -25,7 +26,11 @@ const Login: React.FC = () => { setToken(data?.token ?? '') void messageApi.success('登录成功') setTimeout(() => { - navigate('/') + if (searchParams.has('redirect')) { + navigate(searchParams.get('redirect') ?? '/') + } else { + navigate('/') + } }, 1500) break case SYSTEM_USERNAME_NOT_FOUND: -- 2.49.1 From 49b955169f4aee3ee563fdbf8b816433c54a9e7a Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 16:18:18 +0800 Subject: [PATCH 05/26] Optimize ToolsFramework router --- src/pages/ToolsFramework.tsx | 7 +++++++ src/pages/{Home.tsx => home/index.tsx} | 0 src/pages/{Tools.tsx => tools/index.tsx} | 0 src/router/index.tsx | 16 +++++++++++++--- 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/pages/ToolsFramework.tsx rename src/pages/{Home.tsx => home/index.tsx} (100%) rename src/pages/{Tools.tsx => tools/index.tsx} (100%) diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx new file mode 100644 index 0000000..96c04ad --- /dev/null +++ b/src/pages/ToolsFramework.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +const ToolsFramework: React.FC = () => { + return <> +} + +export default ToolsFramework diff --git a/src/pages/Home.tsx b/src/pages/home/index.tsx similarity index 100% rename from src/pages/Home.tsx rename to src/pages/home/index.tsx diff --git a/src/pages/Tools.tsx b/src/pages/tools/index.tsx similarity index 100% rename from src/pages/Tools.tsx rename to src/pages/tools/index.tsx diff --git a/src/router/index.tsx b/src/router/index.tsx index 18df163..fe6967e 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -17,9 +17,19 @@ const routes: RouteObject[] = [ }, { path: '/tools', - id: 'tools', - Component: React.lazy(() => import('@/pages/Tools')), + id: 'toolsFramework', + Component: React.lazy(() => import('@/pages/ToolsFramework')), children: [ + { + path: '', + id: 'tools', + Component: React.lazy(() => import('@/pages/tools')), + handle: { + name: '全部工具', + menu: true, + auth: false + } + }, { path: 'translation', id: 'tools-translation', @@ -45,7 +55,7 @@ const routes: RouteObject[] = [ { path: '', id: 'home', - Component: React.lazy(() => import('@/pages/Home')), + Component: React.lazy(() => import('@/pages/home')), handle: { name: '主页', menu: true, -- 2.49.1 From 2f48301bda48b3ed1eedb774436f4302fffc90b4 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 16:25:44 +0800 Subject: [PATCH 06/26] Rename header.scss to home-framework.scss --- src/assets/css/pages/{header.scss => home-framework.scss} | 0 src/pages/HomeFramework.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/assets/css/pages/{header.scss => home-framework.scss} (100%) diff --git a/src/assets/css/pages/header.scss b/src/assets/css/pages/home-framework.scss similarity index 100% rename from src/assets/css/pages/header.scss rename to src/assets/css/pages/home-framework.scss diff --git a/src/pages/HomeFramework.tsx b/src/pages/HomeFramework.tsx index 4d77fb9..e7c93fc 100644 --- a/src/pages/HomeFramework.tsx +++ b/src/pages/HomeFramework.tsx @@ -1,5 +1,5 @@ import React from 'react' -import '@/assets/css/pages/header.scss' +import '@/assets/css/pages/home-framework.scss' import router from '@/router' import LoadingMask from '@/components/common/LoadingMask' import HideScrollbar, { HideScrollbarElement } from '@/components/common/HideScrollbar' -- 2.49.1 From c5b140219b4e7734c3572f8cd24a73bb3164226a Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 16:29:35 +0800 Subject: [PATCH 07/26] Remove .tsx --- src/App.tsx | 2 +- src/components/home/Footer.tsx | 4 ++-- src/components/home/OxygenToolbox.tsx | 2 +- src/components/home/Slogan.tsx | 2 +- src/main.tsx | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 869499d..3b7738a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,6 @@ import React from 'react' import router from '@/router' -import LoadingMask from '@/components/common/LoadingMask.tsx' +import LoadingMask from '@/components/common/LoadingMask' const App: React.FC = () => { return ( diff --git a/src/components/home/Footer.tsx b/src/components/home/Footer.tsx index 47c8f62..2200e30 100644 --- a/src/components/home/Footer.tsx +++ b/src/components/home/Footer.tsx @@ -1,8 +1,8 @@ import React from 'react' -import FitCenter from '@/components/common/FitCenter.tsx' +import FitCenter from '@/components/common/FitCenter' import Icon from '@ant-design/icons' import '@/assets/css/components/home/footer.scss' -import FitFullScreen from '@/components/common/FitFullScreen.tsx' +import FitFullScreen from '@/components/common/FitFullScreen' import { NavLink } from 'react-router-dom' const Footer: React.FC = () => { diff --git a/src/components/home/OxygenToolbox.tsx b/src/components/home/OxygenToolbox.tsx index 6423e3b..576bd5b 100644 --- a/src/components/home/OxygenToolbox.tsx +++ b/src/components/home/OxygenToolbox.tsx @@ -1,5 +1,5 @@ import React from 'react' -import FitCenter from '@/components/common/FitCenter.tsx' +import FitCenter from '@/components/common/FitCenter' const OxygenToolbox: React.FC = () => { return ( diff --git a/src/components/home/Slogan.tsx b/src/components/home/Slogan.tsx index 0c32a6e..e0439c0 100644 --- a/src/components/home/Slogan.tsx +++ b/src/components/home/Slogan.tsx @@ -1,7 +1,7 @@ import React from 'react' import Icon from '@ant-design/icons' import '@/assets/css/components/home/slogan.scss' -import FitCenter from '@/components/common/FitCenter.tsx' +import FitCenter from '@/components/common/FitCenter' interface SloganProps { onClickScrollDown: (event: React.MouseEvent) => void diff --git a/src/main.tsx b/src/main.tsx index e102176..0464d85 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom/client' import zh_CN from 'antd/locale/zh_CN' import '@/assets/css/base.scss' import '@/assets/css/common.scss' -import App from './App.tsx' +import App from './App' ReactDOM.createRoot(document.getElementById('root')!).render( -- 2.49.1 From e67f9d14bf2e01ac7245b81569b037cbb5f2d6d0 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 18:28:56 +0800 Subject: [PATCH 08/26] Optimize color in stylesheet --- src/assets/css/common.scss | 6 ++++-- src/assets/css/components/home/footer.scss | 8 +++++--- src/assets/css/constants.scss | 5 ++++- src/assets/css/pages/home-framework.scss | 6 +++--- src/assets/css/pages/login.scss | 6 ++++-- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/assets/css/common.scss b/src/assets/css/common.scss index e1716f7..650a829 100644 --- a/src/assets/css/common.scss +++ b/src/assets/css/common.scss @@ -25,8 +25,8 @@ height: 100%; } -.background-white { - background-color: white; +.background-origin { + background-color: constants.$origin-color; } .center-box { @@ -107,9 +107,11 @@ } .flex-horizontal { + display: flex; flex-direction: row; } .flex-vertical { + display: flex; flex-direction: column; } \ No newline at end of file diff --git a/src/assets/css/components/home/footer.scss b/src/assets/css/components/home/footer.scss index 7abf726..551c276 100644 --- a/src/assets/css/components/home/footer.scss +++ b/src/assets/css/components/home/footer.scss @@ -1,19 +1,21 @@ +@use "@/assets/css/constants" as constants; + .icons { display: flex; gap: 20px; .icon { font-size: 8em; - color: white; + color: constants.$origin-color; } } .links { font-size: 2em; text-decoration: underline; - color: white; + color: constants.$origin-color; > * { - color: white; + color: constants.$origin-color; } } \ No newline at end of file diff --git a/src/assets/css/constants.scss b/src/assets/css/constants.scss index edf5734..ce3b1cf 100644 --- a/src/assets/css/constants.scss +++ b/src/assets/css/constants.scss @@ -1,4 +1,7 @@ -$main-color: #00D4FF; +$origin-color: white; +$main-color: #4E47BB; +$secondary-color: #BAB8E5; +$active-color: #EBECFFD; $background-color: #F5F5F5; $font-main-color: #4D4D4D; $font-secondary-color: #9E9E9E; diff --git a/src/assets/css/pages/home-framework.scss b/src/assets/css/pages/home-framework.scss index 836974e..34717e0 100644 --- a/src/assets/css/pages/home-framework.scss +++ b/src/assets/css/pages/home-framework.scss @@ -8,7 +8,7 @@ z-index: 1; width: 100%; height: 70px; - background-color: white; + background-color: constants.$origin-color; border: { bottom: { width: 1px; @@ -99,7 +99,7 @@ position: absolute; width: 100%; text-align: center; - background-color: white; + background-color: constants.$origin-color; overflow: hidden; .item { @@ -171,7 +171,7 @@ color: constants.$border-color; style: solid; }; - background-color: white; + background-color: constants.$origin-color; z-index: 1; ul { diff --git a/src/assets/css/pages/login.scss b/src/assets/css/pages/login.scss index 22629a8..988f60f 100644 --- a/src/assets/css/pages/login.scss +++ b/src/assets/css/pages/login.scss @@ -1,3 +1,5 @@ +@use "@/assets/css/constants" as constants; + .login-background { display: flex; height: 100vh; @@ -24,7 +26,7 @@ .login-box-left-text { font-size: 3rem; - color: white; + color: constants.$origin-color; font-weight: bold; > div:last-child { @@ -37,7 +39,7 @@ position: relative; height: 100%; flex: 3; - background-color: white; + background-color: constants.$origin-color; } .login-from-text { -- 2.49.1 From 9d04773266fbd78d7e4482148b2bbe821f567266 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 18:29:23 +0800 Subject: [PATCH 09/26] Add menu in ToolsFramework --- src/ant-design.d.ts | 8 ++ src/assets/css/pages/tools-framework.scss | 43 ++++++++ src/{vite-env.d.ts => global.d.ts} | 2 + src/pages/ToolsFramework.tsx | 122 +++++++++++++++++++++- src/router/index.tsx | 47 +++++++++ 5 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 src/ant-design.d.ts create mode 100644 src/assets/css/pages/tools-framework.scss rename src/{vite-env.d.ts => global.d.ts} (91%) diff --git a/src/ant-design.d.ts b/src/ant-design.d.ts new file mode 100644 index 0000000..5ec575f --- /dev/null +++ b/src/ant-design.d.ts @@ -0,0 +1,8 @@ +import * as React from 'react' +import { CustomIconComponentProps } from '@ant-design/icons/es/components/Icon' + +declare global { + type IconComponent = + | React.ComponentType> + | React.ForwardRefExoticComponent +} diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss new file mode 100644 index 0000000..d8b6342 --- /dev/null +++ b/src/assets/css/pages/tools-framework.scss @@ -0,0 +1,43 @@ +@use "@/assets/css/constants" as constants; + +.left-panel { + width: 16%; + background-color: constants.$origin-color; + + .title { + font-size: 2em; + text-align: center; + font-weight: bold; + letter-spacing: 0.6em; + padding: 10px; + color: constants.$main-color; + } + + .content { + ul{ + li { + //background-color: #4E47BB; + margin: 4px 10px; + padding: 4px; + &.item { + background-color: #4E47BB; + } + + .separate { + height: 0; + border: { + width: 1px; + color: constants.$font-secondary-color; + style: solid; + }; + opacity: 0.4; + } + } + } + } +} + +.right-panel { + flex: 1; + background-color: constants.$background-color; +} \ No newline at end of file diff --git a/src/vite-env.d.ts b/src/global.d.ts similarity index 91% rename from src/vite-env.d.ts rename to src/global.d.ts index 1311793..aa1a600 100644 --- a/src/vite-env.d.ts +++ b/src/global.d.ts @@ -1,4 +1,5 @@ /// +/// interface ImportMetaEnv { readonly VITE_API_URL: string @@ -16,6 +17,7 @@ type RouteHandle = { titlePrefix?: string title?: string titlePostfix?: string + icon?: IconComponent } type _Response = { diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index 96c04ad..f59a243 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -1,7 +1,127 @@ import React from 'react' +import FitFullScreen from '@/components/common/FitFullScreen' +import '@/assets/css/pages/tools-framework.scss' +import router from '@/router' +import { NavLink } from 'react-router-dom' +import Icon from '@ant-design/icons' const ToolsFramework: React.FC = () => { - return <> + const frameworkRoute = useMatches()[1] + const routeId = frameworkRoute.id + const routeChildren = router.routes[0].children?.find((value) => value.id === routeId)?.children + + return ( + <> + +
+
氦工具
+
+
    +
  • + + isPending ? ' pending' : isActive ? ' active' : '' + } + > + {routeChildren ? ( + <> + + + {(routeChildren[0].handle as RouteHandle).name} + + + ) : ( + '全部工具' + )} + +
    +
  • +
  • +
    +
  • + {routeChildren?.map((route) => { + return (route.handle as RouteHandle).menu && + route.id !== 'tools' ? ( +
  • + + isPending ? 'pending' : isActive ? 'active' : '' + } + > + + + {(route.handle as RouteHandle).name} + + + {route.children ? ( +
      + {route.children.map((subRoute) => { + return (subRoute.handle as RouteHandle).menu ? ( +
    • + + isPending + ? 'pending' + : isActive + ? 'active' + : '' + } + > + + + { + ( + subRoute.handle as RouteHandle + ).name + } + + +
    • + ) : ( + <> + ) + })} +
    + ) : ( + <> + )} +
  • + ) : ( + <> + ) + })} +
+
+
+
+
+ + ) } export default ToolsFramework diff --git a/src/router/index.tsx b/src/router/index.tsx index fe6967e..6c152d4 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -26,6 +26,7 @@ const routes: RouteObject[] = [ Component: React.lazy(() => import('@/pages/tools')), handle: { name: '全部工具', + icon: React.lazy(() => import('~icons/fatweb/logo.jsx')), menu: true, auth: false } @@ -34,11 +35,57 @@ const routes: RouteObject[] = [ path: 'translation', id: 'tools-translation', Component: React.lazy(() => import('@/pages/tools/Translation')), + children: [ + { + path: '1', + id: '1', + handle: { + name: '翻译1', + menu: true + } + }, + { + path: '2', + id: '2', + handle: { + name: '翻译2', + menu: true + } + } + ], handle: { name: '翻译', menu: true, auth: true } + }, + { + path: 'translation-', + id: 'tools-translation-', + Component: React.lazy(() => import('@/pages/tools/Translation')), + children: [ + { + path: '1-', + id: '1-', + handle: { + name: '翻译1-', + menu: true + } + }, + { + path: '2-', + id: '2-', + handle: { + name: '翻译2-', + menu: true + } + } + ], + handle: { + name: '翻译-', + menu: true, + auth: true + } } ], handle: { -- 2.49.1 From a228d27a5110151c7e842d5c0bc9fa56b25590e6 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 11 Oct 2023 18:44:06 +0800 Subject: [PATCH 10/26] Optimize stylesheet --- src/assets/css/pages/tools-framework.scss | 32 +++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index d8b6342..c1214eb 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -14,13 +14,35 @@ } .content { - ul{ - li { + > ul { + > li { //background-color: #4E47BB; - margin: 4px 10px; - padding: 4px; + margin: 4px 14px; + &.item { - background-color: #4E47BB; + font-size: 1.6em; + border-radius: 8px; + overflow: hidden; + + :hover { + background-color: #4E47BB; + } + } + + a { + display: flex; + padding: 8px 16px; + height: 100%; + width: 100%; + + .icon { + + } + + .text { + flex: 1; + text-align: center; + } } .separate { -- 2.49.1 From 41b0cb6d3ee57e6255569f74bc0e8eb4931dbe88 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Thu, 12 Oct 2023 01:10:09 +0800 Subject: [PATCH 11/26] Fix auth in AuthRoute --- src/AuthRoute.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AuthRoute.tsx b/src/AuthRoute.tsx index 725136c..88565bc 100644 --- a/src/AuthRoute.tsx +++ b/src/AuthRoute.tsx @@ -13,7 +13,7 @@ const AuthRoute = () => { document.title = `${handle?.titlePrefix ?? ''}${ handle?.title ? handle?.title : PRODUCTION_NAME }${handle?.titlePostfix ?? ''}` - if (handle?.auth && !isLogin) { + if (matches.some(({ handle }) => (handle as RouteHandle)?.auth) && !isLogin) { return ( Date: Thu, 12 Oct 2023 01:51:56 +0800 Subject: [PATCH 12/26] Optimize tools route. Optimize multiple menu stylesheet. --- src/assets/css/pages/tools-framework.scss | 18 +++- src/global.d.ts | 11 +++ src/pages/ToolsFramework.tsx | 83 +++++++++++------ src/pages/tools/All.tsx | 7 ++ src/router/index.tsx | 71 +-------------- src/router/tools.tsx | 106 ++++++++++++++++++++++ 6 files changed, 196 insertions(+), 100 deletions(-) create mode 100644 src/pages/tools/All.tsx create mode 100644 src/router/tools.tsx diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index c1214eb..c23a522 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -3,6 +3,7 @@ .left-panel { width: 16%; background-color: constants.$origin-color; + user-select: none; .title { font-size: 2em; @@ -20,12 +21,16 @@ margin: 4px 14px; &.item { - font-size: 1.6em; + font-size: 1.4em; border-radius: 8px; overflow: hidden; - :hover { - background-color: #4E47BB; + a.active { + color: constants.$origin-color; + background-color: constants.$main-color; + } + a.pending { + background-color: #123213; } } @@ -41,12 +46,13 @@ .text { flex: 1; - text-align: center; + margin-left: 10px; } } .separate { height: 0; + margin: 10px 0; border: { width: 1px; color: constants.$font-secondary-color; @@ -54,6 +60,10 @@ }; opacity: 0.4; } + + &.item:hover { + background-color: constants.$background-color; + } } } } diff --git a/src/global.d.ts b/src/global.d.ts index aa1a600..ac9c459 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -10,6 +10,17 @@ interface ImportMeta { readonly env: ImportMetaEnv } +type ToolsJsonObject = { + path: string + id: string + component?: React.ComponentType + name?: string + icon?: IconComponent + menu?: boolean + auth?: boolean + children?: ToolsJsonObject[] +} + type RouteHandle = { name?: string menu?: boolean diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index f59a243..7c2ef8b 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -2,7 +2,6 @@ import React from 'react' import FitFullScreen from '@/components/common/FitFullScreen' import '@/assets/css/pages/tools-framework.scss' import router from '@/router' -import { NavLink } from 'react-router-dom' import Icon from '@ant-design/icons' const ToolsFramework: React.FC = () => { @@ -14,14 +13,18 @@ const ToolsFramework: React.FC = () => { <>
-
氦工具
+
氮工具
    +
  • +
    +
  • - isPending ? ' pending' : isActive ? ' active' : '' + isPending ? 'pending' : isActive ? 'active' : '' } > {routeChildren ? ( @@ -36,29 +39,58 @@ const ToolsFramework: React.FC = () => { {(routeChildren[0].handle as RouteHandle).name} + ) : ( + '主页' + )} + +
  • +
  • + + isPending ? ' pending' : isActive ? ' active' : '' + } + > + {routeChildren ? ( + <> + + + {(routeChildren[1].handle as RouteHandle).name} + + ) : ( '全部工具' )} -
  • {routeChildren?.map((route) => { return (route.handle as RouteHandle).menu && - route.id !== 'tools' ? ( -
  • + route.id !== 'tools' && + route.id !== 'tools-all' ? ( +
  • isPending ? 'pending' : isActive ? 'active' : '' } > - + {(route.handle as RouteHandle).icon ? ( + + ) : undefined} {(route.handle as RouteHandle).name} @@ -85,14 +117,17 @@ const ToolsFramework: React.FC = () => { : '' } > - + {(subRoute.handle as RouteHandle) + .icon ? ( + + ) : undefined} { ( @@ -102,18 +137,12 @@ const ToolsFramework: React.FC = () => {
  • - ) : ( - <> - ) + ) : undefined })}
- ) : ( - <> - )} + ) : undefined} - ) : ( - <> - ) + ) : undefined })}
diff --git a/src/pages/tools/All.tsx b/src/pages/tools/All.tsx new file mode 100644 index 0000000..85e812d --- /dev/null +++ b/src/pages/tools/All.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +const All: React.FC = () => { + return <> +} + +export default All diff --git a/src/router/index.tsx b/src/router/index.tsx index 6c152d4..ea360d9 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -1,4 +1,5 @@ import React from 'react' +import tools from '@/router/tools' const routes: RouteObject[] = [ { @@ -19,75 +20,7 @@ const routes: RouteObject[] = [ path: '/tools', id: 'toolsFramework', Component: React.lazy(() => import('@/pages/ToolsFramework')), - children: [ - { - path: '', - id: 'tools', - Component: React.lazy(() => import('@/pages/tools')), - handle: { - name: '全部工具', - icon: React.lazy(() => import('~icons/fatweb/logo.jsx')), - menu: true, - auth: false - } - }, - { - path: 'translation', - id: 'tools-translation', - Component: React.lazy(() => import('@/pages/tools/Translation')), - children: [ - { - path: '1', - id: '1', - handle: { - name: '翻译1', - menu: true - } - }, - { - path: '2', - id: '2', - handle: { - name: '翻译2', - menu: true - } - } - ], - handle: { - name: '翻译', - menu: true, - auth: true - } - }, - { - path: 'translation-', - id: 'tools-translation-', - Component: React.lazy(() => import('@/pages/tools/Translation')), - children: [ - { - path: '1-', - id: '1-', - handle: { - name: '翻译1-', - menu: true - } - }, - { - path: '2-', - id: '2-', - handle: { - name: '翻译2-', - menu: true - } - } - ], - handle: { - name: '翻译-', - menu: true, - auth: true - } - } - ], + children: tools, handle: { name: '工具', title: '工具', diff --git a/src/router/tools.tsx b/src/router/tools.tsx new file mode 100644 index 0000000..43ea3f6 --- /dev/null +++ b/src/router/tools.tsx @@ -0,0 +1,106 @@ +import React from 'react' + +const toolsJsonObjects: ToolsJsonObject[] = [ + { + path: '', + id: 'tools', + component: React.lazy(() => import('@/pages/tools')), + name: '主页', + icon: React.lazy(() => import('~icons/fatweb/logo.jsx')), + menu: true, + auth: false + }, + { + path: 'all', + id: 'tools-all', + component: React.lazy(() => import('@/pages/tools')), + name: '全部工具', + icon: React.lazy(() => import('~icons/fatweb/logo.jsx')), + menu: true, + auth: false + }, + { + path: 'translation', + id: 'tools-translation', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false, + children: [ + { + path: '1', + id: '1', + name: '翻译1', + menu: true, + auth: false + }, + { + path: '2', + id: '2', + name: '翻译2', + menu: true, + auth: false + } + ] + }, + { + path: 'translation-', + id: 'tools-translation-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false, + children: [ + { + path: '1-', + id: '1-', + name: '翻译1-', + menu: true, + auth: false + }, + { + path: '2-', + id: '2-', + name: '翻译2-', + menu: true, + auth: false + } + ] + }, + { + path: 'translation--', + id: 'tools-translation--', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + } +] + +const tools: RouteObject[] = toolsJsonObjects.map((value) => ({ + path: value.path, + id: value.id, + Component: value.component, + handle: { + name: value.name, + icon: value.icon, + menu: value.menu, + auth: value.auth + }, + children: value.children?.map((value) => ({ + path: value.path, + id: value.id, + Component: value.component, + handle: { + name: value.name, + icon: value.icon, + menu: value.menu, + auth: value.auth + } + })) +})) + +export default tools -- 2.49.1 From 6a7cae831975441ffbf220bba967fd1da8fe84f2 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Thu, 12 Oct 2023 16:18:24 +0800 Subject: [PATCH 13/26] Optimize submenu in ToolsFramework. Optimize code --- src/AuthRoute.tsx | 8 +- src/assets/css/constants.scss | 7 +- src/assets/css/pages/tools-framework.scss | 88 +++++++--- src/components/common/FitCenter.tsx | 2 +- src/components/common/FitFullScreen.tsx | 2 +- src/components/common/Indicator.tsx | 2 +- src/global.d.ts | 3 + src/pages/HomeFramework.tsx | 20 +-- src/pages/ToolsFramework.tsx | 199 ++++++++++++---------- src/router/tools.tsx | 11 +- src/utils/common.ts | 6 +- 11 files changed, 214 insertions(+), 134 deletions(-) diff --git a/src/AuthRoute.tsx b/src/AuthRoute.tsx index 88565bc..7335e5e 100644 --- a/src/AuthRoute.tsx +++ b/src/AuthRoute.tsx @@ -16,9 +16,9 @@ const AuthRoute = () => { if (matches.some(({ handle }) => (handle as RouteHandle)?.auth) && !isLogin) { return ( ((props, ref return ( <>
= (props) => { return (
  • diff --git a/src/global.d.ts b/src/global.d.ts index ac9c459..e64304b 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -15,6 +15,9 @@ type ToolsJsonObject = { id: string component?: React.ComponentType name?: string + titlePrefix?: string + title?: string + titlePostfix?: string icon?: IconComponent menu?: boolean auth?: boolean diff --git a/src/pages/HomeFramework.tsx b/src/pages/HomeFramework.tsx index e7c93fc..d63978e 100644 --- a/src/pages/HomeFramework.tsx +++ b/src/pages/HomeFramework.tsx @@ -84,7 +84,7 @@ const HomeFramework: React.FC = () => { >
    -
    +
    FatWeb @@ -115,11 +115,9 @@ const HomeFramework: React.FC = () => { key={subRoute.id} > { })}
    {
    -
    +
      {routeChildren?.map((route) => { return ( diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index 7c2ef8b..a0dff56 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -1,13 +1,38 @@ import React from 'react' import FitFullScreen from '@/components/common/FitFullScreen' import '@/assets/css/pages/tools-framework.scss' -import router from '@/router' import Icon from '@ant-design/icons' +import { toolsJsonObjects } from '@/router/tools.tsx' +import _ from 'lodash' const ToolsFramework: React.FC = () => { - const frameworkRoute = useMatches()[1] - const routeId = frameworkRoute.id - const routeChildren = router.routes[0].children?.find((value) => value.id === routeId)?.children + const location = useLocation() + + const [multipleMenuShown, setMultipleMenuShown] = useState( + toolsJsonObjects.map((value) => ({ + id: value.id, + path: value.path, + shown: `${location.pathname}/`.startsWith(`/tools/${value.path}/`) + })) + ) + + useEffect(() => { + const temp = _.clone(multipleMenuShown) + temp.forEach((value) => { + value.shown = `${location.pathname}/`.startsWith(`/tools/${value.path}/`) + }) + setMultipleMenuShown(temp) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [location]) + + const switchSubmenu = (menuId: string) => { + return () => { + const temp = _.clone(multipleMenuShown) + const menu = temp.find(({ id }) => id === menuId) + menu && (menu.shown = !menu.shown) + setMultipleMenuShown(temp) + } + } return ( <> @@ -20,92 +45,93 @@ const ToolsFramework: React.FC = () => {
    • - - isPending ? 'pending' : isActive ? 'active' : '' - } - > - {routeChildren ? ( - <> - - - {(routeChildren[0].handle as RouteHandle).name} - - - ) : ( - '主页' - )} - +
      + + isPending ? 'pending' : isActive ? 'active' : '' + } + > + + {toolsJsonObjects[0].name} + +
    • - - isPending ? ' pending' : isActive ? ' active' : '' - } - > - {routeChildren ? ( - <> - - - {(routeChildren[1].handle as RouteHandle).name} - - - ) : ( - '全部工具' - )} - +
      + + isPending ? ' pending' : isActive ? ' active' : '' + } + > + + {toolsJsonObjects[1].name} + +
    • - {routeChildren?.map((route) => { - return (route.handle as RouteHandle).menu && - route.id !== 'tools' && - route.id !== 'tools-all' ? ( + {toolsJsonObjects.map((tool) => { + return tool.menu && + tool.id !== 'tools' && + tool.id !== 'tools-all' ? (
    • id === tool.id + )?.shown ?? false + ? ' show' + : '' + }` + : 'item' + } + key={tool.id} > - - isPending ? 'pending' : isActive ? 'active' : '' - } - > - {(route.handle as RouteHandle).icon ? ( - +
      + {tool.children ? ( +
      + +
      ) : undefined} - - {(route.handle as RouteHandle).name} - - - {route.children ? ( + + isPending ? 'pending' : isActive ? 'active' : '' + } + > + {tool.children ? undefined : tool.icon ? ( + + ) : undefined} + {tool.name} + +
      + {tool.children ? (
        - {route.children.map((subRoute) => { - return (subRoute.handle as RouteHandle).menu ? ( -
      • + {tool.children.map((subTool) => { + return subTool.menu ? ( +
      • { : '' } > - {(subRoute.handle as RouteHandle) - .icon ? ( + {subTool.icon ? ( ) : undefined} - { - ( - subRoute.handle as RouteHandle - ).name - } + {subTool.name}
      • diff --git a/src/router/tools.tsx b/src/router/tools.tsx index 43ea3f6..5c675d2 100644 --- a/src/router/tools.tsx +++ b/src/router/tools.tsx @@ -1,6 +1,8 @@ import React from 'react' -const toolsJsonObjects: ToolsJsonObject[] = [ +const defaultTitle = '氮工具' + +export const toolsJsonObjects: ToolsJsonObject[] = [ { path: '', id: 'tools', @@ -15,6 +17,7 @@ const toolsJsonObjects: ToolsJsonObject[] = [ id: 'tools-all', component: React.lazy(() => import('@/pages/tools')), name: '全部工具', + titlePostfix: ' - 全部工具', icon: React.lazy(() => import('~icons/fatweb/logo.jsx')), menu: true, auth: false @@ -86,6 +89,9 @@ const tools: RouteObject[] = toolsJsonObjects.map((value) => ({ Component: value.component, handle: { name: value.name, + titlePrefix: value.titlePrefix, + title: value.title ?? defaultTitle, + titlePostfix: value.titlePostfix, icon: value.icon, menu: value.menu, auth: value.auth @@ -96,6 +102,9 @@ const tools: RouteObject[] = toolsJsonObjects.map((value) => ({ Component: value.component, handle: { name: value.name, + titlePrefix: value.titlePrefix, + title: value.title ?? defaultTitle, + titlePostfix: value.titlePostfix, icon: value.icon, menu: value.menu, auth: value.auth diff --git a/src/utils/common.ts b/src/utils/common.ts index 96f1784..7d0f9ce 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -18,14 +18,14 @@ export function setCookie( daysToLive: number | null, path: string | null ): void { - let cookie = name + '=' + encodeURIComponent(value) + let cookie = `${name}=${encodeURIComponent(value)}` if (typeof daysToLive === 'number') { cookie = `${cookie}; max-age=${daysToLive * 24 * 60 * 60}` } if (typeof path === 'string') { - cookie += '; path=' + path + cookie = `${cookie}; path=${path}` } document.cookie = cookie @@ -61,7 +61,7 @@ export function getToken(): string | null { } export function removeCookie(name: string): void { - document.cookie = name + '=; max-age=0' + document.cookie = `${name}=; max-age=0` } export function removeLocalStorage(name: string): void { -- 2.49.1 From ac3c1dbc2c460e59bdcf916eb3e7fd37a89a1f00 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Thu, 12 Oct 2023 18:34:14 +0800 Subject: [PATCH 14/26] Optimize submenu in ToolsFramework --- .../css/components/common/hide-scrollbar.scss | 1 - src/assets/css/pages/tools-framework.scss | 118 ++++---- src/components/common/HideScrollbar.tsx | 9 +- src/pages/HomeFramework.tsx | 1 + src/pages/ToolsFramework.tsx | 267 ++++++++---------- src/router/tools.tsx | 182 +++++++++++- 6 files changed, 367 insertions(+), 211 deletions(-) diff --git a/src/assets/css/components/common/hide-scrollbar.scss b/src/assets/css/components/common/hide-scrollbar.scss index 799a993..5a9f7c9 100644 --- a/src/assets/css/components/common/hide-scrollbar.scss +++ b/src/assets/css/components/common/hide-scrollbar.scss @@ -14,7 +14,6 @@ .hide-scrollbar-content { display: inline-block; width: 100%; - min-width: 900px; } } diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index 4534112..e9a54d0 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -1,4 +1,5 @@ @use "@/assets/css/constants" as constants; +@use "@/assets/css/mixins" as mixins; body { background-color: constants.$background-color; @@ -21,16 +22,24 @@ body { .content { > ul { > li { - margin: 4px 14px; &.item { + position: relative; + margin: 4px 14px; font-size: 1.4em; - border-radius: 8px; - overflow: hidden; .menu-bt { - .icon { - margin-right: 16px; + border-radius: 8px; + overflow: hidden; + + .icon-box { + cursor: pointer; + width: 26px; + height: 26px; + + .icon { + margin-right: 16px; + } } a { @@ -38,6 +47,7 @@ body { padding: 8px 16px; height: 100%; width: 100%; + transition: all 0.2s; .text { flex: 1; @@ -50,54 +60,60 @@ body { } } + .submenu { + display: none; + position: fixed; + padding-left: 20px; + left: 100%; + top: 0; + + .content { + display: flex; + flex-direction: column; + gap: 2px; + padding: 10px 10px; + background-color: constants.$origin-color; + border-radius: 8px; + + .item { + border-radius: 8px; + white-space: nowrap; + overflow: hidden; + + a { + display: block; + padding: 8px 16px; + transition: all 0.2s; + + &.active { + color: constants.$origin-color; + background-color: constants.$main-color !important; + } + } + + &:hover a { + background-color: constants.$background-color; + } + } + } + } + &:hover { background-color: constants.$background-color; - } - } - &.multiple-item { - font-size: 1.4em; - border-radius: 8px; - overflow: hidden; - - .menu-bt { - display: flex; - - .icon-box { - cursor: pointer; - padding: 8px 16px; - - .icon { - transition: all 0.3s ease; - transform: rotate(180deg); - } - } - - a { - display: flex; - padding: { - top: 8px; - bottom: 8px; - right: 16px; - }; - height: 100%; - width: 100%; - - .text { - flex: 1; - } - } - } - - .submenu { - - } - - &.show { - .menu-bt { - .icon-box { - .icon { - transform: rotate(360deg); + .submenu { + display: block; + animation: 0.3s ease; + @include mixins.unique-keyframes { + 0% { + display: block; + transform: translateX(-10px); + opacity: 0; + } + 100% { + display: block; + transform: translateX(0); + opacity: 1; } } } @@ -106,7 +122,7 @@ body { .separate { height: 0; - margin: 10px 0; + margin: 10px 5px; border: { width: 1px; color: constants.$font-secondary-color; diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index de3a10a..ab6d9cf 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -10,6 +10,7 @@ interface HideScrollbarProps isHiddenVerticalScrollbarWhenFull?: boolean isShowHorizontalScrollbar?: boolean isHiddenHorizontalScrollbarWhenFull?: boolean + minWidth?: string | number } export interface HideScrollbarElement { @@ -138,7 +139,6 @@ const HideScrollbar = forwardRef((prop const lastScrollbarClickPositionRef = useRef({ x: -1, y: -1 }) const lastScrollbarTouchPositionRef = useRef({ x: -1, y: -1 }) const lastTouchPositionRef = useRef({ x: -1, y: -1 }) - const [verticalScrollbarWidth, setVerticalScrollbarWidth] = useState(0) const [verticalScrollbarLength, setVerticalScrollbarLength] = useState(100) const [verticalScrollbarPosition, setVerticalScrollbarPosition] = useState(0) const [verticalScrollbarOnClick, setVerticalScrollbarOnClick] = useState(false) @@ -157,6 +157,7 @@ const HideScrollbar = forwardRef((prop isHiddenVerticalScrollbarWhenFull, isShowHorizontalScrollbar, isHiddenHorizontalScrollbarWhenFull, + minWidth, ..._props } = props @@ -365,9 +366,6 @@ const HideScrollbar = forwardRef((prop useEffect(() => { const windowResizeListener = () => { - setVerticalScrollbarWidth( - (rootRef.current?.offsetWidth ?? 0) - (rootRef.current?.clientWidth ?? 0) - ) setHorizontalScrollbarWidth( (rootRef.current?.offsetHeight ?? 0) - (rootRef.current?.clientHeight ?? 0) ) @@ -457,7 +455,6 @@ const HideScrollbar = forwardRef((prop className={'hide-scrollbar-selection'} tabIndex={0} style={{ - width: `calc(100vw + ${verticalScrollbarWidth}px)`, height: `calc(100vh + ${horizontalScrollbarWidth}px)`, touchAction: isPreventAnyScroll ? 'none' : '', msTouchAction: isPreventAnyScroll ? 'none' : '' @@ -469,7 +466,7 @@ const HideScrollbar = forwardRef((prop onTouchMove={isPreventAnyScroll ? handleDefaultTouchmove : undefined} onScroll={handleDefaultScroll} > -
        +
        {props.children}
        diff --git a/src/pages/HomeFramework.tsx b/src/pages/HomeFramework.tsx index d63978e..56993c1 100644 --- a/src/pages/HomeFramework.tsx +++ b/src/pages/HomeFramework.tsx @@ -81,6 +81,7 @@ const HomeFramework: React.FC = () => { ref={hideScrollbarRef} isPreventVerticalScroll={preventScroll} isShowHorizontalScrollbar={true} + minWidth={'900px'} >
        diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index a0dff56..941d44d 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -3,166 +3,129 @@ import FitFullScreen from '@/components/common/FitFullScreen' import '@/assets/css/pages/tools-framework.scss' import Icon from '@ant-design/icons' import { toolsJsonObjects } from '@/router/tools.tsx' -import _ from 'lodash' +import HideScrollbar from '@/components/common/HideScrollbar.tsx' const ToolsFramework: React.FC = () => { - const location = useLocation() - - const [multipleMenuShown, setMultipleMenuShown] = useState( - toolsJsonObjects.map((value) => ({ - id: value.id, - path: value.path, - shown: `${location.pathname}/`.startsWith(`/tools/${value.path}/`) - })) - ) - - useEffect(() => { - const temp = _.clone(multipleMenuShown) - temp.forEach((value) => { - value.shown = `${location.pathname}/`.startsWith(`/tools/${value.path}/`) - }) - setMultipleMenuShown(temp) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [location]) - - const switchSubmenu = (menuId: string) => { - return () => { - const temp = _.clone(multipleMenuShown) - const menu = temp.find(({ id }) => id === menuId) - menu && (menu.shown = !menu.shown) - setMultipleMenuShown(temp) - } - } - return ( <>
        -
        氮工具
        -
        -
          -
        • -
          -
        • -
        • -
          - - isPending ? 'pending' : isActive ? 'active' : '' - } - > - - {toolsJsonObjects[0].name} - -
          -
        • -
        • -
          - - isPending ? ' pending' : isActive ? ' active' : '' - } - > - - {toolsJsonObjects[1].name} - -
          -
        • -
        • -
          -
        • - {toolsJsonObjects.map((tool) => { - return tool.menu && - tool.id !== 'tools' && - tool.id !== 'tools-all' ? ( -
        • id === tool.id - )?.shown ?? false - ? ' show' - : '' - }` - : 'item' - } - key={tool.id} - > -
          - {tool.children ? ( -
          +
          氮工具
          +
          +
            +
          • +
            +
          • +
          • +
            + + isPending ? 'pending' : isActive ? 'active' : '' + } + > +
            + +
            + + {toolsJsonObjects[0].name} + +
            +
            +
          • +
          • +
            + + isPending ? ' pending' : isActive ? ' active' : '' + } + > +
            + +
            + + {toolsJsonObjects[1].name} + +
            +
            +
          • +
          • +
            +
          • + {toolsJsonObjects.map((tool) => { + return tool.menu && + tool.id !== 'tools' && + tool.id !== 'tools-all' ? ( +
          • +
            + + isPending + ? 'pending' + : isActive + ? 'active' + : '' + } > - -
            +
            + {tool.icon ? ( + + ) : undefined} +
            + {tool.name} + +
          + {tool.children ? ( +
            +
            + {tool.children.map((subTool) => { + return subTool.menu ? ( +
          • + + isPending + ? 'pending' + : isActive + ? 'active' + : '' + } + > + + {subTool.name} + + +
          • + ) : undefined + })} +
            +
          ) : undefined} - - isPending ? 'pending' : isActive ? 'active' : '' - } - > - {tool.children ? undefined : tool.icon ? ( - - ) : undefined} - {tool.name} - -
          - {tool.children ? ( -
            - {tool.children.map((subTool) => { - return subTool.menu ? ( -
          • - - isPending - ? 'pending' - : isActive - ? 'active' - : '' - } - > - {subTool.icon ? ( - - ) : undefined} - - {subTool.name} - - -
          • - ) : undefined - })} -
          - ) : undefined} -
        • - ) : undefined - })} -
        -
        + + ) : undefined + })} +
      +
    • +
    diff --git a/src/router/tools.tsx b/src/router/tools.tsx index 5c675d2..e87043f 100644 --- a/src/router/tools.tsx +++ b/src/router/tools.tsx @@ -8,7 +8,6 @@ export const toolsJsonObjects: ToolsJsonObject[] = [ id: 'tools', component: React.lazy(() => import('@/pages/tools')), name: '主页', - icon: React.lazy(() => import('~icons/fatweb/logo.jsx')), menu: true, auth: false }, @@ -35,6 +34,7 @@ export const toolsJsonObjects: ToolsJsonObject[] = [ path: '1', id: '1', name: '翻译1', + icon: React.lazy(() => import('~icons/fatweb/logo.jsx')), menu: true, auth: false }, @@ -80,6 +80,186 @@ export const toolsJsonObjects: ToolsJsonObject[] = [ icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), menu: true, auth: false + }, + { + path: 'translation--1', + id: 'tools-translation--1', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--1', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--2', + id: 'tools-translation--2', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--2', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--3', + id: 'tools-translation--3', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--3', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--4', + id: 'tools-translation--4', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--4', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--5', + id: 'tools-translation--5', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--5', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--6', + id: 'tools-translation--6', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--6', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--7', + id: 'tools-translation--7', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--7', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--8', + id: 'tools-translation--8', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--8', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--9', + id: 'tools-translation--9', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--9', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--10', + id: 'tools-translation--10', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--10', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--1-', + id: 'tools-translation--1-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--1-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--2-', + id: 'tools-translation--2-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--2-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--3-', + id: 'tools-translation--3-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--3-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--4-', + id: 'tools-translation--4-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--4-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--5-', + id: 'tools-translation--5-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--5-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--6-', + id: 'tools-translation--6-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--6-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--7-', + id: 'tools-translation--7-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--7-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--8-', + id: 'tools-translation--8-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--8-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--9-', + id: 'tools-translation--9-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--9-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false + }, + { + path: 'translation--10-', + id: 'tools-translation--10-', + component: React.lazy(() => import('@/pages/tools/Translation')), + name: '翻译--10-', + icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), + menu: true, + auth: false } ] -- 2.49.1 From 36b5acfea9425526a89d8cba12ca1c4f3a1af6a9 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Thu, 12 Oct 2023 23:26:10 +0800 Subject: [PATCH 15/26] Fix HideScrollbar --- src/components/common/HideScrollbar.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index ab6d9cf..8ffa513 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -139,6 +139,7 @@ const HideScrollbar = forwardRef((prop const lastScrollbarClickPositionRef = useRef({ x: -1, y: -1 }) const lastScrollbarTouchPositionRef = useRef({ x: -1, y: -1 }) const lastTouchPositionRef = useRef({ x: -1, y: -1 }) + const [verticalScrollbarWidth, setVerticalScrollbarWidth] = useState(0) const [verticalScrollbarLength, setVerticalScrollbarLength] = useState(100) const [verticalScrollbarPosition, setVerticalScrollbarPosition] = useState(0) const [verticalScrollbarOnClick, setVerticalScrollbarOnClick] = useState(false) @@ -366,6 +367,9 @@ const HideScrollbar = forwardRef((prop useEffect(() => { const windowResizeListener = () => { + setVerticalScrollbarWidth( + (rootRef.current?.offsetWidth ?? 0) - (rootRef.current?.clientWidth ?? 0) + ) setHorizontalScrollbarWidth( (rootRef.current?.offsetHeight ?? 0) - (rootRef.current?.clientHeight ?? 0) ) @@ -455,6 +459,7 @@ const HideScrollbar = forwardRef((prop className={'hide-scrollbar-selection'} tabIndex={0} style={{ + width: `calc(100vw + ${verticalScrollbarWidth}px)`, height: `calc(100vh + ${horizontalScrollbarWidth}px)`, touchAction: isPreventAnyScroll ? 'none' : '', msTouchAction: isPreventAnyScroll ? 'none' : '' -- 2.49.1 From 1c05de7f20b77ca49db01b44a8ba2baff1b39db4 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Thu, 12 Oct 2023 23:27:21 +0800 Subject: [PATCH 16/26] Temp --- .../css/components/common/hide-scrollbar.scss | 4 --- src/assets/css/pages/tools-framework.scss | 35 +++++++++++-------- src/pages/ToolsFramework.tsx | 10 +++--- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/assets/css/components/common/hide-scrollbar.scss b/src/assets/css/components/common/hide-scrollbar.scss index 5a9f7c9..df0b567 100644 --- a/src/assets/css/components/common/hide-scrollbar.scss +++ b/src/assets/css/components/common/hide-scrollbar.scss @@ -17,10 +17,6 @@ } } - ::-webkit-scrollbar { - display: none; - } - .scrollbar { position: absolute; z-index: 1000; diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index e9a54d0..9fbb602 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -6,10 +6,16 @@ body { } .left-panel { + display: flex; + flex-direction: column; width: 16%; background-color: constants.$origin-color; user-select: none; + .hide-scrollbar-selection { + height: 100% !important; + } + .title { font-size: 2em; text-align: center; @@ -61,8 +67,8 @@ body { } .submenu { - display: none; - position: fixed; + display: block; + position: absolute; padding-left: 20px; left: 100%; top: 0; @@ -99,7 +105,9 @@ body { } &:hover { - background-color: constants.$background-color; + a { + background-color: constants.$background-color; + } .submenu { display: block; @@ -119,20 +127,19 @@ body { } } } - - .separate { - height: 0; - margin: 10px 5px; - border: { - width: 1px; - color: constants.$font-secondary-color; - style: solid; - }; - opacity: 0.4; - } } } } + .separate { + height: 0; + margin: 10px 5px; + border: { + width: 1px; + color: constants.$font-secondary-color; + style: solid; + }; + opacity: 0.4; + } } .right-panel { diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index 941d44d..4cd80cf 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -10,13 +10,11 @@ const ToolsFramework: React.FC = () => { <>
    - -
    氮工具
    +
    氮工具
    +
    +
      -
    • -
      -
    • {
    + +
    氮工具
    -- 2.49.1 From a8129e8afff86c3d36c5c211e97174a6a4b6743a Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 13 Oct 2023 11:14:24 +0800 Subject: [PATCH 17/26] Optimize HideScrollbar --- .../css/components/common/hide-scrollbar.scss | 7 +++++-- src/components/common/HideScrollbar.tsx | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/assets/css/components/common/hide-scrollbar.scss b/src/assets/css/components/common/hide-scrollbar.scss index df0b567..1d604dc 100644 --- a/src/assets/css/components/common/hide-scrollbar.scss +++ b/src/assets/css/components/common/hide-scrollbar.scss @@ -1,6 +1,7 @@ @use '@/assets/css/constants' as constants; .hide-scrollbar-mask { + position: relative; width: 100%; height: 100%; overflow: hidden; @@ -49,8 +50,9 @@ padding: 12px 4px; width: 16px; height: 100%; - right: 0; + left: 100%; top: 0; + transform: translateX(-100%); } .horizontal-scrollbar { @@ -58,6 +60,7 @@ width: 100%; height: 16px; left: 0; - bottom: 0; + top: 100%; + transform: translateY(-100%); } } \ No newline at end of file diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index 8ffa513..44e158f 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -459,8 +459,8 @@ const HideScrollbar = forwardRef((prop className={'hide-scrollbar-selection'} tabIndex={0} style={{ - width: `calc(100vw + ${verticalScrollbarWidth}px)`, - height: `calc(100vh + ${horizontalScrollbarWidth}px)`, + width: `calc(${maskRef.current?.clientWidth}px + ${verticalScrollbarWidth}px)`, + height: `calc(${maskRef.current?.clientHeight}px + ${horizontalScrollbarWidth}px)`, touchAction: isPreventAnyScroll ? 'none' : '', msTouchAction: isPreventAnyScroll ? 'none' : '' }} @@ -482,6 +482,13 @@ const HideScrollbar = forwardRef((prop verticalScrollbarLength === 100) } className={'scrollbar vertical-scrollbar'} + style={{ + height: maskRef.current ? maskRef.current?.clientHeight - 1 : undefined, + top: maskRef.current?.clientTop, + left: maskRef.current + ? maskRef.current?.clientLeft + maskRef.current?.clientWidth - 1 + : undefined + }} >
    ((prop horizontalScrollbarLength === 100) } className={'scrollbar horizontal-scrollbar'} + style={{ + width: maskRef.current ? maskRef.current?.clientWidth - 1 : undefined, + left: maskRef.current?.clientLeft, + top: maskRef.current + ? maskRef.current?.clientTop + maskRef.current?.clientHeight - 1 + : undefined + }} >
    Date: Fri, 13 Oct 2023 11:33:14 +0800 Subject: [PATCH 18/26] Add scrollbar width setting to HideScrollbar --- .../css/components/common/hide-scrollbar.scss | 10 ++++++++-- src/components/common/HideScrollbar.tsx | 14 +++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/assets/css/components/common/hide-scrollbar.scss b/src/assets/css/components/common/hide-scrollbar.scss index 1d604dc..780168a 100644 --- a/src/assets/css/components/common/hide-scrollbar.scss +++ b/src/assets/css/components/common/hide-scrollbar.scss @@ -48,19 +48,25 @@ .vertical-scrollbar { padding: 12px 4px; - width: 16px; height: 100%; left: 100%; top: 0; transform: translateX(-100%); + + .box { + width: 8px; + } } .horizontal-scrollbar { padding: 4px 12px; width: 100%; - height: 16px; left: 0; top: 100%; transform: translateY(-100%); + + .box { + height: 8px; + } } } \ No newline at end of file diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index 44e158f..2cf3b8f 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -11,6 +11,8 @@ interface HideScrollbarProps isShowHorizontalScrollbar?: boolean isHiddenHorizontalScrollbarWhenFull?: boolean minWidth?: string | number + minHeight?: string | number + scrollbarWidth?: string | number } export interface HideScrollbarElement { @@ -159,6 +161,8 @@ const HideScrollbar = forwardRef((prop isShowHorizontalScrollbar, isHiddenHorizontalScrollbarWhenFull, minWidth, + minHeight, + scrollbarWidth, ..._props } = props @@ -471,7 +475,11 @@ const HideScrollbar = forwardRef((prop onTouchMove={isPreventAnyScroll ? handleDefaultTouchmove : undefined} onScroll={handleDefaultScroll} > -
    +
    {props.children}
    @@ -490,7 +498,7 @@ const HideScrollbar = forwardRef((prop : undefined }} > -
    +
    ((prop : undefined }} > -
    +
    Date: Fri, 13 Oct 2023 15:34:22 +0800 Subject: [PATCH 19/26] Optimize submenu in ToolsFramework --- .../css/components/common/hide-scrollbar.scss | 4 + src/assets/css/pages/tools-framework.scss | 35 ++- src/pages/ToolsFramework.tsx | 254 ++++++++++-------- src/router/tools.tsx | 18 +- 4 files changed, 187 insertions(+), 124 deletions(-) diff --git a/src/assets/css/components/common/hide-scrollbar.scss b/src/assets/css/components/common/hide-scrollbar.scss index 780168a..2cf545e 100644 --- a/src/assets/css/components/common/hide-scrollbar.scss +++ b/src/assets/css/components/common/hide-scrollbar.scss @@ -18,6 +18,10 @@ } } + ::-webkit-scrollbar { + display: none; + } + .scrollbar { position: absolute; z-index: 1000; diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index 9fbb602..d0ba705 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -12,10 +12,6 @@ body { background-color: constants.$origin-color; user-select: none; - .hide-scrollbar-selection { - height: 100% !important; - } - .title { font-size: 2em; text-align: center; @@ -26,9 +22,20 @@ body { } .content { - > ul { - > li { + display: flex; + min-height: 0; + flex-direction: column; + .toolsMenu { + min-height: 0; + + .hide-scrollbar-mask { + flex: 1; + } + } + + ul { + > li { &.item { position: relative; margin: 4px 14px; @@ -61,17 +68,16 @@ body { &.active { color: constants.$origin-color; - background-color: constants.$main-color; + background-color: constants.$main-color !important; } } } .submenu { - display: block; - position: absolute; + display: none; + position: fixed; padding-left: 20px; - left: 100%; - top: 0; + z-index: 10000; .content { display: flex; @@ -105,8 +111,10 @@ body { } &:hover { - a { - background-color: constants.$background-color; + .menu-bt { + a { + background-color: constants.$background-color; + } } .submenu { @@ -130,6 +138,7 @@ body { } } } + .separate { height: 0; margin: 10px 5px; diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index 4cd80cf..d69d129 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -6,125 +6,159 @@ import { toolsJsonObjects } from '@/router/tools.tsx' import HideScrollbar from '@/components/common/HideScrollbar.tsx' const ToolsFramework: React.FC = () => { + const [submenuTop, setSubmenuTop] = useState(0) + const [submenuLeft, setSubmenuLeft] = useState(0) + + const showSubmenu = (e: React.MouseEvent) => { + const parentElement = e.currentTarget.parentElement + if (parentElement && parentElement.childElementCount === 2) { + const parentClientRect = parentElement.getBoundingClientRect() + if (parentClientRect.top <= screen.height / 2) { + setSubmenuTop(parentClientRect.top) + } else { + setSubmenuTop( + parentClientRect.top - + (parentElement.lastElementChild?.clientHeight ?? 0) + + e.currentTarget.clientHeight + ) + } + setSubmenuLeft(parentClientRect.right) + } + } + return ( <>
    氮工具
    - -
    -
      -
    • -
      - - isPending ? 'pending' : isActive ? 'active' : '' - } - > -
      - -
      - - {toolsJsonObjects[0].name} - -
      -
      -
    • -
    • -
      - - isPending ? ' pending' : isActive ? ' active' : '' - } - > -
      - -
      - - {toolsJsonObjects[1].name} - -
      -
      -
    • -
    • -
      -
    • - {toolsJsonObjects.map((tool) => { - return tool.menu && - tool.id !== 'tools' && - tool.id !== 'tools-all' ? ( -
    • -
      - - isPending - ? 'pending' - : isActive - ? 'active' - : '' - } +
      +
        +
      • +
        + + isPending ? 'pending' : isActive ? 'active' : '' + } + > +
        + +
        + {toolsJsonObjects[0].name} +
        +
        +
      • +
      • +
        + + isPending ? ' pending' : isActive ? ' active' : '' + } + > +
        + +
        + {toolsJsonObjects[1].name} +
        +
        +
      • +
      • +
        +
      • +
      +
      + +
        + {toolsJsonObjects.map((tool) => { + return tool.menu && + tool.id !== 'tools' && + tool.id !== 'tools-all' ? ( +
      • +
        -
        - {tool.icon ? ( - - ) : undefined} -
        - {tool.name} - -
        - {tool.children ? ( -
          -
          - {tool.children.map((subTool) => { - return subTool.menu ? ( -
        • - - isPending - ? 'pending' - : isActive - ? 'active' - : '' - } + + isPending + ? 'pending' + : isActive + ? 'active' + : '' + } + > +
          + {tool.icon ? ( + + ) : undefined} +
          + {tool.name} +
          +
        • + {tool.children ? ( +
            +
            + {tool.children.map((subTool) => { + return subTool.menu ? ( +
          • - - {subTool.name} - - -
          • - ) : undefined - })} -
            -
          - ) : undefined} - - ) : undefined - })} -
        + + isPending + ? 'pending' + : isActive + ? 'active' + : '' + } + > + + {subTool.name} + + +
      • + ) : undefined + })} +
      +
    + ) : undefined} +
  • + ) : undefined + })} + +
    - - +
    氮工具
    diff --git a/src/router/tools.tsx b/src/router/tools.tsx index e87043f..b6c658b 100644 --- a/src/router/tools.tsx +++ b/src/router/tools.tsx @@ -259,7 +259,23 @@ export const toolsJsonObjects: ToolsJsonObject[] = [ name: '翻译--10-', icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')), menu: true, - auth: false + auth: false, + children: [ + { + path: '1-1', + id: '1-1', + name: '翻译1-', + menu: true, + auth: false + }, + { + path: '2-1', + id: '2-1', + name: '翻译2-', + menu: true, + auth: false + } + ] } ] -- 2.49.1 From fea57c86327531e6e21d66a17e34ff0e345cc16e Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 13 Oct 2023 15:59:14 +0800 Subject: [PATCH 20/26] Optimize submenu in ToolsFramework --- src/assets/css/pages/tools-framework.scss | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index d0ba705..3526d8e 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -8,7 +8,7 @@ body { .left-panel { display: flex; flex-direction: column; - width: 16%; + width: clamp(180px, 20vw, 240px); background-color: constants.$origin-color; user-select: none; @@ -25,13 +25,11 @@ body { display: flex; min-height: 0; flex-direction: column; + flex: 1; .toolsMenu { min-height: 0; - - .hide-scrollbar-mask { - flex: 1; - } + flex: 1; } ul { -- 2.49.1 From c1691d3e8e2027f6ed731fce623311558986420f Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 13 Oct 2023 17:42:48 +0800 Subject: [PATCH 21/26] Optimize svg --- src/assets/svg/down.svg | 2 +- src/assets/svg/github.svg | 2 +- src/assets/svg/jenkins.svg | 2 +- src/assets/svg/loading.svg | 2 +- src/assets/svg/logo.svg | 2 +- src/assets/svg/menu.svg | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/assets/svg/down.svg b/src/assets/svg/down.svg index 872d226..587e1d1 100644 --- a/src/assets/svg/down.svg +++ b/src/assets/svg/down.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/github.svg b/src/assets/svg/github.svg index fdf2ea5..02c1634 100644 --- a/src/assets/svg/github.svg +++ b/src/assets/svg/github.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/jenkins.svg b/src/assets/svg/jenkins.svg index 51fbbc6..ee77645 100644 --- a/src/assets/svg/jenkins.svg +++ b/src/assets/svg/jenkins.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/loading.svg b/src/assets/svg/loading.svg index a7c3d67..140bea2 100644 --- a/src/assets/svg/loading.svg +++ b/src/assets/svg/loading.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/logo.svg b/src/assets/svg/logo.svg index 243d161..bae41f6 100644 --- a/src/assets/svg/logo.svg +++ b/src/assets/svg/logo.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/menu.svg b/src/assets/svg/menu.svg index 46ac707..f506c1b 100644 --- a/src/assets/svg/menu.svg +++ b/src/assets/svg/menu.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file -- 2.49.1 From a48af3da92902ff2bd2653e01fe2d1bba19ef54d Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 13 Oct 2023 17:51:38 +0800 Subject: [PATCH 22/26] Optimize HideScrollbar --- src/components/common/HideScrollbar.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index 2cf3b8f..f86e5fb 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -45,6 +45,7 @@ export interface HideScrollbarElement { listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions ): void + refreshLayout(): void } const HideScrollbar = forwardRef((props, ref) => { @@ -128,6 +129,9 @@ const HideScrollbar = forwardRef((prop options?: boolean | EventListenerOptions ): void { rootRef.current?.removeEventListener(type, listener, options) + }, + refreshLayout(): void { + setRefreshTime(Date.now()) } } }, @@ -141,6 +145,7 @@ const HideScrollbar = forwardRef((prop const lastScrollbarClickPositionRef = useRef({ x: -1, y: -1 }) const lastScrollbarTouchPositionRef = useRef({ x: -1, y: -1 }) const lastTouchPositionRef = useRef({ x: -1, y: -1 }) + const [refreshTime, setRefreshTime] = useState(0) const [verticalScrollbarWidth, setVerticalScrollbarWidth] = useState(0) const [verticalScrollbarLength, setVerticalScrollbarLength] = useState(100) const [verticalScrollbarPosition, setVerticalScrollbarPosition] = useState(0) @@ -479,6 +484,7 @@ const HideScrollbar = forwardRef((prop className={'hide-scrollbar-content'} ref={contentRef} style={{ minWidth, minHeight }} + data-refresh={refreshTime} > {props.children} -- 2.49.1 From e32f12d301e3250c053261676de0174d1c08fc15 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 13 Oct 2023 17:59:21 +0800 Subject: [PATCH 23/26] Finish sidebar in ToolsFramework --- src/assets/css/pages/tools-framework.scss | 74 +++++++++++++++++++---- src/assets/svg/expand.svg | 1 + src/pages/ToolsFramework.tsx | 42 +++++++++---- src/router/tools.tsx | 1 + 4 files changed, 95 insertions(+), 23 deletions(-) create mode 100644 src/assets/svg/expand.svg diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index 3526d8e..46c8d95 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -11,14 +11,41 @@ body { width: clamp(180px, 20vw, 240px); background-color: constants.$origin-color; user-select: none; + transition: all .3s; + white-space: nowrap; .title { - font-size: 2em; - text-align: center; + display: flex; + align-items: center; font-weight: bold; - letter-spacing: 0.6em; - padding: 10px; + padding: 10px 14px; color: constants.$main-color; + + .icon-box { + display: flex; + justify-content: center; + align-items: center; + padding: 10px; + width: 40px; + height: 40px; + font-size: constants.$SIZE_ICON_SM; + border-radius: 8px; + span { + transform: rotateZ(180deg); + transition: all .3s; + } + + &:hover { + background-color: constants.$background-color; + } + } + + .text { + flex: 1; + font-size: 2em; + text-align: center; + letter-spacing: 0.6em; + } } .content { @@ -42,26 +69,29 @@ body { .menu-bt { border-radius: 8px; overflow: hidden; + height: 40px; .icon-box { + display: flex; + justify-content: center; + align-items: center; + padding: 0 10px; + width: 40px; + height: 40px; + font-size: constants.$SIZE_ICON_SM; cursor: pointer; - width: 26px; - height: 26px; - - .icon { - margin-right: 16px; - } } a { display: flex; - padding: 8px 16px; + align-items: center; height: 100%; width: 100%; transition: all 0.2s; .text { flex: 1; + padding-left: 8px; } &.active { @@ -147,6 +177,28 @@ body { }; opacity: 0.4; } + + &.hide { + width: 68px; + + .title { + .icon-box { + span { + transform: rotateZ(360deg); + transition: all .3s; + } + } + .text { + display: none; + } + } + + .menu-bt { + .text { + display: none; + } + } + } } .right-panel { diff --git a/src/assets/svg/expand.svg b/src/assets/svg/expand.svg new file mode 100644 index 0000000..95e5060 --- /dev/null +++ b/src/assets/svg/expand.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index d69d129..f9e94bb 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -3,11 +3,20 @@ import FitFullScreen from '@/components/common/FitFullScreen' import '@/assets/css/pages/tools-framework.scss' import Icon from '@ant-design/icons' import { toolsJsonObjects } from '@/router/tools.tsx' -import HideScrollbar from '@/components/common/HideScrollbar.tsx' +import HideScrollbar, { HideScrollbarElement } from '@/components/common/HideScrollbar.tsx' const ToolsFramework: React.FC = () => { + const hideScrollbarRef = useRef(null) const [submenuTop, setSubmenuTop] = useState(0) const [submenuLeft, setSubmenuLeft] = useState(0) + const [hideSidebar, setHideSidebar] = useState(false) + + const switchSidebar = () => { + setHideSidebar(!hideSidebar) + setTimeout(() => { + hideScrollbarRef.current?.refreshLayout() + }, 300) + } const showSubmenu = (e: React.MouseEvent) => { const parentElement = e.currentTarget.parentElement @@ -29,8 +38,13 @@ const ToolsFramework: React.FC = () => { return ( <> -
    -
    氮工具
    +
    +
    + + + + 氮工具 +
      @@ -44,10 +58,12 @@ const ToolsFramework: React.FC = () => { } >
      - + {toolsJsonObjects[0].icon ? ( + + ) : undefined}
      {toolsJsonObjects[0].name} @@ -62,10 +78,12 @@ const ToolsFramework: React.FC = () => { } >
      - + {toolsJsonObjects[1].icon ? ( + + ) : undefined}
      {toolsJsonObjects[1].name} @@ -78,8 +96,8 @@ const ToolsFramework: React.FC = () => {
        {toolsJsonObjects.map((tool) => { diff --git a/src/router/tools.tsx b/src/router/tools.tsx index b6c658b..a98995c 100644 --- a/src/router/tools.tsx +++ b/src/router/tools.tsx @@ -7,6 +7,7 @@ export const toolsJsonObjects: ToolsJsonObject[] = [ path: '', id: 'tools', component: React.lazy(() => import('@/pages/tools')), + icon: React.lazy(() => import('~icons/fatweb/logo.jsx')), name: '主页', menu: true, auth: false -- 2.49.1 From 05c68a2ab78ff575a2ed80f7c2b9b430a7700210 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 13 Oct 2023 18:18:08 +0800 Subject: [PATCH 24/26] Add sidebar footer in ToolsFramework.tsx --- src/assets/css/pages/tools-framework.scss | 36 +++++++++++++++++++++++ src/pages/ToolsFramework.tsx | 14 +++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index 46c8d95..f1dc864 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -30,6 +30,7 @@ body { height: 40px; font-size: constants.$SIZE_ICON_SM; border-radius: 8px; + cursor: pointer; span { transform: rotateZ(180deg); transition: all .3s; @@ -45,6 +46,7 @@ body { font-size: 2em; text-align: center; letter-spacing: 0.6em; + transform: translateX(0.3em); } } @@ -178,6 +180,40 @@ body { opacity: 0.4; } + .footer { + display: flex; + align-items: center; + font-weight: bold; + padding: 10px 14px; + color: constants.$main-color; + + .icon-box { + display: flex; + justify-content: center; + align-items: center; + padding: 10px; + width: 40px; + height: 40px; + font-size: constants.$SIZE_ICON_SM; + border-radius: 8px; + span { + transform: rotateZ(180deg); + transition: all .3s; + } + + &:hover { + background-color: constants.$background-color; + } + } + + .text { + flex: 1; + font-size: 2em; + text-align: center; + letter-spacing: 0.6em; + } + } + &.hide { width: 68px; diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index f9e94bb..519ea17 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -4,15 +4,17 @@ import '@/assets/css/pages/tools-framework.scss' import Icon from '@ant-design/icons' import { toolsJsonObjects } from '@/router/tools.tsx' import HideScrollbar, { HideScrollbarElement } from '@/components/common/HideScrollbar.tsx' +import { getLocalStorage, setLocalStorage } from '@/utils/common.ts' const ToolsFramework: React.FC = () => { const hideScrollbarRef = useRef(null) const [submenuTop, setSubmenuTop] = useState(0) const [submenuLeft, setSubmenuLeft] = useState(0) - const [hideSidebar, setHideSidebar] = useState(false) + const [hideSidebar, setHideSidebar] = useState(getLocalStorage('hideSidebar') === 'false') const switchSidebar = () => { setHideSidebar(!hideSidebar) + setLocalStorage('hideSidebar', hideSidebar ? 'true' : 'false') setTimeout(() => { hideScrollbarRef.current?.refreshLayout() }, 300) @@ -90,7 +92,7 @@ const ToolsFramework: React.FC = () => {
    • -
      +
    @@ -177,7 +179,13 @@ const ToolsFramework: React.FC = () => {
    -
    氮工具
    +
    +
    + + + + 氮工具 +
    -- 2.49.1 From fdc2135ce24978510321ca1000e260b23cbda31c Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 13 Oct 2023 22:12:09 +0800 Subject: [PATCH 25/26] Optimize HideScrollbar --- src/components/common/HideScrollbar.tsx | 44 +++++++++++++++---------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index f86e5fb..2af301c 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -13,6 +13,7 @@ interface HideScrollbarProps minWidth?: string | number minHeight?: string | number scrollbarWidth?: string | number + animationTransitionTime?: number } export interface HideScrollbarElement { @@ -131,7 +132,7 @@ const HideScrollbar = forwardRef((prop rootRef.current?.removeEventListener(type, listener, options) }, refreshLayout(): void { - setRefreshTime(Date.now()) + refreshLayout() } } }, @@ -168,6 +169,7 @@ const HideScrollbar = forwardRef((prop minWidth, minHeight, scrollbarWidth, + animationTransitionTime, ..._props } = props @@ -374,24 +376,32 @@ const HideScrollbar = forwardRef((prop ) } + const refreshLayout = () => { + setRefreshTime(Date.now()) + } + useEffect(() => { const windowResizeListener = () => { - setVerticalScrollbarWidth( - (rootRef.current?.offsetWidth ?? 0) - (rootRef.current?.clientWidth ?? 0) - ) - setHorizontalScrollbarWidth( - (rootRef.current?.offsetHeight ?? 0) - (rootRef.current?.clientHeight ?? 0) - ) - - rootRef.current && - setVerticalScrollbarLength( - (rootRef.current.clientHeight / (contentRef.current?.clientHeight ?? 0)) * 100 + setTimeout(() => { + setVerticalScrollbarWidth( + (rootRef.current?.offsetWidth ?? 0) - (rootRef.current?.clientWidth ?? 0) + ) + setHorizontalScrollbarWidth( + (rootRef.current?.offsetHeight ?? 0) - (rootRef.current?.clientHeight ?? 0) ) - rootRef.current && - setHorizontalScrollbarLength( - (rootRef.current.clientWidth / (contentRef.current?.clientWidth ?? 0)) * 100 - ) + rootRef.current && + setVerticalScrollbarLength( + (rootRef.current.clientHeight / (contentRef.current?.clientHeight ?? 0)) * + 100 + ) + + rootRef.current && + setHorizontalScrollbarLength( + (rootRef.current.clientWidth / (contentRef.current?.clientWidth ?? 0)) * 100 + ) + refreshLayout() + }, animationTransitionTime) return windowResizeListener } @@ -493,7 +503,7 @@ const HideScrollbar = forwardRef((prop hidden={ !isShowVerticalScrollbar || ((isHiddenVerticalScrollbarWhenFull ?? true) && - verticalScrollbarLength === 100) + verticalScrollbarLength >= 100) } className={'scrollbar vertical-scrollbar'} style={{ @@ -530,7 +540,7 @@ const HideScrollbar = forwardRef((prop hidden={ !isShowHorizontalScrollbar || ((isHiddenHorizontalScrollbarWhenFull ?? true) && - horizontalScrollbarLength === 100) + horizontalScrollbarLength >= 100) } className={'scrollbar horizontal-scrollbar'} style={{ -- 2.49.1 From 507ed1eb9a1fd615526a03be1b7010f07cbf3c42 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Sat, 14 Oct 2023 01:09:02 +0800 Subject: [PATCH 26/26] Finish sidebar in ToolsFramework --- src/assets/css/pages/tools-framework.scss | 36 +++++++++++++---------- src/assets/svg/home.svg | 1 + src/assets/svg/user.svg | 1 + src/components/common/HideScrollbar.tsx | 1 + src/pages/ToolsFramework.tsx | 7 +++-- 5 files changed, 27 insertions(+), 19 deletions(-) create mode 100644 src/assets/svg/home.svg create mode 100644 src/assets/svg/user.svg diff --git a/src/assets/css/pages/tools-framework.scss b/src/assets/css/pages/tools-framework.scss index f1dc864..b95691f 100644 --- a/src/assets/css/pages/tools-framework.scss +++ b/src/assets/css/pages/tools-framework.scss @@ -13,6 +13,7 @@ body { user-select: none; transition: all .3s; white-space: nowrap; + overflow: hidden; .title { display: flex; @@ -184,33 +185,30 @@ body { display: flex; align-items: center; font-weight: bold; - padding: 10px 14px; + padding: 8px 14px; color: constants.$main-color; .icon-box { display: flex; justify-content: center; align-items: center; + margin-left: 4px; padding: 10px; - width: 40px; - height: 40px; - font-size: constants.$SIZE_ICON_SM; - border-radius: 8px; - span { - transform: rotateZ(180deg); - transition: all .3s; - } - - &:hover { - background-color: constants.$background-color; - } + width: 32px; + height: 32px; + font-size: constants.$SIZE_ICON_XS; + border: 2px constants.$font-secondary-color solid; + color: constants.$font-secondary-color; + border-radius: 50%; + cursor: pointer; } .text { flex: 1; - font-size: 2em; - text-align: center; - letter-spacing: 0.6em; + padding-left: 8px; + font-size: 1.4em; + color: constants.$font-main-color; + user-select: text; } } @@ -234,6 +232,12 @@ body { display: none; } } + + .footer { + .text { + display: none; + } + } } } diff --git a/src/assets/svg/home.svg b/src/assets/svg/home.svg new file mode 100644 index 0000000..ee81985 --- /dev/null +++ b/src/assets/svg/home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svg/user.svg b/src/assets/svg/user.svg new file mode 100644 index 0000000..1ac062a --- /dev/null +++ b/src/assets/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index 2af301c..df8f916 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -446,6 +446,7 @@ const HideScrollbar = forwardRef((prop window.removeEventListener('resize', windowResizeListener) } }, [ + animationTransitionTime, horizontalScrollbarLength, isPreventAnyScroll, isPreventHorizontalScroll, diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index 519ea17..fb3c76d 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -99,6 +99,7 @@ const ToolsFramework: React.FC = () => {
      @@ -181,10 +182,10 @@ const ToolsFramework: React.FC = () => {
    - - + + - 氮工具 + 未登录
    -- 2.49.1