This commit is contained in:
seb
2026-08-01 02:08:39 +02:00
parent 6d720d34ed
commit 4ea593a0c8
7 changed files with 211 additions and 33 deletions

View File

@@ -1,28 +1,90 @@
import { Component } from 'react';
import Box from '@mui/material/Box';
import { thumb } from '../../api';
import ThumbHashImage from './ThumbHashImage';
export default function ArticlePhoto({ imageUrl }) {
return (
<Box
sx={{
width: 200,
height: 200,
maxWidth: '100%',
borderRadius: 2,
overflow: 'hidden',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
bgcolor: imageUrl ? 'transparent' : 'action.hover',
}}
>
{imageUrl ? (
<Box
component="img"
src={imageUrl}
alt=""
sx={{ width: '100%', height: '100%', objectFit: 'contain' }}
/>
) : null}
</Box>
);
class ArticlePhoto extends Component {
constructor(props) {
super(props);
this.state = { thumbLoaded: false };
this.handleThumbLoad = this.handleThumbLoad.bind(this);
this.handleThumbError = this.handleThumbError.bind(this);
}
componentDidUpdate(prevProps) {
if (prevProps.photo?.fullHash !== this.props.photo?.fullHash) {
this.setState({ thumbLoaded: false });
}
}
handleThumbLoad() {
this.setState({ thumbLoaded: true });
}
handleThumbError() {
this.setState({ thumbLoaded: false });
}
render() {
const { photo } = this.props;
const { thumbLoaded } = this.state;
const fullHash = photo?.fullHash;
const hasPreview = photo?.thumbHash != null;
const aspectRatio =
photo?.thumbW != null && photo?.thumbH != null
? `${photo.thumbW} / ${photo.thumbH}`
: '1 / 1';
return (
<Box
sx={{
position: 'relative',
width: 200,
height: 200,
maxWidth: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 2,
overflow: 'hidden',
bgcolor: 'rgba(0, 0, 0, 0.35)',
}}
>
{hasPreview && !thumbLoaded ? (
<Box
sx={{
position: 'absolute',
maxWidth: '100%',
maxHeight: '100%',
aspectRatio,
width: photo.thumbW >= photo.thumbH ? '100%' : 'auto',
height: photo.thumbH > photo.thumbW ? '100%' : 'auto',
}}
>
<ThumbHashImage thumbHash={photo.thumbHash} />
</Box>
) : null}
{fullHash ? (
<Box
component="img"
src={thumb.url(fullHash)}
alt=""
onLoad={this.handleThumbLoad}
onError={this.handleThumbError}
sx={{
display: 'block',
maxWidth: '100%',
maxHeight: '100%',
width: 'auto',
height: 'auto',
objectFit: 'contain',
opacity: thumbLoaded ? 1 : 0,
}}
/>
) : null}
</Box>
);
}
}
export default ArticlePhoto;