feat: wip: new-virtualized-list

release/desktop
moonrailgun 3 years ago
parent 66fbf1a024
commit 3003ac965f

@ -39,6 +39,7 @@
"react-router-dom": "^5.2.0",
"react-transition-group": "^4.4.2",
"react-use-gesture": "^9.1.3",
"react-virtualized": "^9.22.3",
"react-virtualized-auto-sizer": "^1.0.6",
"socket.io-client": "^4.1.2",
"str2int": "^1.1.0",
@ -63,6 +64,7 @@
"@types/react-router": "^5.1.15",
"@types/react-router-dom": "^5.1.7",
"@types/react-transition-group": "^4.4.2",
"@types/react-virtualized": "^9.21.14",
"@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/webpack": "^5.28.0",
"@types/webpack-dev-server": "^4.3.1",

@ -0,0 +1,175 @@
import React, {
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
} from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { ChatMessage, t, usePrevious, useUpdateRef } from 'tailchat-shared';
import { messageReverseItemId } from './const';
import { buildMessageItemRow } from './Item';
import type { MessageListProps } from './types';
import {
List,
CellMeasurer,
CellMeasurerCache,
ListRowRenderer,
InfiniteLoader,
} from 'react-virtualized';
// const OVERSCAN_COUNT_BACKWARD = 80;
// const OVERSCAN_COUNT_FORWARD = 80;
// const HEIGHT_TRIGGER_FOR_MORE_POSTS = 200; // 触发加载更多的方法
// const postListStyle = {
// padding: '14px 0px 7px',
// };
// const virtListStyles: React.CSSProperties = {
// position: 'absolute',
// bottom: 0,
// maxHeight: '100%',
// };
// const dynamicListStyle: React.CSSProperties = {}; // TODO
export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
(props) => {
const listRef = useRef<List>(null);
// const postListRef = useRef<HTMLDivElement>(null);
// const [isBottom, setIsBottom] = useState(true);
// useLockScroll(props.messages, listRef);
useEffect(() => {
listRef.current?.scrollToRow(props.messages.length - 1);
}, [props.messages]);
// const handleScroll = (info: OnScrollInfo) => {
// const {
// clientHeight,
// scrollOffset,
// scrollHeight,
// scrollDirection,
// scrollUpdateWasRequested,
// } = info;
// if (scrollHeight <= 0) {
// return;
// }
// const didUserScrollBackwards =
// scrollDirection === 'backward' && !scrollUpdateWasRequested;
// const isOffsetWithInRange = scrollOffset < HEIGHT_TRIGGER_FOR_MORE_POSTS;
// if (
// didUserScrollBackwards &&
// isOffsetWithInRange &&
// !props.isLoadingMore
// ) {
// // 加载更多历史信息
// props.onLoadMore();
// }
// if (clientHeight + scrollOffset === scrollHeight) {
// // 当前滚动条位于底部
// setIsBottom(true);
// props.onUpdateReadedMessage(
// props.messages[props.messages.length - 1]._id
// );
// }
// };
// const onUpdateReadedMessageRef = useUpdateRef(props.onUpdateReadedMessage);
// useEffect(() => {
// if (props.messages.length === 0) {
// return;
// }
// if (postListRef.current?.scrollTop === 0) {
// // 当前列表在最低
// onUpdateReadedMessageRef.current(
// props.messages[props.messages.length - 1]._id
// );
// }
// }, [props.messages.length]);
/**
*
*/
const rowRenderer: ListRowRenderer = ({ index, key, parent, style }) => {
// if (key === messageReverseItemId.OLDER_MESSAGES_LOADER) {
// return (
// <div key={key} className="text-center text-gray-400">
// {t('加载中...')}
// </div>
// );
// } else if (key === messageReverseItemId.TEXT_CHANNEL_INTRO) {
// return (
// <div key={key} className="text-center text-gray-400">
// {t('到顶了')}
// </div>
// );
// }
return (
<CellMeasurer
cache={measurerCache}
columnIndex={0}
key={key}
rowIndex={index}
parent={parent}
>
{({ measure, registerChild }) => (
<div
ref={(el) => el && registerChild && registerChild(el)}
onLoad={measure}
style={style}
>
{buildMessageItemRow(props.messages, props.messages[index]._id)}
{/* {buildMessageItemRow(props.messages, key)} */}
</div>
)}
</CellMeasurer>
);
};
// const itemData = useMemo(
// () => [
// ...props.messages.map((m) => m._id).reverse(),
// props.hasMoreMessage
// ? messageReverseItemId.OLDER_MESSAGES_LOADER
// : messageReverseItemId.TEXT_CHANNEL_INTRO,
// ],
// [props.messages, props.hasMoreMessage]
// );
const measurerCache = useMemo(
() =>
new CellMeasurerCache({
fixedWidth: true,
minHeight: 24,
}),
[]
);
return (
<AutoSizer>
{({ height, width }) => (
<List
ref={listRef}
height={height}
width={width}
overscanRowCount={0}
rowCount={props.messages.length}
deferredMeasurementCache={measurerCache}
rowHeight={measurerCache.rowHeight}
rowRenderer={rowRenderer}
onRowsRendered={({ startIndex }) => console.log(startIndex)}
scrollToIndex={props.messages.length - 1}
scrollToAlignment="end"
/>
)}
</AutoSizer>
);
}
);
VirtualizedMessageList.displayName = 'VirtualizedMessageList';

