Web: Components: moved to react-virtualized, fixed blue screen

This commit is contained in:
Nikita Gopienko 2022-08-12 10:35:32 +03:00
parent 492ed86674
commit 28c73a4a7c
4 changed files with 120 additions and 154 deletions

View File

@ -1,8 +1,6 @@
import React, { memo, useCallback, useEffect, useRef } from "react";
import AutoSizer from "react-virtualized-auto-sizer";
import InfiniteLoader from "react-window-infinite-loader";
import { VariableSizeList as List, areEqual } from "react-window";
//import Scroll from "./Scroll";
import React, { useCallback } from "react";
import { InfiniteLoader, WindowScroller, AutoSizer } from "react-virtualized";
import { StyledList } from "./StyledInfiniteLoader";
const GridComponent = ({
hasMoreFiles,
@ -11,36 +9,26 @@ const GridComponent = ({
loadMoreItems,
onScroll,
countTilesInRow,
selectedFolderId,
children,
className,
listRef,
scroll,
}) => {
const gridRef = useRef(null);
useEffect(() => {
//TODO: inf-scroll it is slow
//console.log("resetAfterIndex");
gridRef?.current?.resetAfterIndex(0);
}, [selectedFolderId]);
const isItemLoaded = useCallback(
(index) => {
({ index }) => {
return !hasMoreFiles || index * countTilesInRow < filesLength;
},
[filesLength, hasMoreFiles, countTilesInRow]
);
const renderTile = memo(({ index, style }) => {
const renderTile = ({ index, style, key }) => {
return (
<div className="window-item" style={style}>
<div className="window-item" style={style} key={key}>
{children[index]}
</div>
);
}, areEqual);
};
const getItemSize = (index) => {
const getItemSize = ({ index }) => {
const itemClassNames = children[index]?.props?.className;
const isFile = itemClassNames?.includes("isFile");
const isFolder = itemClassNames?.includes("isFolder");
@ -56,41 +44,40 @@ const GridComponent = ({
return isFolder ? folderHeight : isFile ? fileHeight : titleHeight;
};
const renderGrid = ({ height, width }) => {
return (
<InfiniteLoader
isItemLoaded={isItemLoaded}
itemCount={itemCount}
loadMoreItems={loadMoreItems}
>
{({ onItemsRendered, ref }) => (
<List
onScroll={onScroll}
className={className}
height={height}
width={width}
itemCount={children.length}
itemSize={getItemSize}
onItemsRendered={onItemsRendered}
ref={(refList) => {
ref(listRef);
gridRef.current = refList;
listRef.current = refList;
}}
//outerElementType={Scroll}
overscanCount={5} //TODO: inf-scroll
style={{ height: "100% !important", overflow: "hidden" }}
>
{renderTile}
</List>
)}
</InfiniteLoader>
);
};
//console.log("GridComponent render");
return <AutoSizer>{renderGrid}</AutoSizer>;
return (
<InfiniteLoader
isRowLoaded={isItemLoaded}
rowCount={itemCount}
loadMoreRows={loadMoreItems}
>
{({ onRowsRendered, registerChild }) => (
<WindowScroller scrollElement={scroll}>
{({ height, isScrolling, onChildScroll, scrollTop }) => (
<AutoSizer>
{({ width }) => (
<StyledList
autoHeight
height={height}
onRowsRendered={onRowsRendered}
ref={registerChild}
rowCount={children.length}
rowHeight={getItemSize}
rowRenderer={renderTile}
width={width}
className={className}
isScrolling={isScrolling}
onChildScroll={onChildScroll}
scrollTop={scrollTop}
overscanRowCount={3}
onScroll={onScroll}
/>
)}
</AutoSizer>
)}
</WindowScroller>
)}
</InfiniteLoader>
);
};
export default GridComponent;

View File

@ -1,33 +1,18 @@
import React, { useRef } from "react";
import React from "react";
import PropTypes from "prop-types";
import { WindowScroller } from "react-virtualized";
import { isMobileOnly } from "react-device-detect";
import ListComponent from "./List";
import GridComponent from "./Grid";
const InfiniteLoaderComponent = (props) => {
const ref = useRef(null);
const scroll = isMobileOnly
? document.querySelector("#customScrollBar > .scroll-body")
: document.querySelector("#sectionScroll > .scroll-body");
const onScroll = ({ scrollTop }) => {
ref.current.scrollTo(scrollTop);
};
return (
<>
<WindowScroller scrollElement={scroll} onScroll={onScroll}>
{() => <div />}
</WindowScroller>
{props.viewAs === "tile" ? (
<GridComponent listRef={ref} {...props} />
) : (
<ListComponent listRef={ref} {...props} />
)}
</>
return props.viewAs === "tile" ? (
<GridComponent scroll={scroll} {...props} />
) : (
<ListComponent scroll={scroll} {...props} />
);
};
InfiniteLoaderComponent.propTypes = {

View File

@ -1,54 +1,42 @@
import React, { memo, useCallback, useEffect, useRef } from "react";
import AutoSizer from "react-virtualized-auto-sizer";
import InfiniteLoader from "react-window-infinite-loader";
import { FixedSizeList as List, areEqual } from "react-window";
//import Scroll from "./Scroll";
import React, { useCallback } from "react";
import { InfiniteLoader, WindowScroller, AutoSizer } from "react-virtualized";
import Loaders from "@docspace/common/components/Loaders";
import { StyledTableLoader, StyledRowLoader } from "./StyledInfiniteLoader";
import { StyledList } from "./StyledInfiniteLoader";
const ListComponent = ({
viewAs,
hasMoreFiles,
filesLength,
itemCount,
onScroll,
loadMoreItems,
itemSize,
onScroll,
columnStorageName,
selectedFolderId,
children,
className,
listRef,
scroll,
}) => {
const listComponentRef = useRef(null);
useEffect(() => {
//TODO: inf-scroll it is slow
listComponentRef?.current?.resetAfterIndex(0);
}, [selectedFolderId]);
const renderRow = memo(({ index, style }) => {
const isLoaded = isItemLoaded(index + 1);
if (!isLoaded) return getLoader(style);
const renderRow = ({ key, index, style }) => {
const isLoaded = isItemLoaded({ index: index + 2 });
if (!isLoaded) return getLoader(style, key);
return (
<div className="row-list-item window-item" style={style}>
<div className="row-list-item window-item" style={style} key={key}>
{children[index]}
</div>
);
}, areEqual);
};
const isItemLoaded = useCallback(
(index) => !hasMoreFiles || index < filesLength,
({ index }) => !hasMoreFiles || index < filesLength,
[filesLength, hasMoreFiles]
);
const renderTable = memo(({ index, style }) => {
const renderTable = ({ index, style, key }) => {
const storageSize = localStorage.getItem(columnStorageName);
const isLoaded = isItemLoaded(index + 1);
if (!isLoaded) return getLoader(style);
const isLoaded = isItemLoaded({ index: index + 2 });
if (!isLoaded) return getLoader(style, key);
return (
<div
@ -58,66 +46,78 @@ const ListComponent = ({
display: "grid",
gridTemplateColumns: storageSize,
}}
key={key}
>
{children[index]}
</div>
);
}, areEqual);
};
const getLoader = (style) => {
const getLoader = (style, key) => {
switch (viewAs) {
case "table":
return (
<StyledTableLoader
<Loaders.TableLoader
key={key}
style={style}
className="table-container_body-loader"
>
<Loaders.TableLoader count={2} />
</StyledTableLoader>
count={1}
/>
);
case "row":
return (
<StyledRowLoader style={style} className="row-loader">
<Loaders.Rows count={2} />
</StyledRowLoader>
<Loaders.Rows
key={key}
style={style}
className="row-loader"
count={1}
/>
);
default:
return <></>;
}
};
const renderList = ({ height, width }) => {
return (
<InfiniteLoader
isItemLoaded={isItemLoaded}
itemCount={itemCount}
loadMoreItems={loadMoreItems}
>
{({ onItemsRendered, ref }) => (
<List
onScroll={onScroll}
className={className}
height={height}
width={width}
itemCount={children.length}
itemSize={itemSize}
onItemsRendered={onItemsRendered}
ref={(refList) => {
ref(listRef);
listComponentRef.current = refList;
listRef.current = refList;
}}
style={{ height: "100% !important", overflow: "hidden" }}
//outerElementType={Scroll}
>
{viewAs === "table" ? renderTable : renderRow}
</List>
)}
</InfiniteLoader>
);
};
return (
<InfiniteLoader
isRowLoaded={isItemLoaded}
rowCount={itemCount}
loadMoreRows={loadMoreItems}
>
{({ onRowsRendered, registerChild }) => (
<WindowScroller scrollElement={scroll}>
{({ height, isScrolling, onChildScroll, scrollTop }) => {
if (height === undefined) {
height = scroll.getBoundingClientRect().height;
}
return <AutoSizer>{renderList}</AutoSizer>;
return (
<AutoSizer>
{({ width }) => (
<StyledList
autoHeight
height={height}
onRowsRendered={onRowsRendered}
ref={registerChild}
rowCount={children.length}
rowHeight={itemSize}
rowRenderer={viewAs === "table" ? renderTable : renderRow}
width={width}
className={className}
isScrolling={isScrolling}
onChildScroll={onChildScroll}
scrollTop={scrollTop}
overscanRowCount={3}
onScroll={onScroll}
/>
)}
</AutoSizer>
);
}}
</WindowScroller>
)}
</InfiniteLoader>
);
};
export default ListComponent;

View File

@ -1,17 +1,7 @@
import { List } from "react-virtualized";
import styled from "styled-components";
import Base from "../themes/base";
const StyledTableLoader = styled.div`
grid-column-start: 1;
grid-column-end: -1;
display: grid;
padding-top: 16px;
`;
const StyledRowLoader = styled.div`
padding-top: 16px;
`;
const StyledScroll = styled.div`
overflow: scroll;
@ -38,8 +28,12 @@ const StyledScroll = styled.div`
scrollbar-color: ${({ theme }) => theme.scrollbar.backgroundColorVertical};
`;
const StyledList = styled(List)`
outline: none;
`;
StyledScroll.defaultProps = {
theme: Base,
};
export { StyledTableLoader, StyledRowLoader, StyledScroll };
export { StyledScroll, StyledList };