forum scroll down

This commit is contained in:
PhilReact 2024-09-14 19:51:31 +03:00
parent 753ba200d4
commit a6db86f051
2 changed files with 207 additions and 106 deletions

View File

@ -147,7 +147,8 @@ export const NewThread = ({
getSecretKey, getSecretKey,
closeCallback, closeCallback,
postReply, postReply,
myName myName,
setPostReply
}: NewMessageProps) => { }: NewMessageProps) => {
const { show } = React.useContext(MyContext); const { show } = React.useContext(MyContext);
@ -171,6 +172,7 @@ export const NewThread = ({
const closeModal = () => { const closeModal = () => {
setIsOpen(false); setIsOpen(false);
setValue(""); setValue("");
setPostReply(null)
}; };
async function publishQDNResource() { async function publishQDNResource() {
@ -399,7 +401,8 @@ export const NewThread = ({
> >
<ComposeContainer <ComposeContainer
sx={{ sx={{
padding: "15px", padding: isMobile ? '5px' : "15px",
justifyContent: isMobile ? 'flex-start' : 'revert'
}} }}
onClick={() => setIsOpen(true)} onClick={() => setIsOpen(true)}
> >

View File

@ -1,10 +1,6 @@
import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "react"; import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Box, Button, IconButton, Skeleton } from "@mui/material"; import { Box, Button, IconButton, Skeleton } from "@mui/material";
import { ShowMessage } from "./ShowMessageWithoutModal"; import { ShowMessage } from "./ShowMessageWithoutModal";
// import {
// setIsLoadingCustom,
// } from '../../state/features/globalSlice'
import { import {
ComposeP, ComposeP,
GroupContainer, GroupContainer,
@ -24,8 +20,8 @@ import { decryptPublishes, getTempPublish } from "../../Chat/GroupAnnouncements"
import { LoadingSnackbar } from "../../Snackbar/LoadingSnackbar"; import { LoadingSnackbar } from "../../Snackbar/LoadingSnackbar";
import { subscribeToEvent, unsubscribeFromEvent } from "../../../utils/events"; import { subscribeToEvent, unsubscribeFromEvent } from "../../../utils/events";
import RefreshIcon from "@mui/icons-material/Refresh"; import RefreshIcon from "@mui/icons-material/Refresh";
import { getBaseApi } from "../../../background"; import { getBaseApiReact, isMobile } from "../../../App";
import { getBaseApiReact } from "../../../App"; import { ArrowDownward as ArrowDownwardIcon, ArrowUpward as ArrowUpwardIcon } from '@mui/icons-material';
interface ThreadProps { interface ThreadProps {
currentThread: any; currentThread: any;
@ -56,7 +52,6 @@ export const Thread = ({
updateThreadActivityCurrentThread updateThreadActivityCurrentThread
}: ThreadProps) => { }: ThreadProps) => {
const [tempPublishedList, setTempPublishedList] = useState([]) const [tempPublishedList, setTempPublishedList] = useState([])
const [messages, setMessages] = useState<any[]>([]); const [messages, setMessages] = useState<any[]>([]);
const [hashMapMailMessages, setHashMapMailMessages] = useState({}); const [hashMapMailMessages, setHashMapMailMessages] = useState({});
const [hasFirstPage, setHasFirstPage] = useState(false); const [hasFirstPage, setHasFirstPage] = useState(false);
@ -66,9 +61,17 @@ export const Thread = ({
const [postReply, setPostReply] = useState(null); const [postReply, setPostReply] = useState(null);
const [hasLastPage, setHasLastPage] = useState(false); const [hasLastPage, setHasLastPage] = useState(false);
// Update: Use a new ref for the scrollable container
const threadContainerRef = useRef(null);
// New state variables
const [showScrollButton, setShowScrollButton] = useState(false);
const [isAtBottom, setIsAtBottom] = useState(false);
const secretKeyRef = useRef(null); const secretKeyRef = useRef(null);
const currentThreadRef = useRef(null); const currentThreadRef = useRef(null);
const containerRef = useRef(null); const containerRef = useRef(null);
useEffect(() => { useEffect(() => {
currentThreadRef.current = currentThread; currentThreadRef.current = currentThread;
}, [currentThread]); }, [currentThread]);
@ -85,7 +88,6 @@ export const Thread = ({
secretKey, secretKey,
}); });
const fullObject = { const fullObject = {
...message, ...message,
...(responseDataMessage || {}), ...(responseDataMessage || {}),
@ -97,23 +99,23 @@ export const Thread = ({
[message.identifier]: fullObject, [message.identifier]: fullObject,
}; };
}); });
} catch (error) {} } catch (error) { }
}; };
const setTempData = async ()=> { const setTempData = async () => {
try { try {
let threadId = currentThread.threadId; let threadId = currentThread.threadId;
const keyTemp = 'thread-post' const keyTemp = 'thread-post'
const getTempAnnouncements = await getTempPublish() const getTempAnnouncements = await getTempPublish()
if(getTempAnnouncements?.[keyTemp]){ if (getTempAnnouncements?.[keyTemp]) {
let tempData = [] let tempData = []
Object.keys(getTempAnnouncements?.[keyTemp] || {}).map((key)=> { Object.keys(getTempAnnouncements?.[keyTemp] || {}).map((key) => {
const value = getTempAnnouncements?.[keyTemp][key] const value = getTempAnnouncements?.[keyTemp][key]
if(value.data?.threadId === threadId){ if (value.data?.threadId === threadId) {
tempData.push(value.data) tempData.push(value.data)
} }
@ -126,7 +128,6 @@ export const Thread = ({
} }
const getMailMessages = React.useCallback( const getMailMessages = React.useCallback(
async (groupInfo: any, before, after, isReverse) => { async (groupInfo: any, before, after, isReverse) => {
try { try {
@ -178,7 +179,7 @@ export const Thread = ({
} }
if (fullArrayMsg.length === 0){ if (fullArrayMsg.length === 0) {
setTempData() setTempData()
return; return;
} }
@ -221,7 +222,6 @@ export const Thread = ({
} catch (error) { } catch (error) {
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
}, },
[messages, secretKey] [messages, secretKey]
@ -287,8 +287,6 @@ export const Thread = ({
} }
if (currentThread && secretKey && !firstMount.current) { if (currentThread && secretKey && !firstMount.current) {
getMessagesMiddleware(); getMessagesMiddleware();
// saveTimestamp(currentThread, user.name)
} }
}, [currentThread, secretKey]); }, [currentThread, secretKey]);
const messageCallback = useCallback((msg: any) => { const messageCallback = useCallback((msg: any) => {
@ -350,7 +348,7 @@ export const Thread = ({
} else { } else {
fullArrayMsg.unshift(fullObject); fullArrayMsg.unshift(fullObject);
} }
} catch (error) {} } catch (error) { }
} }
setMessages(fullArrayMsg); setMessages(fullArrayMsg);
} catch (error) { } catch (error) {
@ -360,25 +358,6 @@ export const Thread = ({
[messages] [messages]
); );
// const checkNewMessagesFunc = useCallback(() => {
// let isCalling = false
// interval.current = setInterval(async () => {
// if (isCalling) return
// isCalling = true
// const res = await checkNewMessages(currentThread)
// isCalling = false
// }, 8000)
// }, [checkNewMessages, currentThrefirstMount.current = truead])
// useEffect(() => {
// checkNewMessagesFunc()
// return () => {
// if (interval?.current) {
// clearInterval(interval.current)
// }
// }
// }, [checkNewMessagesFunc])
const openNewPostWithQuote = useCallback((reply) => { const openNewPostWithQuote = useCallback((reply) => {
setPostReply(reply); setPostReply(reply);
}, []); }, []);
@ -419,15 +398,71 @@ export const Thread = ({
return sortedList; return sortedList;
}, [tempPublishedList, messages]); }, [tempPublishedList, messages]);
// Updated useEffect to handle scroll and overflow
useEffect(() => {
const container = threadContainerRef.current; // Updated reference
if (!container) return;
const handleScroll = () => {
const { scrollTop, scrollHeight, clientHeight } = container;
// Check if user is at the bottom
if (scrollTop + clientHeight >= scrollHeight - 5) {
setIsAtBottom(true);
} else {
setIsAtBottom(false);
}
// Initial check if content overflows
if (container.scrollHeight > container.clientHeight) {
setShowScrollButton(true);
} else {
setShowScrollButton(false);
}
};
setTimeout(() => {
handleScroll()
}, 400);
container.addEventListener('scroll', handleScroll);
// Cleanup
return () => {
container.removeEventListener('scroll', handleScroll);
};
}, [messages]);
// Function to scroll to the top or bottom of the container
const scrollToPosition = () => {
const container = threadContainerRef.current; // Updated reference
if (!container) return;
if (isAtBottom) {
container.scrollTo({ top: 0, behavior: 'smooth' }); // Scroll to top
} else {
container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' }); // Scroll to bottom
}
};
console.log('showScrollButton', showScrollButton)
if (!currentThread) return null; if (!currentThread) return null;
return ( return (
<GroupContainer <GroupContainer
sx={{ sx={{
position: "relative", position: "relative",
overflow: "auto",
width: "100%", width: "100%",
display: 'flex',
flexDirection: 'column',
overflow: 'hidden'
}} }}
// Removed the ref from here since the scrollable area has changed
> >
<Box sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
flexShrink: 0 // Corrected property name
}}>
<NewThread <NewThread
groupInfo={groupInfo} groupInfo={groupInfo}
isMessage={true} isMessage={true}
@ -440,10 +475,63 @@ export const Thread = ({
postReply={postReply} postReply={postReply}
myName={userInfo?.name} myName={userInfo?.name}
publishCallback={setTempData} publishCallback={setTempData}
setPostReply={setPostReply}
/> />
<ThreadContainerFullWidth> <Box sx={{
<ThreadContainer > display: 'flex',
<Spacer height="30px" /> gap: isMobile ? '5px' : '25px',
alignItems: 'center'
}}>
<ShowMessageReturnButton
sx={{
padding: isMobile && '5px',
minWidth: isMobile && '50px'
}}
onClick={() => {
setMessages([]);
closeThread();
}}
>
<MailIconImg src={ReturnSVG} />
{!isMobile && (
<ComposeP>Return to Threads</ComposeP>
)}
</ShowMessageReturnButton>
{/* Conditionally render the scroll buttons */}
{showScrollButton && (
isAtBottom ? (
<ArrowUpwardIcon
onClick={scrollToPosition}
sx={{
color: 'white',
cursor: 'pointer',
fontSize: isMobile ? '28px' : '36px',
}}
/>
) : (
<ArrowDownwardIcon
onClick={scrollToPosition}
sx={{
color: 'white',
cursor: 'pointer',
fontSize: isMobile ? '28px' : '36px',
}}
/>
)
)}
</Box>
</Box>
<ThreadContainerFullWidth
sx={{
flexGrow: 1,
overflow: 'auto'
}}
ref={threadContainerRef} // Updated ref attached here
>
<ThreadContainer>
<Spacer height={isMobile ? '10px' : '30px'} />
<Box <Box
sx={{ sx={{
width: "100%", width: "100%",
@ -452,18 +540,12 @@ export const Thread = ({
justifyContent: "space-between", justifyContent: "space-between",
}} }}
> >
<GroupNameP>{currentThread?.threadData?.title}</GroupNameP> <GroupNameP sx={{
fontSize: isMobile && '18px'
<ShowMessageReturnButton }}>{currentThread?.threadData?.title}</GroupNameP>
onClick={() => {
setMessages([]);
closeThread();
}}
>
<MailIconImg src={ReturnSVG} />
<ComposeP>Return to Threads</ComposeP>
</ShowMessageReturnButton>
</Box> </Box>
<Spacer height={'15px'} />
<Box <Box
sx={{ sx={{
width: "100%", width: "100%",
@ -474,15 +556,25 @@ export const Thread = ({
}} }}
> >
<Button <Button
sx={{
padding: isMobile && '5px',
fontSize: isMobile && '14px',
textTransformation: 'capitalize'
}}
onClick={() => { onClick={() => {
getMailMessages(currentThread, null, null, false); getMailMessages(currentThread, null, null, false);
}} }}
disabled={!hasFirstPage} disabled={!hasFirstPage}
variant="contained" variant="contained"
> >
First Page First
</Button> </Button>
<Button <Button
sx={{
padding: isMobile && '5px',
fontSize: isMobile && '14px',
textTransformation: 'capitalize'
}}
onClick={() => { onClick={() => {
getMailMessages( getMailMessages(
currentThread, currentThread,
@ -494,9 +586,14 @@ export const Thread = ({
disabled={!hasPreviousPage} disabled={!hasPreviousPage}
variant="contained" variant="contained"
> >
Previous Page Previous
</Button> </Button>
<Button <Button
sx={{
padding: isMobile && '5px',
fontSize: isMobile && '14px',
textTransformation: 'capitalize'
}}
onClick={() => { onClick={() => {
getMailMessages( getMailMessages(
currentThread, currentThread,
@ -508,20 +605,25 @@ export const Thread = ({
disabled={!hasNextPage} disabled={!hasNextPage}
variant="contained" variant="contained"
> >
Next page Next
</Button> </Button>
<Button <Button
sx={{
padding: isMobile && '5px',
fontSize: isMobile && '14px',
textTransformation: 'capitalize'
}}
onClick={() => { onClick={() => {
getMailMessages(currentThread, null, null, true); getMailMessages(currentThread, null, null, true);
}} }}
disabled={!hasLastPage} disabled={!hasLastPage}
variant="contained" variant="contained"
> >
Last page Last
</Button> </Button>
</Box> </Box>
<Spacer height="60px" /> <Spacer height={isMobile ? '10px' : '30px'} />
{combinedListTempAndReal.map((message) => { {combinedListTempAndReal.map((message, index, list) => {
let fullMessage = message; let fullMessage = message;
if (hashMapMailMessages[message?.identifier]) { if (hashMapMailMessages[message?.identifier]) {
@ -534,7 +636,7 @@ export const Thread = ({
myName={userInfo?.name} myName={userInfo?.name}
/> />
); );
} else if(message?.tempData){ } else if (message?.tempData) {
return ( return (
<ShowMessage <ShowMessage
key={message?.identifier} key={message?.identifier}
@ -650,10 +752,6 @@ export const Thread = ({
)} )}
</ThreadContainer> </ThreadContainer>
</ThreadContainerFullWidth> </ThreadContainerFullWidth>
{/* {messages.length >= 20 && (
<LazyLoad onLoadMore={()=> getMailMessages(currentThread, false, true)}></LazyLoad>
)} */}
<LoadingSnackbar <LoadingSnackbar
open={isLoading} open={isLoading}
info={{ info={{