forked from MumbleGO/mumbleFrontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b76fa79
commit 063d948
Showing
13 changed files
with
316 additions
and
63 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,27 @@ | ||
const Message = ({ message }: { message?: any }) => { | ||
const fromMe = message.fromMe; | ||
const chatClass = fromMe ? "chat-end" : "chat-start"; | ||
const img = fromMe | ||
? "https://avatar.iran.liara.run/public/boy?username=johndoe" | ||
: "https://avatar.iran.liara.run/public/boy?username=janedoe"; | ||
import { useAuthContext } from "../../context/AuthContext"; | ||
import useConversation, { MessageType } from "../../zustand/useConversation"; | ||
import { extractTime } from "../../utils/extractTime"; | ||
|
||
const bubbleBg = fromMe ? "bg-blue-500" : ""; | ||
return ( | ||
<div className={`chat ${chatClass}`}> | ||
<div className='hidden md:block chat-image avatar'> | ||
<div className='w-6 md:w-10 rounded-full'> | ||
<img alt='Tailwind CSS chat bubble component' src={img} /> | ||
</div> | ||
</div> | ||
<p className={`chat-bubble text-white ${bubbleBg} text-sm md:text-md`}>{message.body}</p> | ||
<span className='chat-footer opacity-50 text-xs flex gap-1 items-center text-white'>22:59</span> | ||
</div> | ||
); | ||
const Message = ({ message }: { message: MessageType }) => { | ||
const { authUser } = useAuthContext(); | ||
const { selectedConversation } = useConversation(); | ||
|
||
const fromMe = message?.senderId === authUser?.id; | ||
const img = fromMe ? authUser?.profilePic : selectedConversation?.profilePic; | ||
const chatClass = fromMe ? "chat-end" : "chat-start"; | ||
|
||
const bubbleBg = fromMe ? "bg-blue-500" : ""; | ||
const shakeClass = message.shouldShake ? "shake" : ""; | ||
return ( | ||
<div className={`chat ${chatClass}`}> | ||
<div className='hidden md:block chat-image avatar'> | ||
<div className='w-6 md:w-10 rounded-full'> | ||
<img alt='Tailwind CSS chat bubble component' src={img} /> | ||
</div> | ||
</div> | ||
<p className={`chat-bubble text-white ${bubbleBg} ${shakeClass} text-sm md:text-md`}>{message.body}</p> | ||
<span className='chat-footer opacity-50 text-xs flex gap-1 items-center text-white'>{extractTime(message.createdAt)}</span> | ||
</div> | ||
); | ||
}; | ||
export default Message; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,43 @@ | ||
import { MessageCircle } from "lucide-react"; | ||
import { useAuthContext } from "../../context/AuthContext"; | ||
import useConversation from "../../zustand/useConversation"; | ||
import MessageInput from "./MessageInput"; | ||
import Messages from "./Messages"; | ||
|
||
// import { MessageCircle } from "lucide-react"; | ||
|
||
const MessageContainer = () => { | ||
return ( | ||
<div className='w-full flex flex-col'> | ||
<> | ||
{/* Header */} | ||
<div className='bg-slate-500 px-4 py-2 mb-2'> | ||
<span className='label-text'>To:</span> <span className='text-gray-900 font-bold'>John doe</span> | ||
</div> | ||
const { selectedConversation } = useConversation(); | ||
|
||
<Messages /> | ||
<MessageInput /> | ||
</> | ||
</div> | ||
); | ||
return ( | ||
<div className='w-full flex flex-col'> | ||
{!selectedConversation ? ( | ||
<NoChatSelected /> | ||
) : ( | ||
|
||
<> | ||
{/* Header */} | ||
<div className='bg-slate-500 px-4 py-2 mb-2'> | ||
<span className='label-text'>To:</span> <span className='text-gray-900 font-bold'>{selectedConversation.fullname}</span> | ||
</div> | ||
|
||
<Messages /> | ||
<MessageInput /> | ||
</> | ||
)} | ||
</div> | ||
); | ||
}; | ||
export default MessageContainer; | ||
|
||
// const NoChatSelected = () => { | ||
// return ( | ||
// <div className='flex items-center justify-center w-full h-full'> | ||
// <div className='px-4 text-center sm:text-lg md:text-xl text-gray-200 font-semibold flex flex-col items-center gap-2'> | ||
// <p>Welcome 👋 John Doe ❄</p> | ||
// <p>Select a chat to start messaging</p> | ||
// <MessageCircle className='text-3xl md:text-6xl text-center' /> | ||
// </div> | ||
// </div> | ||
// ); | ||
// }; | ||
const NoChatSelected = () => { | ||
const { authUser } = useAuthContext(); | ||
return ( | ||
<div className='flex items-center justify-center w-full h-full'> | ||
<div className='px-4 text-center sm:text-lg md:text-xl text-gray-200 font-semibold flex flex-col items-center gap-2'> | ||
<p>Welcome 👋 {authUser?.fullname} ❄</p> | ||
<p>Select a chat to start messaging</p> | ||
<MessageCircle className='text-3xl md:text-6xl text-center' /> | ||
</div> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,21 @@ | ||
import { DUMMY_MESSAGES } from "../../dummy_data/dummy"; | ||
import useChatScroll from "../../hooks/useChatScroll"; | ||
import useGetMessages from "../../hooks/useGetMessages"; | ||
import MessageSkeleton from "../skeletons/MessageSkeleton"; | ||
import Message from "./Message"; | ||
|
||
const Messages = () => { | ||
return ( | ||
<div className='px-4 flex-1 overflow-auto'> | ||
{DUMMY_MESSAGES.map((message) => ( | ||
<Message key={message.id} message={message} /> | ||
))} | ||
</div> | ||
); | ||
const { loading, messages } = useGetMessages(); | ||
const ref = useChatScroll(messages) as React.MutableRefObject<HTMLDivElement>; | ||
return ( | ||
<div className='px-4 flex-1 overflow-auto' ref={ref}> | ||
{loading && [...Array(3)].map((_, idx) => <MessageSkeleton key={idx} />)} | ||
|
||
{!loading && messages.map((message) => <Message key={message.id} message={message} />)} | ||
|
||
{!loading && messages.length === 0 && ( | ||
<p className='text-center text-white'>Send a message to start the conversation</p> | ||
)} | ||
</div> | ||
); | ||
}; | ||
export default Messages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useEffect, useRef } from "react"; | ||
|
||
function useChatScroll(dep: any) { | ||
const ref = useRef<HTMLElement>(); | ||
|
||
useEffect(() => { | ||
setTimeout(() => { | ||
if (ref.current) { | ||
ref.current.scrollTop = ref.current.scrollHeight; | ||
} | ||
}, 100); | ||
}, [dep]); | ||
|
||
return ref; | ||
} | ||
|
||
export default useChatScroll; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { useEffect, useState } from "react"; | ||
import toast from "react-hot-toast"; | ||
import { ConversationType } from "../zustand/useConversation"; | ||
|
||
const useGetConversations = () => { | ||
const [loading, setLoading] = useState(false); | ||
const [conversations, setConversations] = useState<ConversationType[]>([]); | ||
|
||
useEffect(() => { | ||
const getConversations = async () => { | ||
setLoading(true); | ||
try { | ||
const res = await fetch("/api/message/conversations"); | ||
const data = await res.json(); | ||
if (data.error) { | ||
throw new Error(data.error); | ||
} | ||
setConversations(data); | ||
} catch (error: any) { | ||
toast.error(error.message); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
getConversations(); | ||
}, []); | ||
|
||
return { loading, conversations }; | ||
}; | ||
export default useGetConversations; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { useEffect, useState } from "react"; | ||
import useConversation from "../zustand/useConversation"; | ||
import toast from "react-hot-toast"; | ||
|
||
const useGetMessages = () => { | ||
const [loading, setLoading] = useState(false); | ||
const { messages, setMessages, selectedConversation } = useConversation(); | ||
|
||
useEffect(() => { | ||
const getMessages = async () => { | ||
if (!selectedConversation) return; | ||
setLoading(true); | ||
setMessages([]); | ||
try { | ||
const res = await fetch(`/api/message/${selectedConversation.id}`); | ||
const data = await res.json(); | ||
if (!res.ok) throw new Error(data.error || "An error occurred"); | ||
setMessages(data); | ||
} catch (error: any) { | ||
toast.error(error.message); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
getMessages(); | ||
}, [selectedConversation, setMessages]); | ||
|
||
return { messages, loading }; | ||
}; | ||
export default useGetMessages; |
Oops, something went wrong.