"use client" import { Button } from "@/components/ui/button" import { ScrollArea } from "@/components/ui/scroll-area" import { clearUnread, db } from "@/lib/db" import { QuestionMarkIcon } from "@phosphor-icons/react" import { formatDistanceToNow } from "date-fns" import { useLiveQuery } from "dexie-react-hooks" import { Globe2Icon, GlobeIcon, HomeIcon, MessageSquarePlusIcon, SettingsIcon, UsersIcon, XIcon } from "lucide-react" import { useRouter } from "next/navigation" import { useMemo } from "react" import UserCard from "../user/user-card" // Mock channels for testing scroll behavior - set to true to enable const ENABLE_MOCK_CHANNELS = true function createMockChannel(id: string, name: string, message: string, hoursAgo: number): SiPher.Channel { return { id: `mock-${id}`, name, type: "DM" as SiPher.Channel["type"], participants: ["current-user", `user-${id}`], isOpen: true, metadata: {}, times: { createdAt: Date.now() - 1000 * 60 * 60 * 24 * 30, updatedAt: Date.now() - 1000 * 60 * 60 * hoursAgo, lastMessage: { content: message } as unknown as SiPher.Channel["times"]["lastMessage"], lastMessageAt: Date.now() - 1000 * 60 * 60 * hoursAgo } } } // const mockChannels: SiPher.Channel[] = ENABLE_MOCK_CHANNELS ? [ // createMockChannel("1", "Alice Johnson", "Hey, are you coming to the meeting?", 0.08), // createMockChannel("2", "Bob Smith", "The project looks great!", 0.5), // createMockChannel("3", "Charlie Brown", "Can you review my PR?", 1), // createMockChannel("4", "Diana Prince", "Thanks for the help!", 2), // createMockChannel("5", "Edward Norton", "Let's catch up soon", 5), // createMockChannel("6", "Fiona Green", "Did you see the news?", 12), // createMockChannel("7", "George Wilson", "Meeting at 3pm", 24), // createMockChannel("8", "Hannah Baker", "Sounds good to me!", 48), // createMockChannel("9", "Ivan Petrov", "I'll send over the files", 72), // createMockChannel("10", "Julia Roberts", "Great work on that!", 96), // createMockChannel("11", "Kevin Hart", "LOL that's hilarious", 120), // createMockChannel("12", "Laura Palmer", "See you tomorrow", 144), // ] : [] export interface ChannelListProps { currentChannel: SiPher.Channel | null openDmChannels: SiPher.Channel[] page: SiPher.PageTypes onPageChange: (page: SiPher.PageTypes) => void emptyMessage?: string dmChannel?: { id: string participantDetails: { id: string name: string username: string displayUsername: string image: string status: "online" | "busy" | "offline" | "away" isCurrentUser: boolean }[] } onChannelSelect?: () => void isMobile?: boolean } export function ChannelList({ currentChannel, openDmChannels, page, onPageChange, emptyMessage = "No messages yet", dmChannel, onChannelSelect, isMobile, }: ChannelListProps) { const router = useRouter() const unreadCount = useLiveQuery( () => db.unreadCounts.toArray(), [] ) // Combine real channels with mock channels for testing, sorted by most recent activity const allDmChannels = useMemo(() => { return [...openDmChannels].sort((a, b) => { const aTime = a.times?.lastMessageAt ?? a.times?.updatedAt ?? 0 const bTime = b.times?.lastMessageAt ?? b.times?.updatedAt ?? 0 return bTime - aTime // Descending order (most recent first) }) }, [openDmChannels]) const handleNavigation = (path: string) => { router.push(path) onChannelSelect?.() } return (
{/* Channel List Header - Navigation Items (Desktop only) */} {!isMobile && ( <>
{/* Divider with label */}
)} {/* Mobile Navigation Buttons */} {isMobile && (
)} {/* Channel List */}
Global Nests
{/* Nest Type Selector */}
{[ { id: 'global', icon: GlobeIcon, label: 'Global', description: 'Worldwide nests' }, { id: 'continental', icon: Globe2Icon, label: 'Continent', description: 'Nests by continent' }, { id: 'country', icon: HomeIcon, label: 'Country', description: 'Your country nests' }, ].map((nest) => { const isActive = nest.id === 'global' // TODO: Replace with actual state const Icon = nest.icon return ( ) })}
{(page === "friends" || !currentChannel) && (
{/* DM Header */}
Direct Messages
{allDmChannels.length > 0 && (
{allDmChannels.map((channel) => { const isActive = dmChannel?.id === channel.id const lastMessage = channel.times?.lastMessage const lastMessageTime = channel.times?.lastMessageAt const channelUnreadCount = unreadCount?.find((unread) => unread.channelId === channel.id)?.count ?? 0 if (!channel.isOpen) return null; return (
{ clearUnread(channel.id) console.log("Cleared unread count for channel", channel.id) handleNavigation(`/channels/me/${channel.id}`) }} >
{channelUnreadCount > 0 && ( {channelUnreadCount > 99 ? '99+' : channelUnreadCount} )}
{/* Channel Info */}
{channel.name} {lastMessageTime && ( {formatDistanceToNow(lastMessageTime, { addSuffix: false })} )}
{lastMessage && ( {lastMessage.content} )}
{/* Close button - always visible on mobile, hover-visible on desktop */}
) })}
)} {allDmChannels.length === 0 && (
{emptyMessage}
)}
)} {page !== "friends" && currentChannel && (
No channels
)}
) }