diff --git a/client/src/app/pages/dashboard/users/games/_game/_playtype/folders/FolderComparePage.tsx b/client/src/app/pages/dashboard/users/games/_game/_playtype/folders/FolderComparePage.tsx index d8fb498ea..d8658a8b7 100644 --- a/client/src/app/pages/dashboard/users/games/_game/_playtype/folders/FolderComparePage.tsx +++ b/client/src/app/pages/dashboard/users/games/_game/_playtype/folders/FolderComparePage.tsx @@ -11,13 +11,14 @@ import useLUGPTSettings from "components/util/useLUGPTSettings"; import React, { useContext, useEffect, useMemo, useState } from "react"; import { Button, Col, Form, Row } from "react-bootstrap"; import { Link } from "react-router-dom"; -import { FolderDocument, GetGamePTConfig, PublicUserDocument } from "tachi-common"; +import { COLOUR_SET, FolderDocument, GetGamePTConfig, PublicUserDocument } from "tachi-common"; import { UGPTFolderReturns, UGPTStatsReturn } from "types/api-returns"; import { GamePT } from "types/react"; import { ComparePBsDataset } from "types/tables"; import UserSelectModal from "components/util/modal/UserSelectModal"; import UserIcon from "components/util/UserIcon"; import { UserContext } from "context/UserContext"; +import MiniTable from "components/tables/components/MiniTable"; export default function RivalCompareFolderPage({ reqUser, @@ -41,11 +42,11 @@ export default function RivalCompareFolderPage({ // [settings?.rivals.join(",")] ); - if (!data) { + if (!data && !error) { return ; } - let suggestUsers = data; + let suggestUsers = data ?? []; // if the user viewing this page is logged in and *is not* // the person this page is for @@ -57,7 +58,7 @@ export default function RivalCompareFolderPage({ return (
- {suggestUsers && ( + {suggestUsers.length > 0 && ( <> {suggestUsers.map((e) => ( @@ -90,10 +91,11 @@ export default function RivalCompareFolderPage({ excludeMsg="Can't pick the same user!" /> {selectedUser !== null && folder !== null && ( @@ -180,12 +182,20 @@ function FolderCompare({ + + + + setShouldIncludeNotPlayed(!shouldIncludeNotPlayed)} - label="Include charts you haven't both played?" + label="Include charts without plays?" /> {gptConfig.supportsESD && ( ); } + +function CompareCard({ + dataset, + baseUsername, + otherUsername, +}: { + dataset: ComparePBsDataset; + + baseUsername: string; + otherUsername: string; +}) { + // this code sucks + let scoreWin = 0; + let scoreDraw = 0; + let scoreLoss = 0; + let lampWin = 0; + let lampDraw = 0; + let lampLoss = 0; + + for (const d of dataset) { + if (!d.compare && !d.base) { + scoreDraw++; + lampDraw++; + continue; + } + + if (!d.compare) { + scoreWin++; + lampWin++; + continue; + } + + if (!d.base) { + scoreLoss++; + lampLoss++; + continue; + } + + if (d.base.scoreData.percent > d.compare.scoreData.percent) { + scoreWin++; + } else if (d.base.scoreData.percent < d.compare.scoreData.percent) { + scoreLoss++; + } else { + scoreDraw++; + } + + if (d.base.scoreData.lampIndex > d.compare.scoreData.lampIndex) { + lampWin++; + } else if (d.base.scoreData.lampIndex < d.compare.scoreData.lampIndex) { + lampLoss++; + } else { + lampDraw++; + } + } + + return ( + + + + + + + {baseUsername} Win + + {scoreWin} + + + {((100 * scoreWin) / dataset.length).toFixed(2)}% + + + + Draw + {scoreDraw} + + {((100 * scoreDraw) / dataset.length).toFixed(2)}% + + + + {otherUsername} Win + {scoreLoss} + + {((100 * scoreLoss) / dataset.length).toFixed(2)}% + + + + + + + + {baseUsername} Win + + {lampWin} + + + {((100 * lampWin) / dataset.length).toFixed(2)}% + + + + Draw + {lampDraw} + + {((100 * lampDraw) / dataset.length).toFixed(2)}% + + + + {otherUsername} Loss + {lampLoss} + + {((100 * lampLoss) / dataset.length).toFixed(2)}% + + + + + + + + ); +} diff --git a/client/src/components/tables/cells/PBCompareCell.tsx b/client/src/components/tables/cells/PBCompareCell.tsx index f39e47a66..9a65d8233 100644 --- a/client/src/components/tables/cells/PBCompareCell.tsx +++ b/client/src/components/tables/cells/PBCompareCell.tsx @@ -35,12 +35,12 @@ export default function PBCompareCell({ } let scoreRenderFn = (k: number) => k.toString(); + let shouldShowPercent = false; switch (game) { case "chunithm": case "ddr": case "gitadora": - case "jubeat": case "maimai": case "usc": case "sdvx": @@ -48,10 +48,16 @@ export default function PBCompareCell({ case "wacca": case "museca": scoreRenderFn = FormatMillions; + shouldShowPercent = false; + break; + case "jubeat": + scoreRenderFn = FormatMillions; + shouldShowPercent = true; break; case "bms": case "iidx": scoreRenderFn = (k: number) => k.toString(); + shouldShowPercent = true; break; } @@ -87,8 +93,12 @@ export default function PBCompareCell({ {compareType === "score" ? ( <> {(cmpScore > 0 ? "+" : "") + scoreRenderFn(cmpScore)} -
- ({fmtCmpPercent}) + {shouldShowPercent && ( + <> +
+ ({fmtCmpPercent}) + + )} {esdDiff !== undefined && ( <>
diff --git a/client/src/components/tables/rivals/ComparePBsTable.tsx b/client/src/components/tables/rivals/ComparePBsTable.tsx index 427d66eaf..80d3c0857 100644 --- a/client/src/components/tables/rivals/ComparePBsTable.tsx +++ b/client/src/components/tables/rivals/ComparePBsTable.tsx @@ -1,19 +1,21 @@ import { NumericSOV, StrSOV } from "util/sorts"; +import { CreatePBCompareSearchParams } from "util/tables/create-search"; import React, { useState } from "react"; import { Game, IDStrings, Playtype } from "tachi-common"; import { ESDCompare } from "tachi-common/lib/esd"; import { ComparePBsDataset } from "types/tables"; import DifficultyCell from "../cells/DifficultyCell"; +import PBCompareCell from "../cells/PBCompareCell"; import TitleCell from "../cells/TitleCell"; +import SelectableCompareType from "../components/SelectableCompareType"; import TachiTable, { Header, ZTableTHProps } from "../components/TachiTable"; import ShortScoreCoreCells from "../game-core-cells/ShortScoreCoreCells"; import ChartHeader from "../headers/ChartHeader"; -import PBCompareCell from "../cells/PBCompareCell"; -import SelectableCompareType from "../components/SelectableCompareType"; export default function ComparePBsTable({ dataset, game, + playtype, baseUser, compareUser, shouldESD, @@ -79,6 +81,7 @@ export default function ComparePBsTable({ entryName="Charts" defaultReverseSort defaultSortMode="Vs." + searchFunctions={CreatePBCompareSearchParams(game, playtype)} rowFunction={(data) => ( )} diff --git a/client/src/util/tables/create-search.ts b/client/src/util/tables/create-search.ts index cb742c7d7..3f611b100 100644 --- a/client/src/util/tables/create-search.ts +++ b/client/src/util/tables/create-search.ts @@ -1,14 +1,14 @@ import { HumanFriendlyStrToGradeIndex, HumanFriendlyStrToLampIndex } from "util/str-to-num"; import { ValueGetterOrHybrid } from "util/ztable/search"; import { + BMS_TABLES, ChartDocument, Game, GamePTConfig, GetGamePTConfig, IDStrings, - BMS_TABLES, } from "tachi-common"; -import { FolderDataset, PBDataset, ScoreDataset } from "types/tables"; +import { ComparePBsDataset, FolderDataset, PBDataset, ScoreDataset } from "types/tables"; import { Playtype } from "types/tachi"; function GetBMSTableVal(chart: ChartDocument<"bms:7K" | "bms:14K">, key: string) { @@ -88,6 +88,24 @@ export function CreateDefaultPBSearchParams( return searchFunctions; } +export function CreatePBCompareSearchParams( + game: Game, + playtype: Playtype +) { + const searchFunctions: Record[0]>> = { + artist: (x) => x.song.artist, + title: (x) => x.song.title, + difficulty: (x) => x.chart.difficulty, + level: (x) => x.chart.levelNum, + }; + + if (game === "bms") { + HandleBMSNonsense(searchFunctions, playtype, (k) => k); + } + + return searchFunctions; +} + export function CreateDefaultFolderSearchParams( game: Game, playtype: Playtype