Skip to content

Commit

Permalink
revert new message list
Browse files Browse the repository at this point in the history
  • Loading branch information
Puyodead1 committed Jul 17, 2024
1 parent a8c91ca commit 1634a98
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 158 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@
"react": "^18.2.0",
"react-advanced-cropper": "^0.19.6",
"react-colorful": "^5.6.1",
"react-content-loader": "^7.0.2",
"react-device-detect": "^2.2.3",
"react-dom": "^18.2.0",
"react-fps-stats": "^0.3.1",
"react-hook-form": "^7.51.3",
"react-infinite-scroll-component": "^6.1.0",
"react-loading-skeleton": "^3.4.0",
"react-markdown": "^9.0.1",
"react-measure": "^2.5.2",
Expand All @@ -71,7 +71,6 @@
"reoverlay": "^1.0.3",
"styled-components": "5.3.11",
"use-resize-observer": "^9.1.0",
"virtua": "^0.33.1",
"yup": "^1.4.0"
},
"devDependencies": {
Expand Down
56 changes: 17 additions & 39 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 0 additions & 27 deletions src/components/SkeletonLoader.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/messaging/MessageGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function MessageGroup({ group }: Props) {
<>
{messages.map((message, index) => {
if (message.type === MessageType.Default || message.type === MessageType.Reply) {
return <Message key={message.id} message={message} header={index === 0} />;
return <Message key={message.id} message={message} header={index === messages.length - 1} />;
} else return <SystemMessage key={message.id} message={message} />;
})}
</>
Expand Down
152 changes: 65 additions & 87 deletions src/components/messaging/MessageList.tsx
Original file line number Diff line number Diff line change
@@ -1,90 +1,83 @@
import { observer } from "mobx-react-lite";
import React, { useEffect, useRef, useState } from "react";
import React from "react";
import InfiniteScroll from "react-infinite-scroll-component";
import PulseLoader from "react-spinners/PulseLoader";
import styled from "styled-components";
import useResizeObserver from "use-resize-observer";
import { VList, VListHandle } from "virtua";
import useLogger from "../../hooks/useLogger";
import { useAppStore } from "../../stores/AppStore";
import { MessageGroup as MessageGroupType } from "../../stores/MessageStore";
import Channel from "../../stores/objects/Channel";
import Guild from "../../stores/objects/Guild";
import { Permissions } from "../../utils/Permissions";
import { HorizontalDivider } from "../Divider";
import SkeletonLoader from "../SkeletonLoader.tsx";
import MessageGroup from "./MessageGroup";

export const MessageAreaWidthContext = React.createContext(0);
export const MESSAGE_AREA_PADDING = 82;

const Container = styled.div`
flex: 1 1 auto;
overflow-y: auto;
display: flex;
flex: 1;
flex-direction: column-reverse;
`;

const EndMessageContainer = styled.div`
margin: 16px 16px 0 16px;
`;

const Spacer = styled.div`
height: 20px;
`;

interface Props {
guild: Guild;
channel: Channel;
before?: string;
}

/**
* Main component for rendering the messages list of a channel
*/
function MessageList({ guild, channel, before }: Props) {
function MessageList({ guild, channel }: Props) {
const app = useAppStore();
const logger = useLogger("MessageList.tsx");
const [hasMore, setHasMore] = useState(true);
const [canView, setCanView] = useState(false);
const [loading, setLoading] = useState(true);
const [hasMore, setHasMore] = React.useState(true);
const [canView, setCanView] = React.useState(false);
const messageGroups = channel.messages.groups;
const wrapperRef = useRef<HTMLDivElement>(null);
const { width } = useResizeObserver<HTMLDivElement>({ ref: wrapperRef });
const ref = useRef<VListHandle>(null);
const ref = React.useRef<HTMLDivElement>(null);
const { width } = useResizeObserver<HTMLDivElement>({ ref });

useEffect(() => {
// if (before) {
// // find message group containing the message
// const group = messageGroups.find((x) => x.messages.some((y) => y.id === before));
// const index = group
// ? messageGroups.indexOf(group) +
// (hasMore
// ? 10
// : 0) /** +10 to account for the "skeleton" divs used to add some padding for scrolling */
// : -1;
// if (index !== -1) {
// ref.current?.scrollToIndex(index);
React.useEffect(() => {
const permission = Permissions.getPermission(app.account!.id, guild, channel);
const hasPermission = permission.has("READ_MESSAGE_HISTORY");
setCanView(hasPermission);

// return;
// }
// }
if (!hasPermission) {
logger.debug("User cannot view this channel. Aborting initial message fetch.");
return;
}

// this is for switching to a channel with cached messages, it ensures that we correctly set hasMore to false if there are messages but its less than 50
if (channel.messages.count > 0 && channel.messages.count < 50) setHasMore(false);
if (guild && channel && channel.messages.count === 0) {
channel.getMessages(app, true).then((r) => {
if (r < 50) {
setHasMore(false);
}
});
}

const hasSkeleton = hasMore || loading;
ref.current?.scrollToIndex(channel.messages.count + (hasSkeleton ? 30 : 0));
}, [messageGroups, hasMore, loading]);
return () => {
logger.debug("MessageList unmounted");
setHasMore(true);
setCanView(false);
};
}, [guild, channel]);

const fetchMore = React.useCallback(() => {
setLoading(true);
if (!channel.messages.count) {
logger.warn("channel has no messages, aborting!");
setLoading(false);
return;
}
// get last group
const lastGroup = messageGroups[messageGroups.length - 1];
if (!lastGroup) {
logger.warn("No last group found, aborting fetchMore");
setLoading(false);
return;
}
// ignore queued messages
Expand All @@ -93,40 +86,12 @@ function MessageList({ guild, channel, before }: Props) {
const before = lastGroup.messages[0].id;
logger.debug(`Fetching 50 messages before ${before} for channel ${channel.id}`);
channel.getMessages(app, false, 50, before).then((r) => {
if (r < 50) setHasMore(false);
setLoading(false);
if (r < 50) {
setHasMore(false);
}
});
}, [channel, messageGroups]);

useEffect(() => {
const permission = Permissions.getPermission(app.account!.id, guild, channel);
const hasPermission = permission.has("READ_MESSAGE_HISTORY");
setCanView(hasPermission);

if (!hasPermission) {
logger.debug("User cannot view this channel. Aborting initial message fetch.");
return;
}

if (guild && channel && channel.messages.count === 0) {
logger.debug(`Fetching 50 messages for channel ${channel.id}`);
channel.getMessages(app, true).then((r) => {
if (r < 50) setHasMore(false);

setLoading(false);
});
} else if (channel.messages.count !== 0) {
setLoading(false);
}

return () => {
logger.debug("MessageList unmounted");
setLoading(true);
setHasMore(true);
setCanView(false);
};
}, [guild, channel]);

const renderGroup = React.useCallback(
(group: MessageGroupType) => (
<MessageGroup key={`messageGroup-${group.messages[group.messages.length - 1].id}`} group={group} />
Expand All @@ -136,32 +101,45 @@ function MessageList({ guild, channel, before }: Props) {

return (
<MessageAreaWidthContext.Provider value={(width ?? 0) - MESSAGE_AREA_PADDING}>
<Container>
<Container id="scrollable-div" ref={ref}>
{canView ? (
<VList
ref={ref}
<InfiniteScroll
dataLength={messageGroups.length}
next={fetchMore}
style={{
flex: 1,
}}
reverse
>
{Array.from({
length: hasMore || loading ? 30 : 0,
}).map((_, i) => (
<SkeletonLoader />
))}
{!loading && !hasMore && (
display: "flex",
flexDirection: "column-reverse",
marginBottom: 30,
overflow: "hidden",
}} // to put endMessage and loader to the top.
hasMore={hasMore}
inverse={true}
loader={
<PulseLoader
style={{
display: "flex",
justifyContent: "center",
alignContent: "center",
margin: 30,
}}
color="var(--primary)"
/>
}
// FIXME: seems to be broken in react-infinite-scroll-component when using inverse
scrollThreshold={0.5}
scrollableTarget="scrollable-div"
endMessage={
<EndMessageContainer>
<h1 style={{ fontWeight: 700, margin: "8px 0" }}>Welcome to #{channel.name}!</h1>
<p style={{ color: "var(--text-secondary)" }}>
This is the start of the #{channel.name} channel.
</p>
<HorizontalDivider />
</EndMessageContainer>
)}
{messageGroups.map((group, index) => renderGroup(group))}
<Spacer />
</VList>
}
>
{messageGroups.map((group) => renderGroup(group))}
</InfiniteScroll>
) : (
<div
style={{
Expand Down
Loading

0 comments on commit 1634a98

Please sign in to comment.