feat: improve game group banner code (#1597)

This commit is contained in:
zk
2026-05-26 22:27:44 +01:00
committed by GitHub
parent 388e6736c2
commit f7a973ca28
37 changed files with 57 additions and 3 deletions
@@ -3,6 +3,7 @@ import Divider from "#components/util/Divider";
import LinkButton from "#components/util/LinkButton";
import { TachiConfig } from "#lib/config";
import { ToCDNURL } from "#util/api";
import { DEFAULT_GAME_BANNER_REL_PATH } from "#util/game-group-banner-counts";
import React from "react";
// This page is currently unused,
@@ -17,7 +18,7 @@ export default function LandingPage() {
<div
className="hero-bg-image"
style={{
backgroundImage: `url(${ToCDNURL("/game-banners/default")})`,
backgroundImage: `url(${ToCDNURL(DEFAULT_GAME_BANNER_REL_PATH)})`,
}}
/>
<div
@@ -30,6 +30,7 @@ import { ToCDNURL } from "#util/api";
import { IsSupportedGame } from "#util/asserts";
import { ChangeOpacity } from "#util/color-opacity";
import { CreateChartLink } from "#util/data";
import { getGameGroupBannerRelPathForWeekday } from "#util/game-group-banner-counts";
import { SelectRightChart } from "#util/misc";
import { NumericSOV, StrSOV } from "#util/sorts";
import React, { useContext, useEffect, useState } from "react";
@@ -70,7 +71,7 @@ function V3GameRoutes() {
setBackground(null);
return;
}
setBackground(ToCDNURL(`/game-banners/${GameToGameGroup(gameParam)}`));
setBackground(ToCDNURL(getGameGroupBannerRelPathForWeekday(GameToGameGroup(gameParam))));
}, [gameParam, setBackground]);
if (!IsSupportedGame(gameParam)) {
@@ -1,5 +1,6 @@
import { BackgroundContext } from "#context/BackgroundContext";
import { ToCDNURL } from "#util/api";
import { DEFAULT_GAME_BANNER_REL_PATH } from "#util/game-group-banner-counts";
import React, { useContext, useEffect, useRef, useState } from "react";
import { type LayoutStyles } from "../Layout";
@@ -8,7 +9,7 @@ export default function BackgroundImage({ styles }: { styles: LayoutStyles }) {
const { background } = useContext(BackgroundContext);
const resolvedBg = background
? `url(${background})`
: `url(${ToCDNURL("/game-banners/default")})`;
: `url(${ToCDNURL(DEFAULT_GAME_BANNER_REL_PATH)})`;
const [committedBg, setCommittedBg] = useState(resolvedBg);
const [incomingBg, setIncomingBg] = useState<string | null>(null);
@@ -0,0 +1,51 @@
import type { GameGroup } from "tachi-common";
/** Fallback hero/background when no game is selected or a group has no variants. */
export const DEFAULT_GAME_BANNER_REL_PATH = "/game-banners/default.webp";
/**
* How many CDN banner variants exist per game group, named
* `{gameGroup}-{n}.webp` with `n` in `[1, count]` (one-based).
*
* Bump the count when new banner images are added for a group on the CDN.
*/
export const GAME_GROUP_BANNER_COUNTS = {
iidx: 1,
museca: 1,
chunithm: 1,
bms: 1,
gitadora: 1,
jubeat: 1,
maimai: 1,
maimaidx: 1,
popn: 1,
sdvx: 1,
usc: 1,
wacca: 1,
pms: 1,
itg: 1,
arcaea: 1,
ongeki: 1,
ddr: 1,
} as const satisfies Record<GameGroup, number>;
export function getGameGroupBannerCount(gameGroup: GameGroup): number {
return GAME_GROUP_BANNER_COUNTS[gameGroup];
}
/**
* CDN-relative path for this group's banner. Picks `{gameGroup}-n.webp` where
* `n = ((local weekday from Date#getDay()) % count) + 1` — same backdrop all Sunday, etc.
*
* Bump GAME_GROUP_BANNER_COUNTS when adding images; weekdays cycle indices in `[1, count]`.
*/
export function getGameGroupBannerRelPathForWeekday(gameGroup: GameGroup): string {
const count = GAME_GROUP_BANNER_COUNTS[gameGroup];
if (count <= 0) {
return DEFAULT_GAME_BANNER_REL_PATH;
}
const weekday = new Date().getDay(); // 0 = Sunday … 6 = Saturday
const n = (weekday % count) + 1;
return `/game-banners/${gameGroup}-${n}.webp`;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 988 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 489 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 694 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB