fix: scrolling
This commit is contained in:
parent
d236f23b38
commit
22e6470ab8
|
@ -1,6 +1,11 @@
|
|||
import './chat--messages.scss';
|
||||
|
||||
import React, {useLayoutEffect, useRef} from 'react';
|
||||
import React, {
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
|
||||
import {channelMessagesSelector} from '~/common/state/chat';
|
||||
|
@ -16,23 +21,35 @@ export default function ChatMessages() {
|
|||
const channel = useChannel();
|
||||
const $messages = useRef(null);
|
||||
const {current} = $messages;
|
||||
const isAtTheBottom = !current
|
||||
? true
|
||||
: 0 === current.scrollTop || (
|
||||
current.scrollHeight
|
||||
=== current.scrollTop
|
||||
+ ['margin-top', 'margin-bottom'].reduce((r, property) => (
|
||||
r + parseInt(window.getComputedStyle(current).getPropertyValue(property), 10)
|
||||
), current.offsetHeight)
|
||||
);
|
||||
const heightWatch = current && current.scrollHeight;
|
||||
const [, setIsAtBottom] = useState(true);
|
||||
const [outerHeight, setOuterHeight] = useState(0);
|
||||
const [scrollTop, setScrollTop] = useState(0);
|
||||
const [scrollHeight, setScrollHeight] = useState(Infinity);
|
||||
const messages = useSelector((state) => channelMessagesSelector(state, channel));
|
||||
const messageCount = messages && messages.length;
|
||||
useEffect(() => {
|
||||
const onResize = () => {
|
||||
setOuterHeight(
|
||||
!current
|
||||
? 0
|
||||
: ['margin-top', 'margin-bottom'].reduce((r, property) => (
|
||||
r + parseInt(window.getComputedStyle(current).getPropertyValue(property), 10)
|
||||
), current.offsetHeight),
|
||||
);
|
||||
setScrollHeight(!current ? 0 : current.scrollHeight);
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onResize();
|
||||
});
|
||||
useLayoutEffect(() => {
|
||||
if (isAtTheBottom) {
|
||||
current?.scrollTo(0, !current ? 0 : current.scrollHeight);
|
||||
const isAtBottom = !current
|
||||
? true
|
||||
: 0 === scrollTop || scrollTop + outerHeight >= scrollHeight;
|
||||
setIsAtBottom(isAtBottom);
|
||||
if (isAtBottom) {
|
||||
current?.scrollTo(0, scrollHeight);
|
||||
}
|
||||
}, [current, heightWatch, messageCount, isAtTheBottom]);
|
||||
}, [current, messageCount, outerHeight, scrollHeight, scrollTop]);
|
||||
if (!channel) {
|
||||
return null;
|
||||
}
|
||||
|
@ -42,6 +59,7 @@ export default function ChatMessages() {
|
|||
<div className="chat--messagesSmoosh" />
|
||||
<div
|
||||
className="chat--messagesList"
|
||||
onScroll={({target: {scrollTop}}) => setScrollTop(Math.round(scrollTop))}
|
||||
ref={$messages}
|
||||
>
|
||||
{messages && messages.map((message) => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user