117 lines
3.4 KiB
JavaScript
117 lines
3.4 KiB
JavaScript
import Box from '@mui/material/Box';
|
|
import ThumbHashImage, { getThumbHashDimensions } from '../article/ThumbHashImage';
|
|
import brandAutomat from '../../automats/brandAutomat';
|
|
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,
|
|
};
|
|
}
|
|
|
|
if (!brand) return null;
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
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',
|
|
bgcolor: TINT_ROW_HOVER,
|
|
boxShadow: SHADOW_THUMB_RING,
|
|
...sx,
|
|
}}
|
|
>
|
|
<ThumbHashImage
|
|
thumbHash={thumbHash}
|
|
width={calcWidth}
|
|
height={size}
|
|
/>
|
|
</Box>
|
|
);
|
|
}
|