Rewrite GIFV component with React hooks (#24552)
This commit is contained in:
		
					parent
					
						
							
								e5c0b16735
							
						
					
				
			
			
				commit
				
					
						cf3fa1e814
					
				
			
		
					 4 changed files with 70 additions and 78 deletions
				
			
		|  | @ -1,76 +0,0 @@ | |||
| import React from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| 
 | ||||
| export default class GIFV extends React.PureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|     src: PropTypes.string.isRequired, | ||||
|     alt: PropTypes.string, | ||||
|     lang: PropTypes.string, | ||||
|     width: PropTypes.number, | ||||
|     height: PropTypes.number, | ||||
|     onClick: PropTypes.func, | ||||
|   }; | ||||
| 
 | ||||
|   state = { | ||||
|     loading: true, | ||||
|   }; | ||||
| 
 | ||||
|   handleLoadedData = () => { | ||||
|     this.setState({ loading: false }); | ||||
|   }; | ||||
| 
 | ||||
|   componentWillReceiveProps (nextProps) { | ||||
|     if (nextProps.src !== this.props.src) { | ||||
|       this.setState({ loading: true }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   handleClick = e => { | ||||
|     const { onClick } = this.props; | ||||
| 
 | ||||
|     if (onClick) { | ||||
|       e.stopPropagation(); | ||||
|       onClick(); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   render () { | ||||
|     const { src, width, height, alt, lang } = this.props; | ||||
|     const { loading } = this.state; | ||||
| 
 | ||||
|     return ( | ||||
|       <div className='gifv' style={{ position: 'relative' }}> | ||||
|         {loading && ( | ||||
|           <canvas | ||||
|             width={width} | ||||
|             height={height} | ||||
|             role='button' | ||||
|             tabIndex={0} | ||||
|             aria-label={alt} | ||||
|             title={alt} | ||||
|             lang={lang} | ||||
|             onClick={this.handleClick} | ||||
|           /> | ||||
|         )} | ||||
| 
 | ||||
|         <video | ||||
|           src={src} | ||||
|           role='button' | ||||
|           tabIndex={0} | ||||
|           aria-label={alt} | ||||
|           title={alt} | ||||
|           lang={lang} | ||||
|           muted | ||||
|           loop | ||||
|           autoPlay | ||||
|           playsInline | ||||
|           onClick={this.handleClick} | ||||
|           onLoadedData={this.handleLoadedData} | ||||
|           style={{ position: loading ? 'absolute' : 'static', top: 0, left: 0 }} | ||||
|         /> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										68
									
								
								app/javascript/mastodon/components/gifv.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								app/javascript/mastodon/components/gifv.tsx
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,68 @@ | |||
| import React, { useCallback, useState } from 'react'; | ||||
| 
 | ||||
| type Props = { | ||||
|   src: string; | ||||
|   key: string; | ||||
|   alt?: string; | ||||
|   lang?: string; | ||||
|   width: number; | ||||
|   height: number; | ||||
|   onClick?: () => void; | ||||
| } | ||||
| 
 | ||||
| export const GIFV: React.FC<Props> = ({ | ||||
|   src, | ||||
|   alt, | ||||
|   lang, | ||||
|   width, | ||||
|   height, | ||||
|   onClick, | ||||
| })=> { | ||||
|   const [loading, setLoading] = useState(true); | ||||
| 
 | ||||
|   const handleLoadedData: React.ReactEventHandler<HTMLVideoElement> = useCallback(() => { | ||||
|     setLoading(false); | ||||
|   }, [setLoading]); | ||||
| 
 | ||||
|   const handleClick: React.MouseEventHandler = useCallback((e) => { | ||||
|     if (onClick) { | ||||
|       e.stopPropagation(); | ||||
|       onClick(); | ||||
|     } | ||||
|   }, [onClick]); | ||||
| 
 | ||||
|   return ( | ||||
|     <div className='gifv' style={{ position: 'relative' }}> | ||||
|       {loading && ( | ||||
|         <canvas | ||||
|           width={width} | ||||
|           height={height} | ||||
|           role='button' | ||||
|           tabIndex={0} | ||||
|           aria-label={alt} | ||||
|           title={alt} | ||||
|           lang={lang} | ||||
|           onClick={handleClick} | ||||
|         /> | ||||
|       )} | ||||
| 
 | ||||
|       <video | ||||
|         src={src} | ||||
|         role='button' | ||||
|         tabIndex={0} | ||||
|         aria-label={alt} | ||||
|         title={alt} | ||||
|         lang={lang} | ||||
|         muted | ||||
|         loop | ||||
|         autoPlay | ||||
|         playsInline | ||||
|         onClick={handleClick} | ||||
|         onLoadedData={handleLoadedData} | ||||
|         style={{ position: loading ? 'absolute' : 'static', top: 0, left: 0 }} | ||||
|       /> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default GIFV; | ||||
|  | @ -383,7 +383,7 @@ class FocalPointModal extends ImmutablePureComponent { | |||
|             {focals && ( | ||||
|               <div className={classNames('focal-point', { dragging })} ref={this.setRef} onMouseDown={this.handleMouseDown} onTouchStart={this.handleTouchStart}> | ||||
|                 {media.get('type') === 'image' && <ImageLoader src={media.get('url')} width={width} height={height} alt='' />} | ||||
|                 {media.get('type') === 'gifv' && <GIFV src={media.get('url')} width={width} height={height} />} | ||||
|                 {media.get('type') === 'gifv' && <GIFV src={media.get('url')} key={media.get('url')} width={width} height={height} />} | ||||
| 
 | ||||
|                 <div className='focal-point__preview'> | ||||
|                   <strong><FormattedMessage id='upload_modal.preview_label' defaultMessage='Preview ({ratio})' values={{ ratio: '16:9' }} /></strong> | ||||
|  |  | |||
|  | @ -186,7 +186,7 @@ class MediaModal extends ImmutablePureComponent { | |||
|             src={image.get('url')} | ||||
|             width={width} | ||||
|             height={height} | ||||
|             key={image.get('preview_url')} | ||||
|             key={image.get('url')} | ||||
|             alt={image.get('description')} | ||||
|             lang={language} | ||||
|             onClick={this.toggleNavigation} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue