Skip to content

Commit

Permalink
Merge pull request #7 from stephan-rz/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
stephan-rz authored May 19, 2024
2 parents 7399220 + a823032 commit 8150e10
Show file tree
Hide file tree
Showing 18 changed files with 471 additions and 69 deletions.
65 changes: 62 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.51.2",
"react-hot-toast": "^2.4.1",
"react-spinners": "^0.13.8",
"resend": "^3.2.0",
"zod": "^3.22.4"
"zod": "^3.22.4",
"zustand": "^4.5.2"
},
"devDependencies": {
"@types/bcrypt": "^5.0.2",
Expand Down
9 changes: 9 additions & 0 deletions src/app/(Main)/conversations/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import LoadingModal from "@/components/modals/loading-modal"

const Loading = () => {
return (
<LoadingModal/>
)
}

export default Loading
57 changes: 57 additions & 0 deletions src/app/api/conversations/[conversationId]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { currentUser } from "@/lib/auth";
import { db } from "@/lib/db";
import { pusherServer } from "@/lib/pusher";
import { NextResponse } from "next/server";

interface IParams {
conversationId?: string;
}

export async function DELETE(
request: Request,
{ params }: { params: IParams }
) {
const user = await currentUser();

if (!user) {
return new NextResponse("Unauthorized", { status: 401 });
}

try {
const { conversationId } = params;

const conversation = await db.conversation.findUnique({
where: {
id: conversationId
},
include: {
users: true
}
});

if(!conversation) {
return new NextResponse("Invalid ID", { status: 400 });
}

await db.conversation.deleteMany({
where: {
id: conversationId,
userIds: {
hasSome: [user?.id!]
}
}
});

conversation.users.forEach((user) => {
if (user.email) {
pusherServer.trigger(user.email, 'conversation:remove', conversation)
}
})

return new NextResponse("Conversation deleted", { status: 200 });

} catch (error) {
console.log(error, "ERROR_CONVERSATION_DELETE");
return new NextResponse("Internal server error", { status: 500 });
}
}
12 changes: 12 additions & 0 deletions src/app/api/conversations/[conversationId]/seen/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { currentUser } from "@/lib/auth";
import { db } from "@/lib/db";
import { pusherServer } from "@/lib/pusher";
import { NextResponse } from "next/server";

interface IParams {
Expand Down Expand Up @@ -61,6 +62,17 @@ export async function POST(
}
});

await pusherServer.trigger(user?.email as string, 'conversation:update' , {
id: conversationId,
message: [updatedMessage]
})

if(lastMessage.seenIds.indexOf(user?.id as string) !== -1) {
return NextResponse.json(conversation);
}

await pusherServer.trigger(conversationId!, 'message:update', updatedMessage);

return NextResponse.json(updatedMessage);

} catch (error) {
Expand Down
7 changes: 7 additions & 0 deletions src/app/api/conversations/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { currentUser } from "@/lib/auth";
import { NextResponse } from "next/server";
import { db } from "@/lib/db";
import { pusherServer } from "@/lib/pusher";

export async function POST(
request: Request
Expand Down Expand Up @@ -88,6 +89,12 @@ export async function POST(
}
})

newConversation.users.map((user) => {
if(user.email) {
pusherServer.trigger(user.email, 'conversation:new', newConversation)
}
})

return NextResponse.json(newConversation)

} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function RootLayout({
return (
<html lang="en">
<body className={poppins.className}>
<SessionProvider>
<SessionProvider >
<NextProvider>
{children}
</NextProvider>
Expand Down
9 changes: 7 additions & 2 deletions src/components/avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { Avatar } from "@nextui-org/react"
import { User } from "@prisma/client"

export const UserAvatar = (image: string) => {
interface UserAvatarProps {
user?: User
}

export const UserAvatar = ({ user }: UserAvatarProps) => {
return (
<div className="relative">
<Avatar src={image} alt="avatar" showFallback />
<Avatar src={user?.image as string} alt="avatar" showFallback />
<span className="absolute block rounded-full bg-green-500 ring-2 ring-white top-[2px] right-[2px] h-2 w-2 md:h-2 md:w-2" />
</div>
)
Expand Down
11 changes: 11 additions & 0 deletions src/components/conversations/chat-body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,25 @@ const ChatBody = ({ initialMessages }: ChatBodyProps) => {
})

bottomRef?.current?.scrollIntoView();
}

const updateMessageHandler = (newMessage: FullMessageType) => {
setMessages((current) => current!.map((currentMessage) => {
if(currentMessage.id === newMessage.id) {
return newMessage;
}

return currentMessage;
}));
}

pusherClient.bind('messages:new', messageHandler);
pusherClient.bind('message:update', updateMessageHandler)

return () => {
pusherClient.unsubscribe(conversationId as string);
pusherClient.unbind('messages:new', messageHandler);
pusherClient.unbind('message:update', updateMessageHandler)
}
}, [conversationId]);

Expand Down
7 changes: 2 additions & 5 deletions src/components/conversations/chat-header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use client"

import useOtherUser from "@/hooks/use-other-user";
import { Avatar } from "@nextui-org/react";
import { Conversation, User } from "@prisma/client";
import { ArrowLeft, Ellipsis } from "lucide-react";
import Link from "next/link";
import { useMemo, useState } from "react";
import ProfileDrawer from "./profile-drawer";
import { UserAvatar } from "../avatar";

interface ChatHeaderProps {
conversation: Conversation & {
Expand Down Expand Up @@ -38,10 +38,7 @@ const ChatHeader = ({ conversation }: ChatHeaderProps) => {
<Link href="/conversations" className="lg:hidden block text-white hover:text-primary transition cursor-pointer">
<ArrowLeft size={24} />
</Link>
<div className="relative">
<Avatar src={otherUser?.image as string} alt="avatar" showFallback />
<span className="absolute block rounded-full bg-green-500 ring-2 ring-white top-[2px] right-[2px] h-2 w-2 md:h-2 md:w-2" />
</div>
<UserAvatar user={otherUser} />
<div className="flex flex-col">
<div className="truncate">
{conversation.name || otherUser.name}
Expand Down
8 changes: 3 additions & 5 deletions src/components/conversations/conversation-box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import useOtherUser from "@/hooks/use-other-user"
import { useCurrentUser } from "@/hooks/use-current-user"
import { cn } from "@/lib/utils"
import { Avatar } from "@nextui-org/react"
import { UserAvatar } from "../avatar"

interface ConversationBoxProps {
data: FullConversationType,
Expand Down Expand Up @@ -60,13 +61,10 @@ const ConversationBox = ({

return (
<button onClick={handleClick} className={cn("w-full relative flex items-center space-x-3 p-3 hover:bg-zinc-700 rounded-lg transition cursor-pointer", selected ? "bg-zinc-800" : "bg-zinc-900")}>
<div className="relative">
<Avatar src={otherUser?.image as string} alt="avatar" showFallback/>
<span className="absolute block rounded-full bg-green-500 ring-2 ring-white top-[2px] right-[2px] h-2 w-2 md:h-2 md:w-2"/>
</div>
<UserAvatar user={otherUser} />
<div className="min-w-0 flex-1">
<div className="focus:outline-none">
<div className="flex justify-between items-center mb-1">
<div className="flex justify-between gap-3 items-center mb-1">
<p className="text-md truncate font-medium text-white">{data.name || otherUser.name}</p>
{lastMessage?.createdAt && (
<p className="text-xs text-white/50 font-light">
Expand Down
Loading

0 comments on commit 8150e10

Please sign in to comment.