Add type annotation for DisplayName component (#24752)
This commit is contained in:
		
					parent
					
						
							
								ab7716cff4
							
						
					
				
			
			
				commit
				
					
						349cae0b57
					
				
			
		
					 17 changed files with 130 additions and 94 deletions
				
			
		|  | @ -1,7 +1,7 @@ | |||
| import React from 'react'; | ||||
| import renderer from 'react-test-renderer'; | ||||
| import { fromJS }  from 'immutable'; | ||||
| import DisplayName from '../display_name'; | ||||
| import { DisplayName } from '../display_name'; | ||||
| 
 | ||||
| describe('<DisplayName />', () => { | ||||
|   it('renders display name + account name', () => { | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ import React from 'react'; | |||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { Avatar } from './avatar'; | ||||
| import DisplayName from './display_name'; | ||||
| import { DisplayName } from './display_name'; | ||||
| import { IconButton } from './icon_button'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
|  |  | |||
|  | @ -1,79 +0,0 @@ | |||
| import React from 'react'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { autoPlayGif } from 'mastodon/initial_state'; | ||||
| import Skeleton from 'mastodon/components/skeleton'; | ||||
| 
 | ||||
| export default class DisplayName extends React.PureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|     account: ImmutablePropTypes.map, | ||||
|     others: ImmutablePropTypes.list, | ||||
|     localDomain: PropTypes.string, | ||||
|   }; | ||||
| 
 | ||||
|   handleMouseEnter = ({ currentTarget }) => { | ||||
|     if (autoPlayGif) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const emojis = currentTarget.querySelectorAll('.custom-emoji'); | ||||
| 
 | ||||
|     for (var i = 0; i < emojis.length; i++) { | ||||
|       let emoji = emojis[i]; | ||||
|       emoji.src = emoji.getAttribute('data-original'); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   handleMouseLeave = ({ currentTarget }) => { | ||||
|     if (autoPlayGif) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const emojis = currentTarget.querySelectorAll('.custom-emoji'); | ||||
| 
 | ||||
|     for (var i = 0; i < emojis.length; i++) { | ||||
|       let emoji = emojis[i]; | ||||
|       emoji.src = emoji.getAttribute('data-static'); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   render () { | ||||
|     const { others, localDomain } = this.props; | ||||
| 
 | ||||
|     let displayName, suffix, account; | ||||
| 
 | ||||
|     if (others && others.size > 1) { | ||||
|       displayName = others.take(2).map(a => <bdi key={a.get('id')}><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi>).reduce((prev, cur) => [prev, ', ', cur]); | ||||
| 
 | ||||
|       if (others.size - 2 > 0) { | ||||
|         suffix = `+${others.size - 2}`; | ||||
|       } | ||||
|     } else if ((others && others.size > 0) || this.props.account) { | ||||
|       if (others && others.size > 0) { | ||||
|         account = others.first(); | ||||
|       } else { | ||||
|         account = this.props.account; | ||||
|       } | ||||
| 
 | ||||
|       let acct = account.get('acct'); | ||||
| 
 | ||||
|       if (acct.indexOf('@') === -1 && localDomain) { | ||||
|         acct = `${acct}@${localDomain}`; | ||||
|       } | ||||
| 
 | ||||
|       displayName = <bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi>; | ||||
|       suffix      = <span className='display-name__account'>@{acct}</span>; | ||||
|     } else { | ||||
|       displayName = <bdi><strong className='display-name__html'><Skeleton width='10ch' /></strong></bdi>; | ||||
|       suffix = <span className='display-name__account'><Skeleton width='7ch' /></span>; | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|       <span className='display-name' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}> | ||||
|         {displayName} {suffix} | ||||
|       </span> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										115
									
								
								app/javascript/mastodon/components/display_name.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								app/javascript/mastodon/components/display_name.tsx
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,115 @@ | |||
| import React from 'react'; | ||||
| import { autoPlayGif } from '..//initial_state'; | ||||
| import Skeleton from './skeleton'; | ||||
| import { Account } from '../../types/resources'; | ||||
| import { List } from 'immutable'; | ||||
| 
 | ||||
| type Props = { | ||||
|   account: Account; | ||||
|   others: List<Account>; | ||||
|   localDomain: string; | ||||
| }; | ||||
| export class DisplayName extends React.PureComponent<Props> { | ||||
|   handleMouseEnter: React.ReactEventHandler<HTMLSpanElement> = ({ | ||||
|     currentTarget, | ||||
|   }) => { | ||||
|     if (autoPlayGif) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const emojis = | ||||
|       currentTarget.querySelectorAll<HTMLImageElement>('img.custom-emoji'); | ||||
| 
 | ||||
|     emojis.forEach((emoji) => { | ||||
|       const originalSrc = emoji.getAttribute('data-original'); | ||||
|       if (originalSrc != null) emoji.src = originalSrc; | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|   handleMouseLeave: React.ReactEventHandler<HTMLSpanElement> = ({ | ||||
|     currentTarget, | ||||
|   }) => { | ||||
|     if (autoPlayGif) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const emojis = | ||||
|       currentTarget.querySelectorAll<HTMLImageElement>('img.custom-emoji'); | ||||
| 
 | ||||
|     emojis.forEach((emoji) => { | ||||
|       const staticSrc = emoji.getAttribute('data-static'); | ||||
|       if (staticSrc != null) emoji.src = staticSrc; | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|   render() { | ||||
|     const { others, localDomain } = this.props; | ||||
| 
 | ||||
|     let displayName: React.ReactNode, suffix: React.ReactNode, account: Account; | ||||
| 
 | ||||
|     if (others && others.size > 1) { | ||||
|       displayName = others | ||||
|         .take(2) | ||||
|         .map((a) => ( | ||||
|           <bdi key={a.get('id')}> | ||||
|             <strong | ||||
|               className='display-name__html' | ||||
|               dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} | ||||
|             /> | ||||
|           </bdi> | ||||
|         )) | ||||
|         .reduce((prev, cur) => [prev, ', ', cur]); | ||||
| 
 | ||||
|       if (others.size - 2 > 0) { | ||||
|         suffix = `+${others.size - 2}`; | ||||
|       } | ||||
|     } else if ((others && others.size > 0) || this.props.account) { | ||||
|       if (others && others.size > 0) { | ||||
|         account = others.first(); | ||||
|       } else { | ||||
|         account = this.props.account; | ||||
|       } | ||||
| 
 | ||||
|       let acct = account.get('acct'); | ||||
| 
 | ||||
|       if (acct.indexOf('@') === -1 && localDomain) { | ||||
|         acct = `${acct}@${localDomain}`; | ||||
|       } | ||||
| 
 | ||||
|       displayName = ( | ||||
|         <bdi> | ||||
|           <strong | ||||
|             className='display-name__html' | ||||
|             dangerouslySetInnerHTML={{ | ||||
|               __html: account.get('display_name_html'), | ||||
|             }} | ||||
|           /> | ||||
|         </bdi> | ||||
|       ); | ||||
|       suffix = <span className='display-name__account'>@{acct}</span>; | ||||
|     } else { | ||||
|       displayName = ( | ||||
|         <bdi> | ||||
|           <strong className='display-name__html'> | ||||
|             <Skeleton width='10ch' /> | ||||
|           </strong> | ||||
|         </bdi> | ||||
|       ); | ||||
|       suffix = ( | ||||
|         <span className='display-name__account'> | ||||
|           <Skeleton width='7ch' /> | ||||
|         </span> | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|       <span | ||||
|         className='display-name' | ||||
|         onMouseEnter={this.handleMouseEnter} | ||||
|         onMouseLeave={this.handleMouseLeave} | ||||
|       > | ||||
|         {displayName} {suffix} | ||||
|       </span> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | @ -4,7 +4,7 @@ import PropTypes from 'prop-types'; | |||
| import { Avatar } from './avatar'; | ||||
| import { AvatarOverlay } from './avatar_overlay'; | ||||
| import { RelativeTimestamp } from './relative_timestamp'; | ||||
| import DisplayName from './display_name'; | ||||
| import { DisplayName } from './display_name'; | ||||
| import StatusContent from './status_content'; | ||||
| import StatusActionBar from './status_action_bar'; | ||||
| import AttachmentList from './attachment_list'; | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; | |||
| import { FormattedMessage } from 'react-intl'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import { AvatarOverlay } from '../../../components/avatar_overlay'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import { DisplayName } from '../../../components/display_name'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| 
 | ||||
| export default class MovedNote extends ImmutablePureComponent { | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import React from 'react'; | ||||
| import { Avatar } from '../../../components/avatar'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import { DisplayName } from '../../../components/display_name'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; | |||
| import PropTypes from 'prop-types'; | ||||
| import { Avatar } from '../../../components/avatar'; | ||||
| import { IconButton } from '../../../components/icon_button'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import { DisplayName } from '../../../components/display_name'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import AttachmentList from 'mastodon/components/attachment_list'; | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import PropTypes from 'prop-types'; | |||
| import { connect } from 'react-redux'; | ||||
| import { makeGetAccount } from 'mastodon/selectors'; | ||||
| import { Avatar } from 'mastodon/components/avatar'; | ||||
| import DisplayName from 'mastodon/components/display_name'; | ||||
| import { DisplayName } from 'mastodon/components/display_name'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import Button from 'mastodon/components/button'; | ||||
| import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import PropTypes from 'prop-types'; | |||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { Avatar } from '../../../components/avatar'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import { DisplayName } from '../../../components/display_name'; | ||||
| import { IconButton } from '../../../components/icon_button'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ import { makeGetAccount } from '../../../selectors'; | |||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import { Avatar } from '../../../components/avatar'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import { DisplayName } from '../../../components/display_name'; | ||||
| import { injectIntl } from 'react-intl'; | ||||
| 
 | ||||
| const makeMapStateToProps = () => { | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import { makeGetAccount } from '../../../selectors'; | |||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import { Avatar } from '../../../components/avatar'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import { DisplayName } from '../../../components/display_name'; | ||||
| import { IconButton } from '../../../components/icon_button'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
| import { removeFromListEditor, addToListEditor } from '../../../actions/lists'; | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ import React from 'react'; | |||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { Avatar } from 'mastodon/components/avatar'; | ||||
| import DisplayName from 'mastodon/components/display_name'; | ||||
| import { DisplayName } from 'mastodon/components/display_name'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { IconButton } from 'mastodon/components/icon_button'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ import PropTypes from 'prop-types'; | |||
| import { IconButton } from 'mastodon/components/icon_button'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { Avatar } from 'mastodon/components/avatar'; | ||||
| import DisplayName from 'mastodon/components/display_name'; | ||||
| import { DisplayName } from 'mastodon/components/display_name'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import PropTypes from 'prop-types'; | |||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import StatusContent from 'mastodon/components/status_content'; | ||||
| import { Avatar } from 'mastodon/components/avatar'; | ||||
| import DisplayName from 'mastodon/components/display_name'; | ||||
| import { DisplayName } from 'mastodon/components/display_name'; | ||||
| import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; | ||||
| import Option from './option'; | ||||
| import MediaAttachments from 'mastodon/components/media_attachments'; | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ import React from 'react'; | |||
| import PropTypes from 'prop-types'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import { Avatar } from '../../../components/avatar'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import { DisplayName } from '../../../components/display_name'; | ||||
| import StatusContent from '../../../components/status_content'; | ||||
| import MediaGallery from '../../../components/media_gallery'; | ||||
| import { Link } from 'react-router-dom'; | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import Button from '../../../components/button'; | |||
| import StatusContent from '../../../components/status_content'; | ||||
| import { Avatar } from '../../../components/avatar'; | ||||
| import { RelativeTimestamp } from '../../../components/relative_timestamp'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import { DisplayName } from '../../../components/display_name'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import { Icon }  from 'mastodon/components/icon'; | ||||
| import AttachmentList from 'mastodon/components/attachment_list'; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue