hooked the socket to messages and applyed a fix
This commit is contained in:
parent
5da047a274
commit
a105e6180e
@ -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}>
|
||||||
|
@ -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
80
hooks/use-chat-socket.ts
Normal 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]);
|
||||||
|
}
|
@ -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",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user