0
0
Fork 0

Add support for fediverse:creator OpenGraph tag (#30398)

This commit is contained in:
Eugen Rochko 2024-05-29 01:34:33 +02:00 committed by GitHub
parent 4a77e477ee
commit 128987eded
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 105 additions and 15 deletions

View file

@ -6,6 +6,8 @@ import { PureComponent } from 'react';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import Immutable from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
@ -13,6 +15,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import DescriptionIcon from '@/material-icons/400-24px/description-fill.svg?react';
import OpenInNewIcon from '@/material-icons/400-24px/open_in_new.svg?react';
import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react';
import { Avatar } from 'mastodon/components/avatar';
import { Blurhash } from 'mastodon/components/blurhash';
import { Icon } from 'mastodon/components/icon';
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
@ -56,6 +59,20 @@ const addAutoPlay = html => {
return html;
};
const MoreFromAuthor = ({ author }) => (
<div className='more-from-author'>
<svg viewBox='0 0 79 79' className='logo logo--icon' role='img'>
<use xlinkHref='#logo-symbol-icon' />
</svg>
<FormattedMessage id='link_preview.more_from_author' defaultMessage='More from {name}' values={{ name: <Link to={`/@${author.get('acct')}`}><Avatar account={author} size={16} /> {author.get('display_name')}</Link> }} />
</div>
);
MoreFromAuthor.propTypes = {
author: ImmutablePropTypes.map,
};
export default class Card extends PureComponent {
static propTypes = {
@ -136,6 +153,7 @@ export default class Card extends PureComponent {
const interactive = card.get('type') === 'video';
const language = card.get('language') || '';
const largeImage = (card.get('image')?.length > 0 && card.get('width') > card.get('height')) || interactive;
const showAuthor = !!card.get('author_account');
const description = (
<div className='status-card__content'>
@ -146,7 +164,7 @@ export default class Card extends PureComponent {
<strong className='status-card__title' title={card.get('title')} lang={language}>{card.get('title')}</strong>
{card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>}
{!showAuthor && (card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>)}
</div>
);
@ -235,10 +253,14 @@ export default class Card extends PureComponent {
}
return (
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
{embed}
{description}
</a>
<>
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage, bottomless: showAuthor })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
{embed}
{description}
</a>
{showAuthor && <MoreFromAuthor author={card.get('author_account')} />}
</>
);
}

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Show profile anyway",
"limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
"link_preview.author": "By {name}",
"link_preview.more_from_author": "More from {name}",
"lists.account.add": "Add to list",
"lists.account.remove": "Remove from list",
"lists.delete": "Delete list",

View file

@ -3896,6 +3896,10 @@ $ui-header-logo-wordmark-width: 99px;
border: 1px solid var(--background-border-color);
border-radius: 8px;
&.bottomless {
border-radius: 8px 8px 0 0;
}
&__actions {
bottom: 0;
inset-inline-start: 0;
@ -10223,3 +10227,42 @@ noscript {
}
}
}
.more-from-author {
font-size: 14px;
color: $darker-text-color;
background: var(--surface-background-color);
border: 1px solid var(--background-border-color);
border-top: 0;
border-radius: 0 0 8px 8px;
padding: 15px;
display: flex;
align-items: center;
gap: 8px;
.logo {
height: 16px;
color: $darker-text-color;
}
& > span {
display: flex;
align-items: center;
gap: 8px;
}
a {
display: inline-flex;
align-items: center;
gap: 4px;
font-weight: 500;
color: $primary-text-color;
text-decoration: none;
&:hover,
&:focus,
&:active {
color: $highlight-text-color;
}
}
}