mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-03 04:18:16 +03:00
feat: just a bunch of cleanup
- no deduping, ui improvements, general fixups
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import React, { Fragment } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { GetGameConfig } from "tachi-common";
|
||||
|
||||
export function Breadcrumbs({ items }: { items: string[] }) {
|
||||
const url = location.pathname;
|
||||
@@ -12,17 +13,28 @@ export function Breadcrumbs({ items }: { items: string[] }) {
|
||||
<Link className="opacity-75 hover-opacity-100" to="/">
|
||||
<i className="flaticon2-shelter text-white icon-1x" />
|
||||
</Link>
|
||||
{items.map((name, index) => (
|
||||
<Fragment key={index}>
|
||||
<span className="label label-dot label-sm bg-white opacity-75 mx-3" />
|
||||
<Link
|
||||
className="text-white text-hover-white opacity-75 hover-opacity-100"
|
||||
to={`/${parts.slice(0, index + 1).join("/")}`}
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
</Fragment>
|
||||
))}
|
||||
{items.map((name, index) => {
|
||||
// Skip playtype in the breadcrumbs if the game only has one playtype.
|
||||
// @hack
|
||||
// this only works if the game has one playtype called "Single".
|
||||
// Some games (like pop'n) have one playtype, but it's called
|
||||
// 9B. They'll just have to cope.
|
||||
if (items[index - 2] === "Games" && name === "Single") {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment key={index}>
|
||||
<span className="label label-dot label-sm bg-white opacity-75 mx-3" />
|
||||
<Link
|
||||
className="text-white text-hover-white opacity-75 hover-opacity-100"
|
||||
to={`/${parts.slice(0, index + 1).join("/")}`}
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -129,6 +129,10 @@ function SessionScoreStatBreakdown({
|
||||
Record<Grades[IDStrings], { score: ScoreDocument; scoreInfo: SessionScoreInfo }[]>
|
||||
> = {};
|
||||
|
||||
// dedupe grades/lamps for repeat plays
|
||||
const isBestGradeThisSession = new Map();
|
||||
const isBestLampThisSession = new Map();
|
||||
|
||||
for (const scoreInfo of sessionData.session.scoreInfo) {
|
||||
const score = scoreMap.get(scoreInfo.scoreID);
|
||||
|
||||
@@ -139,15 +143,51 @@ function SessionScoreStatBreakdown({
|
||||
continue;
|
||||
}
|
||||
|
||||
const g = isBestGradeThisSession.get(score.chartID);
|
||||
const l = isBestLampThisSession.get(score.chartID);
|
||||
|
||||
// if we haven't saw this chart before
|
||||
// or the score we have saw for this chart before had a worse grade
|
||||
if (!g || (g.scoreData.gradeIndex && g < score.scoreData.gradeIndex)) {
|
||||
isBestGradeThisSession.set(score.chartID, score);
|
||||
}
|
||||
|
||||
// same but for lamp
|
||||
if (!l || (l.scoreData.lampIndex && l < score.scoreData.lampIndex)) {
|
||||
isBestLampThisSession.set(score.chartID, score);
|
||||
}
|
||||
}
|
||||
|
||||
for (const scoreInfo of sessionData.session.scoreInfo) {
|
||||
const score = scoreMap.get(scoreInfo.scoreID);
|
||||
|
||||
if (!score) {
|
||||
console.error(
|
||||
`Session score info contains scoreID ${scoreInfo.scoreID}, but no score exists?`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const wasBestLamp = isBestLampThisSession.get(score.chartID)?.scoreID === score.scoreID;
|
||||
const wasBestGrade =
|
||||
isBestGradeThisSession.get(score.chartID)?.scoreID === score.scoreID;
|
||||
|
||||
if (scoreInfo.isNewScore) {
|
||||
PartialArrayRecordAssign(newLamps, score.scoreData.lamp, { score, scoreInfo });
|
||||
PartialArrayRecordAssign(newGrades, score.scoreData.grade, { score, scoreInfo });
|
||||
if (wasBestLamp) {
|
||||
PartialArrayRecordAssign(newLamps, score.scoreData.lamp, { score, scoreInfo });
|
||||
}
|
||||
if (wasBestGrade) {
|
||||
PartialArrayRecordAssign(newGrades, score.scoreData.grade, {
|
||||
score,
|
||||
scoreInfo,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (scoreInfo.lampDelta > 0) {
|
||||
if (scoreInfo.lampDelta > 0 && wasBestLamp) {
|
||||
PartialArrayRecordAssign(newLamps, score.scoreData.lamp, { score, scoreInfo });
|
||||
}
|
||||
|
||||
if (scoreInfo.gradeDelta > 0) {
|
||||
if (scoreInfo.gradeDelta > 0 && wasBestLamp) {
|
||||
PartialArrayRecordAssign(newGrades, score.scoreData.grade, {
|
||||
score,
|
||||
scoreInfo,
|
||||
|
||||
@@ -17,7 +17,12 @@ export default function SelectableRanking({
|
||||
} & ZTableTHProps) {
|
||||
const { settings } = useLUGPTSettings();
|
||||
|
||||
if (rankingViewMode === "both-if-self" || rankingViewMode === "global-no-switch" || !settings) {
|
||||
if (
|
||||
rankingViewMode === "both-if-self" ||
|
||||
rankingViewMode === "global-no-switch" ||
|
||||
!settings ||
|
||||
settings.rivals.length === 0
|
||||
) {
|
||||
return (
|
||||
<SortableTH
|
||||
changeSort={changeSort}
|
||||
|
||||
@@ -53,7 +53,7 @@ export default function ImportDropdown({ data }: { data: ImportDataset[0] }) {
|
||||
{currentUser?.id === data.userID && (
|
||||
<SelectButton setValue={setView} value={view} id="manage">
|
||||
<Icon type="trash" />
|
||||
Manage Import
|
||||
Revert Import
|
||||
</SelectButton>
|
||||
)}
|
||||
<HasDevModeOn>
|
||||
|
||||
@@ -166,18 +166,18 @@ export default function ScoreDropdown<I extends IDStrings = IDStrings>({
|
||||
Goals & Quests{targetData && ` (${targetData.goals.length})`}
|
||||
</SelectButton>
|
||||
)}
|
||||
{currentUser?.id === user.id && (
|
||||
<SelectButton setValue={setView} value={view} id="manage">
|
||||
<Icon type="trash" />
|
||||
Manage Score
|
||||
</SelectButton>
|
||||
)}
|
||||
{currentUser && (
|
||||
<SelectButton setValue={setView} value={view} id="rivals">
|
||||
<Icon type="users" />
|
||||
Rivals
|
||||
</SelectButton>
|
||||
)}
|
||||
{currentUser?.id === user.id && (
|
||||
<SelectButton setValue={setView} value={view} id="manage">
|
||||
<Icon type="trash" />
|
||||
Delete Score
|
||||
</SelectButton>
|
||||
)}
|
||||
<HasDevModeOn>
|
||||
<SelectButton setValue={setView} value={view} id="debug">
|
||||
<Icon type="bug" />
|
||||
|
||||
@@ -41,10 +41,7 @@ function Row({ data }: { data: ImportDataset[0] }) {
|
||||
return (
|
||||
<DropdownRow dropdown={<ImportDropdown data={data} />}>
|
||||
<td>
|
||||
<Link
|
||||
className="gentle-link"
|
||||
to={`/u/${data.__related.user.username}`}
|
||||
>
|
||||
<Link className="gentle-link" to={`/u/${data.__related.user.username}`}>
|
||||
{data.__related.user.username}
|
||||
</Link>
|
||||
</td>
|
||||
|
||||
@@ -19,7 +19,7 @@ export default function ImportViewerOptions({
|
||||
<>
|
||||
<Card header="Options">
|
||||
<Select
|
||||
name="Made with intent (i.e. not by an automated hook or IR)"
|
||||
name="Made with user intent (i.e. not an automatic upload by an IR or hook)"
|
||||
allowNull
|
||||
unselectedName="Either"
|
||||
setValue={setUserIntent}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Game, GetGamePTConfig } from "tachi-common";
|
||||
import { Playtype } from "tachi-common";
|
||||
import { Game, GetGamePTConfig, Playtype } from "tachi-common";
|
||||
import useLUGPTSettings from "./useLUGPTSettings";
|
||||
|
||||
export function useBucket(game: Game, playtype: Playtype) {
|
||||
|
||||
Reference in New Issue
Block a user