import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Button, Flex, Form, InputNumber, Segmented, Space, Switch } from "antd"; import { chunk } from 'lodash'; import type { BasePlayer } from "../types"; import { GroupMember } from "./GroupMember"; import { sneckGroup } from "../utils/common"; import { useLoaderData } from "react-router"; import { SyncOutlined } from "@ant-design/icons"; import { useRequest } from "ahooks"; interface Player extends BasePlayer { } interface CustomPlayer extends Player { nowScore: never; index: number; id: string; } interface Props { players?: Player[]; sneckMode: boolean; isPassedGame: boolean; } enum OrderScore { 年度积分 = '年度积分', 当前积分 = '当前积分', } export const GroupingPrediction: React.FC = props => { const { uidScore } = useLoaderData<{ uidScore: Map}>(); const uidScoreRequest = useRequest(async () => { const uids = props.players?.map(player => player.uid).filter(Boolean); const data = await fetch(`/api/user/nowScores`, { method: "POST", body: JSON.stringify({ uids }), }).then(res => res.json()).catch(() => ({})); return new Map(Object.entries(data)); }, { manual: true, refreshDeps: [props.players]}); console.debug('uidScore', uidScore); const [maxPlayerSize, setMaxPlayerSize] = useState(48); const [nowScoreGroup, setNowScoreGroup] = useState( props.isPassedGame ? OrderScore.年度积分 : OrderScore.当前积分 ); const refactoredPlayers = useMemo(() => { return nowScoreGroup === OrderScore.当前积分 ? props.players?.map(e => { const nowScore = uidScore.get(e.uid) || uidScoreRequest.data?.get(e.uid); return { ...e, score: !Number.isNaN(Number(nowScore)) ? nowScore : e.score, } }) : [...props.players ?? []]; }, [nowScoreGroup, props.players, uidScore, uidScoreRequest]); const players = useMemo(() => { return (refactoredPlayers as CustomPlayer[]) ?.slice(0, maxPlayerSize) ?.sort((a, b) => Number(b.score) - Number(a.score)) ?.map((e, i) => ({ ...e, index: i + 1, id: `${i}-${e.name}-${e.score}` })) ?? []; }, [refactoredPlayers, maxPlayerSize]); const [groupLen, setGroupLen] = useState(6); useEffect(() => { if (props.players) { if (players.length < 48) { setMaxPlayerSize(players.length); } if (players.length <= 12) { setGroupLen(1); } } }, [props.players?.length]); const [sneckMode, setSneckMode] = useState(props.sneckMode); const chunkSize = useMemo(() => Math.floor((players.length ?? 0) / groupLen) || 1, [players, groupLen]); const grouped = useMemo(() => { return chunk(players, chunkSize); }, [chunkSize, players]); const sneckedGroups = useMemo(() => { const sneckIndexGroups = sneckGroup(players.length, groupLen); return sneckIndexGroups.map(g => { const subGroup = g.map(i => ({ ...players[i], })).filter(Boolean) as CustomPlayer[]; return subGroup; }); }, [players, grouped, groupLen, maxPlayerSize]); const handleSyncUidScore = useCallback(() => { uidScoreRequest.runAsync(); }, []); return ( <> setMaxPlayerSize(e || props.players?.length || 0)} max={props.players?.length} /> setGroupLen(e ?? 1)} min={1} max={26} /> { !sneckMode && grouped.map((p, i) => )} { sneckMode && sneckedGroups.map((p, i) => )} ); }