feat: HG mode - změna obrázků, animace v modálech
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Successful in 27s
CI / Build server (push) Successful in 29s
CI / Build client (push) Successful in 43s
CI / Playwright E2E tests (push) Successful in 2m2s
CI / Build and push Docker image (push) Successful in 45s
CI / Notify (push) Successful in 2s
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Successful in 27s
CI / Build server (push) Successful in 29s
CI / Build client (push) Successful in 43s
CI / Playwright E2E tests (push) Successful in 2m2s
CI / Build and push Docker image (push) Successful in 45s
CI / Notify (push) Successful in 2s
This commit is contained in:
1 parent
5147651e7c
commit
2a54a1d41f
7 files changed
+198
-2
No files matched your search
+18
-1
@@ -278,6 +278,15 @@ export const UMA_CHARACTERS: { name: string, quote?: string, round?: boolean, im
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Obrázky stylu Hell Girl — plamen (jednorázová animace při otevření dialogu a změně dne)
|
||||
* a symbol ohně ze znělky (ozdoba u titulku dne). Cachují se stejně jako obrázky postav.
|
||||
*/
|
||||
const HELLGIRL_IMAGES = {
|
||||
flame: 'https://www.jigokutsushin.it/images/flame.gif',
|
||||
symbol: 'https://images.seeklogo.com/logo-png/6/1/hell-girl-fire-symbol-logo-png_seeklogo-66173.png',
|
||||
};
|
||||
|
||||
/** Po neúspěšném stažení obrázku se další pokus smí provést až po této době. */
|
||||
const RETRY_AFTER_MS = 10 * 60 * 1000;
|
||||
const MAX_IMAGE_BYTES = 2 * 1024 * 1024;
|
||||
@@ -290,7 +299,10 @@ const imageKey = (url: string) => `confetti_img_${imageId(url)}`;
|
||||
const imageUrl = (url: string) => `/api/confetti/image/${imageId(url)}`;
|
||||
|
||||
/** Povolené obrázky: ID → zdrojová URL (nic jiného server nestáhne). */
|
||||
const ALLOWED_IMAGES = new Map(UMA_CHARACTERS.flatMap(c => c.icon ? [...c.images, c.icon] : c.images).map(url => [imageId(url), url]));
|
||||
const ALLOWED_IMAGES = new Map([
|
||||
...UMA_CHARACTERS.flatMap(c => c.icon ? [...c.images, c.icon] : c.images),
|
||||
...Object.values(HELLGIRL_IMAGES),
|
||||
].map(url => [imageId(url), url]));
|
||||
const failedAt = new Map<string, number>();
|
||||
const inFlight = new Map<string, Promise<CachedImage | undefined>>();
|
||||
|
||||
@@ -305,6 +317,11 @@ export function getConfettiCharacters() {
|
||||
}));
|
||||
}
|
||||
|
||||
/** Obrázky stylu Hell Girl pro klienta — vedou na cachující proxy tohoto serveru. */
|
||||
export function getHellGirlImages() {
|
||||
return { flame: imageUrl(HELLGIRL_IMAGES.flame), symbol: imageUrl(HELLGIRL_IMAGES.symbol) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrátí obrázek konfet dle jeho ID. Poprvé ho stáhne a uloží do storage, další
|
||||
* požadavky (i při výpadku internetu) obslouží z cache. Stahují se jen URL ze seznamu výše.
|
||||
|
||||
+5
-1
@@ -29,7 +29,7 @@ import changelogRoutes from "./routes/changelogRoutes";
|
||||
import groupRoutes from "./routes/groupRoutes";
|
||||
import storeRoutes from "./routes/storeRoutes";
|
||||
import butterflyRoutes from "./routes/butterflyRoutes";
|
||||
import { getConfettiCharacters, getConfettiImage } from "./confetti";
|
||||
import { getConfettiCharacters, getConfettiImage, getHellGirlImages } from "./confetti";
|
||||
import { getTrustedRemoteUser, parseTrustedIps } from "./trustedHeaders";
|
||||
import { getGroupLimits } from "./limits";
|
||||
|
||||
@@ -222,6 +222,10 @@ app.get("/api/confetti/umamusume", (_req, res) => {
|
||||
res.set('Cache-Control', 'no-cache').json(getConfettiCharacters());
|
||||
});
|
||||
|
||||
app.get("/api/confetti/hellgirl", (_req, res) => {
|
||||
res.set('Cache-Control', 'no-cache').json(getHellGirlImages());
|
||||
});
|
||||
|
||||
app.get("/api/confetti/image/:id", async (req, res, next) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
|
||||
Reference in new issue
Block a user