Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dm): Integrated the reading and sending of text based messages #183

Draft
wants to merge 14 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 61 additions & 79 deletions components/common/chat/bubble_message/bubble_message.tsx
Original file line number Diff line number Diff line change
@@ -1,95 +1,77 @@
import * as React from 'react'
import moment from 'moment'
import { DirectMessageResponse } from '@/types/graphql'

export const BubbleMessage = ({
message,
messages,
currentUserID,
}: BubbleMessageProps) => {
return (
<div className="container ">
<div className="">
<div>
<div className="w-full">
<div className="relative w-full p-6 overflow-y-auto h-[40rem]">
<ul className="space-y-2">
{message.length > 0 &&
message.map(
(
{ message, user, timestamp },
index
) => (
<>
<li
className={`flex items-center left-li ${
user.id ===
currentUserID
? 'flex-row-reverse'
: 'justify-start'
}`}
key={index}
>
<div className="w-50 h-50 px-2">
<img
src={user.image}
alt="User profile picture"
className="shadow-lg rounded-full max-w-full h-8 aspect-square"
/>
</div>
<div
className={`relative max-w-xl px-4 py-2 text-white ${
user.id ===
currentUserID
? 'bg-blue-300'
: 'bg-gray-300'
} rounded shadow`}
>
<span className="block">
{message}
<div className="container w-full h-[calc(100vh_-_5rem)] overflow-y-scroll">
<div className="relative w-full p-6 pb-0 overflow-y-auto h-full">
<ul className="space-y-2">
{messages.length > 0 &&
messages.map(
({ body, author, recipient, createdAt }, index) => (
<>
<li
className={`flex items-center left-li ${
author.id === currentUserID
? 'flex-row-reverse'
: 'justify-start'
}`}
key={index}
>
<div className="w-50 h-50 px-2">
<img
src={author.picURL}
alt="User profile picture"
className="shadow-lg rounded-full max-w-full h-8 aspect-square"
/>
</div>
<div
className={`relative max-w-xl px-4 py-2 text-white ${
author.id === currentUserID
? 'bg-blue-300'
: 'bg-gray-300'
} rounded shadow`}
>
<span className="block">
{body}
</span>
</div>
<div className="w-50 h-50 px-2 opacity-50">
<span className="block text-xs text-slate-500">
{author.id === currentUserID ? (
<>
{moment(createdAt)
.utcOffset(-480)
.format('hh:mm A')}
<span className="inline-block -scale-x--1 -scale-y-1 align-middle">
//
</span>
</div>
<div className="w-50 h-50 px-2 opacity-50">
<span className="block text-xs text-slate-500">
<span>// </span>
{moment(
timestamp
).format('hh:mm A')}
</span>
</div>
</li>
{message[index + 1] && (
<li className="flex justify-center right-li">
<div className="w-50 h-50 px-2 t-100">
<span className="block text-xs text-slate-500">
{/* {moment */}
{/* .unix(timestamp1) */}
{/* .format( */}
{/* 'dddd, MMMM Do, hh:mm a' */}
{/* )} */}
</span>
</div>
</li>
</>
) : (
<>
<span>//</span>
{moment(createdAt)
.utcOffset(-480)
.format('hh:mm A')}
</>
)}
</>
)
)}
</ul>
</div>
</div>
</div>
</span>
</div>
</li>
</>
)
)}
</ul>
</div>
</div>
)
}

export type BubbleMessageProps = {
message: MessageProps
currentUserID: string | number
messages: DirectMessageResponse[]
currentUserID: string
}
export type MessageProps = {
user: {
id: string | number
image: string
}
message: string
timestamp: number
}[]
208 changes: 152 additions & 56 deletions components/common/chat/chat_history/chat_history.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,173 @@ import * as React from 'react'
import moment from 'moment'

import { FaTrash, FaArchive } from 'react-icons/fa'
import { DirectMessageResponse } from '@/types/graphql'

export const ChatHistory = ({ messages, handle }: ChatHistoryProps) => {
const [isChecked, setIsChecked] = React.useState(0 ?? null)
// const [isNotified, setIsNotified] = React.useState(0 ?? null)

export const ChatHistory = ({
messages,
handle,
handleSelect,
selected,
}: ChatHistoryProps) => {
return (
<div className="flex flex-col w-full h-full max-h-screen border-r-2 overflow-y-scroll">
{messages?.length &&
messages.map((message, messageIndex) => (
<div
className={`flex flex-row py-4 px-2 justify-center items-center border-b-2 relative before:absolute before:left-0 before:top-0 before:h-full before:w-1 before:bg-blue-100 before:transition-opacity before:block
${isChecked === messageIndex ? ' before:opacity-100' : ' before:opacity-0'}`}
className={`flex flex-row gap-1 py-4 px-2 justify-center items-center border-b-2 relative before:absolute before:left-0 before:top-0 before:h-full before:w-1 before:bg-royalblue before:bg-opacity-25 before:transition-opacity before:block
${
selected === message.recipient.id
? ' before:opacity-100'
: ' before:opacity-0'
}`}
key={messageIndex}
onClick={() => setIsChecked(messageIndex)}
onClick={() => handleSelect(message.recipient.id)}
>
<div
className={`
${
messages[messageIndex].newNotification ===
true
? ' rounded-full mx-1 bg-blue-500 h-2.5 w-5 flex items-center justify-center'
: ''
}`}
></div>
<div className="w-1/4">
<img
src={message.image}
className="object-cover h-12 w-12 rounded-full aspect-square"
alt=""
{message.recipient.__typename === 'Group' ? (
<GroupChatListItem
timestamp={message.createdAt}
name={
'name' in message.recipient
? message.recipient.name
: 'Unknown'
}
messages={messages}
handle={handle}
messageIndex={messageIndex}
/>
) : (
<UserChatListItem
messageIndex={messageIndex}
handle={handle}
messages={messages}
timestamp={message.createdAt}
lastName={
'lastName' in message.recipient
? message.recipient.lastName
: 'Unknown'
}
firstName={
'firstName' in message.recipient
? message.recipient.firstName
: 'Unknown'
}
picURL={
'picURL' in message.recipient
? message.recipient.picURL
: 'Unknown'
}
/>
</div>
<div className="w-full">
<div className="flex flex-col gap-3">
<div className="text-lg font-semibold">
{message.name}
</div>
<span className="text-gray-500 text-xs">
{moment(message.timestamp).fromNow()}
</span>
</div>
</div>
<div className="flex flex-row">
<button className="flex items-center justify-center px-4 cursor-pointer">
<FaTrash
size={20}
className="mr-1"
onClick={handle}
/>
</button>
<button className="flex items-center justify-center px-4 cursor-pointer">
<FaArchive
size={20}
className="mr-1"
onClick={handle}
/>
</button>
</div>
)}
</div>
))}
</div>
)
}

type ChatHistoryProps = {
messages: HistoryProps[]
const GroupChatListItem = ({
messages,
messageIndex,
name,
timestamp,
handle,
}: {
messages: DirectMessageResponse[]
messageIndex: number
name: string
timestamp: Date
handle: () => void
}) => {
return (
<>
<div
className={`${
messages[messageIndex].newNotification === true
? ' rounded-full mx-1 bg-blue-500 h-2.5 w-5 flex items-center justify-center'
: ''
}`}
></div>
<div className="w-1/4">
<div className="rounded-full w-12 object-cover, aspect-square flex items-center justify-center bg-royalblue">
<span
className="text-4xl text-white font-bold"
style={{
fontSize: '18pt',
}}
>
{name.split(' ')[0][0]}
</span>
</div>
</div>
<div className="w-full">
<div className="flex flex-col">
<div className="text-lg font-semibold">{name}</div>
<span className="text-gray-500 text-xs">
{moment(timestamp).utcOffset(-480).format('hh:mm A')}
</span>
</div>
</div>
<div className="flex flex-row">
<button className="flex items-center justify-center px-0.5 cursor-pointer">
<FaTrash size={20} className="mr-1" onClick={handle} />
</button>
<button className="flex items-center justify-center px-0.5 cursor-pointer">
<FaArchive size={20} className="mr-1" onClick={handle} />
</button>
</div>
</>
)
}
type HistoryProps = {
name: string
image: string
selected: boolean
timestamp: number
newNotification: boolean

const UserChatListItem = ({
messages,
messageIndex,
firstName,
lastName,
picURL,
handle,
timestamp,
}) => {
return (
<>
<div
className={`${
messages[messageIndex].newNotification === true
? ' rounded-full mx-1 bg-blue-500 h-2.5 w-5 flex items-center justify-center'
: ''
}`}
></div>
<div className="w-1/4">
<img
src={picURL}
className="object-cover w-12 rounded-full aspect-square"
alt="The profile picture of the user you are sending a message to."
/>
</div>
<div className="w-full">
<div className="flex flex-col">
<div className="text-lg font-semibold">
{firstName} {lastName}
</div>
<span className="text-gray-500 text-xs">
{moment(timestamp).utcOffset(-480).format('hh:mm A')}
</span>
</div>
</div>
<div className="flex flex-row">
<button className="flex items-center justify-center px-0.5 cursor-pointer">
<FaTrash size={20} className="mr-1" onClick={handle} />
</button>
<button className="flex items-center justify-center px-0.5 cursor-pointer">
<FaArchive size={20} className="mr-1" onClick={handle} />
</button>
</div>
</>
)
}

type ChatHistoryProps = {
messages: DirectMessageResponse[]
handle: () => void
handleSelect: (id: string) => void
selected: string
}
Loading