This commit is contained in:
zkldi
2021-09-04 14:25:58 +01:00
parent 21f1faa1b2
commit 451238d324
7 changed files with 108 additions and 30 deletions
@@ -13,7 +13,7 @@ import AsyncLoader from "components/util/AsyncLoader";
import UGPTRatingsTable from "components/user/UGPTStatsOverview";
import LinkButton from "components/util/LinkButton";
import { UGSWithRankingData } from "types/api-returns";
import RankingData from "components/user/UGPTRankingData";
import RankingData, { LazyRankingData } from "components/user/UGPTRankingData";
import ReferToUser from "components/util/ReferToUser";
interface Props {
@@ -96,7 +96,7 @@ function GameStatContainer({ ugs, reqUser }: { ugs: UGSWithRankingData } & Props
header={FormatGame(ugs.game, ugs.playtype)}
>
<UGPTRatingsTable ugs={ugs} />
<RankingData ranking={ugs.__rankingData.ranking} outOf={ugs.__rankingData.outOf} />
<LazyRankingData ranking={ugs.__rankingData.ranking} outOf={ugs.__rankingData.outOf} />
</Card>
);
}
@@ -4,7 +4,8 @@ import Card from "components/layout/page/Card";
import MiniTable from "components/tables/components/MiniTable";
import GentleLink from "components/util/GentleLink";
import LoadingWrapper from "components/util/LoadingWrapper";
import React from "react";
import { useProfileRatingAlg } from "components/util/useScoreRatingAlg";
import React, { useState } from "react";
import { useQuery } from "react-query";
import { Link } from "react-router-dom";
import {
@@ -15,11 +16,12 @@ import {
IDStrings,
integer,
PublicUserDocument,
UGSRatingsLookup,
UserGameStats,
} from "tachi-common";
import { GameClassSets } from "tachi-common/js/game-classes";
import { GPTLeaderboard, UGPTLeaderboardAdjacent } from "types/api-returns";
import { GamePT } from "types/react";
import { GamePT, SetState } from "types/react";
import { APIFetchV1, UnsuccessfulAPIFetchResponse } from "util/api";
import { ChangeOpacity } from "util/color-opacity";
@@ -40,7 +42,10 @@ export default function LeaderboardsPage({
`${reqUser.username}'s ${FormatGame(game, playtype)} Leaderboard`
);
const url = `/users/${reqUser.id}/games/${game}/${playtype}/leaderboard-adjacent`;
const defaultRating = useProfileRatingAlg(game, playtype);
const [alg, setAlg] = useState(defaultRating);
const url = `/users/${reqUser.id}/games/${game}/${playtype}/leaderboard-adjacent?alg=${alg}`;
const { isLoading, error, data } = useQuery<LeaderboardsData, UnsuccessfulAPIFetchResponse>(
url,
@@ -52,7 +57,7 @@ export default function LeaderboardsPage({
}
const lRes = await APIFetchV1<GPTLeaderboard>(
`/games/${game}/${playtype}/leaderboard?limit=3`
`/games/${game}/${playtype}/leaderboard?limit=3&alg=${alg}`
);
if (!lRes.success) {
@@ -68,7 +73,7 @@ export default function LeaderboardsPage({
return (
<LoadingWrapper {...{ dataset: data, isLoading, error }}>
<LeaderboardsPageContent {...{ reqUser, game, playtype, data: data! }} />
<LeaderboardsPageContent {...{ reqUser, game, playtype, data: data!, alg, setAlg }} />
</LoadingWrapper>
);
}
@@ -78,9 +83,12 @@ function LeaderboardsPageContent({
game,
playtype,
data,
alg,
}: {
reqUser: PublicUserDocument;
data: LeaderboardsData;
alg: UGSRatingsLookup[IDStrings];
setAlg: SetState<UGSRatingsLookup[IDStrings]>;
} & GamePT) {
const { stats, leaderboard } = data;
@@ -97,8 +105,6 @@ function LeaderboardsPageContent({
// hack - we aren't returned from this api call for some reason.
userMap.set(reqUser.id, reqUser);
const gptConfig = GetGamePTConfig(game, playtype);
const bestNearbyUser = stats.thisUsersRanking.ranking - stats.above.length;
function LeaderboardRow({ s, i }: { s: UserGameStats; i: integer }) {
@@ -125,7 +131,7 @@ function LeaderboardsPageContent({
{userMap.get(s.userID)?.username}
</GentleLink>
</td>
<td>{(s.ratings[gptConfig.defaultProfileRatingAlg] ?? 0).toFixed(2)}</td>
<td>{(s.ratings[alg] ?? 0).toFixed(2)}</td>
{/* temp */}
<td>
{Object.entries(s.classes).length
@@ -156,7 +162,7 @@ function LeaderboardsPageContent({
</Link>
}
>
<MiniTable className="text-center" headers={["Position", "User", "Rating", "Classes"]}>
<MiniTable className="text-center" headers={["Position", "User", alg, "Classes"]}>
<>
{bestNearbyUser > 1 &&
leaderboard.gameStats
+22 -12
View File
@@ -155,18 +155,8 @@ function UserGamePlaytypeRoutes({ reqUser, game }: { reqUser: PublicUserDocument
const { user } = useContext(UserContext);
const { setSettings } = useContext(UGPTSettingsContext);
const { isLoading, error, data } = useQuery<UGPTStatsReturn, APIFetchV1Return<UserGameStats>>(
[reqUser.id, game, playtype],
async () => {
const res = await APIFetchV1<UGPTStatsReturn>(
`/users/${reqUser.id}/games/${game}/${playtype}`
);
if (!res.success) {
console.error(res);
throw res;
}
useEffect(() => {
(async () => {
if (user) {
const settingsRes = await APIFetchV1<UGPTSettings>(
`/users/${user.id}/games/${game}/${playtype}/settings`
@@ -177,8 +167,28 @@ function UserGamePlaytypeRoutes({ reqUser, game }: { reqUser: PublicUserDocument
throw settingsRes;
}
console.log(settingsRes.body);
setSettings(settingsRes.body);
}
})();
return () => {
setSettings(null);
};
}, [user, game, playtype]);
const { isLoading, error, data } = useQuery<UGPTStatsReturn, APIFetchV1Return<UserGameStats>>(
[reqUser.id, game, playtype],
async () => {
const res = await APIFetchV1<UGPTStatsReturn>(
`/users/${reqUser.id}/games/${game}/${playtype}`
);
if (!res.success) {
console.error(res);
throw res;
}
return res.body;
},
+2 -1
View File
@@ -21,6 +21,7 @@ import ProfileBadges from "./ProfileBadges";
import { GameClassSets } from "tachi-common/js/game-classes";
import UGPTRatingsTable from "./UGPTStatsOverview";
import RankingData from "./UGPTRankingData";
import { useProfileRatingAlg } from "components/util/useScoreRatingAlg";
export function UGPTHeaderBody({
reqUser,
@@ -78,7 +79,7 @@ export function UGPTHeaderBody({
<UGPTRatingsTable ugs={stats.gameStats} />
</div>
<div className="col-12 col-lg-3">
<RankingData ranking={stats.rankingData.ranking} outOf={stats.rankingData.outOf} />
<RankingData rankingData={stats.rankingData} game={game} playtype={playtype} />
</div>
</>
);
+43 -1
View File
@@ -1,6 +1,48 @@
import { useProfileRatingAlg } from "components/util/useScoreRatingAlg";
import React from "react";
import { IDStrings, integer, UGSRatingsLookup } from "tachi-common";
import { GamePT } from "types/react";
export default function RankingData({ ranking, outOf }: { ranking: number; outOf: number }) {
export default function RankingData({
rankingData,
game,
playtype,
}: {
rankingData: Record<UGSRatingsLookup[IDStrings], { ranking: number; outOf: integer }>;
} & GamePT) {
const alg = useProfileRatingAlg(game, playtype);
const extendData = [];
for (const k in rankingData) {
const key = k as UGSRatingsLookup[IDStrings];
if (key !== alg) {
extendData.push(
<div className="col-12">
<small className="text-muted">
{key}: #{rankingData[key].ranking}/{rankingData[key].outOf}
</small>
</div>
);
}
}
return (
<div className="row text-center">
<div className="col-12">
<h4>Ranking{extendData.length ? ` (${alg})` : ""}</h4>
</div>
<div className="col-12">
<strong className="display-4">#{rankingData[alg].ranking}</strong>
<span className="text-muted">/{rankingData[alg].outOf}</span>
</div>
{extendData}
</div>
);
}
export function LazyRankingData({ ranking, outOf }: { ranking: integer; outOf: integer }) {
return (
<div className="row text-center">
<div className="col-12">
@@ -6,6 +6,7 @@ import {
IDStrings,
ScoreCalculatedDataLookup,
SessionCalculatedDataLookup,
UGSRatingsLookup,
} from "tachi-common";
import { Playtype } from "types/tachi";
@@ -38,3 +39,18 @@ export function useSessionRatingAlg<I extends IDStrings = IDStrings>(
return settings.preferences.preferredSessionAlg as SessionCalculatedDataLookup[I];
}
export function useProfileRatingAlg<I extends IDStrings = IDStrings>(
game: Game,
playtype: Playtype
): UGSRatingsLookup[I] {
const { settings } = useContext(UGPTSettingsContext);
if (!settings?.preferences.preferredProfileAlg) {
const gptConfig = GetGamePTConfig(game, playtype);
return gptConfig.defaultProfileRatingAlg as UGSRatingsLookup[I];
}
return settings.preferences.preferredProfileAlg as UGSRatingsLookup[I];
}
+8 -5
View File
@@ -13,7 +13,7 @@ import {
ChartDocument,
SongDocument,
PBScoreDocument,
ShowcaseStatDetails,
UGSRatingsLookup,
} from "tachi-common";
export interface UGPTStatsReturn<I extends IDStrings = IDStrings> {
@@ -21,10 +21,13 @@ export interface UGPTStatsReturn<I extends IDStrings = IDStrings> {
firstScore: ScoreDocument<I>;
mostRecentScore: ScoreDocument<I>;
totalScores: number;
rankingData: {
ranking: integer;
outOf: integer;
};
rankingData: Record<
UGSRatingsLookup[I],
{
ranking: integer;
outOf: integer;
}
>;
}
export interface UGPTLeaderboardAdjacent {