diff --git a/src/components/Root.js b/src/components/Root.tsx similarity index 68% rename from src/components/Root.js rename to src/components/Root.tsx index 8c06100b7a1249f9ff24a4a894d1c7fcf86039b9..adb76a72e684025e56ae3da8f9cd4a08e262c8d3 100644 --- a/src/components/Root.js +++ b/src/components/Root.tsx @@ -1,9 +1,11 @@ import './Root.css'; import React, { lazy, Suspense } from 'react'; +import { PartialRouteObject } from 'react-router'; import { HashRouter as Router, useRoutes } from 'react-router-dom'; import { RecoilRoot } from 'recoil'; import { About } from 'src/components/about/About'; +import { Head } from 'src/components/shared/Head'; import { actions, initialState } from '../store'; import APIConfig from './APIConfig'; @@ -16,40 +18,45 @@ import SideBar from './SideBar'; import StateProvider from './StateProvider'; import StyleGuide from './StyleGuide'; -const Connections = lazy(() => - import( - /* webpackChunkName: "conns" */ - /* webpackPrefetch: true */ - './Connections' - ) +const Connections = lazy( + () => + import( + /* webpackChunkName: "conns" */ + /* webpackPrefetch: true */ + './Connections' + ) ); -const Config = lazy(() => - import( - /* webpackChunkName: "config" */ - /* webpackPrefetch: true */ - './Config' - ) +const Config = lazy( + () => + import( + /* webpackChunkName: "config" */ + /* webpackPrefetch: true */ + './Config' + ) ); -const Logs = lazy(() => - import( - /* webpackChunkName: "logs" */ - /* webpackPrefetch: true */ - './Logs' - ) +const Logs = lazy( + () => + import( + /* webpackChunkName: "logs" */ + /* webpackPrefetch: true */ + './Logs' + ) ); -const Proxies = lazy(() => - import( - /* webpackChunkName: "proxies" */ - /* webpackPrefetch: true */ - './proxies/Proxies' - ) +const Proxies = lazy( + () => + import( + /* webpackChunkName: "proxies" */ + /* webpackPrefetch: true */ + './proxies/Proxies' + ) ); -const Rules = lazy(() => - import( - /* webpackChunkName: "rules" */ - /* webpackPrefetch: true */ - './Rules' - ) +const Rules = lazy( + () => + import( + /* webpackChunkName: "rules" */ + /* webpackPrefetch: true */ + './Rules' + ) ); const routes = [ @@ -61,7 +68,7 @@ const routes = [ { path: '/rules', element: <Rules /> }, { path: '/about', element: <About /> }, __DEV__ ? { path: '/style', element: <StyleGuide /> } : false, -].filter(Boolean); +].filter(Boolean) as PartialRouteObject[]; function RouteInnerApp() { return useRoutes(routes); @@ -94,6 +101,7 @@ const Root = () => ( <StateProvider initialState={initialState} actions={actions}> <Router> <div className={s0.app}> + <Head /> <Suspense fallback={<Loading2 />}> <App /> </Suspense> diff --git a/src/components/shared/Head.tsx b/src/components/shared/Head.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5997a3a8d78d855b9c6794314e59771db01c2eed --- /dev/null +++ b/src/components/shared/Head.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import { Helmet } from 'react-helmet'; +import { connect } from 'src/components/StateProvider'; +import { getClashAPIConfig } from 'src/store/app'; + +const mapState = (s) => ({ + apiConfig: getClashAPIConfig(s), +}); + +function HeadImpl({ apiConfig }: { apiConfig: { baseURL: string } }) { + let title = 'yacd'; + try { + title = new URL(apiConfig.baseURL).host; + } catch (e) { + // ignore + } + return ( + <Helmet> + <title>{title}</title> + </Helmet> + ); +} + +export const Head = connect(mapState)(HeadImpl);