From 575bc834f5b20d1e29530fb9663fc9eef7b8bf54 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 May 2022 12:46:21 -0500 Subject: [PATCH 1/4] StillImage: convert to TSX --- app/soapbox/components/still_image.js | 64 -------------------------- app/soapbox/components/still_image.tsx | 46 ++++++++++++++++++ 2 files changed, 46 insertions(+), 64 deletions(-) delete mode 100644 app/soapbox/components/still_image.js create mode 100644 app/soapbox/components/still_image.tsx diff --git a/app/soapbox/components/still_image.js b/app/soapbox/components/still_image.js deleted file mode 100644 index 323960a37..000000000 --- a/app/soapbox/components/still_image.js +++ /dev/null @@ -1,64 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; - -import { getSettings } from 'soapbox/actions/settings'; - -const mapStateToProps = state => ({ - autoPlayGif: getSettings(state).get('autoPlayGif'), -}); - -export default @connect(mapStateToProps) -class StillImage extends React.PureComponent { - - static propTypes = { - alt: PropTypes.string, - autoPlayGif: PropTypes.bool.isRequired, - className: PropTypes.node, - src: PropTypes.string.isRequired, - style: PropTypes.object, - }; - - static defaultProps = { - alt: '', - className: '', - style: {}, - } - - hoverToPlay() { - const { autoPlayGif, src } = this.props; - return src && !autoPlayGif && (src.endsWith('.gif') || src.startsWith('blob:')); - } - - setCanvasRef = c => { - this.canvas = c; - } - - setImageRef = i => { - this.img = i; - } - - handleImageLoad = () => { - if (this.hoverToPlay()) { - const img = this.img; - const canvas = this.canvas; - canvas.width = img.naturalWidth; - canvas.height = img.naturalHeight; - canvas.getContext('2d').drawImage(img, 0, 0); - } - } - - render() { - const { alt, className, src, style } = this.props; - const hoverToPlay = this.hoverToPlay(); - - return ( -
- {alt} - {hoverToPlay && } -
- ); - } - -} diff --git a/app/soapbox/components/still_image.tsx b/app/soapbox/components/still_image.tsx new file mode 100644 index 000000000..d2ee256a3 --- /dev/null +++ b/app/soapbox/components/still_image.tsx @@ -0,0 +1,46 @@ +import classNames from 'classnames'; +import React, { useRef } from 'react'; + +import { useSettings } from 'soapbox/hooks'; + +interface IStillImage { + /** Image alt text. */ + alt?: string, + /** Extra class names for the outer
container. */ + className?: string, + /** URL to the image */ + src: string, + /** Extra CSS styles on the outer
element. */ + style?: React.CSSProperties, +} + +/** Renders images on a canvas, only playing GIFs if autoPlayGif is enabled. */ +const StillImage: React.FC = ({ alt, className, src, style }) => { + const settings = useSettings(); + const autoPlayGif = settings.get('autoPlayGif'); + + const canvas = useRef(null); + const img = useRef(null); + + const hoverToPlay = ( + src && !autoPlayGif && (src.endsWith('.gif') || src.startsWith('blob:')) + ); + + const handleImageLoad = () => { + if (hoverToPlay && canvas.current && img.current) { + canvas.current.width = img.current.naturalWidth; + canvas.current.height = img.current.naturalHeight; + canvas.current.getContext('2d')?.drawImage(img.current, 0, 0); + } + }; + + + return ( +
+ {alt} + {hoverToPlay && } +
+ ); +}; + +export default StillImage; From 84839a51044660fe2dd05a2d9fda481ac0d51dc1 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 May 2022 12:56:52 -0500 Subject: [PATCH 2/4] Convert legacy Avatar component to TSX --- app/soapbox/components/avatar.js | 39 ------------------------------- app/soapbox/components/avatar.tsx | 38 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 39 deletions(-) delete mode 100644 app/soapbox/components/avatar.js create mode 100644 app/soapbox/components/avatar.tsx diff --git a/app/soapbox/components/avatar.js b/app/soapbox/components/avatar.js deleted file mode 100644 index d5000264d..000000000 --- a/app/soapbox/components/avatar.js +++ /dev/null @@ -1,39 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; - -import StillImage from 'soapbox/components/still_image'; - -export default class Avatar extends React.PureComponent { - - static propTypes = { - account: ImmutablePropTypes.record, - size: PropTypes.number, - style: PropTypes.object, - className: PropTypes.string, - }; - - render() { - const { account, size, className } = this.props; - if (!account) return null; - - // : TODO : remove inline and change all avatars to be sized using css - const style = !size ? {} : { - width: `${size}px`, - height: `${size}px`, - }; - - return ( - - ); - } - -} diff --git a/app/soapbox/components/avatar.tsx b/app/soapbox/components/avatar.tsx new file mode 100644 index 000000000..9d4fbaa7c --- /dev/null +++ b/app/soapbox/components/avatar.tsx @@ -0,0 +1,38 @@ +import classNames from 'classnames'; +import React from 'react'; + +import StillImage from 'soapbox/components/still_image'; + +import type { Account } from 'soapbox/types/entities'; + +interface IAvatar { + account?: Account | null, + size?: number, + className?: string, +} + +/** + * Legacy avatar component. + * @see soapbox/components/ui/avatar/avatar.tsx + * @deprecated + */ +const Avatar: React.FC = ({ account, size, className }) => { + if (!account) return null; + + // : TODO : remove inline and change all avatars to be sized using css + const style: React.CSSProperties = !size ? {} : { + width: `${size}px`, + height: `${size}px`, + }; + + return ( + + ); +}; + +export default Avatar; From 939c74fe44efdbd13806791c0268a5600ab0b17a Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 7 May 2022 12:58:12 -0500 Subject: [PATCH 3/4] UI Avatar: add overflow-hidden className --- app/soapbox/components/ui/avatar/avatar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/soapbox/components/ui/avatar/avatar.tsx b/app/soapbox/components/ui/avatar/avatar.tsx index 6818509e8..1b02c6d25 100644 --- a/app/soapbox/components/ui/avatar/avatar.tsx +++ b/app/soapbox/components/ui/avatar/avatar.tsx @@ -25,7 +25,7 @@ const Avatar = (props: IAvatar) => { return ( Date: Sat, 7 May 2022 13:37:24 -0500 Subject: [PATCH 4/4] Fix avatar test --- app/soapbox/components/__tests__/avatar.test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/soapbox/components/__tests__/avatar.test.js b/app/soapbox/components/__tests__/avatar.test.js index 6b50083ed..55abca520 100644 --- a/app/soapbox/components/__tests__/avatar.test.js +++ b/app/soapbox/components/__tests__/avatar.test.js @@ -1,11 +1,12 @@ -import { fromJS } from 'immutable'; import React from 'react'; +import { normalizeAccount } from 'soapbox/normalizers'; + import { render, screen } from '../../jest/test-helpers'; import Avatar from '../avatar'; describe('', () => { - const account = fromJS({ + const account = normalizeAccount({ username: 'alice', acct: 'alice', display_name: 'Alice',