import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { useServerStore } from "../stores/server.ts"; import { useChannelStore } from "../stores/channel.ts"; import { useLayoutStore } from "../stores/layout.ts"; import { CreateServerModal } from "./CreateServerModal.tsx"; import { JoinServerModal } from "./JoinServerModal.tsx"; import { ServerSettingsModal } from "./ServerSettingsModal.tsx"; import { InviteModal } from "./InviteModal.tsx"; import { useContextMenu } from "./ContextMenu.tsx"; import { api } from "../lib/api.ts"; function getInitials(name: string): string { const words = name.trim().split(/\s+/); if (words.length === 1) { return words[0].slice(0, 2).toUpperCase(); } return (words[0][0] + words[words.length - 1][0]).toUpperCase(); } export function ServerBar() { const servers = useServerStore((state) => state.servers); const activeServerId = useServerStore((state) => state.activeServerId); const fetchServers = useServerStore((state) => state.fetchServers); const setActiveServer = useServerStore((state) => state.setActiveServer); const setActiveChannel = useChannelStore((state) => state.setActiveChannel); const { isDM, setDM } = useLayoutStore(); const navigate = useNavigate(); const [showCreate, setShowCreate] = useState(false); const [showJoin, setShowJoin] = useState(false); const [settingsServerId, setSettingsServerId] = useState(null); const [inviteServer, setInviteServer] = useState<{ id: string; name: string } | null>(null); const { showMenu, MenuPortal } = useContextMenu(); useEffect(() => { fetchServers().then(() => { // ponytail: restore last active server + channel from localStorage try { const raw = localStorage.getItem('dumpster:lastChannel'); if (raw) { const { serverId, channelId } = JSON.parse(raw); const srv = useServerStore.getState().servers.find((s) => s.id === serverId); if (srv) { setActiveServer(serverId); setDM(false); // Fetch channels then restore the channel useChannelStore.getState().fetchChannels(serverId).then(() => { const ch = useChannelStore.getState().channelsByServer[serverId]?.find((c) => c.id === channelId); if (ch) { setActiveChannel(channelId); } }); } } } catch { /* ignore bad localStorage */ } }); }, [fetchServers, setActiveServer, setActiveChannel, setDM]); const handleSelect = (id: string) => { setActiveServer(id); setActiveChannel(null); setDM(false); navigate('/'); }; const handleDM = () => { setActiveServer(null); setActiveChannel(null); setDM(true); navigate('/dm'); }; const handleServerContextMenu = (e: React.MouseEvent, server: { id: string; name: string }) => { showMenu(e, [ { label: 'Server Settings', icon: '⚙', onClick: () => setSettingsServerId(server.id) }, { label: 'Invite People', icon: '📨', onClick: () => setInviteServer({ id: server.id, name: server.name }) }, { label: 'Leave Server', icon: '🚪', danger: true, onClick: () => leaveServer(server.id, server.name) }, ]); }; const leaveServer = async (serverId: string, serverName: string) => { if (!confirm(`Leave "${serverName}"? You'll need an invite to rejoin.`)) return; try { await api.delete(`/servers/${serverId}/members/me`); fetchServers(); if (activeServerId === serverId) { setActiveServer(null); setDM(true); } } catch { /* ignore */ } }; return ( <>
{servers.map((server) => ( ))}
{showCreate && setShowCreate(false)} />} {showJoin && setShowJoin(false)} />} {settingsServerId && ( setSettingsServerId(null)} /> )} {inviteServer && ( setInviteServer(null)} /> )} {MenuPortal} ); }