Fix display of failed-to-load image attachments in web UI (#34217)

This commit is contained in:
Eugen Rochko 2025-03-21 11:23:49 +01:00 committed by GitHub
parent a2981a0997
commit 1960aac90b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 2 deletions

View File

@ -38,6 +38,7 @@ class Item extends PureComponent {
state = { state = {
loaded: false, loaded: false,
error: false,
}; };
handleMouseEnter = (e) => { handleMouseEnter = (e) => {
@ -81,6 +82,10 @@ class Item extends PureComponent {
this.setState({ loaded: true }); this.setState({ loaded: true });
}; };
handleImageError = () => {
this.setState({ error: true });
};
render () { render () {
const { attachment, lang, index, size, standalone, displayWidth, visible } = this.props; const { attachment, lang, index, size, standalone, displayWidth, visible } = this.props;
@ -148,6 +153,7 @@ class Item extends PureComponent {
lang={lang} lang={lang}
style={{ objectPosition: `${x}% ${y}%` }} style={{ objectPosition: `${x}% ${y}%` }}
onLoad={this.handleImageLoad} onLoad={this.handleImageLoad}
onError={this.handleImageError}
/> />
</a> </a>
); );
@ -183,7 +189,7 @@ class Item extends PureComponent {
} }
return ( return (
<div className={classNames('media-gallery__item', { standalone, 'media-gallery__item--tall': height === 100, 'media-gallery__item--wide': width === 100 })} key={attachment.get('id')}> <div className={classNames('media-gallery__item', { standalone, 'media-gallery__item--error': this.state.error, 'media-gallery__item--tall': height === 100, 'media-gallery__item--wide': width === 100 })} key={attachment.get('id')}>
<Blurhash <Blurhash
hash={attachment.get('blurhash')} hash={attachment.get('blurhash')}
dummy={!useBlurhash} dummy={!useBlurhash}

View File

@ -26,11 +26,16 @@ export const MediaItem: React.FC<{
displayMedia === 'show_all', displayMedia === 'show_all',
); );
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
const [error, setError] = useState(false);
const handleImageLoad = useCallback(() => { const handleImageLoad = useCallback(() => {
setLoaded(true); setLoaded(true);
}, [setLoaded]); }, [setLoaded]);
const handleImageError = useCallback(() => {
setError(true);
}, [setError]);
const handleMouseEnter = useCallback( const handleMouseEnter = useCallback(
(e: React.MouseEvent<HTMLVideoElement>) => { (e: React.MouseEvent<HTMLVideoElement>) => {
if (e.target instanceof HTMLVideoElement) { if (e.target instanceof HTMLVideoElement) {
@ -98,6 +103,7 @@ export const MediaItem: React.FC<{
alt={description} alt={description}
lang={lang} lang={lang}
onLoad={handleImageLoad} onLoad={handleImageLoad}
onError={handleImageError}
/> />
<div className='media-gallery__item__overlay media-gallery__item__overlay--corner'> <div className='media-gallery__item__overlay media-gallery__item__overlay--corner'>
@ -118,6 +124,7 @@ export const MediaItem: React.FC<{
lang={lang} lang={lang}
style={{ objectPosition: `${x}% ${y}%` }} style={{ objectPosition: `${x}% ${y}%` }}
onLoad={handleImageLoad} onLoad={handleImageLoad}
onError={handleImageError}
/> />
); );
} else if (['video', 'gifv'].includes(type)) { } else if (['video', 'gifv'].includes(type)) {
@ -173,7 +180,11 @@ export const MediaItem: React.FC<{
} }
return ( return (
<div className='media-gallery__item media-gallery__item--square'> <div
className={classNames('media-gallery__item media-gallery__item--square', {
'media-gallery__item--error': error,
})}
>
<Blurhash <Blurhash
hash={blurhash} hash={blurhash}
className={classNames('media-gallery__preview', { className={classNames('media-gallery__preview', {

View File

@ -6902,6 +6902,10 @@ a.status-card {
filter: var(--overlay-icon-shadow); filter: var(--overlay-icon-shadow);
} }
} }
&--error img {
visibility: hidden;
}
} }
.media-gallery__item-thumbnail { .media-gallery__item-thumbnail {