Web frontend: perf panel, cover warmup, incremental browse rendering

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-21 11:42:33 +02:00
parent 9fd106b757
commit 2db4368fc9
24 changed files with 1178 additions and 255 deletions

View File

@@ -122,4 +122,20 @@ export const api = {
request<TippenRunResult>("/tippen/runs", { method: "POST", body: JSON.stringify(body) }),
};
export const coverUrl = (albumId: string) => `/api/albums/${albumId}/cover`;
/** Cover URL. `thumb` is the small file for cards and rows; only the play view needs
* `full`. With a `version` (`Album.cover_v`) the URL names one exact set of bytes and the
* server marks it immutable, so the browser never asks for it twice; without one it
* revalidates on every use. */
export function coverUrl(
albumId: string,
{ size = "full", version }: { size?: "thumb" | "full"; version?: number } = {},
): string {
const params: string[] = [];
if (size === "thumb") params.push("size=thumb");
if (version) params.push(`v=${version}`);
return `/api/albums/${albumId}/cover${params.length ? `?${params.join("&")}` : ""}`;
}
/** Largest `Cover` `size` (CSS px) that is served the thumbnail; the play view's 340 gets
* the full file. Keep in step with `THUMB_COVER_PX` in the backend's `library/cache.py`. */
export const THUMB_MAX_SIZE = 220;