mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-11 08:48:15 +03:00
feat: set default rival or global rankings
This commit is contained in:
@@ -236,6 +236,7 @@ function ScoreLeaderboard({ game, playtype }: GamePT) {
|
||||
showChart
|
||||
indexCol
|
||||
alg={alg}
|
||||
defaultRankingViewMode="both-if-self"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
UnsuccessfulAPIResponse,
|
||||
} from "tachi-common";
|
||||
import { GamePT, SetState } from "types/react";
|
||||
import usePreferredRanking from "components/util/usePreferredRanking";
|
||||
|
||||
export default function ScoresPage({
|
||||
reqUser,
|
||||
@@ -177,6 +178,8 @@ function PBsOverview({
|
||||
|
||||
const { data, error } = useFetchPBs(url, reqUser);
|
||||
|
||||
const preferredRanking = usePreferredRanking();
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
@@ -195,7 +198,8 @@ function PBsOverview({
|
||||
showPlaycount={showPlaycount}
|
||||
indexCol={indexCol}
|
||||
alg={alg}
|
||||
playtype={playtype as "SP" | "DP"}
|
||||
playtype={playtype}
|
||||
defaultRankingViewMode={preferredRanking}
|
||||
/>
|
||||
</LoadingWrapper>
|
||||
) : (
|
||||
|
||||
@@ -104,6 +104,7 @@ function PreferencesForm({ reqUser, game, playtype }: Props) {
|
||||
gameSpecific: settings!.preferences.gameSpecific as any,
|
||||
defaultTable: settings!.preferences.defaultTable,
|
||||
scoreBucket: settings!.preferences.scoreBucket ?? gptConfig.scoreBucket,
|
||||
preferredRanking: settings!.preferences.preferredRanking ?? "global",
|
||||
},
|
||||
onSubmit: async (values) => {
|
||||
const rj = await APIFetchV1<PublicUserDocument>(
|
||||
@@ -221,6 +222,21 @@ function PreferencesForm({ reqUser, game, playtype }: Props) {
|
||||
breakdown. You can still view all the same stats!
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
<Form.Group>
|
||||
<Form.Label>Preferred Ranking</Form.Label>
|
||||
<Form.Control
|
||||
as="select"
|
||||
id="preferredRanking"
|
||||
value={formik.values.preferredRanking}
|
||||
onChange={formik.handleChange}
|
||||
>
|
||||
<option value="global">Global Rankings</option>
|
||||
<option value="rival">Rival Rankings</option>
|
||||
</Form.Control>
|
||||
<Form.Text className="text-muted">
|
||||
What should {TachiConfig.name} default to when showing your score rankings?
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
<Form.Group>
|
||||
<Form.Label>Preferred Table</Form.Label>
|
||||
<Form.Control
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { NumericSOV, StrSOV } from "util/sorts";
|
||||
import { CreateDefaultFolderSearchParams } from "util/tables/create-search";
|
||||
import Muted from "components/util/Muted";
|
||||
import usePreferredRanking from "components/util/usePreferredRanking";
|
||||
import useScoreRatingAlg from "components/util/useScoreRatingAlg";
|
||||
import React, { useState } from "react";
|
||||
import { Game, IDStrings, ScoreCalculatedDataLookup } from "tachi-common";
|
||||
import { FolderDataset } from "types/tables";
|
||||
import { Playtype } from "types/tachi";
|
||||
import Muted from "components/util/Muted";
|
||||
import useLUGPTSettings from "components/util/useLUGPTSettings";
|
||||
import DifficultyCell from "../cells/DifficultyCell";
|
||||
import IndicatorsCell from "../cells/IndicatorsCell";
|
||||
import RankingCell, { RankingViewMode } from "../cells/RankingCell";
|
||||
@@ -33,10 +33,12 @@ export default function FolderTable<I extends IDStrings = IDStrings>({
|
||||
}) {
|
||||
const defaultRating = useScoreRatingAlg(game, playtype);
|
||||
|
||||
const { settings } = useLUGPTSettings();
|
||||
const preferredRanking = usePreferredRanking();
|
||||
|
||||
const [rating, setRating] = useState(defaultRating);
|
||||
const [rankingViewMode, setRankingViewMode] = useState<RankingViewMode>("global");
|
||||
const [rankingViewMode, setRankingViewMode] = useState<RankingViewMode>(
|
||||
preferredRanking ?? "global"
|
||||
);
|
||||
|
||||
const headers: Header<FolderDataset[0]>[] = [
|
||||
ChartHeader(game, (k) => k),
|
||||
|
||||
@@ -40,7 +40,7 @@ export default function PBTable<I extends IDStrings = IDStrings>({
|
||||
playtype: Playtype;
|
||||
game: Game;
|
||||
alg?: ScoreCalculatedDataLookup[I];
|
||||
defaultRankingViewMode?: RankingViewMode;
|
||||
defaultRankingViewMode?: RankingViewMode | null;
|
||||
}) {
|
||||
const defaultRating = useScoreRatingAlg(game, playtype);
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { UGPTSettings } from "tachi-common";
|
||||
import useLUGPTSettings from "./useLUGPTSettings";
|
||||
|
||||
export default function usePreferredRanking():
|
||||
| UGPTSettings["preferences"]["preferredRanking"]
|
||||
| null {
|
||||
const { settings } = useLUGPTSettings();
|
||||
|
||||
return settings?.preferences.preferredRanking ?? null;
|
||||
}
|
||||
@@ -1471,6 +1471,7 @@ export interface UGPTSettings<I extends IDStrings = IDStrings> extends MongoDBDo
|
||||
stats: Array<ShowcaseStatDetails>;
|
||||
scoreBucket: "grade" | "lamp" | null;
|
||||
defaultTable: string | null;
|
||||
preferredRanking: "global" | "rival" | null;
|
||||
gameSpecific: UGPTSpecificPreferences[I];
|
||||
};
|
||||
rivals: Array<integer>;
|
||||
|
||||
@@ -43,6 +43,7 @@ export async function CreateGameSettings(userID: integer, game: Game, playtype:
|
||||
preferredScoreAlg: null,
|
||||
scoreBucket: null,
|
||||
defaultTable: null,
|
||||
preferredRanking: null,
|
||||
stats: [],
|
||||
gameSpecific,
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import UGPTAddPreferredRanking from "./migrations/add-preferredRanking-to-ugpt";
|
||||
import UGPTRivalsMigration from "./migrations/add-rivals-to-ugpt";
|
||||
import RecalcBrokenIIDXNotecounts from "./migrations/recalc-broken-iidx-notecounts";
|
||||
import RemoveIIDXBeginners from "./migrations/remove-iidx-beginners";
|
||||
@@ -27,7 +28,7 @@ export const FAKE_MIGRATION: Migration = {
|
||||
const REGISTERED_MIGRATIONS: Array<Migration> =
|
||||
Environment.nodeEnv === "test"
|
||||
? [FAKE_MIGRATION]
|
||||
: [UGPTRivalsMigration, RemoveMultifolderStats];
|
||||
: [UGPTRivalsMigration, RemoveMultifolderStats, UGPTAddPreferredRanking];
|
||||
|
||||
// only apply type-specific migrations if we're not in testing
|
||||
if (Environment.nodeEnv !== "test") {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import db from "external/mongo/db";
|
||||
import type { Migration } from "utils/types";
|
||||
|
||||
const migration: Migration = {
|
||||
id: "add-preferredRanking-to-ugpt",
|
||||
up: async () => {
|
||||
await db["game-settings"].update(
|
||||
{},
|
||||
{
|
||||
$set: {
|
||||
"preferences.preferredRanking": null,
|
||||
},
|
||||
},
|
||||
{ multi: true }
|
||||
);
|
||||
},
|
||||
down: async () => {
|
||||
await db["game-settings"].update(
|
||||
{},
|
||||
{
|
||||
$unset: { "preferences.preferredRanking": 1 },
|
||||
},
|
||||
{ multi: true }
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default migration;
|
||||
@@ -53,6 +53,7 @@ router.patch(
|
||||
preferredSessionAlg: p.optional(p.nullable(p.isIn(gptConfig.sessionRatingAlgs))),
|
||||
preferredProfileAlg: p.optional(p.nullable(p.isIn(gptConfig.profileRatingAlgs))),
|
||||
defaultTable: "*?string",
|
||||
preferredRanking: optNull(p.isIn("global", "rival")),
|
||||
|
||||
// This is handled with game-specific schema validation below.
|
||||
gameSpecific: optNull(gameSpecificSchema),
|
||||
@@ -104,6 +105,10 @@ router.patch(
|
||||
updateQuery[`preferences.defaultTable`] = body.defaultTable;
|
||||
}
|
||||
|
||||
if (body.preferredRanking !== undefined) {
|
||||
updateQuery[`preferences.preferredRanking`] = body.preferredRanking;
|
||||
}
|
||||
|
||||
if (body.gameSpecific) {
|
||||
for (const [key, value] of Object.entries(body.gameSpecific)) {
|
||||
// @ts-expect-error This is a very hacky way of applying changes.
|
||||
|
||||
Reference in New Issue
Block a user