use react-virtualized to speed up user items page
There's a known bug that items with a lot of zones will overflow the row… filing that as a separate fix tho!
This commit is contained in:
parent
6762c6d3fa
commit
0c2ec4685e
4 changed files with 79 additions and 5 deletions
|
@ -37,6 +37,7 @@
|
|||
"react-router-dom": "^5.1.2",
|
||||
"react-scripts": "3.4.1",
|
||||
"react-transition-group": "^4.3.0",
|
||||
"react-virtualized": "^9.22.2",
|
||||
"simple-markdown": "^0.7.2",
|
||||
"xmlrpc": "^1.3.2"
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
Portal,
|
||||
Wrap,
|
||||
VStack,
|
||||
useBreakpointValue,
|
||||
useToast,
|
||||
} from "@chakra-ui/core";
|
||||
import {
|
||||
|
@ -30,6 +31,7 @@ import {
|
|||
import gql from "graphql-tag";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import { useQuery, useLazyQuery, useMutation } from "@apollo/client";
|
||||
import { AutoSizer, Grid, WindowScroller } from "react-virtualized";
|
||||
import SimpleMarkdown from "simple-markdown";
|
||||
import DOMPurify from "dompurify";
|
||||
|
||||
|
@ -37,7 +39,6 @@ import HangerSpinner from "./components/HangerSpinner";
|
|||
import { Heading1, Heading2, Heading3 } from "./util";
|
||||
import ItemCard, {
|
||||
ItemBadgeList,
|
||||
ItemCardList,
|
||||
ItemKindBadge,
|
||||
YouOwnThisBadge,
|
||||
YouWantThisBadge,
|
||||
|
@ -234,7 +235,13 @@ function UserItemsPage() {
|
|||
<Heading2 id="owned-items" marginBottom="2">
|
||||
{isCurrentUser ? "Items you own" : `Items ${data.user.username} owns`}
|
||||
</Heading2>
|
||||
<VStack spacing="8" alignItems="stretch">
|
||||
<VStack
|
||||
spacing="8"
|
||||
alignItems="stretch"
|
||||
className={css`
|
||||
clear: both;
|
||||
`}
|
||||
>
|
||||
{listsOfOwnedItems.map((closetList) => (
|
||||
<ClosetList
|
||||
key={closetList.id}
|
||||
|
@ -437,7 +444,7 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
|
|||
</Box>
|
||||
)}
|
||||
{sortedItems.length > 0 ? (
|
||||
<ItemCardList>
|
||||
<VirtualizedItemCardList>
|
||||
{sortedItems.map((item) => (
|
||||
<ItemCard
|
||||
key={item.id}
|
||||
|
@ -454,7 +461,7 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
|
|||
}
|
||||
/>
|
||||
))}
|
||||
</ItemCardList>
|
||||
</VirtualizedItemCardList>
|
||||
) : (
|
||||
<Box fontStyle="italic">This list is empty!</Box>
|
||||
)}
|
||||
|
@ -462,6 +469,51 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
|
|||
);
|
||||
}
|
||||
|
||||
function VirtualizedItemCardList({ children }) {
|
||||
const columnCount = useBreakpointValue({ base: 1, md: 2, lg: 3 });
|
||||
const rowCount = Math.ceil(children.length / columnCount);
|
||||
|
||||
return (
|
||||
<AutoSizer disableHeight>
|
||||
{({ width }) => (
|
||||
<WindowScroller>
|
||||
{({
|
||||
height,
|
||||
isScrolling,
|
||||
onChildScroll,
|
||||
scrollTop,
|
||||
registerChild,
|
||||
}) => (
|
||||
<Box ref={registerChild}>
|
||||
<Grid
|
||||
cellRenderer={({ key, rowIndex, columnIndex, style }) => (
|
||||
<Box
|
||||
key={key}
|
||||
style={style}
|
||||
paddingLeft={columnIndex > 0 ? "6" : "0"}
|
||||
>
|
||||
{children[rowIndex * columnCount + columnIndex]}
|
||||
</Box>
|
||||
)}
|
||||
columnCount={columnCount}
|
||||
columnWidth={width / columnCount}
|
||||
rowCount={rowCount}
|
||||
rowHeight={100}
|
||||
width={width}
|
||||
height={height}
|
||||
autoHeight
|
||||
isScrolling={isScrolling}
|
||||
onScroll={onChildScroll}
|
||||
scrollTop={scrollTop}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</WindowScroller>
|
||||
)}
|
||||
</AutoSizer>
|
||||
);
|
||||
}
|
||||
|
||||
const unsafeMarkdownRules = {
|
||||
autolink: SimpleMarkdown.defaultRules.autolink,
|
||||
br: SimpleMarkdown.defaultRules.br,
|
||||
|
|
|
@ -22,6 +22,7 @@ function ItemCard({ item, badges, ...props }) {
|
|||
<Box
|
||||
as={Link}
|
||||
to={`/items/${item.id}`}
|
||||
display="block"
|
||||
p="2"
|
||||
boxShadow="lg"
|
||||
borderRadius="lg"
|
||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -7240,7 +7240,7 @@ clone-deep@^4.0.1:
|
|||
kind-of "^6.0.2"
|
||||
shallow-clone "^3.0.0"
|
||||
|
||||
clsx@^1.1.1:
|
||||
clsx@^1.0.4, clsx@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
||||
|
@ -8293,6 +8293,14 @@ dom-helpers@^5.0.1:
|
|||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^2.6.7"
|
||||
|
||||
dom-helpers@^5.1.3:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
|
||||
integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^3.0.2"
|
||||
|
||||
dom-serializer@0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
||||
|
@ -15362,6 +15370,18 @@ react-transition-group@^4.3.0:
|
|||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-virtualized@^9.22.2:
|
||||
version "9.22.2"
|
||||
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.2.tgz#217a870bad91e5438f46f01a009e1d8ce1060a5a"
|
||||
integrity sha512-5j4h4FhxTdOpBKtePSs1yk6LDNT4oGtUwjT7Nkh61Z8vv3fTG/XeOf8J4li1AYaexOwTXnw0HFVxsV0GBUqwRw==
|
||||
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-lifecycles-compat "^3.0.4"
|
||||
|
||||
react@^16.13.1, react@^16.8.3:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
||||
|
|
Loading…
Reference in a new issue