diff --git a/src/app/chat/[id]/page.tsx b/src/app/chat/[id]/page.tsx index 8af22d6..11df39b 100644 --- a/src/app/chat/[id]/page.tsx +++ b/src/app/chat/[id]/page.tsx @@ -1,49 +1,26 @@ "use client"; -import { useRef, useState } from "react"; import MessageBox from "@/components/MessageBox"; import AppSidebar from "@/components/Sidebar"; -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"; +import useApp from "@/hooks/use-app"; export default function DMs() { const { id } = useParams<{ id: string }>(); - const wsRef = useRef(null); - const messages = useMessages((s) => s.messages); - const addMessage = useMessages((s) => s.addMessage); - const [userList, setUserList] = useState>({}); - const [user, setUser] = useState(); - const [sidebarOpen, setSidebarOpen] = useState(false); + const app = useApp(); return ( - + setSidebarOpen(true)} - channelName={userList[id]?.display_name || id} - userList={userList} - setUserList={setUserList} - messages={messages - .filter( - (m) => - (m.channel_id === id && m.from === user?.id) || - (m.from === id && m.channel_id === user?.id) - ) - .toReversed()} + app={app} + channelName={app.profiles[id]?.display_name || id} + messages={app.messages.filter( + (m) => + (m.channel_id === id && m.from === app.profile?.id) || + (m.from === id && m.channel_id === app.profile?.id) + )} sendMessage={(message) => { - wsRef.current?.send( + app.node.current?.send( JSON.stringify({ type: "send_message", params: { diff --git a/src/app/chat/page.tsx b/src/app/chat/page.tsx index 31af79b..546180b 100644 --- a/src/app/chat/page.tsx +++ b/src/app/chat/page.tsx @@ -1,59 +1,20 @@ "use client"; -import { useRef, useState } from "react"; import AppSidebar from "@/components/Sidebar"; -import { UserProfile } from "@/hooks/get-user"; -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"; +import useApp from "@/hooks/use-app"; export default function Chat() { - const wsRef = useRef(null); - const [userList, setUserList] = useState>({}); - const messages = useMessages((s) => s.messages); - const addMessage = useMessages((s) => s.addMessage); - const [sidebarOpen, setSidebarOpen] = useState(true); + const app = useApp(); return ( - + Direct Messages - - {/* */} - + ); } - -function DMItem({ - name, - avatar, - status, -}: { - name: string; - avatar: string; - status: string; -}) { - return ( - - -
- {name} - {status} -
-
- ); -} diff --git a/src/app/server/[ip]/page.tsx b/src/app/server/[ip]/page.tsx index d438230..1ad9a43 100644 --- a/src/app/server/[ip]/page.tsx +++ b/src/app/server/[ip]/page.tsx @@ -1,50 +1,47 @@ "use client"; -import { useEffect, useRef, useState } from "react"; +import { useRef, useState } from "react"; import { useParams } from "next/navigation"; import MessageBox from "@/components/MessageBox"; import AppSidebar from "@/components/Sidebar"; -import { Message, Server as ServerType } from "@/types/types"; -import { UserProfile } from "@/hooks/get-user"; -import { StringMap } from "@/types/typeUtils"; +import { Server as ServerType } from "@/types/types"; import auth from "@/lib/auth"; -import { useMessages } from "@/hooks/use-messages"; +import { useServerMessages } from "@/hooks/use-messages"; +import useApp from "@/hooks/use-app"; +import { useEffectOnceWhenReady } from "@/hooks/use-once"; export default function Server() { const { ip } = useParams<{ ip: string }>(); - const wsServerRef = useRef(null); - const wsNodeRef = useRef(null); + const serverRef = useRef(null); const [server, setServer] = useState(); - const [userList, setUserList] = useState>({}); - const messages = useMessages((s) => s.messages); - const addMessage = useMessages((s) => s.addMessage); - const [sidebarOpen, setSidebarOpen] = useState(false); + const app = useApp(); + const { messages, addMessage } = useServerMessages(); - useEffect(() => { - if (!ip) return; - auth(ip, wsServerRef, setServer, addMessage); - }, [ip]); + useEffectOnceWhenReady( + () => { + if (!ip) return; + const msgs = messages[ip]; + auth( + ip, + serverRef, + setServer, + (m) => addMessage(ip, m), + () => {}, + msgs ? msgs[msgs.length - 1]?.id : undefined + ); + }, + [ip, messages], + [undefined, (v) => v[ip]] + ); return ( - {}} - userList={userList} - setUserList={setUserList} - server={server} - > + setSidebarOpen(true)} + app={app} channelName="General" - userList={userList} - setUserList={setUserList} - messages={messages - .filter((m) => m.channel_id === "general") - .toReversed()} + messages={messages[ip]?.filter((m) => m.channel_id === "general") || []} sendMessage={(message) => { - wsServerRef.current?.send( + serverRef.current?.send( JSON.stringify({ type: "send_message", params: { diff --git a/src/components/MessageBox.tsx b/src/components/MessageBox.tsx index 20ad876..d1cc086 100644 --- a/src/components/MessageBox.tsx +++ b/src/components/MessageBox.tsx @@ -10,53 +10,45 @@ import { DropdownMenuContent, DropdownMenuTrigger, } from "./ui/dropdown-menu"; -import { ChevronLeft, ChevronLeftIcon, SmilePlusIcon } from "lucide-react"; -import { useEffect, useRef, useState } from "react"; +import { ChevronLeftIcon, SmilePlusIcon } from "lucide-react"; +import { useEffect, useState } from "react"; import { format, isToday, isYesterday } from "date-fns"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; -import { NumberMap, StringMap } from "@/types/typeUtils"; import { UserProfile } from "@/hooks/get-user"; import axios from "axios"; import ProfilePicture from "./ProfilePicture"; +import App from "@/types/app"; -function MessageContainer({ - message, - userList, - setUserList, -}: { - message: Message; - userList: StringMap; - setUserList: React.Dispatch>>; -}) { +function MessageContainer({ message, app }: { message: Message; app: App }) { useEffect(() => { axios .get("/api/profile/", { params: { id: message.from } }) .then((res) => - setUserList((prev) => ({ + app.setProfiles((prev) => ({ ...prev, [message.from]: res.data as UserProfile, })) ) .catch(() => {}); - }, [message.from, setUserList]); + }, [message.from]); return (
{/*
*/}
- {userList[message.from] - ? userList[message.from].display_name + {app.profiles[message.from] + ? app.profiles[message.from].display_name : message.from}

@@ -139,43 +131,37 @@ function MessageContainer({ } export default function MessageBox({ - messages, - userList, - setUserList, + app, sendMessage, channelName, - toggleSidebar, + messages, }: { - messages: Message[]; - userList: NumberMap; - setUserList: React.Dispatch>>; + app: App; sendMessage: (m: string) => void; channelName?: string; - toggleSidebar: () => void; + messages: Message[]; }) { const [text, setText] = useState(""); return ( -

+
{channelName && (
- + app.setSidebarOpen(true)} + className="cursor-pointer flex" + > {channelName}
)} -
- {messages.map((msg) => ( - +
+ {messages.toReversed().map((msg) => ( + ))}
-