From 57737d76a7c5e95fe6b2fd95a3b02d7605bb9578 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sun, 14 Nov 2021 22:51:27 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BD=BF=E7=94=A8react-virtuoso?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E6=96=B0=E7=9A=84=E5=88=97=E8=A1=A8=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/package.json | 2 +- .../ChatMessageList/VirtualizedList.new.tsx | 190 +++--------------- .../ChatBox/ChatMessageList/types.ts | 2 +- yarn.lock | 20 ++ 4 files changed, 49 insertions(+), 165 deletions(-) diff --git a/web/package.json b/web/package.json index 24a31d35..0a9b2bde 100644 --- a/web/package.json +++ b/web/package.json @@ -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": "*", diff --git a/web/src/components/ChatBox/ChatMessageList/VirtualizedList.new.tsx b/web/src/components/ChatBox/ChatMessageList/VirtualizedList.new.tsx index 0ebaa3c0..28619c28 100644 --- a/web/src/components/ChatBox/ChatMessageList/VirtualizedList.new.tsx +++ b/web/src/components/ChatBox/ChatMessageList/VirtualizedList.new.tsx @@ -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 = React.memo( (props) => { - const listRef = useRef(null); - // const postListRef = useRef(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 ( - //
- // {t('加载中...')} - //
- // ); - // } else if (key === messageReverseItemId.TEXT_CHANNEL_INTRO) { - // return ( - //
- // {t('到顶了')} - //
- // ); - // } - - return ( - - {({ measure, registerChild }) => ( -
el && registerChild && registerChild(el)} - onLoad={measure} - style={style} - > - {buildMessageItemRow(props.messages, props.messages[index]._id)} - {/* {buildMessageItemRow(props.messages, key)} */} -
- )} -
- ); + const listRef = useRef(); + 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 ( - - {({ height, width }) => ( - console.log(startIndex)} - scrollToIndex={props.messages.length - 1} - scrollToAlignment="end" - /> - )} - + + buildMessageItemRow(props.messages, data._id) + } + alignToBottom={true} + startReached={handleLoadMore} + /> ); } ); diff --git a/web/src/components/ChatBox/ChatMessageList/types.ts b/web/src/components/ChatBox/ChatMessageList/types.ts index bce18d78..5256ee14 100644 --- a/web/src/components/ChatBox/ChatMessageList/types.ts +++ b/web/src/components/ChatBox/ChatMessageList/types.ts @@ -5,5 +5,5 @@ export interface MessageListProps { isLoadingMore: boolean; hasMoreMessage: boolean; onUpdateReadedMessage: (lastMessageId: string) => void; - onLoadMore: () => void; + onLoadMore: () => Promise; } diff --git a/yarn.lock b/yarn.lock index 536a43b6..839586ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"