import { Avatar, Button, Card, Divider, Flex, Image, Popconfirm, Radio, Segmented, Spin, Typography, App } from "antd"; import { useFavPlayerStore, type FavPlayer } from "@/store/useFavPlayerStore"; import { useNavigate } from "react-router"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useLogto } from "@logto/react"; import { DeleteOutlined, LoginOutlined, SyncOutlined, UploadOutlined } from "@ant-design/icons"; import { useRequest } from "ahooks"; import type { XCXProfile } from "@/types"; import useAutoLogin from "@/hooks/useAutoLogin"; import { useAuthHeaders } from "@/hooks/useAuthHeaders"; import styled from "styled-components"; enum SortType { DEFAULT = '注册时间', SCORE_UP = '积分升序', SCORE_DOWN = '积分降序', } enum ShowType { LOCAL = '本地收藏', ACCOUNT = '账号收藏', } const StyledContainer = styled.div` .player-name { margin: 0; } .unfav-btn { height: 100%; } `; export function FavePlayersPage() { const { favMap, unFav } = useFavPlayerStore(state => state); const [sortType, setSortType] = useState(SortType.SCORE_DOWN); const [showType, setShowType] = useState(ShowType.LOCAL); const headers = useAuthHeaders(); const { autoSignIn } = useAutoLogin(); const localList = Object.values(favMap); const favListRequest = useRequest(async () => { const res = await fetch(`/api/fav`, { headers }); const data = await res.json(); return data; }, { manual: true, refreshDeps: [headers], cacheTime: 3 * 60 * 1000 }); const list = useMemo(() => { const l = showType === ShowType.LOCAL ? localList : favListRequest.data?.map(e => ({ ...e, name: e.username, avatar: e.realpic, })) || []; switch (sortType) { case SortType.DEFAULT: return l; case SortType.SCORE_UP: return l.sort(({ score: a }, { score: b }) => +a - +b); case SortType.SCORE_DOWN: return l.sort(({ score: b }, { score: a }) => +a - +b); default: return localList; } }, [favMap, sortType, showType, localList, favListRequest]); const navigate = useNavigate(); const { isAuthenticated, getIdTokenClaims } = useLogto(); const message = App.useApp().message; useEffect(() => { if (!isAuthenticated) return; const id = setTimeout(async () => { favListRequest.runAsync(); }, 300); return () => clearTimeout(id); }, [isAuthenticated, getIdTokenClaims]); const handleSyncFav = useCallback(async () => { if (!isAuthenticated) return; const jobs = list.map(async u => { await fetch(`/api/fav/${u.uid}`, { method: 'PUT', headers }); }); message.open({ key: 'sync', content: '同步中...', type: 'loading' }); await Promise.all(jobs); await favListRequest.runAsync(); message.open({ key: 'sync', content: '已同步', type: 'success' }); }, [isAuthenticated, list]); const handleClearLocal = useCallback(() => { list.forEach(e => unFav(e.uid)); }, []); const handleUnFav = useCallback(async (e: FavPlayer) => { if (showType === ShowType.LOCAL) { unFav(e.uid); } if (showType === ShowType.ACCOUNT) { await fetch(`/api/fav/${e.uid}`, { method: 'DELETE', headers }); await favListRequest.runAsync(); } }, [showType, favListRequest, headers]); return ( 收藏的球员 setShowType(e.target.value)} options={[ { label: `${ShowType.LOCAL}(${localList.length})`, value: ShowType.LOCAL}, { label: `${ShowType.ACCOUNT}(${favListRequest.data?.length ?? 0})`, value: ShowType.ACCOUNT} ]} /> )} ) : ( <> {list.map(e => ( {e.avatar?.includes('noavatar') ? {e.name} : } navigate(`/profile/${e.uid}`)} > {e.name} {e.realname} ))} { (showType === ShowType.LOCAL && isAuthenticated && list.length > 0) && ( ) } { (showType === ShowType.LOCAL && !isAuthenticated && list.length > 0) && ( ) } {(showType === ShowType.LOCAL && ( }} > ))} )} ); }