refactor: pull up message feed

This commit is contained in:
Tristan Yang
2023-01-13 21:08:16 +08:00
parent 6ecffe557b
commit d6847c9968
9 changed files with 136 additions and 96 deletions
+2 -1
View File
@@ -35,6 +35,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
const { t } = useTranslation("chat");
const { values: agoraConfig } = useConfig("agora");
const {
pulling,
list: msgIds,
appends,
hasMore,
@@ -175,7 +176,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
>
<StyledChannelChat id={`VOCECHAT_FEED_channel_${cid}`}>
{hasMore ? (
<LoadMore pullUp={pullUp} />
<LoadMore pullUp={pullUp} pulling={pulling} />
) : (
<div className="info">
<h2 className="title">{t("welcome_channel", { name })}</h2>
+2 -1
View File
@@ -18,6 +18,7 @@ type Props = {
};
const DMChat: FC<Props> = ({ uid = 0, dropFiles }) => {
const {
pulling,
list: msgIds,
appends,
hasMore,
@@ -70,7 +71,7 @@ const DMChat: FC<Props> = ({ uid = 0, dropFiles }) => {
}
>
<StyledDMChat id={`VOCECHAT_FEED_user_${uid}`}>
{hasMore ? <LoadMore pullUp={pullUp} /> : null}
{hasMore ? <LoadMore pullUp={pullUp} pulling={pulling} /> : null}
{[...feeds].map((mid, idx) => {
const curr = messageData[mid];
const prev = idx == 0 ? null : messageData[feeds[idx - 1]];
+2 -2
View File
@@ -26,9 +26,9 @@ const DMList: FC<Props> = ({ uids, setDropFiles }) => {
const sessions = uids.map((uid) => {
const mids = userMessage[uid] || [];
if (mids.length == 0) {
return { lastMid: 0, unreads: 0, uid };
return { lastMid: null, unreads: 0, uid };
}
const lastMid = [...mids].pop() || 0;
const lastMid = [...mids].pop();
const readIndex = readUsers[uid];
const { unreads = 0 } = getUnreadCount({
mids,
+12 -30
View File
@@ -1,42 +1,24 @@
import { useRef, useEffect, FC } from "react";
import { memo, useEffect, FC } from "react";
import { Waveform } from "@uiball/loaders";
import { useInViewRef } from "rooks";
type Props = {
pulling?: boolean;
pullUp: () => Promise<void> | null;
};
const LoadMore: FC<Props> = ({ pullUp = null }) => {
const ref = useRef<HTMLDivElement | null>(null);
const LoadMore: FC<Props> = ({ pullUp = null, pulling }) => {
const [myRef, inView] = useInViewRef();
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
const intersecting = entry.isIntersecting;
// const currEle = entry.target;
if (intersecting && pullUp) {
// load more
pullUp();
}
});
},
{ threshold: 0 }
);
let currEle: HTMLDivElement | null = null;
if (ref) {
currEle = ref.current;
if (currEle) {
observer.observe(currEle);
}
if (inView && pullUp && !pulling) {
pullUp();
}
return () => {
if (currEle) {
observer.unobserve(currEle);
}
};
}, [ref, pullUp]);
}, [inView, pullUp, pulling]);
return (
<div className="mt-2 flex justify-center items-center w-full py-2" ref={ref}>
<div data-load-more className="mt-2 flex justify-center items-center w-full py-2" ref={myRef}>
<Waveform size={18} lineWeight={4} speed={1} color="#ccc" />
</div>
);
};
export default LoadMore;
export default memo(LoadMore, (prev, next) => {
return prev.pulling === next.pulling;
});