Update ChatPanel to handle scroll position and message fetching
- Added selectors for isTop, isBottom, and isMiddle in chatSlice. - Removed scrollPosition and stopScrolling states from ChatPanel. - Added onScrollPositionChange function to handle scroll events. - Dispatch onMessagesTop, onMessagesBottom, and onMessagesMiddle actions based on scroll position.
This commit is contained in:
parent
ec440be005
commit
9a906a1c0f
@ -24,6 +24,12 @@ import {
|
||||
selectErrorMessage,
|
||||
selectMessages,
|
||||
selectMessageCount,
|
||||
selectIsBottom,
|
||||
selectIsTop,
|
||||
selectIsMiddle,
|
||||
onMessagesBottom,
|
||||
onMessagesTop,
|
||||
onMessagesMiddle,
|
||||
fetchHistoryMessages,
|
||||
} from './chatSlice';
|
||||
|
||||
@ -89,22 +95,38 @@ const chatPanel = () => {
|
||||
const errorMessage = useAppSelector(selectErrorMessage);
|
||||
const messages = useAppSelector(selectMessages);
|
||||
const messageCount = useAppSelector(selectMessageCount);
|
||||
const isTop = useAppSelector(selectIsTop);
|
||||
const isBottom = useAppSelector(selectIsBottom);
|
||||
const isMiddle = useAppSelector(selectIsMiddle);
|
||||
const [chatContainerRef, chatContainerRect] = useResizeObserver();
|
||||
const scrollViewport = useRef<HTMLDivElement>(null);
|
||||
const { height, width } = useViewportSize();
|
||||
const [scrollPosition, onScrollPositionChange] = useState({ x: 0, y: 0 });
|
||||
const [stopScrolling, setStopScrolling] = useState(false);
|
||||
|
||||
const scrollToBottom = () =>
|
||||
scrollViewport?.current?.scrollTo({ top: scrollViewport.current.scrollHeight, behavior: 'smooth' });
|
||||
|
||||
const timer = useTimeout(() => {
|
||||
// console.log(`stopScrolling:${stopScrolling}`);
|
||||
if (!stopScrolling) {
|
||||
if (isBottom) {
|
||||
scrollToBottom();
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
const onScrollPositionChange = ({ x, y }) => {
|
||||
const sh = scrollViewport.current?.scrollHeight || 0;
|
||||
const vh = scrollViewport.current?.clientHeight || 0;
|
||||
const gap = sh - vh - y;
|
||||
const isBottom = sh < vh ? true : gap < 100;
|
||||
const isTop = y === 0;
|
||||
// console.log(`sh:${sh},vh:${vh},x:${x},y:${y},gap:${gap}`);
|
||||
if (isBottom) {
|
||||
dispatch(onMessagesBottom());
|
||||
} else if (isTop) {
|
||||
dispatch(onMessagesTop());
|
||||
} else {
|
||||
dispatch(onMessagesMiddle());
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchHistoryMessages());
|
||||
messageUtil.registerHandler('receiveMessagePartial', (message: { text: string; }) => {
|
||||
@ -122,17 +144,6 @@ const chatPanel = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const sh = scrollViewport.current?.scrollHeight || 0;
|
||||
const vh = scrollViewport.current?.clientHeight || 0;
|
||||
const isBottom = sh < vh ? true : sh - vh - scrollPosition.y < 3;
|
||||
if (isBottom) {
|
||||
setStopScrolling(false);
|
||||
} else {
|
||||
setStopScrolling(true);
|
||||
}
|
||||
}, [scrollPosition]);
|
||||
|
||||
useEffect(() => {
|
||||
if (generating) {
|
||||
// new a bot message
|
||||
|
@ -24,6 +24,9 @@ export const chatSlice = createSlice({
|
||||
errorMessage: '',
|
||||
messages: <any>[],
|
||||
messageCount: 10,
|
||||
isBottom: true,
|
||||
isMiddle: false,
|
||||
isTop: false,
|
||||
},
|
||||
reducers: {
|
||||
startGenerating: (state, action) => {
|
||||
@ -71,6 +74,21 @@ export const chatSlice = createSlice({
|
||||
},
|
||||
happendError: (state, action) => {
|
||||
state.errorMessage = action.payload;
|
||||
},
|
||||
onMessagesTop: (state) => {
|
||||
state.isTop = true;
|
||||
state.isBottom = false;
|
||||
state.isMiddle = false;
|
||||
},
|
||||
onMessagesBottom: (state) => {
|
||||
state.isTop = false;
|
||||
state.isBottom = true;
|
||||
state.isMiddle = false;
|
||||
},
|
||||
onMessagesMiddle: (state) => {
|
||||
state.isTop = false;
|
||||
state.isBottom = false;
|
||||
state.isMiddle = true;
|
||||
}
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
@ -99,6 +117,9 @@ export const selectCurrentMessage = (state: RootState) => state.chat.currentMess
|
||||
export const selectErrorMessage = (state: RootState) => state.chat.errorMessage;
|
||||
export const selectMessages = (state: RootState) => state.chat.messages;
|
||||
export const selectMessageCount = (state: RootState) => state.chat.messageCount;
|
||||
export const selectIsBottom = (state: RootState) => state.chat.isBottom;
|
||||
export const selectIsTop = (state: RootState) => state.chat.isTop;
|
||||
export const selectIsMiddle = (state: RootState) => state.chat.isMiddle;
|
||||
|
||||
|
||||
export const {
|
||||
@ -112,6 +133,9 @@ export const {
|
||||
popMessage,
|
||||
clearMessages,
|
||||
updateMessage,
|
||||
onMessagesTop,
|
||||
onMessagesBottom,
|
||||
onMessagesMiddle,
|
||||
} = chatSlice.actions;
|
||||
|
||||
export default chatSlice.reducer;
|
Loading…
x
Reference in New Issue
Block a user