diff --git a/package.json b/package.json index 830e7dea..904c978a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vocechat-web", - "version": "0.9.19", + "version": "0.9.20", "homepage": "https://voce.chat", "dependencies": { "@metamask/onboarding": "^1.0.1", diff --git a/src/routes/callback/GithubCallback.tsx b/src/routes/callback/GithubCallback.tsx index a8fb173c..df9ff00f 100644 --- a/src/routes/callback/GithubCallback.tsx +++ b/src/routes/callback/GithubCallback.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect } from "react"; +import { FC, useEffect, useRef } from "react"; import toast from "react-hot-toast"; import { useTranslation } from "react-i18next"; import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query"; @@ -12,58 +12,78 @@ type Props = { code: string; from?: GithubLoginSource; }; + const GithubCallback: FC = ({ code, from = "webapp" }) => { const { t } = useTranslation("auth"); const { t: ct } = useTranslation(); - //拿本地存的 magic token - const magic_token = localStorage.getItem(KEY_LOCAL_MAGIC_TOKEN); + + // 使用 ref 来防止重复调用 + const hasTriedLogin = useRef(false); + const [login, { isLoading, isSuccess, error }] = useLoginMutation(); + useEffect(() => { - if (code && !isLoading) { + // 防止重复调用登录 + if (code && !hasTriedLogin.current && !isLoading && !isSuccess) { + const magic_token = localStorage.getItem(KEY_LOCAL_MAGIC_TOKEN); + hasTriedLogin.current = true; + login({ magic_token, code, type: "github", }); } - }, [code, isLoading]); + }, [code, login, isLoading, isSuccess]); // 完整的依赖项列表 + useEffect(() => { - if (isSuccess) { + if (isSuccess || from == "webapp") { toast.success(ct("tip.login")); + // 通知 widget - if (from == "widget") { + if (from === "widget") { localStorage.setItem("widget", `${new Date().getTime()}`); } + // webapp 跳回首页 - if (from == "webapp") { + if (from === "webapp") { location.href = "/"; } } - }, [isSuccess, from]); - useEffect(() => { - if (error) { - console.log(error); - // todo: why? - switch ((error as FetchBaseQueryError).status) { - case 410: - toast.error( - "No associated account found, please contact user admin for an invitation link to join." - ); - break; - default: - toast.error("Something Error"); - break; - } - } - }, [error]); + }, [isSuccess, from, ct]); + + // useEffect(() => { + // if (error) { + // console.log(error); + + // switch ((error as FetchBaseQueryError).status) { + // case 410: + // toast.error( + // "No associated account found, please contact user admin for an invitation link to join." + // ); + // break; + // default: + // { + // console.log("login error"); + // // toast.error("Something Error"); + // } + // break; + // } + // } + // }, [error]); + const handleClose = () => { window.close(); }; - if (error) return Something Error; + + // if (error) { + // return Something Error; + // } + return (
{ct("action.close")} - {isSuccess && from == "widget" &&

{t("github_cb_tip")}

} + {isSuccess && from === "widget" &&

{t("github_cb_tip")}

} {isLoading ? t("github_logging_in") : t("github_login_success")} diff --git a/src/routes/callback/index.tsx b/src/routes/callback/index.tsx index 5467c0e2..f2119b3d 100644 --- a/src/routes/callback/index.tsx +++ b/src/routes/callback/index.tsx @@ -14,7 +14,7 @@ const StyledWrapper = ({ children }: DOMAttributes & { children? // type Props = { // type: "payment_success"; // }; -// 该页面服务于一些第三方服务的回调,比如stripe付款成功的回调,GitHub登录成功的回调 +// 该页面服务于一些第三方服务的回调,比如 stripe 付款成功的回调,GitHub 登录成功的回调 export default function CallbackPage() { const { type = "", payload = "" } = useParams(); // stripe 付款成功 @@ -25,7 +25,7 @@ export default function CallbackPage() { ); } - // github授权成功 + // github 授权成功 if (type == "github") { const query = new URLSearchParams(location.search); const code = query.get("code") ?? ""; diff --git a/src/routes/login/index.tsx b/src/routes/login/index.tsx index 98c546db..cef0f377 100644 --- a/src/routes/login/index.tsx +++ b/src/routes/login/index.tsx @@ -17,7 +17,7 @@ import SignUpLink from "./SignUpLink"; import SocialLoginButtons from "./SocialLoginButtons"; import { shallowEqual } from "react-redux"; import SelectLanguage from "../../components/Language"; -import Downloads from "../../components/downloads"; +import Downloads from "../../components/Downloads"; const defaultInput = { email: "", diff --git a/src/routes/reg/index.tsx b/src/routes/reg/index.tsx index 9112e224..d7c416a9 100644 --- a/src/routes/reg/index.tsx +++ b/src/routes/reg/index.tsx @@ -4,7 +4,7 @@ import { Outlet, useOutletContext, useSearchParams } from "react-router-dom"; import { useCheckMagicTokenValidMutation } from "@/app/services/auth"; import ExpiredTip from "./ExpiredTip"; import SelectLanguage from "../../components/Language"; -import Downloads from "../../components/downloads"; +import Downloads from "../../components/Downloads"; type ContextType = { token: string }; export default function RegContainer() {