Rewrite GIFV component with React hooks (#24552)

main
fusagiko / takayamaki 2023-04-16 23:09:04 +09:00 committed by GitHub
parent e5c0b16735
commit cf3fa1e814
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 78 deletions

View File

@ -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>
);
}
}

View 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;

View File

@ -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>

View File

@ -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}