From f5aca7434fe6e1e0680a962927624513212208f0 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Wed, 15 Oct 2025 10:40:25 +0200 Subject: [PATCH] DM message caching --- package-lock.json | 32 +++++++++++++++++++++++++++++++- package.json | 3 ++- src/app/chat/[id]/page.tsx | 4 +++- src/app/chat/page.tsx | 4 +++- src/components/Sidebar.tsx | 2 +- src/hooks/use-messages.ts | 27 +++++++++++++++++++++++++++ src/lib/auth.ts | 5 +++-- 7 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 src/hooks/use-messages.ts diff --git a/package-lock.json b/package-lock.json index 6211150..e1c1033 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,8 @@ "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1", "sonner": "^2.0.7", - "tailwind-merge": "^3.3.1" + "tailwind-merge": "^3.3.1", + "zustand": "^5.0.8" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -5443,6 +5444,35 @@ "url": "https://github.com/sponsors/dmonad" } }, + "node_modules/zustand": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz", + "integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 1f0707e..6b383a7 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1", "sonner": "^2.0.7", - "tailwind-merge": "^3.3.1" + "tailwind-merge": "^3.3.1", + "zustand": "^5.0.8" }, "devDependencies": { "@tailwindcss/postcss": "^4", diff --git a/src/app/chat/[id]/page.tsx b/src/app/chat/[id]/page.tsx index eb3d23d..a4715d4 100644 --- a/src/app/chat/[id]/page.tsx +++ b/src/app/chat/[id]/page.tsx @@ -7,6 +7,7 @@ import { Message } from "@/types/types"; import { UserProfile } from "@/hooks/get-user"; import { StringMap } from "@/types/typeUtils"; import { useParams } from "next/navigation"; +import { useMessages } from "@/hooks/use-messages"; // In this testing instance we are assuming that the target's node is localhost // To make this functional we need to add a settings feature to the api @@ -14,7 +15,8 @@ import { useParams } from "next/navigation"; export default function DMs() { const { id } = useParams<{ id: string }>(); const wsRef = useRef(null); - const [messages, setMessages] = useState([]); + const messages = useMessages((s) => s.messages); + const setMessages = useMessages((s) => s.setMessages); const [userList, setUserList] = useState>({}); const [user, setUser] = useState(); diff --git a/src/app/chat/page.tsx b/src/app/chat/page.tsx index 5369886..9ebd33d 100644 --- a/src/app/chat/page.tsx +++ b/src/app/chat/page.tsx @@ -7,11 +7,13 @@ import { StringMap } from "@/types/typeUtils"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import ProfilePicture from "@/components/ProfilePicture"; import { Message } from "@/types/types"; +import { useMessages } from "@/hooks/use-messages"; export default function Chat() { const wsRef = useRef(null); const [userList, setUserList] = useState>({}); - const [messages, setMessages] = useState([]); + const messages = useMessages((s) => s.messages); + const setMessages = useMessages((s) => s.setMessages); return ( ; messages?: Message[]; - setMessages: React.Dispatch>; + setMessages: (m: Message[]) => void; onNewMessage?: (msg: Message) => void; userList: StringMap; setUserList: React.Dispatch>>; diff --git a/src/hooks/use-messages.ts b/src/hooks/use-messages.ts new file mode 100644 index 0000000..6d5ab5e --- /dev/null +++ b/src/hooks/use-messages.ts @@ -0,0 +1,27 @@ +import { Message } from "@/types/types"; +import { create } from "zustand"; +import { persist } from "zustand/middleware"; + +interface MessageStore { + messages: Message[]; + setMessages: (msgs: Message[]) => void; + addMessage: (msg: Message) => void; + clearMessages: () => void; +} + +export const useMessages = create()( + persist( + (set) => ({ + messages: [], + setMessages: (msgs) => set({ messages: msgs }), + addMessage: (msg) => + set((state) => + state.messages.some((m) => m.id === msg.id) + ? state + : { messages: [...state.messages, msg] } + ), + clearMessages: () => set({ messages: [] }), + }), + { name: "chat-messages" } + ) +); diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 629e5d3..083d5fd 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -6,7 +6,8 @@ export default async function auth( id: string, wsRef: RefObject, setServer: Dispatch>, - setMessages: Dispatch>, + setMessages: (m: Message[]) => void, + addMessage: (m: Message) => void, onNewMessage?: (m: Message) => void ) { console.log("Authenticating with server id:", id); @@ -50,7 +51,7 @@ export default async function auth( case "message_create": if (onNewMessage) onNewMessage(data.params as Message); - setMessages((prev) => [...prev, data.params]); + addMessage(data.params as Message); break; } };