frontend/src/chat/ChatOutput.tsx

86 lines
2.5 KiB
TypeScript

import { useEffect, useRef, useState } from "react";
import ChatMessage from "./ChatMessage";
import { Box, Button, ListItemButton } from "@mui/material";
// import { Note } from "models";
import { pond } from "protobuf-ts/pond";
interface Props {
messages: pond.Chat[];
attachmentMap?: Map<string, pond.FileReference[]>;
totalMessages: number;
removeNoteMethod: (index: number) => void;
loadMore: () => void;
}
/**
* will load chat messages for the passed in object and display as a list of chat messages
* @returns List of chat messages
*/
export default function ChatOutput(props: Props) {
const [disableScrollTo, setDisableScrollTo] = useState(false);
const [scrollOffset, setScrollOffset] = useState(0);
const containerRef = useRef<HTMLDivElement>(null);
const ScrollToBottom = () => {
const elementRef = useRef<null | HTMLDivElement>(null);
useEffect(() => {
elementRef?.current?.scrollIntoView({
block: "end"
});
});
let elem = <div ref={elementRef} />;
return elem;
};
const onScroll = () => {
if (!containerRef.current) return;
setDisableScrollTo(true)
const container = containerRef.current;
setScrollOffset(container.scrollHeight - container.scrollTop)
}
useEffect(() => {
if (!containerRef.current) return;
const container = containerRef.current;
container.scrollTop = container.scrollHeight - scrollOffset
}, [props.messages])
const seeMore = () => {
if (!containerRef.current) return;
setDisableScrollTo(true)
const container = containerRef.current;
setScrollOffset(container.scrollHeight - container.scrollTop)
props.loadMore();
};
const displayMessages = () => {
let display = props.messages.map((curMessage, index) => (
<div key={index}>
<ChatMessage
chat={curMessage}
index={index}
// attachments={props.attachmentMap?.get(curMessage.note?.settings?.key)}
removeNoteMethod={props.removeNoteMethod}
/>
</div>
));
return display;
};
return (
<Box ref={containerRef} onScroll={onScroll} style={{
overflowY: "scroll",
overflowX: "hidden",
height: "100%",
}}>
{props.messages.length < props.totalMessages && (
<ListItemButton onClick={seeMore} sx={{ justifyContent: "center"}}>
<Button >See More</Button>
</ListItemButton>
)}
{displayMessages()}
{!disableScrollTo && <ScrollToBottom/>}
</Box>
);
}