refactor(page): 合并本地与远程球员收藏列表逻辑并简化组件

- 将本地列表 (localList) 和请求数据 (favListRequest.data) 的映射逻辑统一至主 list useMemo 中。
- 移除冗余的 showList useMemo,直接基于 showType 动态生成 list。
- 修正 sortType 默认分支显式返回 localList,确保排序逻辑一致性。
- 更新依赖数组并清理未使用的 isAuthenticated 相关逻辑。
- 调整空状态判断条件以匹配新的 list 结构。
This commit is contained in:
kyuuseiryuu 2026-03-09 17:16:21 +09:00
parent 9499de0180
commit d171e496ff

View File

@ -1,5 +1,5 @@
import { Avatar, Button, Card, Divider, Flex, Image, Popconfirm, Radio, Segmented, Spin, Typography } from "antd"; import { Avatar, Button, Card, Divider, Flex, Image, Popconfirm, Radio, Segmented, Spin, Typography } from "antd";
import { useFavPlayerStore } from "../store/useFavPlayerStore"; import { useFavPlayerStore, type FavPlayer } from "../store/useFavPlayerStore";
import { useNavigate } from "react-router"; import { useNavigate } from "react-router";
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import { useLogto } from "@logto/react"; import { useLogto } from "@logto/react";
@ -20,22 +20,28 @@ enum ShowType {
export function FavePlayersPage() { export function FavePlayersPage() {
const { favMap, unFav } = useFavPlayerStore(state => state); const { favMap, unFav } = useFavPlayerStore(state => state);
const [sortType, setSortType] = useState<SortType>(SortType.DEFAULT); const [sortType, setSortType] = useState<SortType>(SortType.DEFAULT);
const list = useMemo(() => { const [showType, setShowType] = useState(ShowType.LOCAL);
const l = Object.values(favMap); const localList = Object.values(favMap);
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 l;
}
}, [favMap, sortType]);
const navigate = useNavigate();
const { isAuthenticated, getIdTokenClaims } = useLogto();
const favListRequest = useRequest<XCXProfile[], [string]>(async (aud: string) => { const favListRequest = useRequest<XCXProfile[], [string]>(async (aud: string) => {
const res = await fetch(`/api/fav/${aud}`); const res = await fetch(`/api/fav/${aud}`);
const data = await res.json(); const data = await res.json();
return data; return data;
}, { manual: true }); }, { manual: true });
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();
useEffect(() => { useEffect(() => {
if (!isAuthenticated) return; if (!isAuthenticated) return;
const id = setTimeout(async () => { const id = setTimeout(async () => {
@ -54,24 +60,12 @@ export function FavePlayersPage() {
await Promise.all(jobs); await Promise.all(jobs);
await favListRequest.runAsync(aud!); await favListRequest.runAsync(aud!);
}, [isAuthenticated, list]); }, [isAuthenticated, list]);
const [showType, setShowType] = useState(ShowType.LOCAL);
const handleClearLocal = useCallback(() => { const handleClearLocal = useCallback(() => {
list.forEach(e => unFav(e.uid)); list.forEach(e => unFav(e.uid));
}, []); }, []);
useEffect(() => { useEffect(() => {
setShowType(isAuthenticated ? ShowType.ACCOUNT : ShowType.LOCAL); setShowType(isAuthenticated ? ShowType.ACCOUNT : ShowType.LOCAL);
}, [isAuthenticated]); }, [isAuthenticated]);
const showList = useMemo(() => {
if (showType === ShowType.LOCAL) {
return list;
}
if (!isAuthenticated) return [];
return favListRequest.data?.map(e => ({
...e,
name: e.username,
avatar: e.realpic,
})) ?? [];
}, [showType, isAuthenticated, list, favListRequest.data]);
return ( return (
<div className="app"> <div className="app">
<Flex vertical gap={48}> <Flex vertical gap={48}>
@ -99,14 +93,14 @@ export function FavePlayersPage() {
/> />
</div> </div>
<Spin spinning={favListRequest.loading}> <Spin spinning={favListRequest.loading}>
{!favListRequest.loading && showList.length === 0 ? ( {!favListRequest.loading && list.length === 0 ? (
<> <>
<Divider></Divider> <Divider></Divider>
</> </>
) : ( ) : (
<> <>
<Flex wrap gap={16} align="center" justify="center"> <Flex wrap gap={16} align="center" justify="center">
{showList.map(e => ( {list.map(e => (
<Card <Card
hoverable hoverable
size="small" size="small"