porkbacon/internal/ui/pages/listdomains/model.go
2026-01-26 21:45:35 +00:00

132 lines
2.8 KiB
Go

package listdomains
import (
"fmt"
"sort"
"git.juancwu.dev/juancwu/porkbacon/internal/porkbun"
"git.juancwu.dev/juancwu/porkbacon/internal/ui/messages"
"github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
type item struct {
domain porkbun.Domain
}
func (i item) Title() string { return i.domain.Domain }
func (i item) Description() string {
return fmt.Sprintf("Status: %s | Expires: %s", i.domain.Status, i.domain.ExpireDate)
}
func (i item) FilterValue() string { return i.domain.Domain }
type Model struct {
loading bool
client *porkbun.Client
list list.Model
spinner spinner.Model
stderr string
}
func New(client *porkbun.Client) Model {
l := list.New([]list.Item{}, list.NewDefaultDelegate(), 0, 0)
l.Title = "My Domains"
l.SetShowHelp(true)
s := spinner.New()
s.Spinner = spinner.Dot
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
return Model{
loading: false,
client: client,
list: l,
spinner: s,
}
}
func (m Model) Init() tea.Cmd {
return m.spinner.Tick
}
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.list.SetSize(msg.Width, msg.Height)
case tea.KeyMsg:
if m.loading {
break
}
if msg.String() == "enter" {
if i, ok := m.list.SelectedItem().(item); ok {
return m, func() tea.Msg {
return messages.DomainSelectedMsg{Domain: &i.domain}
}
}
}
case messages.ListDomainsMsg:
m.loading = true
cmds = append(cmds, listDomains(m.client), m.spinner.Tick)
return m, tea.Batch(cmds...)
case *porkbun.DomainListAllResponse:
m.loading = false
var items []list.Item
for _, domain := range msg.Domains {
items = append(items, item{domain: domain})
}
// Sort by domain name
sort.Slice(items, func(i, j int) bool {
return items[i].(item).domain.Domain < items[j].(item).domain.Domain
})
cmd = m.list.SetItems(items)
cmds = append(cmds, cmd)
case messages.ErrorMsg:
m.stderr = fmt.Sprintf("Error: %v", msg)
m.loading = false
return m, nil
}
if m.loading {
m.spinner, cmd = m.spinner.Update(msg)
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...)
}
m.list, cmd = m.list.Update(msg)
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...)
}
func (m Model) View() string {
if m.stderr != "" {
return fmt.Sprintf("%s\n\n(Press ctrl+c to quit)", m.stderr)
}
if m.loading {
return fmt.Sprintf("\n\n %s Loading... press ctl+c to quit\n\n", m.spinner.View())
}
return m.list.View()
}
func listDomains(client *porkbun.Client) tea.Cmd {
return func() tea.Msg {
resp, err := client.DomainListAll(0, true)
if err != nil {
return messages.ErrorMsg(err)
}
return resp
}
}