package main import ( "fmt" "strings" "github.com/charmbracelet/lipgloss" ) // MemberEntry renders a single member in the member list. func MemberEntry(username string, status string) string { var statusDot string switch status { case "online": statusDot = StatusOnline.Render("●") case "idle": statusDot = StatusIdle.Render("◐") default: statusDot = StatusOffline.Render("○") } return fmt.Sprintf(" %s %s", statusDot, username) } // MemberList renders the member sidebar. func MemberList(user UserProfile, members []MemberEntryData, width, height int, visible bool) string { if !visible { return "" } var lines []string lines = append(lines, CategoryStyle.Render("ONLINE")) if user.Username != "" { lines = append(lines, MemberEntry( user.DisplayName, "online", )) } for _, m := range members { status := m.Status if status == "" { status = "offline" } lines = append(lines, MemberEntry(m.DisplayName, status)) } if len(members) == 0 && user.Username != "" { lines = append(lines, "") lines = append(lines, HelpStyle.Render(" No other members")) } return MemberListStyle. Width(width). Height(height). Render(strings.Join(lines, "\n")) } // MemberEntryData is a lightweight member representation. type MemberEntryData struct { UserID string Username string DisplayName string Status string } // VoiceParticipants renders the voice participant list (used in voice channels). func VoiceParticipants(participants []VoiceParticipant, width int) string { if len(participants) == 0 { return "" } var lines []string lines = append(lines, CategoryStyle.Render("VOICE")) for _, p := range participants { icon := "🔊" if p.State != "connected" { icon = "🔇" } lines = append(lines, fmt.Sprintf(" %s %s", icon, p.Username)) } return lipgloss.NewStyle(). Width(width). Render(strings.Join(lines, "\n")) }