[Glitch] Add server thumbnail alt text to frontend

Port 3473b8a65278783bc74ce2738aea98cca0c7a5ed to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
diondiondion 2026-04-24 12:28:04 +02:00 committed by Claire
parent 77955109ca
commit 2ab8d53694
5 changed files with 43 additions and 15 deletions

View File

@ -2,6 +2,8 @@ import { useState, useCallback, useRef, useId } from 'react';
import { FormattedMessage, useIntl } from 'react-intl';
import classNames from 'classnames';
import type {
OffsetValue,
UsePopperOptions,
@ -18,9 +20,10 @@ import classes from './styles.module.scss';
const offset = [0, 4] as OffsetValue;
const popperConfig = { strategy: 'fixed' } as UsePopperOptions;
export const AltTextBadge: React.FC<{ description: string }> = ({
description,
}) => {
export const AltTextBadge: React.FC<{
description: string;
className?: string;
}> = ({ description, className }) => {
const intl = useIntl();
const uniqueId = useId();
const popoverId = `${uniqueId}-popover`;
@ -48,7 +51,7 @@ export const AltTextBadge: React.FC<{ description: string }> = ({
<button
type='button'
ref={buttonRef}
className='media-gallery__alt__label'
className={classNames('media-gallery__alt__label', className)}
onClick={handleClick}
aria-expanded={open}
aria-controls={popoverId}

View File

@ -3,7 +3,7 @@ import { PureComponent } from 'react';
import { FormattedMessage, defineMessages } from 'react-intl';
import { Link } from 'react-router-dom';
import { NavLink } from 'react-router-dom';
import { connect } from 'react-redux';
@ -18,6 +18,7 @@ import { injectIntl } from './intl';
const messages = defineMessages({
aboutActiveUsers: { id: 'server_banner.about_active_users', defaultMessage: 'People using this server during the last 30 days (Monthly Active Users)' },
aboutThisServer: { id: 'server_banner.more_about_this_server', defaultMessage: 'More about this server'},
});
const mapStateToProps = state => ({
@ -47,9 +48,14 @@ class ServerBanner extends PureComponent {
<FormattedMessage id='server_banner.is_one_of_many' defaultMessage='{domain} is one of the many independent Mastodon servers you can use to participate in the fediverse.' values={{ domain: <strong>{domain}</strong>, mastodon: <a href='https://joinmastodon.org' target='_blank' rel='noopener'>Mastodon</a> }} />
</div>
<Link to='/about'>
<ServerHeroImage blurhash={server.getIn(['thumbnail', 'blurhash'])} src={server.getIn(['thumbnail', 'url'])} className='server-banner__hero' />
</Link>
<NavLink to='/about'>
<ServerHeroImage
blurhash={server.getIn(['thumbnail', 'blurhash'])}
src={server.getIn(['thumbnail', 'url'])}
alt={intl.formatMessage(messages.aboutThisServer)}
className='server-banner__hero'
/>
</NavLink>
<div className='server-banner__description'>
{isLoading ? (

View File

@ -2,9 +2,14 @@ import { useCallback, useState } from 'react';
import classNames from 'classnames';
import { Blurhash } from './blurhash';
import { AltTextBadge } from '../alt_text_badge';
import { Blurhash } from '../blurhash';
import classes from './styles.module.scss';
interface Props {
withAltBadge?: boolean;
alt: string;
src: string;
srcSet?: string;
blurhash?: string;
@ -12,9 +17,11 @@ interface Props {
}
export const ServerHeroImage: React.FC<Props> = ({
alt,
src,
srcSet,
blurhash,
withAltBadge,
className,
}) => {
const [loaded, setLoaded] = useState(false);
@ -24,12 +31,12 @@ export const ServerHeroImage: React.FC<Props> = ({
}, [setLoaded]);
return (
<div
className={classNames('image', { loaded }, className)}
role='presentation'
>
<div className={classNames('image', { loaded }, className)}>
{blurhash && <Blurhash hash={blurhash} className='image__preview' />}
<img src={src} srcSet={srcSet} alt='' onLoad={handleLoad} />
<img src={src} srcSet={srcSet} alt={alt} onLoad={handleLoad} />
{withAltBadge && alt && (
<AltTextBadge description={alt} className={classes.altBadge} />
)}
</div>
);
};

View File

@ -0,0 +1,5 @@
.altBadge {
position: absolute;
bottom: 8px;
inset-inline-end: 8px;
}

View File

@ -82,7 +82,14 @@ class About extends PureComponent {
<Column bindToDocument={!multiColumn} label={intl.formatMessage(messages.title)}>
<div className='scrollable about'>
<div className='about__header'>
<ServerHeroImage blurhash={server.getIn(['thumbnail', 'blurhash'])} src={server.getIn(['thumbnail', 'url'])} srcSet={server.getIn(['thumbnail', 'versions'])?.map((value, key) => `${value} ${key.replace('@', '')}`).join(', ')} className='about__header__hero' />
<ServerHeroImage
withAltBadge
alt={server.getIn(['thumbnail', 'description']) ?? ''}
blurhash={server.getIn(['thumbnail', 'blurhash'])}
src={server.getIn(['thumbnail', 'url'])}
srcSet={server.getIn(['thumbnail', 'versions'])?.map((value, key) => `${value} ${key.replace('@', '')}`).join(', ')}
className='about__header__hero'
/>
<h1>{isLoading ? <Skeleton width='10ch' /> : server.get('domain')}</h1>
<p><FormattedMessage id='about.powered_by' defaultMessage='Decentralized social media powered by {mastodon}' values={{ mastodon: <a href='https://joinmastodon.org' className='about__mail' target='_blank' rel='noopener'>Mastodon</a> }} /></p>
</div>