@ -1,7 +1,8 @@
import React from 'react';
import { NormalMessageList } from './NormalList';
import type { MessageListProps } from './types';
import { VirtualizedMessageList } from './VirtualizedList';
// import { VirtualizedMessageList } from './VirtualizedList';
import { VirtualizedMessageList } from './VirtualizedList.new';
const useVirtualizedList = true; // 是否使用虚拟化列表

@ -2134,6 +2134,14 @@
dependencies:
"@types/react" "*"
"@types/react-virtualized@^9.21.14":
version "9.21.14"
resolved "https://registry.npmmirror.com/@types/react-virtualized/download/@types/react-virtualized-9.21.14.tgz#8d465aa54386a7bebc7b61f71afc588bb800b868"
integrity sha1-jUZapUOGp768e2H3GvxYi7gAuGg=
dependencies:
"@types/prop-types" "*"
"@types/react" "*"
"@types/react@*", "@types/react@^17.0.11":
version "17.0.11"
resolved "https://registry.npmjs.org/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451"
@ -3596,7 +3604,7 @@ cloneable-readable@^1.0.0:
process-nextick-args "^2.0.0"
readable-stream "^2.3.5"
clsx@^1.1.1:
clsx@^1.0.4, clsx@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
@ -4418,7 +4426,7 @@ dom-converter@^0.2.0:
dependencies:
utila "~0.4"
dom-helpers@^5.0.1:
dom-helpers@^5.0.1, dom-helpers@^5.1.3:
version "5.2.1"
resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
@ -9123,6 +9131,11 @@ react-is@^17.0.1:
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.npmmirror.com/react-lifecycles-compat/download/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha1-TxonOv38jzSIqMUWv9p4+HI1I2I=
"react-native-storage@npm:@trpgengine/react-native-storage@^1.0.1":
version "1.0.1"
resolved "https://registry.npmjs.org/@trpgengine/react-native-storage/-/react-native-storage-1.0.1.tgz#7571ec0d837150a4eec123ae7b938084b3c70413"
@ -9206,6 +9219,18 @@ react-virtualized-auto-sizer@^1.0.6:
resolved "https://registry.nlark.com/react-virtualized-auto-sizer/download/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca"
integrity sha1-ZsWxySeAZMXvFpntQKKcEVGPl8o=
react-virtualized@^9.22.3:
version "9.22.3"
resolved "https://registry.nlark.com/react-virtualized/download/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
integrity sha1-9DDxa+sKQttCDb1NNAQDwN4zRCE=
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@^17.0.2:
version "17.0.2"
resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"

Loading…
Cancel
Save