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-router-dom": "^5.1.2",
|
||||||
"react-scripts": "3.4.1",
|
"react-scripts": "3.4.1",
|
||||||
"react-transition-group": "^4.3.0",
|
"react-transition-group": "^4.3.0",
|
||||||
|
"react-virtualized": "^9.22.2",
|
||||||
"simple-markdown": "^0.7.2",
|
"simple-markdown": "^0.7.2",
|
||||||
"xmlrpc": "^1.3.2"
|
"xmlrpc": "^1.3.2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
Portal,
|
Portal,
|
||||||
Wrap,
|
Wrap,
|
||||||
VStack,
|
VStack,
|
||||||
|
useBreakpointValue,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/core";
|
} from "@chakra-ui/core";
|
||||||
import {
|
import {
|
||||||
|
@ -30,6 +31,7 @@ import {
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
import { useHistory, useParams } from "react-router-dom";
|
import { useHistory, useParams } from "react-router-dom";
|
||||||
import { useQuery, useLazyQuery, useMutation } from "@apollo/client";
|
import { useQuery, useLazyQuery, useMutation } from "@apollo/client";
|
||||||
|
import { AutoSizer, Grid, WindowScroller } from "react-virtualized";
|
||||||
import SimpleMarkdown from "simple-markdown";
|
import SimpleMarkdown from "simple-markdown";
|
||||||
import DOMPurify from "dompurify";
|
import DOMPurify from "dompurify";
|
||||||
|
|
||||||
|
@ -37,7 +39,6 @@ import HangerSpinner from "./components/HangerSpinner";
|
||||||
import { Heading1, Heading2, Heading3 } from "./util";
|
import { Heading1, Heading2, Heading3 } from "./util";
|
||||||
import ItemCard, {
|
import ItemCard, {
|
||||||
ItemBadgeList,
|
ItemBadgeList,
|
||||||
ItemCardList,
|
|
||||||
ItemKindBadge,
|
ItemKindBadge,
|
||||||
YouOwnThisBadge,
|
YouOwnThisBadge,
|
||||||
YouWantThisBadge,
|
YouWantThisBadge,
|
||||||
|
@ -234,7 +235,13 @@ function UserItemsPage() {
|
||||||
<Heading2 id="owned-items" marginBottom="2">
|
<Heading2 id="owned-items" marginBottom="2">
|
||||||
{isCurrentUser ? "Items you own" : `Items ${data.user.username} owns`}
|
{isCurrentUser ? "Items you own" : `Items ${data.user.username} owns`}
|
||||||
</Heading2>
|
</Heading2>
|
||||||
<VStack spacing="8" alignItems="stretch">
|
<VStack
|
||||||
|
spacing="8"
|
||||||
|
alignItems="stretch"
|
||||||
|
className={css`
|
||||||
|
clear: both;
|
||||||
|
`}
|
||||||
|
>
|
||||||
{listsOfOwnedItems.map((closetList) => (
|
{listsOfOwnedItems.map((closetList) => (
|
||||||
<ClosetList
|
<ClosetList
|
||||||
key={closetList.id}
|
key={closetList.id}
|
||||||
|
@ -437,7 +444,7 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{sortedItems.length > 0 ? (
|
{sortedItems.length > 0 ? (
|
||||||
<ItemCardList>
|
<VirtualizedItemCardList>
|
||||||
{sortedItems.map((item) => (
|
{sortedItems.map((item) => (
|
||||||
<ItemCard
|
<ItemCard
|
||||||
key={item.id}
|
key={item.id}
|
||||||
|
@ -454,7 +461,7 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ItemCardList>
|
</VirtualizedItemCardList>
|
||||||
) : (
|
) : (
|
||||||
<Box fontStyle="italic">This list is empty!</Box>
|
<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 = {
|
const unsafeMarkdownRules = {
|
||||||
autolink: SimpleMarkdown.defaultRules.autolink,
|
autolink: SimpleMarkdown.defaultRules.autolink,
|
||||||
br: SimpleMarkdown.defaultRules.br,
|
br: SimpleMarkdown.defaultRules.br,
|
||||||
|
|
|
@ -22,6 +22,7 @@ function ItemCard({ item, badges, ...props }) {
|
||||||
<Box
|
<Box
|
||||||
as={Link}
|
as={Link}
|
||||||
to={`/items/${item.id}`}
|
to={`/items/${item.id}`}
|
||||||
|
display="block"
|
||||||
p="2"
|
p="2"
|
||||||
boxShadow="lg"
|
boxShadow="lg"
|
||||||
borderRadius="lg"
|
borderRadius="lg"
|
||||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -7240,7 +7240,7 @@ clone-deep@^4.0.1:
|
||||||
kind-of "^6.0.2"
|
kind-of "^6.0.2"
|
||||||
shallow-clone "^3.0.0"
|
shallow-clone "^3.0.0"
|
||||||
|
|
||||||
clsx@^1.1.1:
|
clsx@^1.0.4, clsx@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||||
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
||||||
|
@ -8293,6 +8293,14 @@ dom-helpers@^5.0.1:
|
||||||
"@babel/runtime" "^7.8.7"
|
"@babel/runtime" "^7.8.7"
|
||||||
csstype "^2.6.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:
|
dom-serializer@0:
|
||||||
version "0.2.2"
|
version "0.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
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"
|
loose-envify "^1.4.0"
|
||||||
prop-types "^15.6.2"
|
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:
|
react@^16.13.1, react@^16.8.3:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
||||||
|
|
Loading…
Reference in a new issue