feat: 当上滚增加历史消息时,锁定滚动条位置

pull/13/head
moonrailgun 4 years ago
parent f463ea332b
commit 082909f3d6

@ -0,0 +1,11 @@
import { useEffect, useRef } from 'react';
export function usePrevious<T>(state: T): T | undefined {
const ref = useRef<T>();
useEffect(() => {
ref.current = state;
});
return ref.current;
}

@ -53,6 +53,7 @@ export { useAsyncFn } from './hooks/useAsyncFn';
export { useAsyncRequest } from './hooks/useAsyncRequest'; export { useAsyncRequest } from './hooks/useAsyncRequest';
export { useDebounce } from './hooks/useDebounce'; export { useDebounce } from './hooks/useDebounce';
export { useMountedState } from './hooks/useMountedState'; export { useMountedState } from './hooks/useMountedState';
export { usePrevious } from './hooks/usePrevious';
export { useRafState } from './hooks/useRafState'; export { useRafState } from './hooks/useRafState';
export { useUpdateRef } from './hooks/useUpdateRef'; export { useUpdateRef } from './hooks/useUpdateRef';

@ -2,13 +2,20 @@ import DynamicSizeList, {
OnScrollInfo, OnScrollInfo,
} from '@/components/DynamicVirtualizedList/DynamicSizeList'; } from '@/components/DynamicVirtualizedList/DynamicSizeList';
import { Divider } from 'antd'; import { Divider } from 'antd';
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, {
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
} from 'react';
import AutoSizer from 'react-virtualized-auto-sizer'; import AutoSizer from 'react-virtualized-auto-sizer';
import { import {
ChatMessage, ChatMessage,
getMessageTimeDiff, getMessageTimeDiff,
shouldShowMessageTime, shouldShowMessageTime,
t, t,
usePrevious,
useUpdateRef, useUpdateRef,
} from 'tailchat-shared'; } from 'tailchat-shared';
import { messageReverseItemId } from './const'; import { messageReverseItemId } from './const';
@ -51,6 +58,7 @@ export const VirtualizedMessageList: React.FC<VirtualizedMessageListProps> =
const listRef = useRef<DynamicSizeList>(null); const listRef = useRef<DynamicSizeList>(null);
const postListRef = useRef<HTMLDivElement>(null); const postListRef = useRef<HTMLDivElement>(null);
const [isBottom, setIsBottom] = useState(true); const [isBottom, setIsBottom] = useState(true);
useLockScroll(props.messages, listRef);
const handleScroll = (info: OnScrollInfo) => { const handleScroll = (info: OnScrollInfo) => {
const { const {
@ -110,7 +118,7 @@ export const VirtualizedMessageList: React.FC<VirtualizedMessageListProps> =
/** /**
* *
*/ */
const renderRow = ({ data, itemId }: any) => { const renderRow = ({ itemId }: any) => {
if (itemId === messageReverseItemId.OLDER_MESSAGES_LOADER) { if (itemId === messageReverseItemId.OLDER_MESSAGES_LOADER) {
return ( return (
<div key={itemId} className="text-center text-gray-400"> <div key={itemId} className="text-center text-gray-400">
@ -208,3 +216,29 @@ export const VirtualizedMessageList: React.FC<VirtualizedMessageListProps> =
); );
}); });
VirtualizedMessageList.displayName = 'VirtualizedMessageList'; VirtualizedMessageList.displayName = 'VirtualizedMessageList';
/**
*
*/
function useLockScroll(
messages: ChatMessage[],
listRef: React.RefObject<DynamicSizeList>
) {
const previousMessages = usePrevious(messages);
const previousScrollHeight = usePrevious(
listRef.current?._outerRef?.scrollHeight
);
useLayoutEffect(() => {
if (previousMessages && messages[0]._id !== previousMessages[0]._id) {
// 增加了历史消息
if (listRef.current?._outerRef) {
// 能够拿到容器
listRef.current.scrollTo(
listRef.current._outerRef.scrollTop +
listRef.current._outerRef.scrollHeight -
(previousScrollHeight || 0)
);
}
}
}, [messages.length, previousMessages?.length]);
}

Loading…
Cancel
Save