1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-22 22:15:17 -04:00

Refactor Movie index to use react-window

This commit is contained in:
Robin Dadswell
2023-03-12 19:03:34 +00:00
committed by Qstick
parent 68832a136e
commit e0b91c6406
95 changed files with 3347 additions and 4922 deletions
@@ -1,95 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { scrollDirections } from 'Helpers/Props';
import styles from './Scroller.css';
class Scroller extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this._scroller = null;
}
componentDidMount() {
const {
scrollDirection,
autoFocus,
scrollTop
} = this.props;
if (this.props.scrollTop != null) {
this._scroller.scrollTop = scrollTop;
}
if (autoFocus && scrollDirection !== scrollDirections.NONE) {
this._scroller.focus({ preventScroll: true });
}
}
//
// Control
_setScrollerRef = (ref) => {
this._scroller = ref;
this.props.registerScroller(ref);
};
//
// Render
render() {
const {
className,
scrollDirection,
autoScroll,
children,
scrollTop,
onScroll,
registerScroller,
...otherProps
} = this.props;
return (
<div
ref={this._setScrollerRef}
className={classNames(
className,
styles.scroller,
styles[scrollDirection],
autoScroll && styles.autoScroll
)}
tabIndex={-1}
{...otherProps}
>
{children}
</div>
);
}
}
Scroller.propTypes = {
className: PropTypes.string,
scrollDirection: PropTypes.oneOf(scrollDirections.all).isRequired,
autoFocus: PropTypes.bool.isRequired,
autoScroll: PropTypes.bool.isRequired,
scrollTop: PropTypes.number,
children: PropTypes.node,
onScroll: PropTypes.func,
registerScroller: PropTypes.func
};
Scroller.defaultProps = {
scrollDirection: scrollDirections.VERTICAL,
autoFocus: true,
autoScroll: true,
registerScroller: () => { /* no-op */ }
};
export default Scroller;
@@ -0,0 +1,90 @@
import classNames from 'classnames';
import { throttle } from 'lodash';
import React, { forwardRef, ReactNode, useEffect, useRef } from 'react';
import ScrollDirection from 'Helpers/Props/ScrollDirection';
import styles from './Scroller.css';
interface ScrollerProps {
className?: string;
scrollDirection?: ScrollDirection;
autoFocus?: boolean;
autoScroll?: boolean;
scrollTop?: number;
initialScrollTop?: number;
children?: ReactNode;
onScroll?: (payload) => void;
}
const Scroller = forwardRef(
(props: ScrollerProps, ref: React.MutableRefObject<HTMLDivElement>) => {
const {
className,
autoFocus = false,
autoScroll = true,
scrollDirection = ScrollDirection.Vertical,
children,
scrollTop,
initialScrollTop,
onScroll,
...otherProps
} = props;
const internalRef = useRef();
const currentRef = ref ?? internalRef;
useEffect(
() => {
if (initialScrollTop != null) {
currentRef.current.scrollTop = initialScrollTop;
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);
useEffect(() => {
if (scrollTop != null) {
currentRef.current.scrollTop = scrollTop;
}
if (autoFocus && scrollDirection !== ScrollDirection.None) {
currentRef.current.focus({ preventScroll: true });
}
}, [autoFocus, currentRef, scrollDirection, scrollTop]);
useEffect(() => {
const div = currentRef.current;
const handleScroll = throttle(() => {
const scrollLeft = div.scrollLeft;
const scrollTop = div.scrollTop;
onScroll?.({ scrollLeft, scrollTop });
}, 10);
div.addEventListener('scroll', handleScroll);
return () => {
div.removeEventListener('scroll', handleScroll);
};
}, [currentRef, onScroll]);
return (
<div
{...otherProps}
ref={currentRef}
className={classNames(
className,
styles.scroller,
styles[scrollDirection],
autoScroll && styles.autoScroll
)}
tabIndex={-1}
>
{children}
</div>
);
}
);
export default Scroller;