refactor: 使用react-virtuoso进行新的列表重构

pull/81/head
moonrailgun 4 years ago
parent 3003ac965f
commit 57737d76a7

@ -39,8 +39,8 @@
"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",
"react-virtuoso": "^2.2.7",
"socket.io-client": "^4.1.2",
"str2int": "^1.1.0",
"tailchat-shared": "*",

@ -1,174 +1,38 @@
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 React, { useRef } from 'react';
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
import { Virtuoso, VirtuosoGridHandle } from 'react-virtuoso';
/**
*
*/
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 listRef = useRef<VirtuosoGridHandle>();
const lastMessageId = useRef('');
const handleLoadMore = () => {
// TODO: 待修复, 这个方法只会被触发一次
lastMessageId.current = props.messages[0]._id;
props.onLoadMore().then(() => {
listRef.current?.scrollToIndex(50);
});
return false;
};
// 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>
<Virtuoso
style={{ height: '100%' }}
ref={listRef as any}
initialTopMostItemIndex={props.messages.length - 1}
data={props.messages}
overscan={100}
itemContent={(index, data) =>
buildMessageItemRow(props.messages, data._id)
}
alignToBottom={true}
startReached={handleLoadMore}
/>
);
}
);

@ -5,5 +5,5 @@ export interface MessageListProps {
isLoadingMore: boolean;
hasMoreMessage: boolean;
onUpdateReadedMessage: (lastMessageId: string) => void;
onLoadMore: () => void;
onLoadMore: () => Promise<void>;
}

@ -2335,6 +2335,18 @@
"@typescript-eslint/types" "4.28.1"
eslint-visitor-keys "^2.0.0"
"@virtuoso.dev/react-urx@^0.2.8":
version "0.2.8"
resolved "https://registry.npmmirror.com/@virtuoso.dev/react-urx/download/@virtuoso.dev/react-urx-0.2.8.tgz#344c5559dca3a7157f34eb9d9c5e7be6f6291d24"
integrity sha1-NExVWdyjpxV/NOudnF575vYpHSQ=
dependencies:
"@virtuoso.dev/urx" "^0.2.8"
"@virtuoso.dev/urx@^0.2.8":
version "0.2.8"
resolved "https://registry.npmmirror.com/@virtuoso.dev/urx/download/@virtuoso.dev/urx-0.2.8.tgz#182884939b2a5420839c48e317059cf265210f84"
integrity sha1-GCiEk5sqVCCDnEjjFwWc8mUhD4Q=
"@webassemblyjs/ast@1.11.0":
version "1.11.0"
resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f"
@ -9231,6 +9243,14 @@ react-virtualized@^9.22.3:
prop-types "^15.7.2"
react-lifecycles-compat "^3.0.4"
react-virtuoso@^2.2.7:
version "2.2.7"
resolved "https://registry.npmmirror.com/react-virtuoso/download/react-virtuoso-2.2.7.tgz?cache=0&sync_timestamp=1636198122025&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-virtuoso%2Fdownload%2Freact-virtuoso-2.2.7.tgz#3aa7243ed79ec6257f0de30679f64e9614533d2e"
integrity sha1-OqckPteexiV/DeMGefZOlhRTPS4=
dependencies:
"@virtuoso.dev/react-urx" "^0.2.8"
"@virtuoso.dev/urx" "^0.2.8"
react@^17.0.2:
version "17.0.2"
resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"

Loading…
Cancel
Save