mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-04-23 19:37:52 +00:00
fix chat list
This commit is contained in:
parent
3615a6e873
commit
78e85f9e79
@ -1,25 +1,85 @@
|
|||||||
import React, { useCallback, useState, useEffect, useRef, useMemo } from 'react';
|
import React, {
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
useCallback,
|
||||||
import { MessageItem } from './MessageItem';
|
useState,
|
||||||
import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events';
|
useEffect,
|
||||||
import { useInView } from 'react-intersection-observer'
|
useRef,
|
||||||
import { Box } from '@mui/material';
|
useMemo,
|
||||||
import { ChatOptions } from './ChatOptions';
|
} from "react";
|
||||||
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||||
|
import { MessageItem } from "./MessageItem";
|
||||||
|
import { subscribeToEvent, unsubscribeFromEvent } from "../../utils/events";
|
||||||
|
import { useInView } from "react-intersection-observer";
|
||||||
|
import { Box } from "@mui/material";
|
||||||
|
import { ChatOptions } from "./ChatOptions";
|
||||||
|
|
||||||
export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId, onReply, handleReaction, chatReferences, tempChatReferences, members, myName, selectedGroup, enableMentions }) => {
|
export const ChatList = ({
|
||||||
|
initialMessages,
|
||||||
|
myAddress,
|
||||||
|
tempMessages,
|
||||||
|
chatId,
|
||||||
|
onReply,
|
||||||
|
handleReaction,
|
||||||
|
chatReferences,
|
||||||
|
tempChatReferences,
|
||||||
|
members,
|
||||||
|
myName,
|
||||||
|
selectedGroup,
|
||||||
|
enableMentions,
|
||||||
|
}) => {
|
||||||
const parentRef = useRef();
|
const parentRef = useRef();
|
||||||
const [messages, setMessages] = useState(initialMessages);
|
const [messages, setMessages] = useState(initialMessages);
|
||||||
const [showScrollButton, setShowScrollButton] = useState(false);
|
const [showScrollButton, setShowScrollButton] = useState(false);
|
||||||
const [showScrollDownButton, setShowScrollDownButton] = useState(false);
|
const [showScrollDownButton, setShowScrollDownButton] = useState(false);
|
||||||
|
|
||||||
const hasLoadedInitialRef = useRef(false);
|
const hasLoadedInitialRef = useRef(false);
|
||||||
|
const scrollingIntervalRef = useRef(null);
|
||||||
|
|
||||||
const showScrollButtonRef = useRef(showScrollButton);
|
// Initialize the virtualizer
|
||||||
|
const rowVirtualizer = useVirtualizer({
|
||||||
|
count: messages.length,
|
||||||
|
getItemKey: (index) => messages[index].signature,
|
||||||
|
getScrollElement: () => parentRef?.current,
|
||||||
|
estimateSize: () => 80, // Provide an estimated height of items, adjust this as needed
|
||||||
|
overscan: 10, // Number of items to render outside the visible area to improve smoothness
|
||||||
|
});
|
||||||
|
|
||||||
// Update the ref whenever the state changes
|
const isAtBottom = useMemo(()=> {
|
||||||
useEffect(() => {
|
if (parentRef.current && rowVirtualizer?.isScrolling !== undefined) {
|
||||||
showScrollButtonRef.current = showScrollButton;
|
const { scrollTop, scrollHeight, clientHeight } = parentRef.current;
|
||||||
}, [showScrollButton]);
|
const atBottom = scrollTop + clientHeight >= scrollHeight - 10; // Adjust threshold as needed
|
||||||
|
return atBottom
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
}, [rowVirtualizer?.isScrolling])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!parentRef.current || rowVirtualizer?.isScrolling === undefined) return;
|
||||||
|
if(isAtBottom){
|
||||||
|
if (scrollingIntervalRef.current) {
|
||||||
|
clearTimeout(scrollingIntervalRef.current);
|
||||||
|
}
|
||||||
|
setShowScrollDownButton(false);
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
if (rowVirtualizer?.isScrolling) {
|
||||||
|
if (scrollingIntervalRef.current) {
|
||||||
|
clearTimeout(scrollingIntervalRef.current);
|
||||||
|
}
|
||||||
|
setShowScrollDownButton(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { scrollTop, scrollHeight, clientHeight } = parentRef.current;
|
||||||
|
const atBottom = scrollHeight - scrollTop - clientHeight <= 300;
|
||||||
|
if (!atBottom) {
|
||||||
|
scrollingIntervalRef.current = setTimeout(() => {
|
||||||
|
setShowScrollDownButton(true);
|
||||||
|
}, 250);
|
||||||
|
} else {
|
||||||
|
setShowScrollDownButton(false);
|
||||||
|
}
|
||||||
|
}, [rowVirtualizer?.isScrolling, isAtBottom]);
|
||||||
|
|
||||||
// Update message list with unique signatures and tempMessages
|
// Update message list with unique signatures and tempMessages
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -32,30 +92,35 @@ useEffect(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const uniqueInitialMessages = Array.from(uniqueInitialMessagesMap.values()).sort(
|
const uniqueInitialMessages = Array.from(
|
||||||
(a, b) => a.timestamp - b.timestamp
|
uniqueInitialMessagesMap.values()
|
||||||
);
|
).sort((a, b) => a.timestamp - b.timestamp);
|
||||||
const totalMessages = [...uniqueInitialMessages, ...(tempMessages || [])]
|
const totalMessages = [...uniqueInitialMessages, ...(tempMessages || [])];
|
||||||
|
|
||||||
if (totalMessages.length === 0) return;
|
if (totalMessages.length === 0) return;
|
||||||
|
|
||||||
setMessages(totalMessages);
|
setMessages(totalMessages);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const hasUnreadMessages = totalMessages.some((msg) => msg.unread && !msg?.chatReference && !msg?.isTemp);
|
const hasUnreadMessages = totalMessages.some(
|
||||||
|
(msg) => msg.unread && !msg?.chatReference && !msg?.isTemp
|
||||||
|
);
|
||||||
if (parentRef.current) {
|
if (parentRef.current) {
|
||||||
const { scrollTop, scrollHeight, clientHeight } = parentRef.current;
|
const { scrollTop, scrollHeight, clientHeight } = parentRef.current;
|
||||||
const atBottom = scrollTop + clientHeight >= scrollHeight - 10; // Adjust threshold as needed
|
const atBottom = scrollTop + clientHeight >= scrollHeight - 10; // Adjust threshold as needed
|
||||||
if (!atBottom && hasUnreadMessages) {
|
if (!atBottom && hasUnreadMessages) {
|
||||||
setShowScrollButton(hasUnreadMessages);
|
setShowScrollButton(hasUnreadMessages);
|
||||||
setShowScrollDownButton(false)
|
setShowScrollDownButton(false);
|
||||||
} else {
|
} else {
|
||||||
handleMessageSeen();
|
handleMessageSeen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasLoadedInitialRef.current) {
|
if (!hasLoadedInitialRef.current) {
|
||||||
const findDivideIndex = totalMessages.findIndex((item)=> !!item?.divide)
|
const findDivideIndex = totalMessages.findIndex(
|
||||||
const divideIndex = findDivideIndex !== -1 ? findDivideIndex : undefined
|
(item) => !!item?.divide
|
||||||
|
);
|
||||||
|
const divideIndex =
|
||||||
|
findDivideIndex !== -1 ? findDivideIndex : undefined;
|
||||||
scrollToBottom(totalMessages, divideIndex);
|
scrollToBottom(totalMessages, divideIndex);
|
||||||
hasLoadedInitialRef.current = true;
|
hasLoadedInitialRef.current = true;
|
||||||
}
|
}
|
||||||
@ -65,19 +130,15 @@ useEffect(() => {
|
|||||||
const scrollToBottom = (initialMsgs, divideIndex) => {
|
const scrollToBottom = (initialMsgs, divideIndex) => {
|
||||||
const index = initialMsgs ? initialMsgs.length - 1 : messages.length - 1;
|
const index = initialMsgs ? initialMsgs.length - 1 : messages.length - 1;
|
||||||
if (rowVirtualizer) {
|
if (rowVirtualizer) {
|
||||||
if(divideIndex){
|
if (divideIndex) {
|
||||||
rowVirtualizer.scrollToIndex(divideIndex, { align: 'start' })
|
rowVirtualizer.scrollToIndex(divideIndex, { align: "start" });
|
||||||
} else {
|
} else {
|
||||||
rowVirtualizer.scrollToIndex(index, { align: 'end' })
|
rowVirtualizer.scrollToIndex(index, { align: "end" });
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleMessageSeen()
|
handleMessageSeen();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleMessageSeen = useCallback(() => {
|
const handleMessageSeen = useCallback(() => {
|
||||||
setMessages((prevMessages) =>
|
setMessages((prevMessages) =>
|
||||||
prevMessages.map((msg) => ({
|
prevMessages.map((msg) => ({
|
||||||
@ -85,236 +146,214 @@ useEffect(() => {
|
|||||||
unread: false,
|
unread: false,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
setShowScrollButton(false)
|
setShowScrollButton(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const sentNewMessageGroupFunc = useCallback(() => {
|
const sentNewMessageGroupFunc = useCallback(() => {
|
||||||
const { scrollHeight, scrollTop, clientHeight } = parentRef.current;
|
const { scrollHeight, scrollTop, clientHeight } = parentRef.current;
|
||||||
|
|
||||||
// Check if the user is within 200px from the bottom
|
// Check if the user is within 200px from the bottom
|
||||||
const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
|
const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
|
||||||
console.log('distanceFromBottom', distanceFromBottom)
|
console.log("distanceFromBottom", distanceFromBottom);
|
||||||
if (distanceFromBottom <= 700) {
|
if (distanceFromBottom <= 700) {
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
}
|
}
|
||||||
}, [messages]);
|
}, [messages]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
subscribeToEvent('sent-new-message-group', sentNewMessageGroupFunc);
|
subscribeToEvent("sent-new-message-group", sentNewMessageGroupFunc);
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribeFromEvent('sent-new-message-group', sentNewMessageGroupFunc);
|
unsubscribeFromEvent("sent-new-message-group", sentNewMessageGroupFunc);
|
||||||
};
|
};
|
||||||
}, [sentNewMessageGroupFunc]);
|
}, [sentNewMessageGroupFunc]);
|
||||||
|
|
||||||
const lastSignature = useMemo(()=> {
|
const lastSignature = useMemo(() => {
|
||||||
if(!messages || messages?.length === 0) return null
|
if (!messages || messages?.length === 0) return null;
|
||||||
const lastIndex = messages.length - 1
|
const lastIndex = messages.length - 1;
|
||||||
return messages[lastIndex]?.signature
|
return messages[lastIndex]?.signature;
|
||||||
}, [messages])
|
}, [messages]);
|
||||||
|
|
||||||
|
const goToMessage = useCallback((idx) => {
|
||||||
// Initialize the virtualizer
|
rowVirtualizer.scrollToIndex(idx);
|
||||||
const rowVirtualizer = useVirtualizer({
|
}, []);
|
||||||
count: messages.length,
|
|
||||||
getItemKey: React.useCallback(
|
|
||||||
(index) => messages[index].signature,
|
|
||||||
[messages]
|
|
||||||
),
|
|
||||||
getScrollElement: () => parentRef.current,
|
|
||||||
estimateSize: () => 80, // Provide an estimated height of items, adjust this as needed
|
|
||||||
overscan: 10, // Number of items to render outside the visible area to improve smoothness
|
|
||||||
observeElementOffset: (instance, cb) => {
|
|
||||||
const offsetCheck = () => {
|
|
||||||
const { scrollHeight, scrollTop, clientHeight } = instance.scrollElement;
|
|
||||||
const atBottom = scrollHeight - scrollTop - clientHeight <= 300;
|
|
||||||
if(showScrollButtonRef.current){
|
|
||||||
setShowScrollDownButton(false)
|
|
||||||
} else
|
|
||||||
if(atBottom){
|
|
||||||
setShowScrollDownButton(false)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
setShowScrollDownButton(true)
|
|
||||||
|
|
||||||
}
|
|
||||||
cb(scrollTop); // Pass scroll offset to callback
|
|
||||||
// setShowScrollToBottom(!atBottom);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initial check and continuous monitoring
|
|
||||||
offsetCheck();
|
|
||||||
instance.scrollElement.addEventListener('scroll', offsetCheck);
|
|
||||||
return () => instance.scrollElement.removeEventListener('scroll', offsetCheck);
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
const goToMessage = useCallback((idx)=> {
|
|
||||||
rowVirtualizer.scrollToIndex(idx)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{
|
<Box
|
||||||
display: 'flex',
|
sx={{
|
||||||
width: '100%',
|
display: "flex",
|
||||||
height: '100%'
|
width: "100%",
|
||||||
}}>
|
height: "100%",
|
||||||
<div style={{
|
}}
|
||||||
height: '100%',
|
>
|
||||||
position: 'relative',
|
<div
|
||||||
display: 'flex',
|
style={{
|
||||||
flexDirection: 'column',
|
height: "100%",
|
||||||
width: '100%'
|
position: "relative",
|
||||||
}}>
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
<div
|
width: "100%",
|
||||||
ref={parentRef}
|
}}
|
||||||
className="List"
|
|
||||||
style={{ flexGrow: 1, overflow: 'auto', position: 'relative', display: 'flex', height: '0px' }}
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
ref={parentRef}
|
||||||
|
className="List"
|
||||||
style={{
|
style={{
|
||||||
height: rowVirtualizer.getTotalSize(),
|
flexGrow: 1,
|
||||||
width: '100%',
|
overflow: "auto",
|
||||||
|
position: "relative",
|
||||||
|
display: "flex",
|
||||||
|
height: "0px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
height: rowVirtualizer.getTotalSize(),
|
||||||
top: 0,
|
width: "100%",
|
||||||
left: 0,
|
|
||||||
width: '100%',
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
|
||||||
const index = virtualRow.index;
|
|
||||||
let message = messages[index];
|
|
||||||
let replyIndex = messages.findIndex((msg) => msg?.signature === message?.repliedTo);
|
|
||||||
let reply;
|
|
||||||
let reactions = null;
|
|
||||||
|
|
||||||
if (message?.repliedTo && replyIndex !== -1) {
|
|
||||||
reply = messages[replyIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message?.message && message?.groupDirectId) {
|
|
||||||
replyIndex = messages.findIndex((msg) => msg?.signature === message?.message?.repliedTo);
|
|
||||||
if (message?.message?.repliedTo && replyIndex !== -1) {
|
|
||||||
reply = messages[replyIndex];
|
|
||||||
}
|
|
||||||
message = {
|
|
||||||
...(message?.message || {}),
|
|
||||||
isTemp: true,
|
|
||||||
unread: false,
|
|
||||||
status: message?.status
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chatReferences && chatReferences[message?.signature]) {
|
|
||||||
if (chatReferences[message.signature]?.reactions) {
|
|
||||||
reactions = chatReferences[message.signature]?.reactions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let isUpdating = false;
|
|
||||||
if (tempChatReferences && tempChatReferences?.find((item) => item?.chatReference === message?.signature)) {
|
|
||||||
isUpdating = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
<div
|
||||||
data-index={virtualRow.index} //needed for dynamic row height measurement
|
|
||||||
ref={rowVirtualizer.measureElement} //measure dynamic row height
|
|
||||||
key={message.signature}
|
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: "absolute",
|
||||||
top: 0,
|
top: 0,
|
||||||
left: '50%', // Move to the center horizontally
|
left: 0,
|
||||||
transform: `translateY(${virtualRow.start}px) translateX(-50%)`, // Adjust for centering
|
width: "100%",
|
||||||
width: '100%', // Control width (90% of the parent)
|
|
||||||
padding: '10px 0',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
overscrollBehavior: 'none',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: '5px'
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MessageItem
|
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
||||||
isLast={index === messages.length - 1}
|
const index = virtualRow.index;
|
||||||
lastSignature={lastSignature}
|
let message = messages[index];
|
||||||
message={message}
|
let replyIndex = messages.findIndex(
|
||||||
onSeen={handleMessageSeen}
|
(msg) => msg?.signature === message?.repliedTo
|
||||||
isTemp={!!message?.isTemp}
|
);
|
||||||
myAddress={myAddress}
|
let reply;
|
||||||
onReply={onReply}
|
let reactions = null;
|
||||||
reply={reply}
|
|
||||||
replyIndex={replyIndex}
|
|
||||||
scrollToItem={goToMessage}
|
|
||||||
handleReaction={handleReaction}
|
|
||||||
reactions={reactions}
|
|
||||||
isUpdating={isUpdating}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{showScrollButton && (
|
|
||||||
<button
|
|
||||||
onClick={() => scrollToBottom()}
|
|
||||||
style={{
|
|
||||||
bottom: 20,
|
|
||||||
position: 'absolute',
|
|
||||||
right: 20,
|
|
||||||
backgroundColor: 'var(--unread)',
|
|
||||||
color: 'white',
|
|
||||||
padding: '10px 20px',
|
|
||||||
borderRadius: '20px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
zIndex: 10,
|
|
||||||
border: 'none',
|
|
||||||
outline: 'none'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Scroll to Unread Messages
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{showScrollDownButton && (
|
|
||||||
<button
|
|
||||||
onClick={() => scrollToBottom()}
|
|
||||||
style={{
|
|
||||||
bottom: 20,
|
|
||||||
position: 'absolute',
|
|
||||||
right: 20,
|
|
||||||
backgroundColor: 'var(--Mail-Background)',
|
|
||||||
color: 'white',
|
|
||||||
padding: '10px 20px',
|
|
||||||
borderRadius: '20px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
zIndex: 10,
|
|
||||||
border: 'none',
|
|
||||||
outline: 'none',
|
|
||||||
fontSize: '16px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Scroll to bottom
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{enableMentions && (
|
|
||||||
<ChatOptions messages={messages} goToMessage={goToMessage} members={members} myName={myName} selectedGroup={selectedGroup}/>
|
|
||||||
|
|
||||||
)}
|
if (message?.repliedTo && replyIndex !== -1) {
|
||||||
</Box>
|
reply = messages[replyIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message?.message && message?.groupDirectId) {
|
||||||
|
replyIndex = messages.findIndex(
|
||||||
|
(msg) => msg?.signature === message?.message?.repliedTo
|
||||||
|
);
|
||||||
|
if (message?.message?.repliedTo && replyIndex !== -1) {
|
||||||
|
reply = messages[replyIndex];
|
||||||
|
}
|
||||||
|
message = {
|
||||||
|
...(message?.message || {}),
|
||||||
|
isTemp: true,
|
||||||
|
unread: false,
|
||||||
|
status: message?.status,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chatReferences && chatReferences[message?.signature]) {
|
||||||
|
if (chatReferences[message.signature]?.reactions) {
|
||||||
|
reactions = chatReferences[message.signature]?.reactions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let isUpdating = false;
|
||||||
|
if (
|
||||||
|
tempChatReferences &&
|
||||||
|
tempChatReferences?.find(
|
||||||
|
(item) => item?.chatReference === message?.signature
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
isUpdating = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-index={virtualRow.index} //needed for dynamic row height measurement
|
||||||
|
ref={rowVirtualizer.measureElement} //measure dynamic row height
|
||||||
|
key={message.signature}
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: "50%", // Move to the center horizontally
|
||||||
|
transform: `translateY(${virtualRow.start}px) translateX(-50%)`, // Adjust for centering
|
||||||
|
width: "100%", // Control width (90% of the parent)
|
||||||
|
padding: "10px 0",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
overscrollBehavior: "none",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: "5px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MessageItem
|
||||||
|
isLast={index === messages.length - 1}
|
||||||
|
lastSignature={lastSignature}
|
||||||
|
message={message}
|
||||||
|
onSeen={handleMessageSeen}
|
||||||
|
isTemp={!!message?.isTemp}
|
||||||
|
myAddress={myAddress}
|
||||||
|
onReply={onReply}
|
||||||
|
reply={reply}
|
||||||
|
replyIndex={replyIndex}
|
||||||
|
scrollToItem={goToMessage}
|
||||||
|
handleReaction={handleReaction}
|
||||||
|
reactions={reactions}
|
||||||
|
isUpdating={isUpdating}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{showScrollButton && (
|
||||||
|
<button
|
||||||
|
onClick={() => scrollToBottom()}
|
||||||
|
style={{
|
||||||
|
bottom: 20,
|
||||||
|
position: "absolute",
|
||||||
|
right: 20,
|
||||||
|
backgroundColor: "var(--unread)",
|
||||||
|
color: "white",
|
||||||
|
padding: "10px 20px",
|
||||||
|
borderRadius: "20px",
|
||||||
|
cursor: "pointer",
|
||||||
|
zIndex: 10,
|
||||||
|
border: "none",
|
||||||
|
outline: "none",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Scroll to Unread Messages
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{showScrollDownButton && (
|
||||||
|
<button
|
||||||
|
onClick={() => scrollToBottom()}
|
||||||
|
style={{
|
||||||
|
bottom: 20,
|
||||||
|
position: "absolute",
|
||||||
|
right: 20,
|
||||||
|
backgroundColor: "var(--Mail-Background)",
|
||||||
|
color: "white",
|
||||||
|
padding: "10px 20px",
|
||||||
|
borderRadius: "20px",
|
||||||
|
cursor: "pointer",
|
||||||
|
zIndex: 10,
|
||||||
|
border: "none",
|
||||||
|
outline: "none",
|
||||||
|
fontSize: "16px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Scroll to bottom
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{enableMentions && (
|
||||||
|
<ChatOptions
|
||||||
|
messages={messages}
|
||||||
|
goToMessage={goToMessage}
|
||||||
|
members={members}
|
||||||
|
myName={myName}
|
||||||
|
selectedGroup={selectedGroup}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user