From 3d8f9c2f8434e5556b5d36d330ec0d9ec1bf66a7 Mon Sep 17 00:00:00 2001 From: zkldi Date: Fri, 20 Aug 2021 02:33:27 +0100 Subject: [PATCH] Score Tables --- client/package.json | 4 +- client/pnpm-lock.yaml | 8 +- client/src/.eslintrc | 1 + client/src/app/pages/LoginPage.tsx | 4 +- client/src/app/pages/RegisterPage.tsx | 3 +- .../app/pages/dashboard/misc/CreditsPage.tsx | 4 +- .../src/components/tables/cells/LampCell.tsx | 10 +- ...DVXScoreCell.tsx => MillionsScoreCell.tsx} | 4 +- .../tables/cells/MusecaJudgementCell.tsx | 41 ++++++ .../components/tables/cells/RatingCell.tsx | 11 ++ .../tables/cells/SDVXJudgementCell.tsx | 41 ++++++ .../src/components/tables/cells/ScoreCell.tsx | 6 +- .../tables/dropdowns/GenericScoreDropdown.tsx | 44 ++---- .../dropdowns/GenericSessionDropdown.tsx | 6 +- .../GenericScoreContentDropdown.tsx | 15 +- .../components/IIDXScoreDropdownParts.tsx | 4 +- .../src/components/tables/pbs/BMSPBTable.tsx | 6 +- .../components/tables/pbs/GenericPBTable.tsx | 131 ++++++++++++++++++ .../src/components/tables/pbs/IIDXPBTable.tsx | 2 +- .../components/tables/pbs/MusecaPBTable.tsx | 119 ++++++++++++++++ client/src/components/tables/pbs/PBTable.tsx | 11 +- .../src/components/tables/pbs/SDVXPBTable.tsx | 25 ++-- .../tables/scores/BMSScoreTable.tsx | 12 +- .../tables/scores/GenericScoreTable.tsx | 113 +++++++++++++++ .../tables/scores/IIDXScoreTable.tsx | 2 +- .../tables/scores/MusecaScoreTable.tsx | 101 ++++++++++++++ .../tables/scores/SDVXScoreTable.tsx | 26 ++-- .../components/tables/scores/ScoreTable.tsx | 10 +- 28 files changed, 657 insertions(+), 107 deletions(-) rename client/src/components/tables/cells/{SDVXScoreCell.tsx => MillionsScoreCell.tsx} (74%) create mode 100644 client/src/components/tables/cells/MusecaJudgementCell.tsx create mode 100644 client/src/components/tables/cells/RatingCell.tsx create mode 100644 client/src/components/tables/cells/SDVXJudgementCell.tsx create mode 100644 client/src/components/tables/pbs/GenericPBTable.tsx create mode 100644 client/src/components/tables/pbs/MusecaPBTable.tsx create mode 100644 client/src/components/tables/scores/GenericScoreTable.tsx create mode 100644 client/src/components/tables/scores/MusecaScoreTable.tsx diff --git a/client/package.json b/client/package.json index 2a1a12c85..0e564407b 100644 --- a/client/package.json +++ b/client/package.json @@ -6,7 +6,7 @@ "start": "node scripts/start.js -o", "build": "node scripts/build.js", "test": "node scripts/test.js", - "lint": "eslint src --fix --ext .ts" + "lint": "eslint src --fix" }, "browserslist": { "production": [ @@ -74,7 +74,7 @@ "resolve": "1.12.0", "resolve-url-loader": "3.1.0", "socicon": "3.0.5", - "tachi-common": "0.1.30" + "tachi-common": "0.1.31" }, "devDependencies": { "@types/humanize-duration": "3.25.1", diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 3de1681b7..cac8da4a1 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -77,7 +77,7 @@ specifiers: serve: 11.2.0 socicon: 3.0.5 style-loader: 1.0.0 - tachi-common: 0.1.30 + tachi-common: 0.1.31 terser-webpack-plugin: 1.4.1 ts-pnp: 1.1.4 typescript: 4.3.5 @@ -141,7 +141,7 @@ dependencies: resolve: 1.12.0 resolve-url-loader: 3.1.0 socicon: 3.0.5 - tachi-common: 0.1.30_typescript@4.3.5 + tachi-common: 0.1.31_typescript@4.3.5 devDependencies: '@types/humanize-duration': 3.25.1 @@ -11483,8 +11483,8 @@ packages: strip-ansi: 6.0.0 dev: true - /tachi-common/0.1.30_typescript@4.3.5: - resolution: {integrity: sha512-bQOhX5VSmfaMpdbkgci1C/r4mcc68bl41fovZcfqvxUv2SFKa4fJL5rc+5durudZy1QGcnmUioexul2ZhdaofA==} + /tachi-common/0.1.31_typescript@4.3.5: + resolution: {integrity: sha512-jaJhv/zW+ye/GAKrYBiJb31shP4hSFhpssM56LUccZJKppDtd56lUu6fFtPWgydt3EIG7fVLqmTQJtDC0WRugg==} dependencies: monk: 7.3.4 tap: 15.0.9_typescript@4.3.5 diff --git a/client/src/.eslintrc b/client/src/.eslintrc index a1b95383a..12e292c66 100644 --- a/client/src/.eslintrc +++ b/client/src/.eslintrc @@ -52,6 +52,7 @@ "react/no-unescaped-entities": ["error", {"forbid": [">", "}"]}], "react/display-name": "off", "import/no-unresolved": "off", + "import/no-named-as-default": "off", "react/prop-types": "warn", "require-await": "warn", "no-await-in-loop": "warn", diff --git a/client/src/app/pages/LoginPage.tsx b/client/src/app/pages/LoginPage.tsx index 353293b4a..c0d562255 100644 --- a/client/src/app/pages/LoginPage.tsx +++ b/client/src/app/pages/LoginPage.tsx @@ -76,9 +76,7 @@ export default function LoginPage() {

Log In

- - Don't have an account? - + Don't have an account? Sign Up! diff --git a/client/src/app/pages/RegisterPage.tsx b/client/src/app/pages/RegisterPage.tsx index 0848c9275..0ad88cc19 100644 --- a/client/src/app/pages/RegisterPage.tsx +++ b/client/src/app/pages/RegisterPage.tsx @@ -154,8 +154,7 @@ export default function RegisterPage() {
I know it sucks to wait around, but the few rules we have are enforced strictly.
- The last thing you'd want is to accidentally get yourself - banned! + The last thing you'd want is to accidentally get yourself banned!

) : ( <> diff --git a/client/src/app/pages/dashboard/misc/CreditsPage.tsx b/client/src/app/pages/dashboard/misc/CreditsPage.tsx index 8d6971179..06a2ec87d 100644 --- a/client/src/app/pages/dashboard/misc/CreditsPage.tsx +++ b/client/src/app/pages/dashboard/misc/CreditsPage.tsx @@ -168,9 +168,7 @@ export default function CreditsPage() {
  • Node TAP
    - - Node TAP is a testing framework that is.not.a("mess") - + Node TAP is a testing framework that is.not.a("mess")
  • diff --git a/client/src/components/tables/cells/LampCell.tsx b/client/src/components/tables/cells/LampCell.tsx index 1b049792a..b72726513 100644 --- a/client/src/components/tables/cells/LampCell.tsx +++ b/client/src/components/tables/cells/LampCell.tsx @@ -2,17 +2,17 @@ import React from "react"; import { GetGamePTConfig, PBScoreDocument, ScoreDocument } from "tachi-common"; import { ChangeOpacity } from "util/color-opacity"; -export default function LampCell({ sc }: { sc: ScoreDocument | PBScoreDocument }) { - console.log(sc.game, sc.playtype); - const gptConfig = GetGamePTConfig(sc.game, sc.playtype); +export default function LampCell({ score }: { score: ScoreDocument | PBScoreDocument }) { + console.log(score.game, score.playtype); + const gptConfig = GetGamePTConfig(score.game, score.playtype); return ( - {sc.scoreData.lamp} + {score.scoreData.lamp} ); } diff --git a/client/src/components/tables/cells/SDVXScoreCell.tsx b/client/src/components/tables/cells/MillionsScoreCell.tsx similarity index 74% rename from client/src/components/tables/cells/SDVXScoreCell.tsx rename to client/src/components/tables/cells/MillionsScoreCell.tsx index 033dde39f..52f06fedc 100644 --- a/client/src/components/tables/cells/SDVXScoreCell.tsx +++ b/client/src/components/tables/cells/MillionsScoreCell.tsx @@ -4,8 +4,8 @@ import { GamePT } from "types/react"; import { ChangeOpacity } from "util/color-opacity"; import { FormatMillions } from "util/misc"; -export default function SDVXScoreCell({ score }: { score: PBScoreDocument | ScoreDocument }) { - const gptConfig = GetGamePTConfig("sdvx", "Single"); +export default function MillionsScoreCell({ score }: { score: PBScoreDocument | ScoreDocument }) { + const gptConfig = GetGamePTConfig(score.game, score.playtype); return ( | PBScoreDocument<"museca:Single">; +}) { + // even if we dont have judgement data, we know what they got. + if (score.scoreData.lamp === "PERFECT CONNECT ALL") { + return ( + + + 0- + 0 + + + ); + } + + // safety + if (score.scoreData.lamp === "CONNECT ALL") { + score.scoreData.judgements.miss = 0; + } + + const judgements = score.scoreData.judgements; + + if (IsNullish(judgements.miss) || IsNullish(judgements.near)) { + return No Data.; + } + + return ( + + + {judgements.near}- + {judgements.miss} + + + ); +} diff --git a/client/src/components/tables/cells/RatingCell.tsx b/client/src/components/tables/cells/RatingCell.tsx new file mode 100644 index 000000000..18210a382 --- /dev/null +++ b/client/src/components/tables/cells/RatingCell.tsx @@ -0,0 +1,11 @@ +import React from "react"; +import { GetGamePTConfig, PBScoreDocument, ScoreDocument } from "tachi-common"; +import { IsNotNullish } from "util/misc"; + +export default function RatingCell({ score }: { score: ScoreDocument | PBScoreDocument }) { + const gptConfig = GetGamePTConfig(score.game, score.playtype); + + const v = score.calculatedData[gptConfig.defaultScoreRatingAlg]; + + return {IsNotNullish(v) ? v!.toFixed(2) : "No Data"}; +} diff --git a/client/src/components/tables/cells/SDVXJudgementCell.tsx b/client/src/components/tables/cells/SDVXJudgementCell.tsx new file mode 100644 index 000000000..3b68e2b18 --- /dev/null +++ b/client/src/components/tables/cells/SDVXJudgementCell.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import { COLOUR_SET, PBScoreDocument, ScoreDocument } from "tachi-common"; +import { IsNullish } from "util/misc"; + +export default function SDVXJudgementCell({ + score, +}: { + score: ScoreDocument<"sdvx:Single"> | PBScoreDocument<"sdvx:Single">; +}) { + // even if we dont have judgement data, we know what they got. + if (score.scoreData.lamp === "PERFECT ULTIMATE CHAIN") { + return ( + + + 0- + 0 + + + ); + } + + // safety + if (score.scoreData.lamp === "ULTIMATE CHAIN") { + score.scoreData.judgements.miss = 0; + } + + const judgements = score.scoreData.judgements; + + if (IsNullish(judgements.miss) || IsNullish(judgements.near)) { + return No Data.; + } + + return ( + + + {judgements.near}- + {judgements.miss} + + + ); +} diff --git a/client/src/components/tables/cells/ScoreCell.tsx b/client/src/components/tables/cells/ScoreCell.tsx index 014f6515c..94e555811 100644 --- a/client/src/components/tables/cells/ScoreCell.tsx +++ b/client/src/components/tables/cells/ScoreCell.tsx @@ -5,17 +5,15 @@ import { ChangeOpacity } from "util/color-opacity"; import { FormatMillions } from "util/misc"; export default function ScoreCell({ - game, - playtype, score, showScore = true, scoreRenderFn, -}: GamePT & { +}: { score: PBScoreDocument | ScoreDocument; showScore?: boolean; scoreRenderFn?: (s: number) => string; }) { - const gptConfig = GetGamePTConfig(game, playtype); + const gptConfig = GetGamePTConfig(score.game, score.playtype); return ( ({ reqUser, chart, scoreState, + thisScore, defaultView = "moreInfo", - DocComponent = GenericScoreContentDropdown, + DocComponent = props => GenericScoreContentDropdown({ renderScoreInfo: false, ...props }), }: { reqUser: PublicUserDocument; chart: ChartDocument; scoreState: ScoreState; defaultView?: "vsPB" | "moreInfo" | "history" | "debug"; + thisScore: ScoreDocument; DocComponent?: (props: { score: ScoreDocument | PBScoreDocument; scoreState: ScoreState; @@ -64,26 +66,6 @@ export default function GenericScoreDropdown({ } ); - const currentScoreDoc: ScoreDocument | PBScoreDocument | null = useMemo(() => { - if (!data) { - // dont worry about this null, it never gets below the rquery checks - return null; - } - - if (view === "pb") { - return data.pb; - } - - const idMap = { - scorePB: data.pb.composedFrom.scorePB, - lampPB: data.pb.composedFrom.lampPB, - ...Object.fromEntries((data.pb.composedFrom.other ?? []).map(e => [e.name, e.scoreID])), - }; - - // @ts-expect-error awful - return data.scores.filter(e => e.scoreID === idMap[view])[0]; - }, [view, data]); - if (error) { return <>An error has occured. Whoops.; } @@ -102,25 +84,21 @@ export default function GenericScoreDropdown({ body = <>; // todo } else if (view === "debug") { body = ; - } else { - body = ; + } else if (view === "moreInfo") { + body = ; } return ( - - - PB Info + + + This Score - - - Best Score - - - - Best Lamp + + + Versus PB diff --git a/client/src/components/tables/dropdowns/GenericSessionDropdown.tsx b/client/src/components/tables/dropdowns/GenericSessionDropdown.tsx index 1bb6c27ea..616534981 100644 --- a/client/src/components/tables/dropdowns/GenericSessionDropdown.tsx +++ b/client/src/components/tables/dropdowns/GenericSessionDropdown.tsx @@ -416,13 +416,11 @@ function ElementStatTable({ }) as ScoreDocument; if (type === "grade") { - preScoreCell = ( - - ); + preScoreCell = ; } else { preScoreCell = ( // @ts-expect-error temp - + ); } } diff --git a/client/src/components/tables/dropdowns/components/GenericScoreContentDropdown.tsx b/client/src/components/tables/dropdowns/components/GenericScoreContentDropdown.tsx index 576c6dac1..d09607c1e 100644 --- a/client/src/components/tables/dropdowns/components/GenericScoreContentDropdown.tsx +++ b/client/src/components/tables/dropdowns/components/GenericScoreContentDropdown.tsx @@ -22,7 +22,7 @@ export function ScoreInfo({ score }: { score: ScoreDocument }) { - + - + @@ -42,9 +42,11 @@ export function ScoreInfo({ score }: { score: ScoreDocument }) { export default function GenericScoreContentDropdown({ score, scoreState, + renderScoreInfo = true, }: { score: ScoreDocument | PBScoreDocument; scoreState: { highlight: boolean; setHighlight: SetState }; + renderScoreInfo?: boolean; }) { const [comment, setComment] = useState(IsScore(score) ? score.comment : null); @@ -55,10 +57,13 @@ export default function GenericScoreContentDropdown({ return ( <>
    -
    +
    +
    + No graphs available :( +
    {IsScore(score) ? ( <> - + {renderScoreInfo && } ) : ( -
    +
    )} diff --git a/client/src/components/tables/dropdowns/components/IIDXScoreDropdownParts.tsx b/client/src/components/tables/dropdowns/components/IIDXScoreDropdownParts.tsx index 54171ad0d..b624dcfdc 100644 --- a/client/src/components/tables/dropdowns/components/IIDXScoreDropdownParts.tsx +++ b/client/src/components/tables/dropdowns/components/IIDXScoreDropdownParts.tsx @@ -21,10 +21,10 @@ export function ScoreInfo({ score }: { score: ScoreDocument<"iidx:SP" | "iidx:DP - + @@ -143,7 +143,7 @@ function Row({ {indexCol && } - + - + {!IsNullish(pb.calculatedData.sieglinde) ? pb.calculatedData.sieglinde!.toFixed(2) diff --git a/client/src/components/tables/pbs/GenericPBTable.tsx b/client/src/components/tables/pbs/GenericPBTable.tsx new file mode 100644 index 000000000..eed1fd7c4 --- /dev/null +++ b/client/src/components/tables/pbs/GenericPBTable.tsx @@ -0,0 +1,131 @@ +import React, { useState } from "react"; +import TitleCell from "../cells/TitleCell"; +import RankingCell from "../cells/RankingCell"; +import TimestampCell from "../cells/TimestampCell"; +import { NumericSOV, StrSOV } from "util/sorts"; +import { PBDataset } from "types/tables"; +import { Game, GetGamePTConfig, PublicUserDocument } from "tachi-common"; +import TachiTable, { Header } from "../components/TachiTable"; +import IndexCell from "../cells/IndexCell"; +import { HumanFriendlyStrToGradeIndex, HumanFriendlyStrToLampIndex } from "util/str-to-num"; +import DropdownRow from "../components/DropdownRow"; +import { IsNullish } from "util/misc"; +import LampCell from "../cells/LampCell"; +import DifficultyCell from "../cells/DifficultyCell"; +import MillionsScoreCell from "../cells/MillionsScoreCell"; +import GenericPBDropdown from "../dropdowns/GenericPBDropdown"; +import SDVXJudgementCell from "../cells/SDVXJudgementCell"; +import ScoreCell from "../cells/ScoreCell"; +import RatingCell from "../cells/RatingCell"; +import { Playtype } from "types/tachi"; + +export default function GenericPBTable({ + dataset, + indexCol = true, + reqUser, + game, + playtype, + showScore, +}: { + dataset: PBDataset; + indexCol?: boolean; + reqUser: PublicUserDocument; + game: Game; + playtype: Playtype; + showScore?: boolean; +}) { + const gptConfig = GetGamePTConfig(game, playtype); + + const headers: Header[] = [ + ["Chart", "Ch.", NumericSOV(x => x.__related.chart.levelNum)], + ["Song", "Song", StrSOV(x => x.__related.song.title)], + ["Score", "Score", NumericSOV(x => x.scoreData.percent)], + ["Lamp", "Lamp", NumericSOV(x => x.scoreData.lampIndex)], + [ + gptConfig.defaultScoreRatingAlg, + gptConfig.defaultScoreRatingAlg, + NumericSOV(x => x.calculatedData[gptConfig.defaultScoreRatingAlg] ?? 0), + ], + ["Ranking", "Rank", NumericSOV(x => x.rankingData.rank)], + ["Last Raised", "Last Raised", NumericSOV(x => x.timeAchieved ?? 0)], + ]; + + if (indexCol) { + headers.unshift(["#", "#", NumericSOV(x => x.__related.index)]); + } + + return ( + x.__related.song.artist, + title: x => x.__related.song.title, + difficulty: x => x.__related.chart.difficulty, + level: x => x.__related.chart.levelNum, + score: x => x.scoreData.score, + percent: x => x.scoreData.percent, + ranking: x => x.rankingData.rank, + lamp: { + valueGetter: x => [x.scoreData.lamp, x.scoreData.lampIndex], + strToNum: HumanFriendlyStrToLampIndex(game, playtype), + }, + grade: { + valueGetter: x => [x.scoreData.grade, x.scoreData.gradeIndex], + strToNum: HumanFriendlyStrToGradeIndex(game, playtype), + }, + }} + defaultSortMode={indexCol ? "#" : undefined} + rowFunction={pb => ( + + )} + /> + ); +} + +function Row({ + pb, + indexCol, + reqUser, + showScore, +}: { + pb: PBDataset[0]; + indexCol: boolean; + reqUser: PublicUserDocument; + showScore?: boolean; +}) { + const [highlight, setHighlight] = useState(pb.highlight); + + const scoreState = { highlight, setHighlight }; + + return ( + + } + className={highlight ? "highlighted-row" : ""} + > + {indexCol && } + + + + + + + + + ); +} diff --git a/client/src/components/tables/pbs/IIDXPBTable.tsx b/client/src/components/tables/pbs/IIDXPBTable.tsx index 35aae2e75..62991d355 100644 --- a/client/src/components/tables/pbs/IIDXPBTable.tsx +++ b/client/src/components/tables/pbs/IIDXPBTable.tsx @@ -132,7 +132,7 @@ function Row({ {indexCol && } - + ; + indexCol?: boolean; + reqUser: PublicUserDocument; + playtype: "Single"; +}) { + const headers: Header[0]>[] = [ + ["Chart", "Ch.", NumericSOV(x => x.__related.chart.levelNum)], + ["Song", "Song", StrSOV(x => x.__related.song.title)], + ["Score", "Score", NumericSOV(x => x.scoreData.percent)], + ["Judgements", "Judge", NumericSOV(x => x.scoreData.percent)], + ["Lamp", "Lamp", NumericSOV(x => x.scoreData.lampIndex)], + ["ktRating", "ktRating", NumericSOV(x => x.calculatedData.ktRating ?? 0)], + ["Ranking", "Rank", NumericSOV(x => x.rankingData.rank)], + ["Last Raised", "Last Raised", NumericSOV(x => x.timeAchieved ?? 0)], + ]; + + if (indexCol) { + headers.unshift(["#", "#", NumericSOV(x => x.__related.index)]); + } + + return ( + x.__related.song.artist, + title: x => x.__related.song.title, + difficulty: x => x.__related.chart.difficulty, + level: x => x.__related.chart.levelNum, + score: x => x.scoreData.score, + percent: x => x.scoreData.percent, + ranking: x => x.rankingData.rank, + lamp: { + valueGetter: x => [x.scoreData.lamp, x.scoreData.lampIndex], + strToNum: HumanFriendlyStrToLampIndex("museca", playtype), + }, + grade: { + valueGetter: x => [x.scoreData.grade, x.scoreData.gradeIndex], + strToNum: HumanFriendlyStrToGradeIndex("museca", playtype), + }, + }} + defaultSortMode={indexCol ? "#" : undefined} + rowFunction={pb => ( + + )} + /> + ); +} + +function Row({ + pb, + indexCol, + reqUser, +}: { + pb: PBDataset<"museca:Single">[0]; + indexCol: boolean; + reqUser: PublicUserDocument; +}) { + const [highlight, setHighlight] = useState(pb.highlight); + + const scoreState = { highlight, setHighlight }; + + return ( + + } + className={highlight ? "highlighted-row" : ""} + > + {indexCol && } + + + + + + + + + + ); +} diff --git a/client/src/components/tables/pbs/PBTable.tsx b/client/src/components/tables/pbs/PBTable.tsx index e22ed5b87..bbad759bb 100644 --- a/client/src/components/tables/pbs/PBTable.tsx +++ b/client/src/components/tables/pbs/PBTable.tsx @@ -5,6 +5,8 @@ import { PublicUserDocument } from "tachi-common"; import IIDXPBTable from "./IIDXPBTable"; import BMSPBTable from "./BMSPBTable"; import SDVXPBTable from "./SDVXPBTable"; +import GenericPBTable from "./GenericPBTable"; +import MusecaPBTable from "./MusecaPBTable"; export default function PBTable({ dataset, @@ -22,13 +24,18 @@ export default function PBTable({ // ever. // eslint-disable-next-line @typescript-eslint/no-explicit-any const props = { dataset, indexCol, reqUser, playtype } as any; + if (game === "iidx") { return ; } else if (game === "bms") { return ; - } else if (game === "sdvx") { + } else if (game === "sdvx" || game === "usc") { return ; + } else if (game === "maimai") { + return ; + } else if (game === "museca") { + return ; } - return <>; + return ; } diff --git a/client/src/components/tables/pbs/SDVXPBTable.tsx b/client/src/components/tables/pbs/SDVXPBTable.tsx index aac8f4f5e..2d899807d 100644 --- a/client/src/components/tables/pbs/SDVXPBTable.tsx +++ b/client/src/components/tables/pbs/SDVXPBTable.tsx @@ -12,7 +12,9 @@ import DropdownRow from "../components/DropdownRow"; import { IsNullish } from "util/misc"; import LampCell from "../cells/LampCell"; import DifficultyCell from "../cells/DifficultyCell"; -import SDVXScoreCell from "../cells/SDVXScoreCell"; +import MillionsScoreCell from "../cells/MillionsScoreCell"; +import GenericPBDropdown from "../dropdowns/GenericPBDropdown"; +import SDVXJudgementCell from "../cells/SDVXJudgementCell"; export default function SDVXPBTable({ dataset, @@ -29,6 +31,7 @@ export default function SDVXPBTable({ ["Chart", "Ch.", NumericSOV(x => x.__related.chart.levelNum)], ["Song", "Song", StrSOV(x => x.__related.song.title)], ["Score", "Score", NumericSOV(x => x.scoreData.percent)], + ["Judgements", "Judge", NumericSOV(x => x.scoreData.percent)], ["Lamp", "Lamp", NumericSOV(x => x.scoreData.lampIndex)], ["VF6", "VF6", NumericSOV(x => x.calculatedData.VF6 ?? 0)], ["Ranking", "Rank", NumericSOV(x => x.rankingData.rank)], @@ -90,22 +93,22 @@ function Row({ return ( - // + } className={highlight ? "highlighted-row" : ""} > {indexCol && } - - + + + {!IsNullish(pb.calculatedData.VF6) ? pb.calculatedData.VF6!.toFixed(3) : "No Data."} diff --git a/client/src/components/tables/scores/BMSScoreTable.tsx b/client/src/components/tables/scores/BMSScoreTable.tsx index 45a05d029..4efa37225 100644 --- a/client/src/components/tables/scores/BMSScoreTable.tsx +++ b/client/src/components/tables/scores/BMSScoreTable.tsx @@ -14,7 +14,8 @@ import { IsNullish } from "util/misc"; import LampCell from "../cells/LampCell"; import BMSDifficultyCell from "../cells/BMSDifficultyCell"; import { Playtype } from "types/tachi"; -import GenericPBDropdown from "../dropdowns/GenericPBDropdown"; +import GenericScoreDropdown from "../dropdowns/GenericScoreDropdown"; +import SDVXJudgementCell from "../cells/SDVXJudgementCell"; export default function BMSScoreTable({ reqUser, @@ -83,10 +84,11 @@ function Row({ @@ -94,7 +96,7 @@ function Row({ > - + - + {!IsNullish(sc.calculatedData.sieglinde) ? sc.calculatedData.sieglinde!.toFixed(2) diff --git a/client/src/components/tables/scores/GenericScoreTable.tsx b/client/src/components/tables/scores/GenericScoreTable.tsx new file mode 100644 index 000000000..e76801657 --- /dev/null +++ b/client/src/components/tables/scores/GenericScoreTable.tsx @@ -0,0 +1,113 @@ +import React, { useState } from "react"; +import { FormatDifficulty } from "tachi-common/js/utils/util"; +import TitleCell from "../cells/TitleCell"; +import TimestampCell from "../cells/TimestampCell"; +import { NumericSOV, StrSOV } from "util/sorts"; +import { ScoreDataset } from "types/tables"; +import { integer, PublicUserDocument, Playtypes, Game, GetGamePTConfig } from "tachi-common"; +import TachiTable from "../components/TachiTable"; +import DifficultyCell from "../cells/DifficultyCell"; +import ScoreCell from "../cells/ScoreCell"; +import { HumanFriendlyStrToGradeIndex, HumanFriendlyStrToLampIndex } from "util/str-to-num"; +import DropdownRow from "../components/DropdownRow"; +import { IsNullish } from "util/misc"; +import LampCell from "../cells/LampCell"; +import MillionsScoreCell from "../cells/MillionsScoreCell"; +import GenericScoreDropdown from "../dropdowns/GenericScoreDropdown"; +import RatingCell from "../cells/RatingCell"; +import { Playtype } from "types/tachi"; + +export default function GenericScoreTable({ + reqUser, + dataset, + pageLen, + playtype, + showScore, + game, +}: { + reqUser: PublicUserDocument; + dataset: ScoreDataset; + pageLen?: integer; + playtype: Playtype; + game: Game; + showScore?: boolean; +}) { + const gptConfig = GetGamePTConfig(game, playtype); + + return ( + x.__related.chart.levelNum)], + ["Song", "Song", StrSOV(x => x.__related.song.title)], + ["Score", "Score", NumericSOV(x => x.scoreData.percent)], + ["Lamp", "Lamp", NumericSOV(x => x.scoreData.lampIndex)], + [ + gptConfig.defaultScoreRatingAlg, + gptConfig.defaultScoreRatingAlg, + NumericSOV(x => x.calculatedData[gptConfig.defaultScoreRatingAlg] ?? 0), + ], + ["Timestamp", "Timestamp", NumericSOV(x => x.timeAchieved ?? 0)], + ]} + entryName="Scores" + searchFunctions={{ + artist: x => x.__related.song.artist, + title: x => x.__related.song.title, + difficulty: x => FormatDifficulty(x.__related.chart, game), + level: x => x.__related.chart.levelNum, + score: x => x.scoreData.score, + percent: x => x.scoreData.percent, + lamp: { + valueGetter: x => [x.scoreData.lamp, x.scoreData.lampIndex], + strToNum: HumanFriendlyStrToLampIndex(game, playtype), + }, + grade: { + valueGetter: x => [x.scoreData.grade, x.scoreData.gradeIndex], + strToNum: HumanFriendlyStrToGradeIndex(game, playtype), + }, + }} + rowFunction={sc => ( + + )} + /> + ); +} + +function Row({ + sc, + reqUser, + showScore, +}: { + sc: ScoreDataset[0]; + reqUser: PublicUserDocument; + showScore?: boolean; +}) { + const [highlight, setHighlight] = useState(sc.highlight); + const [comment, setComment] = useState(sc.comment); + + const scoreState = { highlight, comment, setHighlight, setComment }; + + return ( + + } + > + + + + + + + + ); +} diff --git a/client/src/components/tables/scores/IIDXScoreTable.tsx b/client/src/components/tables/scores/IIDXScoreTable.tsx index aede4cfc5..eef1d48a9 100644 --- a/client/src/components/tables/scores/IIDXScoreTable.tsx +++ b/client/src/components/tables/scores/IIDXScoreTable.tsx @@ -130,7 +130,7 @@ function Row({ > - + ; + pageLen?: integer; + playtype: Playtypes["museca"]; +}) { + return ( + x.__related.chart.levelNum)], + ["Song", "Song", StrSOV(x => x.__related.song.title)], + ["Score", "Score", NumericSOV(x => x.scoreData.percent)], + ["Judgements", "Judge", NumericSOV(x => x.scoreData.percent)], + ["Lamp", "Lamp", NumericSOV(x => x.scoreData.lampIndex)], + ["KtRating", "KtRating", NumericSOV(x => x.calculatedData.ktRating ?? 0)], + + ["Timestamp", "Timestamp", NumericSOV(x => x.timeAchieved ?? 0)], + ]} + entryName="Scores" + searchFunctions={{ + artist: x => x.__related.song.artist, + title: x => x.__related.song.title, + difficulty: x => FormatDifficulty(x.__related.chart, "museca"), + level: x => x.__related.chart.levelNum, + score: x => x.scoreData.score, + percent: x => x.scoreData.percent, + lamp: { + valueGetter: x => [x.scoreData.lamp, x.scoreData.lampIndex], + strToNum: HumanFriendlyStrToLampIndex("museca", "Single"), + }, + grade: { + valueGetter: x => [x.scoreData.grade, x.scoreData.gradeIndex], + strToNum: HumanFriendlyStrToGradeIndex("museca", "Single"), + }, + }} + rowFunction={sc => } + /> + ); +} + +function Row({ + sc, + reqUser, +}: { + sc: ScoreDataset<"museca:Single">[0]; + reqUser: PublicUserDocument; +}) { + const [highlight, setHighlight] = useState(sc.highlight); + const [comment, setComment] = useState(sc.comment); + + const scoreState = { highlight, comment, setHighlight, setComment }; + + return ( + + } + > + + + + + + + + + ); +} diff --git a/client/src/components/tables/scores/SDVXScoreTable.tsx b/client/src/components/tables/scores/SDVXScoreTable.tsx index c74c1fa56..db90c11a2 100644 --- a/client/src/components/tables/scores/SDVXScoreTable.tsx +++ b/client/src/components/tables/scores/SDVXScoreTable.tsx @@ -12,7 +12,8 @@ import { HumanFriendlyStrToGradeIndex, HumanFriendlyStrToLampIndex } from "util/ import DropdownRow from "../components/DropdownRow"; import { IsNullish } from "util/misc"; import LampCell from "../cells/LampCell"; -import SDVXScoreCell from "../cells/SDVXScoreCell"; +import MillionsScoreCell from "../cells/MillionsScoreCell"; +import GenericScoreDropdown from "../dropdowns/GenericScoreDropdown"; export default function SDVXScoreTable({ reqUser, @@ -69,22 +70,21 @@ function Row({ sc, reqUser }: { sc: ScoreDataset<"sdvx:Single">[0]; reqUser: Pub - // + } > - - - {!IsNullish(sc.calculatedData.VF6) ? sc.calculatedData.VF6!.toFixed(2) : "N/A"} + + + {!IsNullish(sc.calculatedData.VF6) ? sc.calculatedData.VF6!.toFixed(3) : "N/A"} ); diff --git a/client/src/components/tables/scores/ScoreTable.tsx b/client/src/components/tables/scores/ScoreTable.tsx index 2357f113d..a46642839 100644 --- a/client/src/components/tables/scores/ScoreTable.tsx +++ b/client/src/components/tables/scores/ScoreTable.tsx @@ -5,6 +5,8 @@ import { PublicUserDocument, integer } from "tachi-common"; import IIDXScoreTable from "./IIDXScoreTable"; import BMSScoreTable from "./BMSScoreTable"; import SDVXScoreTable from "./SDVXScoreTable"; +import GenericScoreTable from "./GenericScoreTable"; +import MusecaScoreTable from "./MusecaScoreTable"; export default function ScoreTable({ dataset, @@ -28,9 +30,13 @@ export default function ScoreTable({ return ; } else if (game === "bms") { return ; - } else if (game === "sdvx") { + } else if (game === "sdvx" || game === "usc") { return ; + } else if (game === "maimai") { + return ; + } else if (game === "museca") { + return ; } - return <>; + return ; }