From 697c028c4ac1dc4aa943efb1b30803b134dc491b Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 1 Jun 2022 20:47:28 -0500 Subject: [PATCH] TimelineQueueButtonHeader: convert to tsx --- .../timeline_queue_button_header.js | 119 ------------------ .../timeline_queue_button_header.tsx | 83 ++++++++++++ 2 files changed, 83 insertions(+), 119 deletions(-) delete mode 100644 app/soapbox/components/timeline_queue_button_header.js create mode 100644 app/soapbox/components/timeline_queue_button_header.tsx diff --git a/app/soapbox/components/timeline_queue_button_header.js b/app/soapbox/components/timeline_queue_button_header.js deleted file mode 100644 index 29a8e787a..000000000 --- a/app/soapbox/components/timeline_queue_button_header.js +++ /dev/null @@ -1,119 +0,0 @@ -import classNames from 'classnames'; -import { throttle } from 'lodash'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { injectIntl } from 'react-intl'; -import { connect } from 'react-redux'; - -import { getSettings } from 'soapbox/actions/settings'; -import Icon from 'soapbox/components/icon'; -import { Text } from 'soapbox/components/ui'; - -const mapStateToProps = state => { - const settings = getSettings(state); - - return { - autoload: settings.get('autoloadTimelines'), - }; -}; - -export default @connect(mapStateToProps) -@injectIntl -class TimelineQueueButtonHeader extends React.PureComponent { - - static propTypes = { - onClick: PropTypes.func.isRequired, - count: PropTypes.number, - message: PropTypes.object.isRequired, - threshold: PropTypes.number, - intl: PropTypes.object.isRequired, - autoload: PropTypes.bool, - autoloadThreshold: PropTypes.number, - }; - - static defaultProps = { - count: 0, - threshold: 400, - autoload: true, - autoloadThreshold: 50, - }; - - state = { - scrolled: false, - } - - componentDidMount() { - this.attachScrollListener(); - } - - componentWillUnmount() { - this.detachScrollListener(); - } - - componentDidUpdate(prevProps, prevState) { - const { scrollTop } = (document.scrollingElement || document.documentElement); - const { count, onClick, autoload, autoloadThreshold } = this.props; - - if (autoload && scrollTop <= autoloadThreshold && count !== prevProps.count) { - onClick(); - } - } - - attachScrollListener() { - window.addEventListener('scroll', this.handleScroll); - } - - detachScrollListener() { - window.removeEventListener('scroll', this.handleScroll); - } - - handleScroll = throttle(() => { - const { scrollTop } = (document.scrollingElement || document.documentElement); - const { threshold, onClick, autoload, autoloadThreshold } = this.props; - - if (autoload && scrollTop <= autoloadThreshold) { - onClick(); - } - - if (scrollTop > threshold) { - this.setState({ scrolled: true }); - } else { - this.setState({ scrolled: false }); - } - }, 150, { trailing: true }); - - scrollUp = () => { - window.scrollTo({ top: 0, behavior: 'smooth' }); - }; - - handleClick = e => { - setTimeout(this.scrollUp, 10); - this.props.onClick(e); - } - - render() { - const { count, message, intl } = this.props; - const { scrolled } = this.state; - - const visible = count > 0 && scrolled; - - const classes = classNames('left-1/2 -translate-x-1/2 fixed top-20 z-50', { - 'hidden': !visible, - }); - - return ( -
- - - - {(count > 0) && ( - - {intl.formatMessage(message, { count })} - - )} - -
- ); - } - -} diff --git a/app/soapbox/components/timeline_queue_button_header.tsx b/app/soapbox/components/timeline_queue_button_header.tsx new file mode 100644 index 000000000..e0d65fc67 --- /dev/null +++ b/app/soapbox/components/timeline_queue_button_header.tsx @@ -0,0 +1,83 @@ +import classNames from 'classnames'; +import { throttle } from 'lodash'; +import React, { useState, useEffect, useCallback } from 'react'; +import { useIntl, MessageDescriptor } from 'react-intl'; + +import Icon from 'soapbox/components/icon'; +import { Text } from 'soapbox/components/ui'; +import { useSettings } from 'soapbox/hooks'; + +interface ITimelineQueueButtonHeader { + onClick: () => void, + count?: number, + message: MessageDescriptor, + threshold?: number, + autoloadThreshold?: number, +} + +const TimelineQueueButtonHeader: React.FC = ({ + onClick, + count = 0, + message, + threshold = 400, + autoloadThreshold = 50, +}) => { + const intl = useIntl(); + const settings = useSettings(); + + const [scrolled, setScrolled] = useState(false); + const autoload = settings.get('autoloadTimelines') === true; + + const handleScroll = useCallback(throttle(() => { + const { scrollTop } = (document.scrollingElement || document.documentElement); + + if (autoload && scrollTop <= autoloadThreshold) { + onClick(); + } + + if (scrollTop > threshold) { + setScrolled(true); + } else { + setScrolled(false); + } + }, 150, { trailing: true }), []); + + const scrollUp = () => { + window.scrollTo({ top: 0, behavior: 'smooth' }); + }; + + const handleClick: React.MouseEventHandler = () => { + setTimeout(scrollUp, 10); + onClick(); + }; + + useEffect(() => { + window.addEventListener('scroll', handleScroll); + + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + + const visible = count > 0 && scrolled; + + const classes = classNames('left-1/2 -translate-x-1/2 fixed top-20 z-50', { + 'hidden': !visible, + }); + + return ( +
+ + + + {(count > 0) && ( + + {intl.formatMessage(message, { count })} + + )} + +
+ ); +}; + +export default TimelineQueueButtonHeader;