~cytrogen/masto-fe

8131a5b330c6fb20ca9aa5cd1ba04c7f9ddc33d2 — Eugen Rochko 2 years ago 6693a4f
Add ALT badges to media that has alternative text in web UI (#24782)

M app/javascript/mastodon/components/media_gallery.jsx => app/javascript/mastodon/components/media_gallery.jsx +15 -42
@@ 81,12 81,10 @@ class Item extends React.PureComponent {
  render () {
    const { attachment, lang, index, size, standalone, displayWidth, visible } = this.props;

    let badges = [], thumbnail;

    let width  = 50;
    let height = 100;
    let top    = 'auto';
    let left   = 'auto';
    let bottom = 'auto';
    let right  = 'auto';

    if (size === 1) {
      width = 100;


@@ 96,45 94,13 @@ class Item extends React.PureComponent {
      height = 50;
    }

    if (size === 2) {
      if (index === 0) {
        right = '2px';
      } else {
        left = '2px';
      }
    } else if (size === 3) {
      if (index === 0) {
        right = '2px';
      } else if (index > 0) {
        left = '2px';
      }

      if (index === 1) {
        bottom = '2px';
      } else if (index > 1) {
        top = '2px';
      }
    } else if (size === 4) {
      if (index === 0 || index === 2) {
        right = '2px';
      }

      if (index === 1 || index === 3) {
        left = '2px';
      }

      if (index < 2) {
        bottom = '2px';
      } else {
        top = '2px';
      }
    if (attachment.get('description')?.length > 0) {
      badges.push(<span key='alt' className='media-gallery__gifv__label'>ALT</span>);
    }

    let thumbnail = '';

    if (attachment.get('type') === 'unknown') {
      return (
        <div className={classNames('media-gallery__item', { standalone })} key={attachment.get('id')} style={{ left: left, top: top, right: right, bottom: bottom, width: `${width}%`, height: `${height}%` }}>
        <div className={classNames('media-gallery__item', { standalone, 'media-gallery__item--tall': height === 100, 'media-gallery__item--wide': width === 100 })} key={attachment.get('id')}>
          <a className='media-gallery__item-thumbnail' href={attachment.get('remote_url') || attachment.get('url')} style={{ cursor: 'pointer' }} title={attachment.get('description')} lang={lang} target='_blank' rel='noopener noreferrer'>
            <Blurhash
              hash={attachment.get('blurhash')}


@@ 184,6 150,8 @@ class Item extends React.PureComponent {
    } else if (attachment.get('type') === 'gifv') {
      const autoPlay = this.getAutoPlay();

      badges.push(<span key='gif' className='media-gallery__gifv__label'>GIF</span>);

      thumbnail = (
        <div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}>
          <video


@@ 201,14 169,12 @@ class Item extends React.PureComponent {
            loop
            muted
          />

          <span className='media-gallery__gifv__label'>GIF</span>
        </div>
      );
    }

    return (
      <div className={classNames('media-gallery__item', { standalone })} key={attachment.get('id')} style={{ left: left, top: top, right: right, bottom: bottom, width: `${width}%`, height: `${height}%` }}>
      <div className={classNames('media-gallery__item', { standalone, 'media-gallery__item--tall': height === 100, 'media-gallery__item--wide': width === 100 })} key={attachment.get('id')}>
        <Blurhash
          hash={attachment.get('blurhash')}
          dummy={!useBlurhash}


@@ 216,7 182,14 @@ class Item extends React.PureComponent {
            'media-gallery__preview--hidden': visible && this.state.loaded,
          })}
        />

        {visible && thumbnail}

        {badges && (
          <div className='media-gallery__item__badges'>
            {badges}
          </div>
        )}
      </div>
    );
  }

M app/javascript/styles/mastodon/components.scss => app/javascript/styles/mastodon/components.scss +23 -17
@@ 6330,32 6330,27 @@ a.status-card.compact:hover {
  z-index: 9999;
}

.media-gallery__gifv__label {
  display: block;
.media-gallery__item__badges {
  position: absolute;
  color: $primary-text-color;
  background: rgba($base-overlay-background, 0.5);
  bottom: 6px;
  inset-inline-start: 6px;
  display: flex;
  gap: 2px;
}

.media-gallery__gifv__label {
  display: block;
  color: $white;
  background: rgba($black, 0.65);
  padding: 2px 6px;
  border-radius: 2px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  font-weight: 700;
  z-index: 1;
  pointer-events: none;
  opacity: 0.9;
  transition: opacity 0.1s ease;
  line-height: 18px;
}

.media-gallery__gifv {
  &:hover {
    .media-gallery__gifv__label {
      opacity: 1;
    }
  }
}

.attachment-list {
  display: flex;
  font-size: 14px;


@@ 6428,17 6423,28 @@ a.status-card.compact:hover {
  position: relative;
  width: 100%;
  min-height: 64px;
  display: grid;
  grid-template-columns: 50% 50%;
  grid-template-rows: 50% 50%;
  gap: 2px;
}

.media-gallery__item {
  border: 0;
  box-sizing: border-box;
  display: block;
  float: left;
  position: relative;
  border-radius: 4px;
  overflow: hidden;

  &--tall {
    grid-row: span 2;
  }

  &--wide {
    grid-column: span 2;
  }

  &.standalone {
    .media-gallery__item-gifv-thumbnail {
      transform: none;