This commit is contained in:
seb
2026-10-04 09:37:09 +02:00
parent da318223c1
commit dd8566eabc
3 changed files with 284 additions and 281 deletions

View File

@@ -3,10 +3,15 @@ import Inventory2OutlinedIcon from '@mui/icons-material/Inventory2Outlined';
import Box from '@mui/material/Box';
import ButtonBase from '@mui/material/ButtonBase';
import Typography from '@mui/material/Typography';
import { Tile, tileBaseSx } from 'dashgui/tiles';
import { TILE_SIZE, Tile, tileBaseSx } from 'dashgui/tiles';
import { formatPrice } from '../../utils/price';
import { articleSku } from '../article/articleRoute';
import { getThumbHashDataUrl, getCachedImage, imageCache } from '../article/ThumbHashImage';
import {
getThumbHashDataUrl,
getCachedImage,
isImageLoaded,
markImageLoaded,
} from '../article/ThumbHashImage';
import { BrandLabel } from '../brand';
import { thumb } from '../../api';
@@ -103,7 +108,26 @@ class ArticleTileBackdrop extends PureComponent {
constructor(props) {
super(props);
this.thumbUrl = getThumbHashDataUrl(props.thumbHash);
this.img = getCachedImage(props.fullHash);
const fullHash = props.fullHash;
if (fullHash) {
const cached = getCachedImage(fullHash);
if (cached) {
this.img = cached;
} else {
const img = new Image();
img.onload = () => {
markImageLoaded(fullHash, img);
if (this.img === img) {
this.paint();
}
};
img.src = thumb.url(fullHash);
this.img = img;
if (img.complete && img.naturalWidth) {
markImageLoaded(fullHash, img);
}
}
}
}
componentDidMount() {
@@ -127,35 +151,37 @@ class ArticleTileBackdrop extends PureComponent {
loadImage() {
const { fullHash } = this.props;
if (fullHash) {
const cached = getCachedImage(fullHash);
if (cached) {
this.img = cached;
if (!fullHash) return;
const cached = getCachedImage(fullHash);
if (cached) {
this.img = cached;
this.paint();
return;
}
if (this.img && this.img.src === thumb.url(fullHash)) {
if (this.img.complete && this.img.naturalWidth) {
markImageLoaded(fullHash, this.img);
this.paint();
return;
}
const img = new Image();
img.onload = () => {
imageCache.set(fullHash, img);
if (this.img === img) {
this.paint();
}
};
img.src = thumb.url(fullHash);
this.img = img;
if (img.complete && img.naturalWidth) {
imageCache.set(fullHash, img);
return;
}
const img = new Image();
img.onload = () => {
markImageLoaded(fullHash, img);
if (this.img === img) {
this.paint();
return;
}
};
img.src = thumb.url(fullHash);
this.img = img;
if (img.complete && img.naturalWidth) {
markImageLoaded(fullHash, img);
this.paint();
}
}
setCanvas = (canvas) => {
this.canvasRef = canvas;
if (!this.img && this.props.fullHash) {
this.img = getCachedImage(this.props.fullHash);
}
if (canvas && typeof ResizeObserver !== 'undefined') {
this.observer?.disconnect();
this.observer = new ResizeObserver(() => this.paint());
@@ -168,16 +194,18 @@ class ArticleTileBackdrop extends PureComponent {
const canvas = this.canvasRef;
if (!canvas) return;
const rect = canvas.getBoundingClientRect();
const dstW = Math.round(rect.width);
const dstH = Math.round(rect.height);
const dstW = Math.round(rect.width) || canvas.clientWidth || TILE_SIZE;
const dstH = Math.round(rect.height) || canvas.clientHeight || TILE_SIZE;
if (!dstW || !dstH) return;
canvas.width = dstW;
canvas.height = dstH;
if (canvas.width !== dstW) canvas.width = dstW;
if (canvas.height !== dstH) canvas.height = dstH;
const ctx = canvas.getContext('2d');
if (!ctx) return;
const img = this.img || getCachedImage(this.props.fullHash);
const img = (this.img && this.img.complete && this.img.naturalWidth)
? this.img
: getCachedImage(this.props.fullHash);
if (img && img.complete && img.naturalWidth && img.naturalHeight) {
this.img = img;
drawContainedWithStretchedEdges(
@@ -192,7 +220,8 @@ class ArticleTileBackdrop extends PureComponent {
};
render() {
const hasCachedImage = Boolean(this.img && this.img.complete && this.img.naturalWidth);
const { fullHash } = this.props;
const showThumb = !isImageLoaded(fullHash) && Boolean(this.thumbUrl);
return (
<Box
sx={{
@@ -203,7 +232,7 @@ class ArticleTileBackdrop extends PureComponent {
overflow: 'hidden',
}}
>
{!hasCachedImage && this.thumbUrl ? (
{showThumb ? (
<Box
component="img"
src={this.thumbUrl}