hooked the socket to messages and applyed a fix

This commit is contained in:
Bob Burningham 2023-10-29 16:28:03 -07:00
parent 5da047a274
commit a105e6180e
4 changed files with 107 additions and 3 deletions

View File

@ -13,6 +13,8 @@ import { Edit, FileIcon, ShieldAlert, ShieldCheck, Trash } from "lucide-react";
import Image from "next/image"; import Image from "next/image";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { useRouter } from "next/navigation";
import { useParams } from "next/navigation";
import { import {
Form, Form,
@ -63,6 +65,16 @@ export const ChatItem = ({
}: ChatItemProps) => { }: ChatItemProps) => {
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const { onOpen } = useModal(); 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(() => { useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
@ -120,13 +132,13 @@ export const ChatItem = ({
return ( return (
<div className="relative group flex items-center hover:bg-black/5 p-4 transition w-full"> <div className="relative group flex items-center hover:bg-black/5 p-4 transition w-full">
<div className="group flex gap-x-2 items-start w-full"> <div className="group flex gap-x-2 items-start w-full">
<div className="cursor-pointer hover:drop-shadow-md transition"> <div onClick={onMemberClick} className="cursor-pointer hover:drop-shadow-md transition">
<UserAvatar src={member.profile.imageUrl}/> <UserAvatar src={member.profile.imageUrl}/>
</div> </div>
<div className="flex flex-col w-full"> <div className="flex flex-col w-full">
<div className="flex items-center gap-x-2"> <div className="flex items-center gap-x-2">
<div className="flex items-center"> <div className="flex items-center">
<p className="font-semibold text-sm hove:underline cursor-pointer"> <p onClick={onMemberClick} className="font-semibold text-sm hover:underline cursor-pointer">
{member.profile.name} {member.profile.name}
</p> </p>
<ActionTooltip label={member.role}> <ActionTooltip label={member.role}>

View File

@ -8,6 +8,7 @@ import { useChatQuery } from "@/hooks/use-chat-query";
import { Loader2, ServerCrash } from "lucide-react"; import { Loader2, ServerCrash } from "lucide-react";
import { Fragment } from "react"; import { Fragment } from "react";
import { ChatItem } from "./chat-item"; import { ChatItem } from "./chat-item";
import { useChatSocket } from "@/hooks/use-chat-socket";
const DATE_FORMAT = "d MMM yyyy, HH:mm"; const DATE_FORMAT = "d MMM yyyy, HH:mm";
@ -41,6 +42,8 @@ export const ChatMessages = ({
type, type,
}: ChatMessagesProps) => { }: ChatMessagesProps) => {
const queryKey = `chat:${chatId}`; const queryKey = `chat:${chatId}`;
const addKey = `chat:${chatId}:messages`;
const updateKey = `chat:${chatId}:messages:update`;
const { const {
data, data,
@ -53,7 +56,8 @@ export const ChatMessages = ({
apiUrl, apiUrl,
paramKey, paramKey,
paramValue, paramValue,
}) });
useChatSocket({ queryKey, addKey, updateKey});
if (status === "pending") { if (status === "pending") {
return ( return (

80
hooks/use-chat-socket.ts Normal file
View File

@ -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]);
}

View File

@ -1,5 +1,13 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
webpack: (config) => {
config.externals.push({
"utf-8-validate": "utf-8-validate",
"bufferutil": "commonjs bufferutil"
})
return config;
},
images: { images: {
domains: [ domains: [
"uploadthing.com", "uploadthing.com",