Skip to content

Commit

Permalink
Merge pull request #111 from BuidlerDAO/nig-672-binmax
Browse files Browse the repository at this point in the history
feat: 调整 store 处理 token 的位置
  • Loading branch information
huangbinjie authored Apr 9, 2024
2 parents a76bf65 + 7e8f56b commit e2e2a38
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 102 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"ci:test:lint": "run-s lint",
"ci:test:unit": "run-s \" test --ci --reporters=\"default\" --reporters=\"github-actions\" \"",
"ci:test:types": "run-s test:types",
"type-check": "tsc --noEmit",
"format": "run-p format:*",
"format:eslint": "run-s \" lint:eslint --fix \"",
"format:prettier": "run-s \" lint:prettier --write \"",
Expand Down
8 changes: 4 additions & 4 deletions src/components/Toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { createPortal } from 'react-dom';
import { Snackbar } from '@mui/material';

import useGlobalStore from '../store/useGlobalStore';
import useToasterStore from '../store/useToasterStore';

// toaster
const XFANS_TOASTER_SUCCESS = 'xfans_toaster_success';
Expand Down Expand Up @@ -34,23 +34,23 @@ export enum ToastMessage {
}

export function success(message: string) {
useGlobalStore.setState({
useToasterStore.setState({
message,
messageType: XFANS_TOASTER_SUCCESS,
messageOpen: true,
});
}

export function error(message: string) {
useGlobalStore.setState({
useToasterStore.setState({
message,
messageType: XFANS_TOASTER_ERROR,
messageOpen: true,
});
}

export default function Toaster() {
const { message, messageType, messageOpen, closeMessage } = useGlobalStore();
const { message, messageType, messageOpen, closeMessage } = useToasterStore();

return createPortal(
<Snackbar
Expand Down
5 changes: 2 additions & 3 deletions src/components/twitterAdded/feedsPage/ethIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { FC, useEffect, useState } from 'react';

import useAccount from '../../../hooks/useAccount';
import { useTweetBatchUserInfo } from '../../../service/tweet';
import useLocalStore from '../../../store/useLocalStore';
import useGlobalStore from '../../../store/useGlobalStore';
import useProfileModal from '../../../store/useProfileModal';
import { NumberDisplayer } from '../../NumberDisplayer';

Expand All @@ -14,7 +13,7 @@ interface FriendPriceProps {
export const FriendPrice: FC<FriendPriceProps> = ({ twitterUsername }) => {
const { openProfile } = useProfileModal((state) => ({ ...state }));
const [userInfo, setUserInfo] = useState<any>({ price: '0' });
const { isShowPrice } = useLocalStore((state) => ({ ...state }));
const { isShowPrice } = useGlobalStore((state) => ({ ...state }));
const { run: batchUserInfo } = useTweetBatchUserInfo(
[twitterUsername],
(result) => {
Expand Down
3 changes: 0 additions & 3 deletions src/components/twitterAdded/twitterPage/userEthIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React, { FC, useEffect, useState } from 'react';

import useAccount from '../../../hooks/useAccount';
import { useTweetBatchUserInfo } from '../../../service/tweet';
import useLocalStore from '../../../store/useLocalStore';
import useProfileModal from '../../../store/useProfileModal';
import { NumberDisplayer } from '../../NumberDisplayer';

Expand All @@ -16,7 +14,6 @@ export const UserPagePrice: FC<UserPagePriceProps> = ({ twitterUsername }) => {
const [elementWidth, setElementWidth] = useState<number | null>(null);
const { openProfile } = useProfileModal((state) => ({ ...state }));
const [userInfo, setUserInfo] = useState<any>({ price: '0' });
const { isShowPrice } = useLocalStore((state) => ({ ...state }));
const useWidth = elementWidth != null ? elementWidth : 0;

const { run: batchUserInfo } = useTweetBatchUserInfo(
Expand Down
1 change: 0 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export const XFANS_CHECK_RETWEET = 'xfans_check_retweet';
export const XFANS_DONE = 'Done';
export const XFANS_VERIFY = 'Verify';
export const XFANS_GO = 'GO';
export const XFANS_USERINFO = 'xfans-userinfo';

// table
export const ROWS_PER_PAGE = 5;
Expand Down
62 changes: 20 additions & 42 deletions src/content/drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ import {
XFANS_MIN_WIDTH,
XFANS_TWITTER_CONTENT_WIDTH,
XFANS_TWITTER_OFFSET,
XFANS_USERINFO,
} from '../../constants';
import { ProfileData } from '../../service/login/me';
import { TwitterOauth2Data } from '../../service/login/twiterOuth2';
import http, { ResultData } from '../../service/request';
import useGlobalStore from '../../store/useGlobalStore';
import useLocalStore from '../../store/useLocalStore';
import useGlobalStore, { PageType } from '../../store/useGlobalStore';
import Profile from '../../welcome/Profile';
import Wallet from '../../welcome/Wallet';
import ProfileModal from '../../welcome/Wallet/Profile';
Expand Down Expand Up @@ -63,45 +61,33 @@ const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })<{
}));

export default function PersistentDrawerRight() {
const { isShowDrawer } = useLocalStore((state) => ({ ...state }));
const { isShowDrawer, goPage, page, logout } = useGlobalStore((state) => ({ ...state }));

const [loginLoading, setLoginLoading] = React.useState(false);

const handleDrawerOpen = () => {
useLocalStore.setState({
useGlobalStore.setState({
isShowDrawer: true,
});
};

const handleDrawerClose = () => {
useLocalStore.setState({
useGlobalStore.setState({
isShowDrawer: false,
});
};

const [pageState, setPageState] = React.useState('login');

React.useEffect(() => {
// 先检查是否需要展开
const loginState = localStorage.getItem('xfans-login-state');
const shouldOpenStateList: string[] = ['waitingRedirect', 'waitingInvite'];
// if (shouldOpenStateList.includes(String(loginState))) {
// useLocalStore.setState({
// isShowDrawer: true,
// });
// }

// 再获取url中的token 作为第一优先级
const urlParams = new URLSearchParams(window.location.search);
const xfansToken = urlParams.get('xfans_token');
if (xfansToken) {
// 登录看是否有效,拿到 invite 状态
useGlobalStore.setState({ token: xfansToken });
localStorage.setItem('xfans-token', xfansToken);
checkProfileData();
} else {
// 获取 xfans_token 参数的值
const localStorageToken = localStorage.getItem('xfans-token');
const localStorageToken = useGlobalStore.getState().token;
if (localStorageToken && localStorageToken.length > 0) {
// 已经有 token 的情况,登录判断 invite 状态
useGlobalStore.setState({ token: localStorageToken });
Expand All @@ -112,7 +98,7 @@ export default function PersistentDrawerRight() {
// 检查xfans写入localStorage的twitterid跟twitter写在cookie里的twitterid是否匹配,不匹配则退出登录
// 针对登出或者切换账号的情况
setInterval(() => {
const userInfo = JSON.parse(localStorage.getItem(XFANS_USERINFO) || '""');
const userInfo = useGlobalStore.getState().userInfo;
if (userInfo && userInfo?.twitterId && userInfo?.twitterId?.length > 0) {
// 读取所有的 cookie
const cookies = document.cookie;
Expand All @@ -133,16 +119,16 @@ export default function PersistentDrawerRight() {
const profileData = (await http.get(`/api/user/me`)) as ResultData<ProfileData>;
if (profileData.code === 0) {
if (profileData.data.isActive) {
setPageState('profile');
goPage(PageType.Profile);
return 'active';
} else if (!profileData.data.isRegistered) {
setPageState('invite');
goPage(PageType.Invite);
return 'waiting invite code';
} else if (!profileData.data.isTaskFinished) {
setPageState('congratulation');
goPage(PageType.Congratulation);
return 'waiting task';
} else {
setPageState('congratulation');
goPage(PageType.Congratulation);
return 'waiting task';
}
}
Expand All @@ -151,8 +137,6 @@ export default function PersistentDrawerRight() {

const clickLogin = async () => {
setLoginLoading(true);
// 设置 waiting redirect 缓存
localStorage.setItem('xfans-login-state', 'waitingRedirect');

// 跳转 login link https://test-xfans-api.d.buidlerdao.xyz/api/user/twitter-oauth2
const link = (await http.get(`/api/user/twitter-oauth2`)) as ResultData<TwitterOauth2Data>;
Expand All @@ -168,20 +152,12 @@ export default function PersistentDrawerRight() {
})) as ResultData;
if (activateData.code === 0) {
toaster.success(toaster.ToastMessage.CONGRATULATION);
setPageState('congratulation');
goPage(PageType.Congratulation);
} else {
toaster.error(toaster.ToastMessage.INVITE_CODE_ERROR);
}
};

const logout = () => {
setPageState('login');
useGlobalStore.setState({ token: '' });
localStorage.setItem('xfans-token', '');
localStorage.setItem('xfans-login-state', '');
localStorage.setItem(XFANS_USERINFO, '');
};

return (
<Box sx={{ display: 'flex' }}>
<ProfileModal />
Expand Down Expand Up @@ -222,18 +198,20 @@ export default function PersistentDrawerRight() {
/>
</div>
<Divider orientation="vertical" flexItem />
{pageState === 'login' && (
{page === PageType.Login && (
<SignInWithXPage showLoading={loginLoading} handleButtonClick={() => clickLogin()} />
)}
{pageState === 'invite' && (
{page === PageType.Invite && (
<InvitePage handleButtonClick={(inviteCode) => clickRegisterInviteCode(inviteCode)} />
)}
{pageState === 'congratulation' && (
<CongratulationPage goProfile={() => setPageState('profile')} />
{page === PageType.Congratulation && (
<CongratulationPage goProfile={() => goPage(PageType.Profile)} />
)}
{page === PageType.Profile && (
<Profile handleButtonClick={() => goPage(PageType.Wallet)} />
)}
{pageState === 'profile' && <Profile handleButtonClick={() => setPageState('wallet')} />}
{pageState === 'wallet' && (
<Wallet back={() => setPageState('profile')} logout={logout} />
{page === PageType.Wallet && (
<Wallet back={() => goPage(PageType.Profile)} logout={logout} />
)}
</div>
</Drawer>
Expand Down
3 changes: 1 addition & 2 deletions src/service/checkStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ export const checkStatus = (status: number) => {
toaster.error(toaster.ToastMessage.REQUEST_FAILURE_RETRY);
break;
case 401:
useGlobalStore.setState({ token: '' });
toaster.error(toaster.ToastMessage.LOGIN_FAILURE_RETRY);
useGlobalStore.getState().logout();
break;
case 403:
useGlobalStore.setState({ token: '' });
toaster.error(toaster.ToastMessage.NO_PERMISSION);
break;
case 404:
Expand Down
5 changes: 3 additions & 2 deletions src/service/user/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { useRequest } from 'ahooks';

import useGlobalStore from '../../store/useGlobalStore';
import useUserStore from '../../store/useUserStore';
import http, { ResultData } from '../request';
import { XFANS_USERINFO } from '../../constants';

const useUserInfo = () => {
const result = useRequest<ResultData<UserInfo>, unknown[]>(() => http.get('/api/user/me'), {
manual: true,
onSuccess(response) {
useUserStore.setState({
userInfo: response.data,
});
localStorage.setItem(XFANS_USERINFO, JSON.stringify(response.data));
useGlobalStore.setState({ userInfo: response.data });
},
});

Expand Down
60 changes: 42 additions & 18 deletions src/store/useGlobalStore.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,49 @@
/**
* @file 全局状态,自动同步到 storage
*/
import { create } from 'zustand';
import { persist } from 'zustand/middleware';

interface GlobalStoreProps {
export enum PageType {
Login = 'login',
Invite = 'invite',
Congratulation = 'congratulation',
Profile = 'profile',
Wallet = 'wallet',
}

export interface GlobalStoreProps {
page: PageType;
token: string;
message: string;
messageType: string;
messageOpen: boolean;
closeMessage: () => void;
isShowPrice: boolean;
isShowDrawer: boolean;
userInfo: UserInfo | null;
goPage(page: PageType): void;
logout(): void;
}

const useGlobalStore = create<GlobalStoreProps>((set) => ({
token: '',
message: '',
messageType: '',
messageOpen: false,
closeMessage() {
set({
messageOpen: false,
message: '',
messageType: '',
});
},
}));
const useGlobalStore = create<GlobalStoreProps>()(
persist(
(set) => ({
page: PageType.Login,
token: '',
isShowPrice: false,
isShowDrawer: false,
userInfo: null,
goPage(page: PageType) {
set({ page });
},
logout() {
set({
token: '',
page: PageType.Login,
});
},
}),
{
name: 'xfans-user-config',
}
)
);

export default useGlobalStore;
21 changes: 0 additions & 21 deletions src/store/useLocalStore.ts

This file was deleted.

23 changes: 23 additions & 0 deletions src/store/useToasterStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { create } from 'zustand';

interface ToasterStoreProps {
message: string;
messageType: string;
messageOpen: boolean;
closeMessage: () => void;
}

const useToasterStore = create<ToasterStoreProps>((set) => ({
message: '',
messageType: '',
messageOpen: false,
closeMessage() {
set({
messageOpen: false,
message: '',
messageType: '',
});
},
}));

export default useToasterStore;
Loading

0 comments on commit e2e2a38

Please sign in to comment.