Fetch image_ids lazily with first image, remove from initial cards load
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-05-15 22:18:04 +02:00
parent 42d1981da9
commit f24bd7a93b
3 changed files with 37 additions and 36 deletions
+26 -29
View File
@@ -45,14 +45,14 @@ function HomePage() {
useEffect(() => {
if (!expandedCardId) return;
const card = cards.find(c => c.id === expandedCardId);
if (!card) return;
const imageId = card.image_ids?.[artworkIndex];
if (!imageId || cardImages[expandedCardId]?.[artworkIndex]) return;
const imageIds = cardImages[expandedCardId]?.ids;
const imageId = imageIds?.[artworkIndex];
if (cardImages[expandedCardId]?.blobs[artworkIndex]) return;
// imageId may be undefined on first load (ids not yet fetched)
fetchCardImage(expandedCardId, imageId)
.then(image => setCardImage(expandedCardId, artworkIndex, image))
.then(({ image, image_ids }) => setCardImage(expandedCardId, artworkIndex, image, image_ids))
.catch(err => console.error('Failed to load card image', err));
}, [expandedCardId, artworkIndex, cards, cardImages, setCardImage]);
}, [expandedCardId, artworkIndex, cardImages, setCardImage]);
const getTotal = useCallback((card) =>
card.printings?.reduce((sum, p) => {
@@ -134,30 +134,27 @@ function HomePage() {
<div style={{ flex: 1, padding: '16px', overflowY: 'auto', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '10px' }}>
{expandedCard ? (
<>
<div style={{ position: 'relative', width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
{cardImages[expandedCardId]?.[artworkIndex] ? (
<img src={cardImages[expandedCardId][artworkIndex]} alt={expandedCard.name} style={{ maxWidth: '100%' }} />
) : (
<div style={{ color: '#444', fontSize: '12px', padding: '2rem' }}>Loading image</div>
)}
{(expandedCard.image_ids?.length ?? 0) > 1 && (
<div style={{ position: 'absolute', bottom: '6px', display: 'flex', alignItems: 'center', gap: '8px' }}>
<button
className="icon-btn"
onClick={() => setArtworkIndex(i => Math.max(0, i - 1))}
disabled={artworkIndex === 0}
></button>
<span style={{ fontSize: '11px', color: '#555' }}>
{artworkIndex + 1} / {expandedCard.image_ids.length}
</span>
<button
className="icon-btn"
onClick={() => setArtworkIndex(i => Math.min(expandedCard.image_ids.length - 1, i + 1))}
disabled={artworkIndex === expandedCard.image_ids.length - 1}
></button>
{(() => {
const imgs = cardImages[expandedCardId];
const blob = imgs?.blobs[artworkIndex];
const ids = imgs?.ids ?? [];
return (
<div style={{ position: 'relative', width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
{blob ? (
<img src={blob} alt={expandedCard.name} style={{ maxWidth: '100%' }} />
) : (
<div style={{ color: '#444', fontSize: '12px', padding: '2rem' }}>Loading image</div>
)}
{ids.length > 1 && (
<div style={{ position: 'absolute', bottom: '6px', display: 'flex', alignItems: 'center', gap: '8px' }}>
<button className="icon-btn" onClick={() => setArtworkIndex(i => Math.max(0, i - 1))} disabled={artworkIndex === 0}></button>
<span style={{ fontSize: '11px', color: '#555' }}>{artworkIndex + 1} / {ids.length}</span>
<button className="icon-btn" onClick={() => setArtworkIndex(i => Math.min(ids.length - 1, i + 1))} disabled={artworkIndex === ids.length - 1}></button>
</div>
)}
</div>
)}
</div>
);
})()}
<div style={{ width: '100%', borderTop: '1px solid #222', paddingTop: '10px', display: 'flex', flexDirection: 'column', gap: '5px' }}>
<span style={{ fontSize: '15px', fontWeight: 600, color: '#e0e0e0' }}>{expandedCard.name}</span>
<div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>