Fixed: restoring scroll position when going back to index page (#6308)

(cherry picked from commit 1bc52d0138c7bcb94ffce31ec05f675387612a62)

Co-authored-by: ta264 <ta264@users.noreply.github.com>
This commit is contained in:
Robin Dadswell 2021-05-12 12:36:20 +01:00 committed by GitHub
parent 4300d8d8c6
commit d7ab9292fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 65 additions and 12 deletions

View File

@ -38,7 +38,7 @@ class Link extends Component {
const linkProps = { target }; const linkProps = { target };
let el = component; let el = component;
if (to) { if (to && typeof to === 'string') {
if ((/\w+?:\/\//).test(to)) { if ((/\w+?:\/\//).test(to)) {
el = 'a'; el = 'a';
linkProps.href = to; linkProps.href = to;
@ -53,6 +53,18 @@ class Link extends Component {
linkProps.to = `${window.Radarr.urlBase}/${to.replace(/^\//, '')}`; linkProps.to = `${window.Radarr.urlBase}/${to.replace(/^\//, '')}`;
linkProps.target = target; linkProps.target = target;
} }
} else if (to && typeof to === 'object') {
el = RouterLink;
linkProps.target = target;
if (to.pathname.startsWith(`${window.Radarr.urlBase}/`)) {
linkProps.to = to;
} else {
const pathname = `${window.Radarr.urlBase}/${to.pathname.replace(/^\//, '')}`;
linkProps.to = {
...to,
pathname
};
}
} }
if (el === 'button' || el === 'input') { if (el === 'button' || el === 'input') {
@ -83,7 +95,7 @@ class Link extends Component {
Link.propTypes = { Link.propTypes = {
className: PropTypes.string, className: PropTypes.string,
component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
to: PropTypes.string, to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
target: PropTypes.string, target: PropTypes.string,
isDisabled: PropTypes.bool, isDisabled: PropTypes.bool,
noRouter: PropTypes.bool, noRouter: PropTypes.bool,

View File

@ -53,7 +53,13 @@ class PageHeader extends Component {
return ( return (
<div className={styles.header}> <div className={styles.header}>
<div className={styles.logoContainer}> <div className={styles.logoContainer}>
<Link to={'/'}> <Link
className={styles.logoLink}
to={{
pathname: '/',
state: { restoreScrollPosition: true }
}}
>
<img <img
className={isSmallScreen ? styles.logo : styles.logoFull} className={isSmallScreen ? styles.logo : styles.logoFull}
src={isSmallScreen ? `${window.Radarr.urlBase}/Content/Images/logo.png` : `${window.Radarr.urlBase}/Content/Images/logo-full.png`} src={isSmallScreen ? `${window.Radarr.urlBase}/Content/Images/logo.png` : `${window.Radarr.urlBase}/Content/Images/logo-full.png`}

View File

@ -39,7 +39,8 @@ class VirtualTable extends Component {
super(props, context); super(props, context);
this.state = { this.state = {
width: 0 width: 0,
scrollRestored: false
}; };
this._grid = null; this._grid = null;
@ -48,11 +49,13 @@ class VirtualTable extends Component {
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
const { const {
items, items,
scrollIndex scrollIndex,
scrollTop
} = this.props; } = this.props;
const { const {
width width,
scrollRestored
} = this.state; } = this.state;
if (this._grid && if (this._grid &&
@ -68,6 +71,11 @@ class VirtualTable extends Component {
columnIndex: 0 columnIndex: 0
}); });
} }
if (this._grid && scrollTop !== undefined && scrollTop !== 0 && !scrollRestored) {
this.setState({ scrollRestored: true });
this._grid.scrollToPosition({ scrollTop });
}
} }
// //
@ -96,6 +104,7 @@ class VirtualTable extends Component {
items, items,
scroller, scroller,
focusScroller, focusScroller,
scrollTop: ignored,
header, header,
headerHeight, headerHeight,
rowRenderer, rowRenderer,
@ -180,6 +189,7 @@ VirtualTable.propTypes = {
className: PropTypes.string.isRequired, className: PropTypes.string.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired, items: PropTypes.arrayOf(PropTypes.object).isRequired,
scrollIndex: PropTypes.number, scrollIndex: PropTypes.number,
scrollTop: PropTypes.number,
scroller: PropTypes.instanceOf(Element).isRequired, scroller: PropTypes.instanceOf(Element).isRequired,
focusScroller: PropTypes.bool.isRequired, focusScroller: PropTypes.bool.isRequired,
header: PropTypes.node.isRequired, header: PropTypes.node.isRequired,

View File

@ -8,7 +8,7 @@ function withScrollPosition(WrappedComponent, scrollPositionKey) {
history history
} = props; } = props;
const scrollTop = history.action === 'POP' ? const scrollTop = history.action === 'POP' || (history.location.state && history.location.state.restoreScrollPosition) ?
scrollPositions[scrollPositionKey] : scrollPositions[scrollPositionKey] :
0; 0;

View File

@ -60,7 +60,8 @@ class MovieIndexOverviews extends Component {
columnCount: 1, columnCount: 1,
posterWidth: 162, posterWidth: 162,
posterHeight: 238, posterHeight: 238,
rowHeight: calculateRowHeight(238, null, props.isSmallScreen, {}) rowHeight: calculateRowHeight(238, null, props.isSmallScreen, {}),
scrollRestored: false
}; };
this._grid = null; this._grid = null;
@ -72,13 +73,15 @@ class MovieIndexOverviews extends Component {
sortKey, sortKey,
overviewOptions, overviewOptions,
jumpToCharacter, jumpToCharacter,
scrollTop,
isMovieEditorActive, isMovieEditorActive,
isSmallScreen isSmallScreen
} = this.props; } = this.props;
const { const {
width, width,
rowHeight rowHeight,
scrollRestored
} = this.state; } = this.state;
if (prevProps.sortKey !== sortKey || if (prevProps.sortKey !== sortKey ||
@ -97,6 +100,11 @@ class MovieIndexOverviews extends Component {
this._grid.recomputeGridSize(); this._grid.recomputeGridSize();
} }
if (this._grid && scrollTop !== 0 && !scrollRestored) {
this.setState({ scrollRestored: true });
this._grid.scrollToPosition({ scrollTop });
}
if (jumpToCharacter != null && jumpToCharacter !== prevProps.jumpToCharacter) { if (jumpToCharacter != null && jumpToCharacter !== prevProps.jumpToCharacter) {
const index = getIndexOfFirstCharacter(items, jumpToCharacter); const index = getIndexOfFirstCharacter(items, jumpToCharacter);
@ -262,6 +270,7 @@ MovieIndexOverviews.propTypes = {
sortKey: PropTypes.string, sortKey: PropTypes.string,
overviewOptions: PropTypes.object.isRequired, overviewOptions: PropTypes.object.isRequired,
jumpToCharacter: PropTypes.string, jumpToCharacter: PropTypes.string,
scrollTop: PropTypes.number.isRequired,
scroller: PropTypes.instanceOf(Element).isRequired, scroller: PropTypes.instanceOf(Element).isRequired,
showRelativeDates: PropTypes.bool.isRequired, showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired, shortDateFormat: PropTypes.string.isRequired,

View File

@ -104,7 +104,8 @@ class MovieIndexPosters extends Component {
columnCount: 1, columnCount: 1,
posterWidth: 162, posterWidth: 162,
posterHeight: 238, posterHeight: 238,
rowHeight: calculateRowHeight(238, null, props.isSmallScreen, {}) rowHeight: calculateRowHeight(238, null, props.isSmallScreen, {}),
scrollRestored: false
}; };
this._isInitialized = false; this._isInitialized = false;
@ -119,14 +120,16 @@ class MovieIndexPosters extends Component {
posterOptions, posterOptions,
jumpToCharacter, jumpToCharacter,
isSmallScreen, isSmallScreen,
isMovieEditorActive isMovieEditorActive,
scrollTop
} = this.props; } = this.props;
const { const {
width, width,
columnWidth, columnWidth,
columnCount, columnCount,
rowHeight rowHeight,
scrollRestored
} = this.state; } = this.state;
if (prevProps.sortKey !== sortKey || if (prevProps.sortKey !== sortKey ||
@ -145,6 +148,11 @@ class MovieIndexPosters extends Component {
this._grid.recomputeGridSize(); this._grid.recomputeGridSize();
} }
if (this._grid && scrollTop !== 0 && !scrollRestored) {
this.setState({ scrollRestored: true });
this._grid.scrollToPosition({ scrollTop });
}
if (jumpToCharacter != null && jumpToCharacter !== prevProps.jumpToCharacter) { if (jumpToCharacter != null && jumpToCharacter !== prevProps.jumpToCharacter) {
const index = getIndexOfFirstCharacter(items, jumpToCharacter); const index = getIndexOfFirstCharacter(items, jumpToCharacter);
@ -157,6 +165,10 @@ class MovieIndexPosters extends Component {
}); });
} }
} }
if (this._grid && scrollTop !== 0) {
this._grid.scrollToPosition({ scrollTop });
}
} }
// //
@ -332,6 +344,7 @@ MovieIndexPosters.propTypes = {
sortKey: PropTypes.string, sortKey: PropTypes.string,
posterOptions: PropTypes.object.isRequired, posterOptions: PropTypes.object.isRequired,
jumpToCharacter: PropTypes.string, jumpToCharacter: PropTypes.string,
scrollTop: PropTypes.number.isRequired,
scroller: PropTypes.instanceOf(Element).isRequired, scroller: PropTypes.instanceOf(Element).isRequired,
showRelativeDates: PropTypes.bool.isRequired, showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired, shortDateFormat: PropTypes.string.isRequired,

View File

@ -87,6 +87,7 @@ class MovieIndexTable extends Component {
isSmallScreen, isSmallScreen,
onSortPress, onSortPress,
scroller, scroller,
scrollTop,
allSelected, allSelected,
allUnselected, allUnselected,
onSelectAllChange, onSelectAllChange,
@ -100,6 +101,7 @@ class MovieIndexTable extends Component {
items={items} items={items}
scrollIndex={this.state.scrollIndex} scrollIndex={this.state.scrollIndex}
isSmallScreen={isSmallScreen} isSmallScreen={isSmallScreen}
scrollTop={scrollTop}
scroller={scroller} scroller={scroller}
rowHeight={38} rowHeight={38}
overscanRowCount={2} overscanRowCount={2}
@ -130,6 +132,7 @@ MovieIndexTable.propTypes = {
sortDirection: PropTypes.oneOf(sortDirections.all), sortDirection: PropTypes.oneOf(sortDirections.all),
jumpToCharacter: PropTypes.string, jumpToCharacter: PropTypes.string,
isSmallScreen: PropTypes.bool.isRequired, isSmallScreen: PropTypes.bool.isRequired,
scrollTop: PropTypes.number,
scroller: PropTypes.instanceOf(Element).isRequired, scroller: PropTypes.instanceOf(Element).isRequired,
onSortPress: PropTypes.func.isRequired, onSortPress: PropTypes.func.isRequired,
allSelected: PropTypes.bool.isRequired, allSelected: PropTypes.bool.isRequired,