diff --git a/components/chat/chat-item.tsx b/components/chat/chat-item.tsx
index 272cfa8..bd9a97b 100644
--- a/components/chat/chat-item.tsx
+++ b/components/chat/chat-item.tsx
@@ -13,6 +13,8 @@ import { Edit, FileIcon, ShieldAlert, ShieldCheck, Trash } from "lucide-react";
import Image from "next/image";
import { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
+import { useRouter } from "next/navigation";
+import { useParams } from "next/navigation";
import {
Form,
@@ -63,6 +65,16 @@ export const ChatItem = ({
}: ChatItemProps) => {
const [isEditing, setIsEditing] = useState(false);
const { onOpen } = useModal();
+ const params = useParams();
+ const router = useRouter();
+
+ const onMemberClick = () => {
+ if (member.id === currentMember.id) {
+ return;
+ }
+
+ router.push(`/servers/${params?.serverId}/conversations/${member.id}`);
+ }
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
@@ -120,13 +132,13 @@ export const ChatItem = ({
return (
-
+
-
+
{member.profile.name}
diff --git a/components/chat/chat-messages.tsx b/components/chat/chat-messages.tsx
index 5087a7e..a655b7e 100644
--- a/components/chat/chat-messages.tsx
+++ b/components/chat/chat-messages.tsx
@@ -8,6 +8,7 @@ import { useChatQuery } from "@/hooks/use-chat-query";
import { Loader2, ServerCrash } from "lucide-react";
import { Fragment } from "react";
import { ChatItem } from "./chat-item";
+import { useChatSocket } from "@/hooks/use-chat-socket";
const DATE_FORMAT = "d MMM yyyy, HH:mm";
@@ -41,6 +42,8 @@ export const ChatMessages = ({
type,
}: ChatMessagesProps) => {
const queryKey = `chat:${chatId}`;
+ const addKey = `chat:${chatId}:messages`;
+ const updateKey = `chat:${chatId}:messages:update`;
const {
data,
@@ -53,7 +56,8 @@ export const ChatMessages = ({
apiUrl,
paramKey,
paramValue,
- })
+ });
+ useChatSocket({ queryKey, addKey, updateKey});
if (status === "pending") {
return (
diff --git a/hooks/use-chat-socket.ts b/hooks/use-chat-socket.ts
new file mode 100644
index 0000000..870b1b8
--- /dev/null
+++ b/hooks/use-chat-socket.ts
@@ -0,0 +1,80 @@
+import { useSocket } from "@/components/providers/socket-provider";
+import { Member, Message, Profile } from "@prisma/client";
+import { useQueryClient } from "@tanstack/react-query";
+import { useEffect } from "react";
+
+type ChatSockerProps = {
+ addKey: string;
+ updateKey: string;
+ queryKey: string;
+}
+
+type MessageWithMemberWithProfile = Message & {
+ member: Member & {
+ profile: Profile;
+ }
+}
+
+export const useChatSocket = ({ addKey, updateKey, queryKey }: ChatSockerProps) => {
+ const { socket } = useSocket();
+ const queryClient = useQueryClient();
+
+ useEffect(() => {
+ if (!socket) return;
+
+ socket.on(addKey, (message: MessageWithMemberWithProfile) => {
+ queryClient.setQueryData([queryKey], ( oldData: any) => {
+ if (!oldData || !oldData.pages || oldData.pages.length === 0) {
+ return oldData;
+ }
+
+ const newData = oldData.pages.map((page: any) => {
+ return {
+ ...page,
+ items: page.items.map((item: MessageWithMemberWithProfile ) => {
+ if (item.id === message.id) {
+ return message;
+ }
+ return item;
+ })
+ }
+ });
+
+ return {
+ ...oldData,
+ pages: newData,
+
+ }
+ })
+ });
+
+ socket.on(addKey, (message: MessageWithMemberWithProfile) => {
+ queryClient.setQueryData([queryKey], (oldData: any) => {
+ if (!oldData || !oldData.pages || oldData.pages.length === 0) {
+ return {
+ pages: [{
+ items: [message],
+ }]
+ }
+ }
+
+ const newData = [...oldData.pages];
+
+ newData[0] = {
+ ...newData[0],
+ items: [message, ...newData[0].items],
+ };
+
+ return {
+ ...oldData,
+ pages: newData,
+ };
+ });
+ });
+
+ return () => {
+ socket.off(addKey);
+ socket.off(updateKey);
+ }
+ }, [queryClient, socket, addKey, updateKey, queryKey]);
+}
\ No newline at end of file
diff --git a/next.config.js b/next.config.js
index 2341245..6ccf4fa 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,5 +1,13 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
+ webpack: (config) => {
+ config.externals.push({
+ "utf-8-validate": "utf-8-validate",
+ "bufferutil": "commonjs bufferutil"
+ })
+
+ return config;
+ },
images: {
domains: [
"uploadthing.com",