refactor: react router (#5073)
* refactor: react router * chore: update * fix: router * refactor: generate router children by navItems * chore: set start page when create window * docs: update UPDATELOG.md
This commit is contained in:
@@ -30,7 +30,7 @@ import { useLockFn } from "ahooks";
|
||||
import React from "react";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router";
|
||||
import { delayGroup, healthcheckProxyProvider } from "tauri-plugin-mihomo-api";
|
||||
|
||||
import { EnhancedCard } from "@/components/home/enhanced-card";
|
||||
|
||||
@@ -22,7 +22,7 @@ import { useLockFn } from "ahooks";
|
||||
import dayjs from "dayjs";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router";
|
||||
|
||||
import { useAppData } from "@/providers/app-data-context";
|
||||
import { openWebUrl, updateProfile } from "@/services/cmds";
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
import { useLockFn } from "ahooks";
|
||||
import { useCallback, useEffect, useMemo, useReducer } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { useSystemState } from "@/hooks/use-system-state";
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
ListItemText,
|
||||
ListItemIcon,
|
||||
} from "@mui/material";
|
||||
import { useMatch, useResolvedPath, useNavigate } from "react-router-dom";
|
||||
import { useMatch, useResolvedPath, useNavigate } from "react-router";
|
||||
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
interface Props {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { DialogRef } from "@/components/base";
|
||||
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
import { routers } from "@/pages/_routers";
|
||||
import { navItems } from "@/pages/_routers";
|
||||
import { copyClashEnv } from "@/services/cmds";
|
||||
import { supportedLanguages } from "@/services/i18n";
|
||||
import { showNotice } from "@/services/noticeService";
|
||||
@@ -170,7 +170,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
|
||||
onGuard={(e) => patchVerge({ start_page: e })}
|
||||
>
|
||||
<Select size="small" sx={{ width: 140, "> div": { py: "7.5px" } }}>
|
||||
{routers.map((page: { label: string; path: string }) => {
|
||||
{navItems.map((page: { label: string; path: string }) => {
|
||||
return (
|
||||
<MenuItem key={page.path} value={page.path}>
|
||||
{t(page.label)}
|
||||
|
||||
@@ -6,11 +6,11 @@ import { ResizeObserver } from "@juggle/resize-observer";
|
||||
import { ComposeContextProvider } from "foxact/compose-context-provider";
|
||||
import React from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { RouterProvider } from "react-router";
|
||||
import { MihomoWebSocket } from "tauri-plugin-mihomo-api";
|
||||
|
||||
import { BaseErrorBoundary } from "./components/base";
|
||||
import Layout from "./pages/_layout";
|
||||
import { router } from "./pages/_routers";
|
||||
import { AppDataProvider } from "./providers/app-data-provider";
|
||||
import { WindowProvider } from "./providers/window";
|
||||
import { initializeLanguage } from "./services/i18n";
|
||||
@@ -64,9 +64,7 @@ const initializeApp = async () => {
|
||||
<BaseErrorBoundary>
|
||||
<WindowProvider>
|
||||
<AppDataProvider>
|
||||
<BrowserRouter>
|
||||
<Layout />
|
||||
</BrowserRouter>
|
||||
<RouterProvider router={router} />
|
||||
</AppDataProvider>
|
||||
</WindowProvider>
|
||||
</BaseErrorBoundary>
|
||||
|
||||
@@ -4,14 +4,15 @@ import { listen } from "@tauri-apps/api/event";
|
||||
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
|
||||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime";
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useLocation, useNavigate, useRoutes } from "react-router-dom";
|
||||
import { Outlet, useNavigate } from "react-router";
|
||||
import { SWRConfig, mutate } from "swr";
|
||||
|
||||
import iconDark from "@/assets/image/icon_dark.svg?react";
|
||||
import iconLight from "@/assets/image/icon_light.svg?react";
|
||||
import LogoSvg from "@/assets/image/logo.svg?react";
|
||||
import { BaseErrorBoundary } from "@/components/base";
|
||||
import { NoticeManager } from "@/components/base/NoticeManager";
|
||||
import { WindowControls } from "@/components/controller/window-controller";
|
||||
import { LayoutItem } from "@/components/layout/layout-item";
|
||||
@@ -31,7 +32,7 @@ import { showNotice } from "@/services/noticeService";
|
||||
import { useThemeMode } from "@/services/states";
|
||||
import getSystem from "@/utils/get-system";
|
||||
|
||||
import { routers } from "./_routers";
|
||||
import { navItems } from "./_routers";
|
||||
|
||||
import "dayjs/locale/ru";
|
||||
import "dayjs/locale/zh-cn";
|
||||
@@ -161,24 +162,12 @@ const Layout = () => {
|
||||
const { t } = useTranslation();
|
||||
const { theme } = useCustomTheme();
|
||||
const { verge } = useVerge();
|
||||
const { language, start_page } = verge ?? {};
|
||||
const { language } = verge ?? {};
|
||||
const { switchLanguage } = useI18n();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const matchedElement = useRoutes(routers);
|
||||
const routersEles = useMemo(() => {
|
||||
if (!matchedElement) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<React.Fragment key={location.pathname}>{matchedElement}</React.Fragment>
|
||||
);
|
||||
}, [matchedElement, location.pathname]);
|
||||
const { addListener } = useListen();
|
||||
const initRef = useRef(false);
|
||||
const overlayRemovedRef = useRef(false);
|
||||
const lastStartPageRef = useRef<string | null>(null);
|
||||
const startPageAppliedRef = useRef(false);
|
||||
const themeReady = useMemo(() => Boolean(theme), [theme]);
|
||||
|
||||
const windowControls = useRef<any>(null);
|
||||
@@ -538,35 +527,6 @@ const Layout = () => {
|
||||
}
|
||||
}, [language, switchLanguage]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!start_page) {
|
||||
lastStartPageRef.current = null;
|
||||
startPageAppliedRef.current = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const normalizedStartPage = start_page.startsWith("/")
|
||||
? start_page
|
||||
: `/${start_page}`;
|
||||
|
||||
if (lastStartPageRef.current !== normalizedStartPage) {
|
||||
lastStartPageRef.current = normalizedStartPage;
|
||||
startPageAppliedRef.current = false;
|
||||
}
|
||||
|
||||
if (startPageAppliedRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
startPageAppliedRef.current = true;
|
||||
|
||||
if (location.pathname === normalizedStartPage) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigate(normalizedStartPage, { replace: true });
|
||||
}, [start_page, navigate, location.pathname]);
|
||||
|
||||
if (!themeReady) {
|
||||
return (
|
||||
<div
|
||||
@@ -584,22 +544,6 @@ const Layout = () => {
|
||||
);
|
||||
}
|
||||
|
||||
if (!routersEles) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: "100vw",
|
||||
height: "100vh",
|
||||
background: mode === "light" ? "#fff" : "#181a1b",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
color: mode === "light" ? "#333" : "#fff",
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SWRConfig
|
||||
value={{
|
||||
@@ -692,7 +636,7 @@ const Layout = () => {
|
||||
</div>
|
||||
|
||||
<List className="the-menu">
|
||||
{routers.map((router) => (
|
||||
{navItems.map((router) => (
|
||||
<LayoutItem
|
||||
key={router.label}
|
||||
to={router.path}
|
||||
@@ -710,7 +654,11 @@ const Layout = () => {
|
||||
|
||||
<div className="layout-content__right">
|
||||
<div className="the-bar"></div>
|
||||
<div className="the-content">{routersEles}</div>
|
||||
<div className="the-content">
|
||||
<BaseErrorBoundary>
|
||||
<Outlet />
|
||||
</BaseErrorBoundary>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Paper>
|
||||
|
||||
@@ -6,6 +6,7 @@ import LockOpenRoundedIcon from "@mui/icons-material/LockOpenRounded";
|
||||
import SettingsRoundedIcon from "@mui/icons-material/SettingsRounded";
|
||||
import SubjectRoundedIcon from "@mui/icons-material/SubjectRounded";
|
||||
import WifiRoundedIcon from "@mui/icons-material/WifiRounded";
|
||||
import { createBrowserRouter, RouteObject } from "react-router";
|
||||
|
||||
import ConnectionsSvg from "@/assets/image/itemicon/connections.svg?react";
|
||||
import HomeSvg from "@/assets/image/itemicon/home.svg?react";
|
||||
@@ -15,8 +16,8 @@ import ProxiesSvg from "@/assets/image/itemicon/proxies.svg?react";
|
||||
import RulesSvg from "@/assets/image/itemicon/rules.svg?react";
|
||||
import SettingsSvg from "@/assets/image/itemicon/settings.svg?react";
|
||||
import UnlockSvg from "@/assets/image/itemicon/unlock.svg?react";
|
||||
import { BaseErrorBoundary } from "@/components/base";
|
||||
|
||||
import Layout from "./_layout";
|
||||
import ConnectionsPage from "./connections";
|
||||
import HomePage from "./home";
|
||||
import LogsPage from "./logs";
|
||||
@@ -26,58 +27,67 @@ import RulesPage from "./rules";
|
||||
import SettingsPage from "./settings";
|
||||
import UnlockPage from "./unlock";
|
||||
|
||||
export const routers = [
|
||||
export const navItems = [
|
||||
{
|
||||
label: "Label-Home",
|
||||
path: "/home",
|
||||
path: "/",
|
||||
icon: [<HomeRoundedIcon key="mui" />, <HomeSvg key="svg" />],
|
||||
element: <HomePage />,
|
||||
Component: HomePage,
|
||||
},
|
||||
{
|
||||
label: "Label-Proxies",
|
||||
path: "/",
|
||||
path: "/proxies",
|
||||
icon: [<WifiRoundedIcon key="mui" />, <ProxiesSvg key="svg" />],
|
||||
element: <ProxiesPage />,
|
||||
Component: ProxiesPage,
|
||||
},
|
||||
{
|
||||
label: "Label-Profiles",
|
||||
path: "/profile",
|
||||
icon: [<DnsRoundedIcon key="mui" />, <ProfilesSvg key="svg" />],
|
||||
element: <ProfilesPage />,
|
||||
Component: ProfilesPage,
|
||||
},
|
||||
{
|
||||
label: "Label-Connections",
|
||||
path: "/connections",
|
||||
icon: [<LanguageRoundedIcon key="mui" />, <ConnectionsSvg key="svg" />],
|
||||
element: <ConnectionsPage />,
|
||||
Component: ConnectionsPage,
|
||||
},
|
||||
{
|
||||
label: "Label-Rules",
|
||||
path: "/rules",
|
||||
icon: [<ForkRightRoundedIcon key="mui" />, <RulesSvg key="svg" />],
|
||||
element: <RulesPage />,
|
||||
Component: RulesPage,
|
||||
},
|
||||
{
|
||||
label: "Label-Logs",
|
||||
path: "/logs",
|
||||
icon: [<SubjectRoundedIcon key="mui" />, <LogsSvg key="svg" />],
|
||||
element: <LogsPage />,
|
||||
Component: LogsPage,
|
||||
},
|
||||
{
|
||||
label: "Label-Unlock",
|
||||
path: "/unlock",
|
||||
icon: [<LockOpenRoundedIcon key="mui" />, <UnlockSvg key="svg" />],
|
||||
element: <UnlockPage />,
|
||||
Component: UnlockPage,
|
||||
},
|
||||
{
|
||||
label: "Label-Settings",
|
||||
path: "/settings",
|
||||
icon: [<SettingsRoundedIcon key="mui" />, <SettingsSvg key="svg" />],
|
||||
element: <SettingsPage />,
|
||||
Component: SettingsPage,
|
||||
},
|
||||
].map((router) => ({
|
||||
...router,
|
||||
element: (
|
||||
<BaseErrorBoundary key={router.label}>{router.element}</BaseErrorBoundary>
|
||||
),
|
||||
}));
|
||||
];
|
||||
|
||||
export const router = createBrowserRouter([
|
||||
{
|
||||
path: "/",
|
||||
Component: Layout,
|
||||
children: navItems.map(
|
||||
(item) =>
|
||||
({
|
||||
path: item.path,
|
||||
Component: item.Component,
|
||||
}) as RouteObject,
|
||||
),
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -32,7 +32,7 @@ import { useLockFn } from "ahooks";
|
||||
import { throttle } from "lodash-es";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useLocation } from "react-router";
|
||||
import useSWR, { mutate } from "swr";
|
||||
import { closeAllConnections } from "tauri-plugin-mihomo-api";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user