"use client"; import { HashIcon, MessageCircle, Plus, Search, Volume2Icon, } from "lucide-react"; import { Server, Channel, Message } from "@/types/types"; import React, { useEffect, useRef, useState } from "react"; import Cookies from "js-cookie"; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "./ui/dialog"; import { Input } from "./ui/input"; import { Label } from "./ui/label"; import { Button } from "./ui/button"; import { Card } from "./ui/card"; import { ScrollArea } from "./ui/scroll-area"; import { useRouter } from "next/navigation"; import useUser, { UserProfile } from "@/hooks/get-user"; import ProfilePicture from "./ProfilePicture"; import auth from "@/lib/auth"; import { toast } from "sonner"; import { StringMap } from "@/types/typeUtils"; import SettingsDialog from "./settings/SettingsDialog"; import Link from "next/link"; import axios from "axios"; import { get, Response } from "@/lib/request"; export default function AppSidebar({ children, chatWith, wsRef, onNewMessage, setUser, server, messages, addMessage, }: Readonly<{ wsRef: React.RefObject; addMessage: (msg: Message) => void; messages?: Message[]; onNewMessage?: (msg: Message) => void; userList: StringMap; setUserList: React.Dispatch>>; chatWith?: string; children?: React.ReactNode; setUser?: React.Dispatch>; server?: Server | undefined; }>) { const [servers, setServers] = useState<[string, string][]>([]); const [newServer, setNewServer] = useState({ name: "", ip: "" }); const router = useRouter(); const user = useUser(); const [userList, setUserList] = useState>({}); const dms = Array.from( new Set(messages?.flatMap((item) => [item.from, item.channel_id]) || []) ); useEffect(() => { const s = Cookies.get("servers")?.split(","); if (s) setServers(s.map((x) => x.trim().split("@") as [string, string])); }, []); useEffect(() => { if (!user?.node_address) return; if (setUser) setUser(user); auth( user?.node_address, wsRef, () => {}, (ms) => ms.forEach(addMessage), (m) => { if (m.from !== chatWith && m.from !== user.id) toast( `New message from ${userList[m.from]?.display_name || m.from}`, { description: m.contents.slice(0, 80), action: { label: "View", onClick: () => router.push(`/chat/${m.from}`), }, } ); if (onNewMessage) onNewMessage(m); }, undefined, messages ? messages[messages.length - 1].id : undefined ); setUserList((prev) => { prev[user.id] = user; return prev; }); }, [chatWith, user]); const handleAddServer = () => { if (!newServer.ip) return; const updatedServers = [ ...servers, [newServer.ip, newServer.name] as [string, string], ]; setServers(updatedServers); Cookies.set("servers", updatedServers.map((x) => x.join("@")).join(","), { expires: 7, }); setNewServer({ name: "", ip: "" }); }; return (
{servers.map( ([ip, name]) => ip && ( ) )} Add server Add a new server to your server list.
setNewServer((prev) => ({ ...prev, name: e.target.value, })) } placeholder="Voxa Server" />
setNewServer((prev) => ({ ...prev, ip: e.target.value, })) } placeholder="192.168.1.5" />
{/* Right column */}
{server ? (

{server.name}

) : (
)}
{server ? ( <> {server.channels.map((channel) => ( ))} ) : ( <> {dms.map((id) => ( ))} )}
{children}
); } function DMItem({ name, id, avatar, status, settings, }: { name: string; id: string; avatar: string; status: string; settings?: boolean; }) { const router = useRouter(); return (
{name} {status}
{settings && ( )} ); } function ChannelProp(channel: Channel) { return ( {channel.name} ); } function ChannelIcon({ kind }: { kind: "text" | "voice" }) { switch (kind) { case "text": return ; case "voice": return ; default: return null; } } function getUser( id: string, userList: StringMap, setUserList: React.Dispatch>> ) { if (userList[id]) return userList[id]; const onResponse = (res: Response) => { setUserList((prev) => { prev[id] = res.data as UserProfile; return prev; }); }; get(`/api/profile/?id=${id}`, onResponse) ?.then(onResponse) .catch((e) => { console.error(e); }); }