132 lines
2.8 KiB
Go
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
|
|
}
|
|
}
|