Jun 10, 2024
0
Level 8
ReactJS Messenger Type, OnInit Scroll to bottom not running
Help, I had it working, then pressed ctrl z and changed something and lost what I had done. I want it to scroll to the bottom of the window when the first set of messages come through, but never to run again since I want the user to scroll up and see previous messages.
import React, { useState, useEffect, useRef } from 'react';
import Modal from '@/Components/Modal';
import { router } from '@inertiajs/react';
export default function Message({ toggle, setToggle, contact }) {
const containerRef = useRef(null);
const [contactNew, setContactNew] = useState([]);
const [values, setValues] = useState({
user_id: contact ? contact.receiver_id : '',
body: '',
});
const [initialLoad, setInitialLoad] = useState(true);
const fetchNewMessages = async () => {
if (!contact?.sender_id || !contact?.receiver_id) {
console.error('Sender ID or Receiver ID is missing');
return [];
}
try {
const response = await fetch(`/dashboard/messages/${contact.sender_id}/${contact.receiver_id}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const newMessages = await response.json();
return newMessages;
} catch (error) {
console.error('Failed to fetch new messages:', error);
return [];
}
};
useEffect(() => {
if (toggle) {
const fetchAndUpdateMessages = async () => {
const newMessages = await fetchNewMessages();
setContactNew(newMessages);
};
fetchAndUpdateMessages(); // Initial fetch on mount
const intervalId = setInterval(fetchAndUpdateMessages, 1000); // Adjust the interval as needed
return () => clearInterval(intervalId); // Cleanup on unmount
}
}, [toggle, contact]);
useEffect(() => {
if (contact && contact.receiver_id) {
setValues((prevValues) => ({
...prevValues,
user_id: contact.receiver_id,
}));
}
}, [contact]);
useEffect(() => {
if (initialLoad && contactNew.length > 0) {
if (containerRef.current) {
containerRef.current.scrollTop = containerRef.current.scrollHeight;
}
setInitialLoad(false);
}
}, [contactNew]);
function handleChange(e) {
const key = e.target.id;
const value = e.target.value;
setValues(values => ({
...values,
[key]: value,
}));
}
function handleSubmit(e) {
e.preventDefault();
router.post('/dashboard/messages', values, {
preserveScroll: true,
preserveState: true,
onSuccess: () => {
setValues({ ...values, body: '' });
},
});
}
function setClose() {
setToggle(false);
}
return (
<Modal show={toggle}>
<div className="space-y-4 p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<img src="/images/icons/icons8-messages-64.png" className="w-8 h-8" alt="Message Icon" />
{contact?.receiver?.name && <p className="font-bold">{contact.receiver.name}</p>}
</div>
<button className="active:scale-95" onClick={setClose}>
<img src="/images/icons/icons8-close-64.png" className="w-8 h-8" alt="Close Icon" />
</button>
</div>
<div className="space-x-4 py-8">
<div ref={containerRef} className="border rounded-lg shadow-md p-4 h-72 overflow-auto">
<div className={`space-y-4`}>
{contactNew?.messages?.map((message, i) => (
<div key={i}>
<p className="font-bold text-gray-400">{message.user.name}</p>
<p className="font-thin">{message.body}</p>
</div>
))}
</div>
</div>
</div>
<form onSubmit={handleSubmit}>
<div className="grid grid-cols-4 gap-4">
<input id="body" onChange={handleChange} value={values.body} className="col-span-3 rounded-lg shadow-md border border-gray-300" type="text" />
<button type="submit" className="rounded-lg shadow-md p-2 border border-gray-300">Send</button>
</div>
</form>
</div>
</Modal>
);
}
Please or to participate in this conversation.