u
This commit is contained in:
@@ -1,119 +1,82 @@
|
||||
import { PureComponent } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import ThumbHashImage, { getThumbHashDimensions } from '../article/ThumbHashImage';
|
||||
import brandAutomat from '../../automats/brandAutomat';
|
||||
import ThumbHashImage from '../article/ThumbHashImage';
|
||||
import {
|
||||
SHADOW_THUMB_RING,
|
||||
TINT_ROW_HOVER,
|
||||
} from '../../colors';
|
||||
|
||||
/**
|
||||
* Extracts thumbHash from various brand representations:
|
||||
* - Direct thumbHash / thumbhash property
|
||||
* - Brand with pics array (e.g. brand.pics[0].thumbHash)
|
||||
* - Brand by name or id looked up in brandAutomat.state.brands
|
||||
*/
|
||||
export function extractBrandThumbInfo(brand, thumbHashOverride) {
|
||||
if (thumbHashOverride) {
|
||||
const dims = getThumbHashDimensions(thumbHashOverride);
|
||||
return {
|
||||
thumbHash: thumbHashOverride,
|
||||
thumbW: dims?.w ?? null,
|
||||
thumbH: dims?.h ?? null,
|
||||
};
|
||||
}
|
||||
export default class BrandThumb extends PureComponent {
|
||||
render() {
|
||||
const {
|
||||
brand,
|
||||
size = 20,
|
||||
fallback = null,
|
||||
sx,
|
||||
} = this.props;
|
||||
const pic = brand?.pics?.[0];
|
||||
|
||||
if (!brand) return null;
|
||||
if (!pic?.thumbHash) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
// Direct thumbHash on brand object
|
||||
let hash = brand.thumbHash ?? brand.thumbhash;
|
||||
let thumbW = brand.thumbW ?? brand.thumbw;
|
||||
let thumbH = brand.thumbH ?? brand.thumbh;
|
||||
|
||||
// Check pics array
|
||||
if (!hash && Array.isArray(brand.pics) && brand.pics.length > 0) {
|
||||
const firstPic = brand.pics[0];
|
||||
hash = firstPic?.thumbHash ?? firstPic?.thumbhash;
|
||||
thumbW = firstPic?.thumbW ?? firstPic?.thumbw;
|
||||
thumbH = firstPic?.thumbH ?? firstPic?.thumbh;
|
||||
}
|
||||
|
||||
// Fallback: look up in brandAutomat
|
||||
if (!hash) {
|
||||
const brands = brandAutomat.state?.brands;
|
||||
if (Array.isArray(brands)) {
|
||||
const id = typeof brand === 'object' ? brand.id : (typeof brand === 'number' ? brand : null);
|
||||
const name = typeof brand === 'object' ? brand.name : (typeof brand === 'string' ? brand : null);
|
||||
const found = brands.find(
|
||||
(b) =>
|
||||
(id != null && b.id === id) ||
|
||||
(name && String(b.name || '').trim().toLowerCase() === String(name).trim().toLowerCase())
|
||||
);
|
||||
if (found) {
|
||||
hash = found.thumbHash ?? found.thumbhash ?? found.pics?.[0]?.thumbHash ?? found.pics?.[0]?.thumbhash;
|
||||
thumbW = found.thumbW ?? found.thumbw ?? found.pics?.[0]?.thumbW ?? found.pics?.[0]?.thumbw;
|
||||
thumbH = found.thumbH ?? found.thumbh ?? found.pics?.[0]?.thumbH ?? found.pics?.[0]?.thumbh;
|
||||
const { thumbHash, thumbW, thumbH } = pic;
|
||||
const ratio = thumbW && thumbH ? thumbW / thumbH : 1;
|
||||
// Contain-fit inside a square `size x size` box, preserving aspect ratio.
|
||||
let innerW = size;
|
||||
let innerH = size;
|
||||
if (Number.isFinite(ratio) && ratio > 0) {
|
||||
if (ratio >= 1) {
|
||||
innerW = size;
|
||||
innerH = Math.max(1, Math.round(size / ratio));
|
||||
} else {
|
||||
innerH = size;
|
||||
innerW = Math.max(1, Math.round(size * ratio));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
component="span"
|
||||
sx={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: size,
|
||||
width: size,
|
||||
minWidth: size,
|
||||
maxWidth: size,
|
||||
flexShrink: 0,
|
||||
verticalAlign: 'middle',
|
||||
lineHeight: 0,
|
||||
my: 0,
|
||||
boxSizing: 'border-box',
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="span"
|
||||
sx={{
|
||||
display: 'block',
|
||||
width: innerW,
|
||||
height: innerH,
|
||||
borderRadius: size >= 24 ? '4px' : '3px',
|
||||
overflow: 'hidden',
|
||||
flexShrink: 0,
|
||||
lineHeight: 0,
|
||||
boxSizing: 'border-box',
|
||||
bgcolor: TINT_ROW_HOVER,
|
||||
boxShadow: SHADOW_THUMB_RING,
|
||||
}}
|
||||
>
|
||||
<ThumbHashImage
|
||||
thumbHash={thumbHash}
|
||||
width={innerW}
|
||||
height={innerH}
|
||||
sx={{ width: innerW, height: innerH, flexShrink: 0 }}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (!hash) return null;
|
||||
|
||||
if (thumbW == null || thumbH == null) {
|
||||
const dims = getThumbHashDimensions(hash);
|
||||
if (dims) {
|
||||
thumbW = dims.w;
|
||||
thumbH = dims.h;
|
||||
}
|
||||
}
|
||||
|
||||
return { thumbHash: hash, thumbW, thumbH };
|
||||
}
|
||||
|
||||
export default function BrandThumb({
|
||||
brand,
|
||||
thumbHash: thumbHashProp,
|
||||
size = 20,
|
||||
fallback = null,
|
||||
sx,
|
||||
}) {
|
||||
const info = extractBrandThumbInfo(brand, thumbHashProp);
|
||||
|
||||
if (!info?.thumbHash) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const { thumbHash, thumbW, thumbH } = info;
|
||||
const ratio = (thumbW && thumbH) ? (thumbW / thumbH) : 1;
|
||||
const calcWidth = Math.round(size * Math.max(0.6, Math.min(ratio, 2.5)));
|
||||
|
||||
return (
|
||||
<Box
|
||||
component="span"
|
||||
sx={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: size,
|
||||
width: calcWidth,
|
||||
minWidth: Math.round(size * 0.6),
|
||||
maxWidth: Math.round(size * 2.5),
|
||||
borderRadius: size >= 24 ? '4px' : '3px',
|
||||
overflow: 'hidden',
|
||||
flexShrink: 0,
|
||||
verticalAlign: 'middle',
|
||||
lineHeight: 0,
|
||||
my: 0,
|
||||
boxSizing: 'border-box',
|
||||
bgcolor: TINT_ROW_HOVER,
|
||||
boxShadow: SHADOW_THUMB_RING,
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
<ThumbHashImage
|
||||
thumbHash={thumbHash}
|
||||
width={calcWidth}
|
||||
height={size}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { default as BrandThumb, extractBrandThumbInfo } from './BrandThumb';
|
||||
export { default as BrandThumb } from './BrandThumb';
|
||||
export { default as BrandLabel } from './BrandLabel';
|
||||
export { default as BrandImageSearchDialog } from './BrandImageSearchDialog';
|
||||
export { default as ArtikelMarke } from './ArtikelMarke';
|
||||
|
||||
Reference in New Issue
Block a user