feat: improve game group banner code (#1597)
@@ -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`;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 988 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 579 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
After Width: | Height: | Size: 330 KiB |
|
Before Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 396 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 489 KiB |
|
After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 230 KiB |
|
After Width: | Height: | Size: 293 KiB |
|
Before Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 286 KiB |
|
Before Width: | Height: | Size: 273 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 694 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 210 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 258 KiB |
|
After Width: | Height: | Size: 278 KiB |
|
Before Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 202 KiB |
|
Before Width: | Height: | Size: 294 KiB |
|
After Width: | Height: | Size: 260 KiB |