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