More big updates (just incase hdd dies or something)

This commit is contained in:
zkldi
2021-07-29 19:15:24 +01:00
parent 3a80c4ac93
commit bc6d4e4d60
16 changed files with 404 additions and 40 deletions
+14 -2
View File
@@ -33,12 +33,24 @@ export default function TimelineChart({
style={{ height: mobileHeight, width: mobileWidth }}
>
<div className="d-flex h-100 justify-content-center align-items-center">
Not Enough Data... Yet.
<div className="text-center">
Not Enough Data... Yet.
<br />
<small className="text-muted">
(You need atleast 7 days worth of data)
</small>
</div>
</div>
</div>
<div className="d-none d-md-block" style={{ height, width }}>
<div className="d-flex h-100 justify-content-center align-items-center">
Not Enough Data... Yet.
<div className="text-center">
Not Enough Data... Yet.
<br />
<small className="text-muted">
(You need atleast 7 days worth of data)
</small>
</div>
</div>
</div>
</>
+50
View File
@@ -0,0 +1,50 @@
import QuickTooltip from "components/layout/misc/QuickTooltip";
import React from "react";
import { Badge } from "react-bootstrap";
import { GetGamePTConfig, IDStrings, integer } from "tachi-common";
import { GameClassSets } from "tachi-common/js/game-classes";
import { GamePT } from "types/react";
import { UppercaseFirst } from "util/misc";
export default function ClassBadge<I extends IDStrings = IDStrings>({
game,
playtype,
classSet,
classValue,
showSetOnHover = true,
}: {
classSet: GameClassSets[I];
classValue: integer;
showSetOnHover?: boolean;
} & GamePT) {
const gptConfig = GetGamePTConfig(game, playtype);
const data = gptConfig.classHumanisedFormat[classSet][classValue];
if (!data) {
throw new Error(`Unknown class value ${classSet}:${classValue}`);
}
let badgeComponent;
if (data.variant) {
badgeComponent = <Badge variant={data.variant}>{data.display}</Badge>;
} else if (data.css) {
badgeComponent = <Badge style={data.css}>{data.display}</Badge>;
} else {
badgeComponent = <Badge variant="secondary">{data.display}</Badge>;
}
if (data.mouseover && showSetOnHover) {
return (
<QuickTooltip text={`${UppercaseFirst(classSet)}: ${data.mouseover}`}>
{badgeComponent}
</QuickTooltip>
);
} else if (data.mouseover) {
return <QuickTooltip text={data.mouseover}>{badgeComponent}</QuickTooltip>;
} else if (showSetOnHover) {
<QuickTooltip text={UppercaseFirst(classSet)}>{badgeComponent}</QuickTooltip>;
}
return badgeComponent;
}
@@ -17,7 +17,11 @@ export function Footer() {
</div>
<div className="nav nav-dark order-1 order-md-2 justify-content-center">
<Link to="/dashboard/credits" className="nav-link px-3">
<Link
to="/dashboard/credits"
className="nav-link px-3"
onClick={() => window.scrollTo(0, 0)}
>
Credits
</Link>
<a
@@ -21,5 +21,5 @@ export default function AllGames() {
}
}
return <MenuDropdown name="All Games">{links}</MenuDropdown>;
return <MenuDropdown name="Games">{links}</MenuDropdown>;
}
@@ -66,7 +66,7 @@ export function HeaderMenu() {
{/* <MenuLink name="Dashboard" to="/dashboard" /> */}
{user && ugs && ugs.length !== 0 && (
<MenuDropdown name="My Games">
<MenuDropdown name="Your Profiles">
{ugs.map(e => (
<MenuLink
key={`${e.game}:${e.playtype}`}
@@ -10,7 +10,9 @@ export default function MiniTable({
colSpan = 1,
}: { className?: string; headers: string[]; colSpan?: integer } & JustChildren) {
return (
<table className={`table table-hover table-striped ${className}`}>
<table
className={`table table-hover table-striped table-vertical-center text-center ${className}`}
>
<thead>
<tr>
{headers.map(e => (
@@ -7,7 +7,7 @@ import { ChangeOpacity } from "util/color-opacity";
import { NumericSOV, StrSOV } from "util/sorts";
import SelectableRating from "../components/SelectableRating";
import { ScoreDataset } from "types/tables";
import { GetGamePTConfig, ScoreCalculatedDataLookup } from "tachi-common";
import { GetGamePTConfig, integer, ScoreCalculatedDataLookup } from "tachi-common";
import TachiTable, { Header } from "../components/TachiTable";
import DifficultyCell from "../cells/DifficultyCell";
import ScoreCell from "../cells/ScoreCell";
@@ -15,7 +15,13 @@ import DeltaCell from "../cells/DeltaCell";
import { HumanFriendlyStrToGradeIndex, HumanFriendlyStrToLampIndex } from "util/str-to-num";
import { nanoid } from "nanoid";
export default function IIDXScoreTable({ dataset }: { dataset: ScoreDataset<"iidx:SP"> }) {
export default function IIDXScoreTable({
dataset,
pageLen,
}: {
dataset: ScoreDataset<"iidx:SP">;
pageLen?: integer;
}) {
const gptConfig = GetGamePTConfig<"iidx:SP">("iidx", "SP");
const [rating, setRating] = useState<ScoreCalculatedDataLookup["iidx:SP"]>(
@@ -25,6 +31,7 @@ export default function IIDXScoreTable({ dataset }: { dataset: ScoreDataset<"iid
return (
<TachiTable
dataset={dataset}
pageLen={pageLen}
headers={[
["Chart", "Ch.", NumericSOV(x => x.__related.chart.levelNum)],
["Song", "Song", StrSOV(x => x.__related.song.title)],
@@ -85,7 +92,27 @@ export default function IIDXScoreTable({ dataset }: { dataset: ScoreDataset<"iid
>
<strong>{sc.scoreData.lamp}</strong>
<br />
<small>[BP: {sc.scoreData.hitMeta.bp ?? "No Data"}]</small>
<small>
[BP: {sc.scoreData.hitMeta.bp ?? "No Data"}
{sc.scoreData.hitMeta.comboBreak
? `, CBRK: ${sc.scoreData.hitMeta.comboBreak}`
: ""}
]
</small>
{sc.scoreData.lamp === "FAILED" && (
<>
<br />
<small className="text-muted">
{sc.scoreData.hitMeta.gsm
? `EC: ${sc.scoreData.hitMeta.gsm.EASY}, NC: ${sc.scoreData.hitMeta.gsm.NORMAL}`
: sc.scoreMeta.gauge === "EASY"
? `EC: ${sc.scoreData.hitMeta.gauge}`
: sc.scoreMeta.gauge === "NORMAL"
? `NC: ${sc.scoreMeta.gauge}`
: ""}
</small>
</>
)}
</td>
{rating === "BPI" ? (
<BPICell bpi={sc.calculatedData.BPI} />
@@ -9,6 +9,7 @@ import {
SessionScoreInfo,
} from "tachi-common";
import { Playtype } from "types/tachi";
import { GetPBs } from "util/data";
import { NumericSOV, StrSOV } from "util/sorts";
import { FormatDuration, FormatTime, MillisToSince } from "util/time";
import IndexCell from "../cells/IndexCell";
@@ -87,7 +88,3 @@ export default function GenericSessionTable({
/>
);
}
function GetPBs(scoreInfo: SessionScoreInfo[]) {
return scoreInfo.map(e => e.isNewScore === true || e.lampDelta > 0 || e.scoreDelta > 0);
}
+23 -7
View File
@@ -1,13 +1,15 @@
import MiniTable from "components/tables/components/MiniTable";
import Divider from "components/util/Divider";
import React from "react";
import { Game, GetGameConfig, PublicUserDocument } from "tachi-common";
import { Game, GetGameConfig, GetGamePTConfig, PublicUserDocument } from "tachi-common";
import { UGPTStatsReturn } from "types/api-returns";
import { Playtype } from "types/tachi";
import { MillisToSince } from "util/time";
import ProfilePicture from "./ProfilePicture";
import Navbar from "components/nav/Navbar";
import NavItem from "components/nav/NavItem";
import ClassBadge from "components/game/ClassBadge";
import { UppercaseFirst } from "util/misc";
export default function UGPTHeader({
reqUser,
@@ -21,6 +23,7 @@ export default function UGPTHeader({
stats: UGPTStatsReturn;
}) {
const gameConfig = GetGameConfig(game);
const gptConfig = GetGamePTConfig(game, playtype);
return (
<div className="row">
@@ -77,18 +80,31 @@ export default function UGPTHeader({
colSpan={2}
>
<>
{gptConfig.supportedClasses.map(k => (
<tr key={k}>
<td>{UppercaseFirst(k)}</td>
<td>
{stats.gameStats.classes[k] ? (
<ClassBadge
showSetOnHover={false}
key={`${k}:${stats.gameStats.classes[k]}`}
game={game}
playtype={playtype}
classSet={k}
classValue={stats.gameStats.classes[k]!}
/>
) : (
"No Data"
)}
</td>
</tr>
))}
{Object.entries(stats.gameStats.ratings).map(([k, v]) => (
<tr key={k}>
<td>{k}</td>
<td>{v.toFixed(2)}</td>
</tr>
))}
{Object.entries(stats.gameStats.classes).map(([k, v]) => (
<tr key={k}>
<td>{k}</td>
<td>{v}</td>
</tr>
))}
</>
</MiniTable>
</div>
+1 -1
View File
@@ -9,7 +9,7 @@ export default function AsyncLoader<T = unknown>({
}: {
promiseFn?: () => Promise<T>;
promise?: Promise<T>;
children: (data: T) => JSX.Element;
children: (data: T) => JSX.Element | null | string | (JSX.Element | string)[];
}) {
const Component = children;
return (