refactor: guest mode

This commit is contained in:
Tristan Yang
2022-09-02 12:39:40 +08:00
parent 333cbb8b4b
commit c4435662c0
8 changed files with 50 additions and 26 deletions
-4
View File
@@ -43,10 +43,6 @@ const tables = [
storeName: "ui", storeName: "ui",
description: "store UI state" description: "store UI state"
} }
// {
// storeName: "message",
// description: "store message with key-val full data",
// },
]; ];
const initCache = () => { const initCache = () => {
const uid = localStorage.getItem(KEY_UID) || ""; const uid = localStorage.getItem(KEY_UID) || "";
+1
View File
@@ -4,6 +4,7 @@ const BASE_URL = process.env.REACT_APP_RELEASE
? `${location.origin}/api` ? `${location.origin}/api`
: `https://dev.voce.chat/api`; : `https://dev.voce.chat/api`;
export const CACHE_VERSION = `0.3.1`; export const CACHE_VERSION = `0.3.1`;
export const GuestRoutes = ["/", "/chat", "/chat/channel/:channel_id"];
export const ContentTypes = { export const ContentTypes = {
text: "text/plain", text: "text/plain",
markdown: "text/markdown", markdown: "text/markdown",
+3 -3
View File
@@ -21,7 +21,7 @@ interface State {
const loginUser = localStorage.getItem(KEY_LOGIN_USER) || ""; const loginUser = localStorage.getItem(KEY_LOGIN_USER) || "";
const initialState: State = { const initialState: State = {
initialized: true, initialized: true,
guest: false, guest: loginUser ? JSON.parse(loginUser).create_by == "guest" : false,
user: loginUser ? JSON.parse(loginUser) : undefined, user: loginUser ? JSON.parse(loginUser) : undefined,
token: localStorage.getItem(KEY_TOKEN) || "", token: localStorage.getItem(KEY_TOKEN) || "",
expireTime: Number(localStorage.getItem(KEY_EXPIRE) || +new Date()), expireTime: Number(localStorage.getItem(KEY_EXPIRE) || +new Date()),
@@ -43,10 +43,10 @@ const authDataSlice = createSlice({
reducers: { reducers: {
setAuthData(state, { payload }: PayloadAction<AuthData>) { setAuthData(state, { payload }: PayloadAction<AuthData>) {
const { initialized = true, user, token, refresh_token, expired_in = 0 } = payload; const { initialized = true, user, token, refresh_token, expired_in = 0 } = payload;
const { uid } = user; const { uid, create_by } = user;
state.initialized = initialized; state.initialized = initialized;
state.user = user; state.user = user;
// state.guest = user.create_by == "guest"; state.guest = create_by == "guest";
state.token = token; state.token = token;
state.refreshToken = refresh_token; state.refreshToken = refresh_token;
// 当前时间往后推expire时长 // 当前时间往后推expire时长
+18 -14
View File
@@ -1,6 +1,7 @@
import { FC, ReactElement, useEffect } from "react"; import { FC, ReactElement } from "react";
import { Navigate } from "react-router-dom"; import { Navigate, useLocation, matchRoutes } from "react-router-dom";
import { useGetInitializedQuery, useLazyGuestLoginQuery } from "../../app/services/auth"; import { GuestRoutes } from "../../app/config";
import { useGetInitializedQuery } from "../../app/services/auth";
import { useGetLoginConfigQuery } from "../../app/services/server"; import { useGetLoginConfigQuery } from "../../app/services/server";
import { useAppSelector } from "../../app/store"; import { useAppSelector } from "../../app/store";
@@ -8,24 +9,27 @@ interface Props {
children: ReactElement; children: ReactElement;
redirectTo?: string; redirectTo?: string;
} }
const GuestAllows = GuestRoutes.map((path) => {
return { path };
});
const RequireAuth: FC<Props> = ({ children, redirectTo = "/login" }) => { const RequireAuth: FC<Props> = ({ children, redirectTo = "/login" }) => {
// GuestRoutes
const location = useLocation();
const matchs = matchRoutes(GuestAllows, location);
const allowGuest = matchs ? !!matchs[0].pathname : false;
const { data: loginConfig, isLoading: fetchingLoginConfig } = useGetLoginConfigQuery(); const { data: loginConfig, isLoading: fetchingLoginConfig } = useGetLoginConfigQuery();
const { isLoading: checkingInitial } = useGetInitializedQuery(); const { isLoading: checkingInitial } = useGetInitializedQuery();
const [guestLogin] = useLazyGuestLoginQuery(); const { token, guest, initialized } = useAppSelector((store) => store.authData);
const { token, initialized } = useAppSelector((store) => store.authData); // console.log("authhhhh", allowGuest);
useEffect(() => {
// 已初始化 , 没token,并且开启了guest,则guest自动登录
if (initialized && !token && loginConfig?.guest) {
guestLogin();
}
}, [token, initialized, loginConfig]);
// 初始化和login配置检查 // 初始化和login配置检查
if (checkingInitial || fetchingLoginConfig) return null; if (checkingInitial || fetchingLoginConfig) return null;
// 未初始化 则先走setup 流程 // 未初始化 则先走setup 流程
if (!initialized) return <Navigate to={`/onboarding`} replace />; if (!initialized) return <Navigate to={`/onboarding`} replace />;
// 开启guest 并且没token 则等待guest登录结果 // 开启guest 并且没token 而且是允许guest访问的路由 则先去过渡页登录
if (loginConfig?.guest && !token) return null; if (loginConfig?.guest && !token && allowGuest) return <Navigate to={"/guest_login"} replace />;
// 登陆者是guest,并且不允许访问
if (token && guest && !allowGuest) return <Navigate to={"/"} replace />;
return token ? children : <Navigate to={redirectTo} replace />; return token ? children : <Navigate to={redirectTo} replace />;
}; };
+15
View File
@@ -0,0 +1,15 @@
// import { useEffect } from "react";
import { Navigate } from "react-router-dom";
import { useGuestLoginQuery } from "../app/services/auth";
import { useAppSelector } from "../app/store";
// type Props = {};
const GuestLogining = () => {
useGuestLoginQuery();
const { token, guest } = useAppSelector((store) => store.authData);
if (token && guest) return <Navigate to={"/"} replace />;
return null;
};
export default GuestLogining;
+1 -1
View File
@@ -55,7 +55,7 @@ export default function HomePage() {
return ( return (
<> <>
<Manifest /> <Manifest />
<Notification /> {!guest && <Notification />}
<StyledWrapper className={guest ? "guest" : ""}> <StyledWrapper className={guest ? "guest" : ""}>
{!guest && ( {!guest && (
<div className={`col left`}> <div className={`col left`}>
+3
View File
@@ -26,6 +26,7 @@ import HomePage from "./home";
import ChatPage from "./chat"; import ChatPage from "./chat";
import Loading from "../common/component/Loading"; import Loading from "../common/component/Loading";
import store, { useAppSelector } from "../app/store"; import store, { useAppSelector } from "../app/store";
import GuestLogining from "./guest";
let toastId: string; let toastId: string;
const PageRoutes = () => { const PageRoutes = () => {
const { const {
@@ -48,6 +49,7 @@ const PageRoutes = () => {
<HashRouter> <HashRouter>
<Suspense fallback={<Loading fullscreen={true} />}> <Suspense fallback={<Loading fullscreen={true} />}>
<Routes> <Routes>
<Route path="/guest_login" element={<GuestLogining />} />
<Route path="/oauth/:token" element={<OAuthPage />} /> <Route path="/oauth/:token" element={<OAuthPage />} />
<Route <Route
path="/login" path="/login"
@@ -91,6 +93,7 @@ const PageRoutes = () => {
<Route path="/onboarding" element={<OnboardingPage />} /> <Route path="/onboarding" element={<OnboardingPage />} />
<Route <Route
key={"main"}
path="/" path="/"
element={ element={
<RequireAuth> <RequireAuth>
+9 -4
View File
@@ -6,6 +6,8 @@ import StyledModal from "../../common/component/styled/Modal";
import Button from "../../common/component/styled/Button"; import Button from "../../common/component/styled/Button";
import Checkbox from "../../common/component/styled/Checkbox"; import Checkbox from "../../common/component/styled/Checkbox";
import useLogout from "../../common/hook/useLogout"; import useLogout from "../../common/hook/useLogout";
import { useNavigate } from "react-router-dom";
import { useAppSelector } from "../../app/store";
const StyledConfirm = styled(StyledModal)` const StyledConfirm = styled(StyledModal)`
.clear { .clear {
@@ -32,6 +34,8 @@ interface Props {
} }
const LogoutConfirmModal: FC<Props> = ({ closeModal }) => { const LogoutConfirmModal: FC<Props> = ({ closeModal }) => {
const token = useAppSelector((store) => store.authData.token);
const navigateTo = useNavigate();
const [clearLocal, setClearLocal] = useState(false); const [clearLocal, setClearLocal] = useState(false);
const { logout, exited, exiting, clearLocalData } = useLogout(); const { logout, exited, exiting, clearLocalData } = useLogout();
const handleLogout = () => { const handleLogout = () => {
@@ -48,12 +52,13 @@ const LogoutConfirmModal: FC<Props> = ({ closeModal }) => {
clearLocalData(); clearLocalData();
} }
toast.success("Logout Successfully"); toast.success("Logout Successfully");
setTimeout(() => {
location.href = `${location.origin}#/login`;
}, 500);
// location.reload();
} }
}, [exited, clearLocal]); }, [exited, clearLocal]);
useEffect(() => {
if (!token) {
navigateTo("/login");
}
}, [token]);
return ( return (
<Modal id="modal-modal"> <Modal id="modal-modal">