mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-03 20:38:17 +03:00
fix: make bms/pms use normal sorting on tables (#1519)
This commit is contained in:
@@ -86,6 +86,9 @@ RUN apt-get update \
|
||||
gh \
|
||||
# MinIO CLI (binary is `minio-client`, not Midnight Commander's `mc`)
|
||||
minio-client \
|
||||
# `xdg-open` so the client vite plugin can launch a browser without
|
||||
# crashing on missing binary (see typescript/client/vite.config.ts).
|
||||
xdg-utils \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV DEBIAN_FRONTEND=readline
|
||||
|
||||
+2
-2
@@ -123,9 +123,9 @@ export default function TableEvolutionReplay({
|
||||
const folderSlugOrder = useMemo(
|
||||
() =>
|
||||
scope.kind === "table"
|
||||
? tableFolderSlugsDisplayOrder(scope.table)
|
||||
? tableFolderSlugsDisplayOrder(scope.table, game)
|
||||
: [scope.folder.slug],
|
||||
[scope],
|
||||
[scope, game],
|
||||
);
|
||||
|
||||
const scrubRef = useRef(0);
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ export default function TableFolderList({
|
||||
|
||||
const dataset = useMemo(() => {
|
||||
const arr = [];
|
||||
for (const folder of tableFolderSlugsDisplayOrder(table)) {
|
||||
for (const folder of tableFolderSlugsDisplayOrder(table, game)) {
|
||||
const data = dataMap.get(folder);
|
||||
|
||||
if (!data) {
|
||||
@@ -56,7 +56,7 @@ export default function TableFolderList({
|
||||
}
|
||||
|
||||
return arr;
|
||||
}, [dataMap, table]);
|
||||
}, [dataMap, table, game]);
|
||||
|
||||
const { user } = useContext(UserContext);
|
||||
|
||||
|
||||
+13
-3
@@ -1,5 +1,6 @@
|
||||
import type { FolderStatsInfo, TableEvolutionEventAPI } from "#types/api-returns";
|
||||
|
||||
import { GPT_CLIENT_IMPLEMENTATIONS } from "#lib/game-implementations";
|
||||
import {
|
||||
type FolderDocument,
|
||||
type GameConfig,
|
||||
@@ -20,9 +21,18 @@ export interface UGPTFolderStats {
|
||||
stats: FolderStatsInfo;
|
||||
}
|
||||
|
||||
/** API `table.folders` is ascending (e.g. Level 1 … 12); show highest folder / level first in chart + table. */
|
||||
export function tableFolderSlugsDisplayOrder(table: TableDocument): string[] {
|
||||
return [...table.folders].reverse();
|
||||
/**
|
||||
* Resolve the order folder slugs should be rendered for `table` in `game`.
|
||||
*
|
||||
* `table.folders` is ascending (e.g. Level 1 … 12), and by default we reverse so the
|
||||
* highest folder / level renders first. Games can opt out via `reverseFolderOrder` on
|
||||
* their GPT client impl, in which case we reverse again — i.e. render in the table's
|
||||
* declared order (currently used for BMS/PMS).
|
||||
*/
|
||||
export function tableFolderSlugsDisplayOrder(table: TableDocument, game: V3Game): string[] {
|
||||
const reverseAgain = GPT_CLIENT_IMPLEMENTATIONS[game].reverseFolderOrder ?? false;
|
||||
|
||||
return reverseAgain ? [...table.folders] : [...table.folders].reverse();
|
||||
}
|
||||
|
||||
export function evoEventTimeMs(ev: TableEvolutionEventAPI): number {
|
||||
|
||||
@@ -14,6 +14,7 @@ import { bgc, CreateRatingSys } from "./_util";
|
||||
|
||||
const BASE_IMPL: GPTClientImplementation<GamesForGroup["bms" | "pms"]> = {
|
||||
sessionImportantScoreCount: 20,
|
||||
reverseFolderOrder: true,
|
||||
difficultyColours: {
|
||||
CHART: COLOUR_SET.gray, // lol
|
||||
},
|
||||
|
||||
@@ -148,4 +148,12 @@ export interface GPTClientImplementation<GPT extends V3Game = V3Game> {
|
||||
* display?
|
||||
*/
|
||||
sessionImportantScoreCount: integer;
|
||||
|
||||
/**
|
||||
* By default folders are rendered in reverse of `table.folders` (so the highest
|
||||
* level / hardest folder shows first). Set this to flip that back — folders will
|
||||
* then be rendered in the order declared by the table. Used for games like BMS/PMS
|
||||
* where the table is already authored in the order the UI should display.
|
||||
*/
|
||||
reverseFolderOrder?: boolean;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ function openLoopbackInBrowserPlugin(): Plugin {
|
||||
useHttps: boolean,
|
||||
) => {
|
||||
if (!httpServer) return;
|
||||
// Opt out for headless dev containers / CI where no browser opener exists.
|
||||
if (process.env.TACHI_NO_OPEN === "1" || process.env.CI) return;
|
||||
const run = () => {
|
||||
const addr = httpServer.address();
|
||||
const port =
|
||||
@@ -29,17 +31,21 @@ function openLoopbackInBrowserPlugin(): Plugin {
|
||||
: (portFallback ?? 3000);
|
||||
const protocol = useHttps ? "https" : "http";
|
||||
const url = `${protocol}://localhost:${port}/`;
|
||||
if (process.platform === "darwin") {
|
||||
spawn("open", [url], { detached: true, stdio: "ignore" }).unref();
|
||||
} else if (process.platform === "win32") {
|
||||
spawn("cmd", ["/c", "start", "", url], {
|
||||
detached: true,
|
||||
stdio: "ignore",
|
||||
shell: false,
|
||||
}).unref();
|
||||
} else {
|
||||
spawn("xdg-open", [url], { detached: true, stdio: "ignore" }).unref();
|
||||
}
|
||||
const [cmd, args]: [string, string[]] =
|
||||
process.platform === "darwin"
|
||||
? ["open", [url]]
|
||||
: process.platform === "win32"
|
||||
? ["cmd", ["/c", "start", "", url]]
|
||||
: ["xdg-open", [url]];
|
||||
const child = spawn(cmd, args, {
|
||||
detached: true,
|
||||
stdio: "ignore",
|
||||
shell: false,
|
||||
});
|
||||
// Without this, a missing opener binary (e.g. no xdg-open in a dev
|
||||
// container) emits an unhandled 'error' event and crashes vite.
|
||||
child.on("error", () => {});
|
||||
child.unref();
|
||||
};
|
||||
if (httpServer.listening) run();
|
||||
else httpServer.once("listening", run);
|
||||
|
||||
Reference in New Issue
Block a user