package main import ( "fmt" "strings" "charm.land/bubbles/v2/progress" tea "charm.land/bubbletea/v2" "charm.land/lipgloss/v2" ) func (m model) View() tea.View { view := tea.NewView(view(m)) view.AltScreen = true return view } func view(m model) string { if m.width == 0 || m.height == 0 { return "Loading..." } if m.err != nil { return fmt.Sprintf("Error: %v\n\nPress q to quit.", m.err) } var b strings.Builder renderQuery(&b, m) if len(m.filtered) == 0 { b.WriteString(" No services found.\n") renderHelp(&b, m) return b.String() } b.WriteString(lipgloss.JoinHorizontal(lipgloss.Left, renderList(m), renderDetails(m))) renderHelp(&b, m) return b.String() } func renderQuery(b *strings.Builder, m model) { b.WriteString(m.query.View()) b.WriteString("\n\n") } func renderHelp(b *strings.Builder, m model) { if height := m.height - strings.Count(b.String(), "\n") - If(m.help.ShowAll, 2, 1); height > 0 { b.WriteString(strings.Repeat("\n", height)) } b.WriteString(m.help.View(m.keys)) } func renderList(m model) string { var panel = lipgloss.NewStyle().Height(m.amount*3 - 1).Width(m.width / 2) var b strings.Builder last := min(len(m.filtered), m.offset+m.amount) for i := m.offset; i < last; i++ { s := m.filtered[i] cursor := " " if i == m.cursor { cursor = ">" } status := status(s.Active) line := fmt.Sprintf( "%s %s %s \n %s\n"+If(i == last-1, "", "\n"), cursor, status, s.Name, s.Desc, ) b.WriteString(line) } return panel.Render(b.String()) } func renderDetails(m model) string { var panel = lipgloss.NewStyle().Height(m.amount*3 - 1).MaxWidth(m.width / 2) var b strings.Builder d := m.detail sys := m.system fmt.Fprintf(&b, "%s\n%s\n\n", d.Name, d.Desc) prog := progress.New(progress.WithColors(lipgloss.White), progress.WithFillCharacters('█', '░'), progress.WithoutPercentage()) if d.Active == "active" { fmt.Fprintf(&b, "▣ Memory - %s / %s\n%s\n\n", d.Memory.Fmt, d.MemoryMax.Alt(sys.Memory).Fmt, prog.ViewAs(d.Memory.Div(d.MemoryMax.Alt(sys.Memory)))) fmt.Fprintf(&b, "≡ Tasks - %s / %s\n%s\n\n", d.Tasks.Fmt, d.TasksMax.Alt(sys.Tasks).Fmt, prog.ViewAs(d.Tasks.Div(d.TasksMax.Alt(sys.Tasks)))) fmt.Fprintf(&b, "⌁ CPU - %ds\n\n", int(d.Cpu)) } fmt.Fprintf(&b, "%s %s / %s / %s\n", status(d.Active), d.Active, d.Load, d.Sub) state := If(d.Active == "active" || d.Active == "failed", 1, If(d.Active == "inactive", -1, 0)) b.WriteString(lipgloss.NewStyle().Width(prog.Width()).Align(lipgloss.Right).Render(If(state == 1, stop, If(state == -1, start, "")))) return panel.Render(b.String()) }