Add support for fediverse:creator OpenGraph tag (#30398)
		
	This commit is contained in:
		
					parent
					
						
							
								4a77e477ee
							
						
					
				
			
			
				commit
				
					
						128987eded
					
				
			
		
					 11 changed files with 105 additions and 15 deletions
				
			
		|  | @ -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')} />} | ||||
|       </> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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", | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue