Merge branch 'fallback-group-images' into 'develop'

Handle errors on Group Headers

See merge request soapbox-pub/soapbox!2465
This commit is contained in:
Chewbacca 2023-04-24 16:20:25 +00:00
commit c5151417d1
2 changed files with 18 additions and 6 deletions

View File

@ -16,10 +16,12 @@ interface IStillImage {
letterboxed?: boolean letterboxed?: boolean
/** Whether to show the file extension in the corner. */ /** Whether to show the file extension in the corner. */
showExt?: boolean showExt?: boolean
/** Callback function if the image fails to load */
onError?(): void
} }
/** Renders images on a canvas, only playing GIFs if autoPlayGif is enabled. */ /** Renders images on a canvas, only playing GIFs if autoPlayGif is enabled. */
const StillImage: React.FC<IStillImage> = ({ alt, className, src, style, letterboxed = false, showExt = false }) => { const StillImage: React.FC<IStillImage> = ({ alt, className, src, style, letterboxed = false, showExt = false, onError }) => {
const settings = useSettings(); const settings = useSettings();
const autoPlayGif = settings.get('autoPlayGif'); const autoPlayGif = settings.get('autoPlayGif');
@ -55,6 +57,7 @@ const StillImage: React.FC<IStillImage> = ({ alt, className, src, style, letterb
alt={alt} alt={alt}
ref={img} ref={img}
onLoad={handleImageLoad} onLoad={handleImageLoad}
onError={onError}
className={clsx(baseClassName, { className={clsx(baseClassName, {
'invisible group-hover:visible': hoverToPlay, 'invisible group-hover:visible': hoverToPlay,
})} })}

View File

@ -1,11 +1,11 @@
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
import React from 'react'; import React, { useState } from 'react';
import { defineMessages, useIntl } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import { openModal } from 'soapbox/actions/modals'; import { openModal } from 'soapbox/actions/modals';
import GroupAvatar from 'soapbox/components/groups/group-avatar'; import GroupAvatar from 'soapbox/components/groups/group-avatar';
import StillImage from 'soapbox/components/still-image'; import StillImage from 'soapbox/components/still-image';
import { HStack, Stack, Text } from 'soapbox/components/ui'; import { HStack, Icon, Stack, Text } from 'soapbox/components/ui';
import { useAppDispatch } from 'soapbox/hooks'; import { useAppDispatch } from 'soapbox/hooks';
import { normalizeAttachment } from 'soapbox/normalizers'; import { normalizeAttachment } from 'soapbox/normalizers';
import { isDefaultHeader } from 'soapbox/utils/accounts'; import { isDefaultHeader } from 'soapbox/utils/accounts';
@ -30,6 +30,8 @@ const GroupHeader: React.FC<IGroupHeader> = ({ group }) => {
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [isHeaderMissing, setIsHeaderMissing] = useState<boolean>(false);
if (!group) { if (!group) {
return ( return (
<div className='-mx-4 -mt-4 sm:-mx-6 sm:-mt-6'> <div className='-mx-4 -mt-4 sm:-mx-6 sm:-mt-6'>
@ -88,20 +90,27 @@ const GroupHeader: React.FC<IGroupHeader> = ({ group }) => {
<StillImage <StillImage
src={group.header} src={group.header}
alt={intl.formatMessage(messages.header)} alt={intl.formatMessage(messages.header)}
className='h-32 w-full bg-gray-200 object-center dark:bg-gray-900/50 md:rounded-t-xl lg:h-52' className='relative h-32 w-full bg-gray-200 object-center dark:bg-gray-900/50 md:rounded-t-xl lg:h-52'
onError={() => setIsHeaderMissing(true)}
/> />
); );
if (!isDefaultHeader(group.header)) { if (!isDefaultHeader(group.header)) {
header = ( header = (
<a href={group.header} onClick={handleHeaderClick} target='_blank'> <a href={group.header} onClick={handleHeaderClick} target='_blank' className='relative'>
{header} {header}
</a> </a>
); );
} }
} }
return header; return (
<div className='flex h-32 w-full items-center justify-center bg-gray-200 dark:bg-gray-800/30 md:rounded-t-xl lg:h-52'>
{isHeaderMissing ? (
<Icon src={require('@tabler/icons/photo-off.svg')} className='h-6 w-6 text-gray-500 dark:text-gray-700' />
) : header}
</div>
);
}; };
return ( return (