mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore: tweak route layout
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { useColorScheme } from "@mui/joy";
|
import { useColorScheme } from "@mui/joy";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
import storage from "./helpers/storage";
|
import storage from "./helpers/storage";
|
||||||
@@ -16,7 +16,6 @@ const App = () => {
|
|||||||
const globalStore = useGlobalStore();
|
const globalStore = useGlobalStore();
|
||||||
const workspaceSettingStore = useWorkspaceSettingStore();
|
const workspaceSettingStore = useWorkspaceSettingStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const { appearance, locale, systemStatus } = globalStore.state;
|
const { appearance, locale, systemStatus } = globalStore.state;
|
||||||
const userSetting = userStore.userSetting;
|
const userSetting = userStore.userSetting;
|
||||||
const workspaceGeneralSetting =
|
const workspaceGeneralSetting =
|
||||||
@@ -30,19 +29,6 @@ const App = () => {
|
|||||||
}
|
}
|
||||||
}, [systemStatus.host]);
|
}, [systemStatus.host]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const initialState = async () => {
|
|
||||||
await workspaceSettingStore.fetchWorkspaceSetting(WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL);
|
|
||||||
try {
|
|
||||||
await userStore.fetchCurrentUser();
|
|
||||||
} catch (error) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Promise.all([initialState()]).then(() => setLoading(false));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
const handleColorSchemeChange = (e: MediaQueryListEvent) => {
|
const handleColorSchemeChange = (e: MediaQueryListEvent) => {
|
||||||
@@ -132,7 +118,7 @@ const App = () => {
|
|||||||
}
|
}
|
||||||
}, [mode]);
|
}, [mode]);
|
||||||
|
|
||||||
return loading ? null : <Outlet />;
|
return <Outlet />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
32
web/src/layouts/CommonContextProvider.tsx
Normal file
32
web/src/layouts/CommonContextProvider.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { initialGlobalState } from "@/store/module";
|
||||||
|
import { useUserStore, useWorkspaceSettingStore } from "@/store/v1";
|
||||||
|
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CommonContextProvider = (props: Props) => {
|
||||||
|
const workspaceSettingStore = useWorkspaceSettingStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const initialState = async () => {
|
||||||
|
await initialGlobalState();
|
||||||
|
await workspaceSettingStore.fetchWorkspaceSetting(WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL);
|
||||||
|
try {
|
||||||
|
await userStore.fetchCurrentUser();
|
||||||
|
} catch (error) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise.all([initialState()]).then(() => setLoading(false));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return loading ? null : <>{props.children}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CommonContextProvider;
|
@@ -1,17 +1,34 @@
|
|||||||
import { Button, IconButton, Tooltip } from "@mui/joy";
|
import { Button, IconButton, Tooltip } from "@mui/joy";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet, useLocation } from "react-router-dom";
|
||||||
import useLocalStorage from "react-use/lib/useLocalStorage";
|
import useLocalStorage from "react-use/lib/useLocalStorage";
|
||||||
import Icon from "@/components/Icon";
|
import Icon from "@/components/Icon";
|
||||||
import Navigation from "@/components/Navigation";
|
import Navigation from "@/components/Navigation";
|
||||||
|
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||||
|
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||||
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||||
import Loading from "@/pages/Loading";
|
import Loading from "@/pages/Loading";
|
||||||
|
import { Routes } from "@/router";
|
||||||
|
|
||||||
function Root() {
|
const HomeLayout = () => {
|
||||||
|
const navigateTo = useNavigateTo();
|
||||||
|
const location = useLocation();
|
||||||
const { sm } = useResponsiveWidth();
|
const { sm } = useResponsiveWidth();
|
||||||
|
const currentUser = useCurrentUser();
|
||||||
const [collapsed, setCollapsed] = useLocalStorage<boolean>("navigation-collapsed", false);
|
const [collapsed, setCollapsed] = useLocalStorage<boolean>("navigation-collapsed", false);
|
||||||
|
|
||||||
|
// Redirect to explore page if not logged in.
|
||||||
|
if (
|
||||||
|
!currentUser &&
|
||||||
|
([Routes.HOME, Routes.TIMELINE, Routes.RESOURCES, Routes.INBOX, Routes.ARCHIVED, Routes.SETTING] as string[]).includes(
|
||||||
|
location.pathname,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
navigateTo("/explore");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full min-h-full">
|
<div className="w-full min-h-full">
|
||||||
<div
|
<div
|
||||||
@@ -56,6 +73,6 @@ function Root() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Root;
|
export default HomeLayout;
|
@@ -9,6 +9,7 @@ import "./css/global.css";
|
|||||||
import "./css/tailwind.css";
|
import "./css/tailwind.css";
|
||||||
import "./helpers/polyfill";
|
import "./helpers/polyfill";
|
||||||
import "./i18n";
|
import "./i18n";
|
||||||
|
import CommonContextProvider from "./layouts/CommonContextProvider";
|
||||||
import "./less/highlight.less";
|
import "./less/highlight.less";
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
import store from "./store";
|
import store from "./store";
|
||||||
@@ -25,7 +26,9 @@ import theme from "./theme";
|
|||||||
root.render(
|
root.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<CssVarsProvider theme={theme}>
|
<CssVarsProvider theme={theme}>
|
||||||
|
<CommonContextProvider>
|
||||||
<RouterProvider router={router} />
|
<RouterProvider router={router} />
|
||||||
|
</CommonContextProvider>
|
||||||
<Toaster position="top-right" />
|
<Toaster position="top-right" />
|
||||||
</CssVarsProvider>
|
</CssVarsProvider>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
|
@@ -1,27 +0,0 @@
|
|||||||
import { useEffect } from "react";
|
|
||||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
|
||||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const AuthStatusProvider = (props: Props) => {
|
|
||||||
const navigateTo = useNavigateTo();
|
|
||||||
const currentUser = useCurrentUser();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!currentUser) {
|
|
||||||
// If not logged in, redirect to explore page by default.
|
|
||||||
navigateTo("/explore");
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!currentUser) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <>{props.children}</>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AuthStatusProvider;
|
|
@@ -1,11 +1,9 @@
|
|||||||
import { lazy } from "react";
|
import { lazy } from "react";
|
||||||
import { createBrowserRouter } from "react-router-dom";
|
import { createBrowserRouter } from "react-router-dom";
|
||||||
import App from "@/App";
|
import App from "@/App";
|
||||||
|
import HomeLayout from "@/layouts/HomeLayout";
|
||||||
import SuspenseWrapper from "@/layouts/SuspenseWrapper";
|
import SuspenseWrapper from "@/layouts/SuspenseWrapper";
|
||||||
import { initialGlobalState } from "@/store/module";
|
|
||||||
import AuthStatusProvider from "./AuthStatusProvider";
|
|
||||||
|
|
||||||
const Root = lazy(() => import("@/layouts/Root"));
|
|
||||||
const SignIn = lazy(() => import("@/pages/SignIn"));
|
const SignIn = lazy(() => import("@/pages/SignIn"));
|
||||||
const SignUp = lazy(() => import("@/pages/SignUp"));
|
const SignUp = lazy(() => import("@/pages/SignUp"));
|
||||||
const AuthCallback = lazy(() => import("@/pages/AuthCallback"));
|
const AuthCallback = lazy(() => import("@/pages/AuthCallback"));
|
||||||
@@ -22,23 +20,22 @@ const About = lazy(() => import("@/pages/About"));
|
|||||||
const NotFound = lazy(() => import("@/pages/NotFound"));
|
const NotFound = lazy(() => import("@/pages/NotFound"));
|
||||||
const PermissionDenied = lazy(() => import("@/pages/PermissionDenied"));
|
const PermissionDenied = lazy(() => import("@/pages/PermissionDenied"));
|
||||||
|
|
||||||
const initialGlobalStateLoader = async () => {
|
export enum Routes {
|
||||||
try {
|
HOME = "/",
|
||||||
await initialGlobalState();
|
TIMELINE = "/timeline",
|
||||||
} catch (error) {
|
RESOURCES = "/resources",
|
||||||
// do nothing.
|
INBOX = "/inbox",
|
||||||
|
ARCHIVED = "/archived",
|
||||||
|
SETTING = "/setting",
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
element: <App />,
|
element: <App />,
|
||||||
loader: () => initialGlobalStateLoader(),
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "/auth/",
|
path: "/auth",
|
||||||
element: <SuspenseWrapper />,
|
element: <SuspenseWrapper />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@@ -57,55 +54,31 @@ const router = createBrowserRouter([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
element: <Root />,
|
element: <HomeLayout />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: Routes.HOME,
|
||||||
element: (
|
element: <Home />,
|
||||||
<AuthStatusProvider>
|
|
||||||
<Home />
|
|
||||||
</AuthStatusProvider>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "timeline",
|
path: Routes.TIMELINE,
|
||||||
element: (
|
element: <Timeline />,
|
||||||
<AuthStatusProvider>
|
|
||||||
<Timeline />
|
|
||||||
</AuthStatusProvider>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "resources",
|
path: Routes.RESOURCES,
|
||||||
element: (
|
element: <Resources />,
|
||||||
<AuthStatusProvider>
|
|
||||||
<Resources />
|
|
||||||
</AuthStatusProvider>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "inbox",
|
path: Routes.INBOX,
|
||||||
element: (
|
element: <Inboxes />,
|
||||||
<AuthStatusProvider>
|
|
||||||
<Inboxes />
|
|
||||||
</AuthStatusProvider>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "archived",
|
path: Routes.ARCHIVED,
|
||||||
element: (
|
element: <Archived />,
|
||||||
<AuthStatusProvider>
|
|
||||||
<Archived />
|
|
||||||
</AuthStatusProvider>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "setting",
|
path: Routes.SETTING,
|
||||||
element: (
|
element: <Setting />,
|
||||||
<AuthStatusProvider>
|
|
||||||
<Setting />
|
|
||||||
</AuthStatusProvider>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "explore",
|
path: "explore",
|
||||||
|
Reference in New Issue
Block a user