Speed up timeline load with portrait thumbs, bootstrap API, and caching.
Add catalog bootstrap endpoint, portrait thumbnail pipeline, lazy queued timeline images, gzip compression, and 3D texture throttling with code-split VirtualGallery.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type {
|
||||
TimelineData,
|
||||
CatalogBootstrap,
|
||||
YearBounds,
|
||||
Artist,
|
||||
ArtistDetail,
|
||||
@@ -62,13 +63,25 @@ export function portraitUrl(path: string | null | undefined, revision?: number):
|
||||
return `${base}${base.includes('?') ? '&' : '?'}v=${revision}`;
|
||||
}
|
||||
|
||||
/** Image for 3D gallery — local cached files only (API fetch is too slow for realtime 3D) */
|
||||
/** Small portrait for timeline / movement flow (~256px). Falls back to full portrait. */
|
||||
export function portraitThumbUrl(
|
||||
artist: {
|
||||
portrait_thumb_path?: string | null;
|
||||
portrait_path?: string | null;
|
||||
},
|
||||
revision?: number
|
||||
): string {
|
||||
const path = artist.portrait_thumb_path || artist.portrait_path;
|
||||
return portraitUrl(path, revision);
|
||||
}
|
||||
|
||||
/** Image for 3D gallery — prefer thumbnail for faster texture loads */
|
||||
export function galleryImageUrl(painting: {
|
||||
thumbnail_path?: string | null;
|
||||
image_path?: string | null;
|
||||
}): string | null {
|
||||
if (painting.image_path) return `/images/${painting.image_path}`;
|
||||
if (painting.thumbnail_path) return `/images/${painting.thumbnail_path}`;
|
||||
if (painting.image_path) return `/images/${painting.image_path}`;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -202,6 +215,14 @@ export interface PaintingCheckupData {
|
||||
export const api = {
|
||||
getBounds: () => fetchJson<YearBounds>(`${API}/bounds`),
|
||||
|
||||
getCatalogBootstrap: (start?: number, end?: number) => {
|
||||
const params = new URLSearchParams();
|
||||
if (start != null) params.set('start', String(start));
|
||||
if (end != null) params.set('end', String(end));
|
||||
const qs = params.toString();
|
||||
return fetchJson<CatalogBootstrap>(`${API}/catalog/bootstrap${qs ? `?${qs}` : ''}`);
|
||||
},
|
||||
|
||||
getTimeline: (start: number, end: number) =>
|
||||
fetchJson<TimelineData>(`${API}/timeline?start=${start}&end=${end}`),
|
||||
|
||||
@@ -345,6 +366,8 @@ export const api = {
|
||||
}
|
||||
return res.json() as Promise<{ checked: boolean; fixed: boolean }>;
|
||||
}),
|
||||
|
||||
preloadArtistImages,
|
||||
};
|
||||
|
||||
export function debugImageProxyUrl(
|
||||
|
||||
Reference in New Issue
Block a user