diff --git a/frontend/src/Components/Table/VirtualTable.js b/frontend/src/Components/Table/VirtualTable.js
index d877b8208..b80619411 100644
--- a/frontend/src/Components/Table/VirtualTable.js
+++ b/frontend/src/Components/Table/VirtualTable.js
@@ -39,7 +39,8 @@ class VirtualTable extends Component {
super(props, context);
this.state = {
- width: 0
+ width: 0,
+ scrollRestored: false
};
this._grid = null;
@@ -48,20 +49,25 @@ class VirtualTable extends Component {
componentDidUpdate(prevProps, prevState) {
const {
items,
- scrollIndex
+ scrollIndex,
+ scrollTop
} = this.props;
const {
- width
+ width,
+ scrollRestored
} = this.state;
- if (this._grid &&
- (prevState.width !== width ||
- hasDifferentItemsOrOrder(prevProps.items, items))) {
+ if (this._grid && (prevState.width !== width || hasDifferentItemsOrOrder(prevProps.items, items))) {
// recomputeGridSize also forces Grid to discard its cache of rendered cells
this._grid.recomputeGridSize();
}
+ if (this._grid && scrollTop !== undefined && scrollTop !== 0 && !scrollRestored) {
+ this.setState({ scrollRestored: true });
+ this._grid.scrollToPosition({ scrollTop });
+ }
+
if (scrollIndex != null && scrollIndex !== prevProps.scrollIndex) {
this._grid.scrollToCell({
rowIndex: scrollIndex,
@@ -98,6 +104,7 @@ class VirtualTable extends Component {
focusScroller,
header,
headerHeight,
+ rowHeight,
rowRenderer,
...otherProps
} = this.props;
@@ -141,6 +148,7 @@ class VirtualTable extends Component {
{header}
@@ -180,16 +187,19 @@ VirtualTable.propTypes = {
className: PropTypes.string.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
scrollIndex: PropTypes.number,
+ scrollTop: PropTypes.number,
scroller: PropTypes.instanceOf(Element).isRequired,
focusScroller: PropTypes.bool.isRequired,
header: PropTypes.node.isRequired,
headerHeight: PropTypes.number.isRequired,
- rowRenderer: PropTypes.func.isRequired
+ rowRenderer: PropTypes.func.isRequired,
+ rowHeight: PropTypes.number.isRequired
};
VirtualTable.defaultProps = {
className: styles.tableContainer,
headerHeight: 38,
+ rowHeight: ROW_HEIGHT,
focusScroller: true
};
diff --git a/frontend/src/Indexer/Index/IndexerIndex.tsx b/frontend/src/Indexer/Index/IndexerIndex.tsx
index 212edbd27..587206066 100644
--- a/frontend/src/Indexer/Index/IndexerIndex.tsx
+++ b/frontend/src/Indexer/Index/IndexerIndex.tsx
@@ -158,7 +158,7 @@ const IndexerIndex = withScrollPosition((props: IndexerIndexProps) => {
const characters = items.reduce((acc, item) => {
let char = item.sortName.charAt(0);
- if (!isNaN(char)) {
+ if (!isNaN(Number(char))) {
char = '#';
}
diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexTable.tsx b/frontend/src/Indexer/Index/Table/IndexerIndexTable.tsx
index bfa7e3d38..939c02abb 100644
--- a/frontend/src/Indexer/Index/Table/IndexerIndexTable.tsx
+++ b/frontend/src/Indexer/Index/Table/IndexerIndexTable.tsx
@@ -92,11 +92,9 @@ function IndexerIndexTable(props: IndexerIndexTableProps) {
const columns = useSelector(columnsSelector);
const { showBanners } = useSelector(selectTableOptions);
- const listRef: React.MutableRefObject = useRef();
+ const listRef = useRef(null);
const [measureRef, bounds] = useMeasure();
const [size, setSize] = useState({ width: 0, height: 0 });
- const windowWidth = window.innerWidth;
- const windowHeight = window.innerHeight;
const rowHeight = useMemo(() => {
return showBanners ? 70 : 38;
@@ -107,8 +105,8 @@ function IndexerIndexTable(props: IndexerIndexTableProps) {
if (isSmallScreen) {
setSize({
- width: windowWidth,
- height: windowHeight,
+ width: window.innerWidth,
+ height: window.innerHeight,
});
return;
@@ -121,14 +119,14 @@ function IndexerIndexTable(props: IndexerIndexTableProps) {
setSize({
width: width - padding * 2,
- height: windowHeight,
+ height: window.innerHeight,
});
}
- }, [isSmallScreen, windowWidth, windowHeight, scrollerRef, bounds]);
+ }, [isSmallScreen, scrollerRef, bounds]);
useEffect(() => {
- const currentScrollListener = isSmallScreen ? window : scrollerRef.current;
- const currentScrollerRef = scrollerRef.current;
+ const currentScrollerRef = scrollerRef.current as HTMLElement;
+ const currentScrollListener = isSmallScreen ? window : currentScrollerRef;
const handleScroll = throttle(() => {
const { offsetTop = 0 } = currentScrollerRef;
@@ -137,7 +135,7 @@ function IndexerIndexTable(props: IndexerIndexTableProps) {
? getWindowScrollTopPosition()
: currentScrollerRef.scrollTop) - offsetTop;
- listRef.current.scrollTo(scrollTop);
+ listRef.current?.scrollTo(scrollTop);
}, 10);
currentScrollListener.addEventListener('scroll', handleScroll);
@@ -166,8 +164,8 @@ function IndexerIndexTable(props: IndexerIndexTableProps) {
scrollTop += offset;
}
- listRef.current.scrollTo(scrollTop);
- scrollerRef.current.scrollTo(0, scrollTop);
+ listRef.current?.scrollTo(scrollTop);
+ scrollerRef.current?.scrollTo(0, scrollTop);
}
}
}, [jumpToCharacter, rowHeight, items, scrollerRef, listRef]);
diff --git a/frontend/src/Search/SearchIndex.js b/frontend/src/Search/SearchIndex.js
index 62748f641..ba25b0912 100644
--- a/frontend/src/Search/SearchIndex.js
+++ b/frontend/src/Search/SearchIndex.js
@@ -154,7 +154,7 @@ class SearchIndex extends Component {
const characters = _.reduce(items, (acc, item) => {
let char = item.sortTitle.charAt(0);
- if (!isNaN(char)) {
+ if (!isNaN(Number(char))) {
char = '#';
}
diff --git a/frontend/src/Store/Selectors/createIndexerClientSideCollectionItemsSelector.js b/frontend/src/Store/Selectors/createIndexerClientSideCollectionItemsSelector.js
index 098562877..c0edaa6dd 100644
--- a/frontend/src/Store/Selectors/createIndexerClientSideCollectionItemsSelector.js
+++ b/frontend/src/Store/Selectors/createIndexerClientSideCollectionItemsSelector.js
@@ -9,12 +9,12 @@ function createUnoptimizedSelector(uiSection) {
const items = indexers.items.map((s) => {
const {
id,
- name
+ sortName
} = s;
return {
id,
- sortName: name
+ sortName
};
});
diff --git a/frontend/src/Store/Selectors/createReleaseClientSideCollectionItemsSelector.js b/frontend/src/Store/Selectors/createReleaseClientSideCollectionItemsSelector.js
index c76ba4236..4bc195aa5 100644
--- a/frontend/src/Store/Selectors/createReleaseClientSideCollectionItemsSelector.js
+++ b/frontend/src/Store/Selectors/createReleaseClientSideCollectionItemsSelector.js
@@ -9,13 +9,13 @@ function createUnoptimizedSelector(uiSection) {
const items = releases.items.map((s) => {
const {
guid,
- title,
+ sortTitle,
indexerId
} = s;
return {
guid,
- sortTitle: title,
+ sortTitle,
indexerId
};
});
@@ -40,7 +40,7 @@ const createMovieEqualSelector = createSelectorCreator(
function createReleaseClientSideCollectionItemsSelector(uiSection) {
return createMovieEqualSelector(
createUnoptimizedSelector(uiSection),
- (movies) => movies
+ (releases) => releases
);
}
diff --git a/frontend/src/Utilities/Array/getIndexOfFirstCharacter.js b/frontend/src/Utilities/Array/getIndexOfFirstCharacter.js
index 5cbb30085..a0dbc4d0d 100644
--- a/frontend/src/Utilities/Array/getIndexOfFirstCharacter.js
+++ b/frontend/src/Utilities/Array/getIndexOfFirstCharacter.js
@@ -1,9 +1,9 @@
export default function getIndexOfFirstCharacter(items, character) {
return items.findIndex((item) => {
- const firstCharacter = item.sortTitle.charAt(0);
+ const firstCharacter = 'sortName' in item ? item.sortName.charAt(0) : item.sortTitle.charAt(0);
if (character === '#') {
- return !isNaN(firstCharacter);
+ return !isNaN(Number(firstCharacter));
}
return firstCharacter === character;
diff --git a/package.json b/package.json
index 9d8d54aff..b3ce34388 100644
--- a/package.json
+++ b/package.json
@@ -73,7 +73,7 @@
"react-router-dom": "5.2.0",
"react-text-truncate": "0.19.0",
"react-use-measure": "2.1.1",
- "react-virtualized": "9.22.3",
+ "react-virtualized": "9.21.1",
"react-window": "1.8.8",
"redux": "4.2.1",
"redux-actions": "2.6.5",
diff --git a/yarn.lock b/yarn.lock
index a21da4ac6..2a0332158 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -980,7 +980,7 @@
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
@@ -2077,6 +2077,14 @@ babel-plugin-transform-react-remove-prop-types@0.4.24:
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a"
integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==
+babel-runtime@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
+ integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==
+ dependencies:
+ core-js "^2.4.0"
+ regenerator-runtime "^0.11.0"
+
balanced-match@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.1.0.tgz#b504bd05869b39259dd0c5efc35d843176dccc4a"
@@ -2326,7 +2334,7 @@ clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
-clsx@^1.0.4:
+clsx@^1.0.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
@@ -2461,6 +2469,11 @@ core-js@3.30.2:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.30.2.tgz#6528abfda65e5ad728143ea23f7a14f0dcf503fc"
integrity sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==
+core-js@^2.4.0:
+ version "2.6.12"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
+ integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
+
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@@ -2730,13 +2743,12 @@ dom-css@^2.0.0:
prefix-style "2.0.1"
to-camel-case "1.0.0"
-dom-helpers@^5.1.3:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
- integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
+"dom-helpers@^2.4.0 || ^3.0.0":
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
+ integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
dependencies:
- "@babel/runtime" "^7.8.7"
- csstype "^3.0.2"
+ "@babel/runtime" "^7.1.2"
dom-serializer@^1.0.1:
version "1.4.1"
@@ -4179,6 +4191,11 @@ line-diff@^2.0.1:
dependencies:
levdist "^1.0.0"
+linear-layout-vector@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/linear-layout-vector/-/linear-layout-vector-0.0.1.tgz#398114d7303b6ecc7fd6b273af7b8401d8ba9c70"
+ integrity sha512-w+nr1ZOVFGyMhwr8JKo0YzqDc8C2Z7pc9UbTuJA4VG/ezlSFEx+7kNrfCYvq7JQ/jHKR+FWy6reNrkVVzm0hSA==
+
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
@@ -4308,7 +4325,7 @@ lodash@4.17.21, lodash@^4.17.14, lodash@^4.17.20, lodash@^4.17.21:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -5099,7 +5116,7 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-prop-types@15.8.1, prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
+prop-types@15.8.1, prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -5394,16 +5411,17 @@ react-use-measure@2.1.1:
dependencies:
debounce "^1.2.1"
-react-virtualized@9.22.3:
- version "9.22.3"
- resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
- integrity sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==
- dependencies:
- "@babel/runtime" "^7.7.2"
- clsx "^1.0.4"
- dom-helpers "^5.1.3"
- loose-envify "^1.4.0"
- prop-types "^15.7.2"
+react-virtualized@9.21.1:
+ version "9.21.1"
+ resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.21.1.tgz#4dbbf8f0a1420e2de3abf28fbb77120815277b3a"
+ integrity sha512-E53vFjRRMCyUTEKuDLuGH1ld/9TFzjf/fFW816PE4HFXWZorESbSTYtiZz1oAjra0MminaUU1EnvUxoGuEFFPA==
+ dependencies:
+ babel-runtime "^6.26.0"
+ clsx "^1.0.1"
+ dom-helpers "^2.4.0 || ^3.0.0"
+ linear-layout-vector "0.0.1"
+ loose-envify "^1.3.0"
+ prop-types "^15.6.0"
react-lifecycles-compat "^3.0.4"
react-window@1.8.8:
@@ -5542,6 +5560,11 @@ regenerate@^1.4.2:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
+regenerator-runtime@^0.11.0:
+ version "0.11.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
+ integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
+
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"