Working DM list

This commit is contained in:
2025-10-15 10:15:32 +02:00
parent bbc2777ad4
commit ab4cf4245f
4 changed files with 59 additions and 9 deletions
+1
View File
@@ -26,6 +26,7 @@ export default function DMs() {
setUserList={setUserList} setUserList={setUserList}
chatWith={id} chatWith={id}
setUser={setUser} setUser={setUser}
messages={messages}
> >
<MessageBox <MessageBox
channelName={userList[id]?.display_name || id} channelName={userList[id]?.display_name || id}
+5 -2
View File
@@ -6,24 +6,27 @@ import { UserProfile } from "@/hooks/get-user";
import { StringMap } from "@/types/typeUtils"; import { StringMap } from "@/types/typeUtils";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import ProfilePicture from "@/components/ProfilePicture"; import ProfilePicture from "@/components/ProfilePicture";
import { Message } from "@/types/types";
export default function Chat() { export default function Chat() {
const wsRef = useRef<WebSocket | null>(null); const wsRef = useRef<WebSocket | null>(null);
const [userList, setUserList] = useState<StringMap<UserProfile>>({}); const [userList, setUserList] = useState<StringMap<UserProfile>>({});
const [messages, setMessages] = useState<Message[]>([]);
return ( return (
<AppSidebar <AppSidebar
wsRef={wsRef} wsRef={wsRef}
userList={userList} userList={userList}
setUserList={setUserList} setUserList={setUserList}
setMessages={() => {}} setMessages={setMessages}
messages={messages}
> >
<Card className="bg-background w-full"> <Card className="bg-background w-full">
<CardHeader> <CardHeader>
<CardTitle>Direct Messages</CardTitle> <CardTitle>Direct Messages</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<DMItem name="Alice" status="online" avatar="" /> {/* <DMItem name="Alice" status="online" avatar="" /> */}
</CardContent> </CardContent>
</Card> </Card>
</AppSidebar> </AppSidebar>
+50 -5
View File
@@ -32,6 +32,8 @@ import auth from "@/lib/auth";
import { toast } from "sonner"; import { toast } from "sonner";
import { StringMap } from "@/types/typeUtils"; import { StringMap } from "@/types/typeUtils";
import SettingsDialog from "./settings/SettingsDialog"; import SettingsDialog from "./settings/SettingsDialog";
import Link from "next/link";
import axios from "axios";
export default function AppSidebar({ export default function AppSidebar({
children, children,
@@ -41,8 +43,10 @@ export default function AppSidebar({
onNewMessage, onNewMessage,
setUser, setUser,
server, server,
messages,
}: Readonly<{ }: Readonly<{
wsRef: React.RefObject<WebSocket | null>; wsRef: React.RefObject<WebSocket | null>;
messages?: Message[];
setMessages: React.Dispatch<React.SetStateAction<Message[]>>; setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
onNewMessage?: (msg: Message) => void; onNewMessage?: (msg: Message) => void;
userList: StringMap<UserProfile>; userList: StringMap<UserProfile>;
@@ -58,6 +62,10 @@ export default function AppSidebar({
const user = useUser(); const user = useUser();
const [userList, setUserList] = useState<StringMap<UserProfile>>({}); const [userList, setUserList] = useState<StringMap<UserProfile>>({});
const dms = Array.from(
new Set(messages?.flatMap((item) => [item.from, item.channel_id]) || [])
);
useEffect(() => { useEffect(() => {
const s = Cookies.get("servers")?.split(","); const s = Cookies.get("servers")?.split(",");
if (s) setServers(s.map((x) => x.trim().split("@") as [string, string])); if (s) setServers(s.map((x) => x.trim().split("@") as [string, string]));
@@ -222,9 +230,19 @@ export default function AppSidebar({
</> </>
) : ( ) : (
<> <>
<DMItem name="Alice" status="online" avatar="" /> {dms.map((id) => (
<DMItem name="Bob" status="offline" avatar="" /> <DMItem
<DMItem name="Charlie" status="away" avatar="" /> name={
getUser(id, userList, setUserList)?.display_name || id
}
id={id}
status="online"
avatar={
getUser(id, userList, setUserList)?.avatar_url || ""
}
key={id}
/>
))}
</> </>
)} )}
</div> </div>
@@ -233,6 +251,7 @@ export default function AppSidebar({
<footer className="mt-auto pb-3 pl-3 pr-3"> <footer className="mt-auto pb-3 pl-3 pr-3">
<DMItem <DMItem
name={user?.display_name || "Loading.."} name={user?.display_name || "Loading.."}
id={user?.id || "me"}
avatar={user?.avatar_url || ""} avatar={user?.avatar_url || ""}
status="online" status="online"
settings settings
@@ -248,11 +267,13 @@ export default function AppSidebar({
function DMItem({ function DMItem({
name, name,
id,
avatar, avatar,
status, status,
settings, settings,
}: { }: {
name: string; name: string;
id: string;
avatar: string; avatar: string;
status: string; status: string;
settings?: boolean; settings?: boolean;
@@ -260,7 +281,10 @@ function DMItem({
const router = useRouter(); const router = useRouter();
return ( return (
<Card className="p-2 flex flex-row items-center gap-2 cursor-pointer hover:bg-accent"> <Link
href={`/chat/${id}`}
className="p-2 flex flex-row items-center gap-2 cursor-pointer hover:bg-accent"
>
<ProfilePicture name={name} url={avatar} /> <ProfilePicture name={name} url={avatar} />
<div className="flex flex-col"> <div className="flex flex-col">
<span className="text-sm font-medium">{name}</span> <span className="text-sm font-medium">{name}</span>
@@ -272,7 +296,7 @@ function DMItem({
tab="profile" tab="profile"
/> />
)} )}
</Card> </Link>
); );
} }
@@ -295,3 +319,24 @@ function ChannelIcon({ kind }: { kind: "text" | "voice" }) {
return null; return null;
} }
} }
function getUser(
id: string,
userList: StringMap<UserProfile>,
setUserList: React.Dispatch<React.SetStateAction<StringMap<UserProfile>>>
) {
if (userList[id]) return userList[id];
axios
.get(`/api/profile/?id=${id}`)
?.then((res) => {
console.log("Fetched user", res.data);
setUserList((prev) => {
prev[id] = res.data as UserProfile;
return prev;
});
})
.catch((e) => {
console.error(e);
});
}
+3 -2
View File
@@ -15,8 +15,9 @@ export default async function auth(
.address as string; .address as string;
console.log("Authenticating with server at:", ip); console.log("Authenticating with server at:", ip);
const server_auth = ((await axios.post("/api/auth", { server_id: id })).data as any) const server_auth = (
.token; (await axios.post("/api/auth", { server_id: id })).data as any
).token;
// Open the WebSocket connection // Open the WebSocket connection
const ws = new WebSocket(`wss://${ip}`); const ws = new WebSocket(`wss://${ip}`);