separate domain listing into its own model
This commit is contained in:
parent
04ebd05a8f
commit
ef2dbcede5
5 changed files with 162 additions and 76 deletions
|
|
@ -7,6 +7,7 @@ type Page int
|
|||
const (
|
||||
PageLogin Page = iota
|
||||
PageMenu
|
||||
PageListDomains
|
||||
)
|
||||
|
||||
type SwitchPageMsg struct {
|
||||
|
|
@ -17,4 +18,7 @@ type SessionReadyMsg struct {
|
|||
Client *porkbun.Client
|
||||
}
|
||||
|
||||
type ListDomainsMsg struct {
|
||||
}
|
||||
|
||||
type ErrorMsg error
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/config"
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/messages"
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/pages/listdomains"
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/pages/login"
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/pages/menu"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
|
|
@ -15,6 +16,7 @@ type MainModel struct {
|
|||
currentPage messages.Page
|
||||
login *login.Model
|
||||
menu *menu.Model
|
||||
listDomains *listdomains.Model
|
||||
isMenuInit bool
|
||||
width int
|
||||
height int
|
||||
|
|
@ -42,6 +44,10 @@ func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
var cmds []tea.Cmd
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
if msg.String() == "ctrl+c" {
|
||||
return m, tea.Quit
|
||||
}
|
||||
case tea.WindowSizeMsg:
|
||||
m.width = msg.Width
|
||||
m.height = msg.Height
|
||||
|
|
@ -50,13 +56,16 @@ func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
return m, nil
|
||||
case messages.SessionReadyMsg:
|
||||
m.menu = menu.New(msg.Client)
|
||||
m.listDomains = listdomains.New(msg.Client)
|
||||
if m.width > 0 && m.height > 0 {
|
||||
newMenu, _ := m.menu.Update(tea.WindowSizeMsg{Width: m.width, Height: m.height})
|
||||
m.menu = newMenu.(*menu.Model)
|
||||
}
|
||||
m.currentPage = messages.PageMenu
|
||||
m.isMenuInit = true
|
||||
return m, m.menu.Init()
|
||||
return m, tea.Batch(m.menu.Init(), m.listDomains.Init())
|
||||
case messages.ListDomainsMsg:
|
||||
m.currentPage = messages.PageListDomains
|
||||
}
|
||||
|
||||
switch m.currentPage {
|
||||
|
|
@ -68,6 +77,10 @@ func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
var newMenu tea.Model
|
||||
newMenu, cmd = m.menu.Update(msg)
|
||||
m.menu = newMenu.(*menu.Model)
|
||||
case messages.PageListDomains:
|
||||
var newModel tea.Model
|
||||
newModel, cmd = m.listDomains.Update(msg)
|
||||
m.listDomains = newModel.(*listdomains.Model)
|
||||
}
|
||||
cmds = append(cmds, cmd)
|
||||
|
||||
|
|
@ -80,6 +93,8 @@ func (m MainModel) View() string {
|
|||
return m.login.View()
|
||||
case messages.PageMenu:
|
||||
return m.menu.View()
|
||||
case messages.PageListDomains:
|
||||
return m.listDomains.View()
|
||||
default:
|
||||
return "Unknown Page"
|
||||
}
|
||||
|
|
|
|||
140
internal/ui/pages/listdomains/model.go
Normal file
140
internal/ui/pages/listdomains/model.go
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
package listdomains
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/porkbun"
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/messages"
|
||||
"github.com/charmbracelet/bubbles/paginator"
|
||||
"github.com/charmbracelet/bubbles/spinner"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
loading bool
|
||||
client *porkbun.Client
|
||||
domains []string
|
||||
paginator paginator.Model
|
||||
spinner spinner.Model
|
||||
stderr string
|
||||
}
|
||||
|
||||
func New(client *porkbun.Client) *Model {
|
||||
p := paginator.New()
|
||||
p.Type = paginator.Dots
|
||||
p.PerPage = 1
|
||||
p.ActiveDot = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "235", Dark: "252"}).Render("•")
|
||||
p.InactiveDot = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "238"}).Render("•")
|
||||
|
||||
s := spinner.New()
|
||||
s.Spinner = spinner.Dot
|
||||
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
|
||||
|
||||
return &Model{
|
||||
loading: false,
|
||||
client: client,
|
||||
domains: nil,
|
||||
paginator: p,
|
||||
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
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
if !m.loading && msg.String() == "esc" {
|
||||
return m, func() tea.Msg {
|
||||
m.loading = false
|
||||
m.domains = nil
|
||||
m.client = nil
|
||||
return messages.SwitchPageMsg{Page: messages.PageMenu}
|
||||
}
|
||||
}
|
||||
|
||||
if len(m.domains) > 0 {
|
||||
m.paginator, cmd = m.paginator.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
case messages.ListDomainsMsg:
|
||||
m.loading = true
|
||||
m.domains = nil
|
||||
return m, tea.Batch(listDomains(m.client), m.spinner.Tick)
|
||||
|
||||
case *porkbun.DomainListAllResponse:
|
||||
m.loading = false
|
||||
for _, domain := range msg.Domains {
|
||||
m.domains = append(m.domains, renderDomain(&domain))
|
||||
}
|
||||
m.paginator.SetTotalPages(len(m.domains))
|
||||
m.paginator.Page = 0
|
||||
|
||||
case messages.ErrorMsg:
|
||||
m.stderr = fmt.Sprintf("Error: %v", msg)
|
||||
return m, nil
|
||||
}
|
||||
|
||||
if m.loading {
|
||||
m.spinner, cmd = m.spinner.Update(msg)
|
||||
return m, tea.Batch(cmd, m.spinner.Tick)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
if len(m.domains) > 0 {
|
||||
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.domains[m.paginator.Page], m.paginator.View())
|
||||
}
|
||||
|
||||
return "Uhh.. This is awkward... Press Esc to go back."
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
func renderDomain(item *porkbun.Domain) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("Domain: " + item.Domain + "\n")
|
||||
b.WriteString("Status: " + item.Status + "\n")
|
||||
b.WriteString("Create Date: " + item.CreateDate + "\n")
|
||||
b.WriteString("Expire Date: " + item.ExpireDate + "\n")
|
||||
b.WriteString("Security Lock: " + item.SecurityLock + "\n")
|
||||
b.WriteString("Whois Privacy: " + item.WhoIsPrivacy + "\n")
|
||||
b.WriteString(fmt.Sprintln("Auto Renew:", item.AutoRenew))
|
||||
b.WriteString(fmt.Sprintln("Not Local:", item.NotLocal))
|
||||
if len(item.Labels) > 0 {
|
||||
b.WriteString("Labels:\n")
|
||||
}
|
||||
for i, label := range item.Labels {
|
||||
b.WriteString("=> " + label.Title)
|
||||
if i < len(item.Labels)-1 {
|
||||
b.WriteString("\n")
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package menu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/porkbun"
|
||||
)
|
||||
|
||||
func renderDomainItem(item *porkbun.Domain) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("Domain: " + item.Domain + "\n")
|
||||
b.WriteString("Status: " + item.Status + "\n")
|
||||
b.WriteString("Create Date: " + item.CreateDate + "\n")
|
||||
b.WriteString("Expire Date: " + item.ExpireDate + "\n")
|
||||
b.WriteString("Security Lock: " + item.SecurityLock + "\n")
|
||||
b.WriteString("Whois Privacy: " + item.WhoIsPrivacy + "\n")
|
||||
b.WriteString(fmt.Sprintln("Auto Renew:", item.AutoRenew))
|
||||
b.WriteString(fmt.Sprintln("Not Local:", item.NotLocal))
|
||||
if len(item.Labels) > 0 {
|
||||
b.WriteString("Labels:\n")
|
||||
}
|
||||
for i, label := range item.Labels {
|
||||
b.WriteString("=> " + label.Title)
|
||||
if i < len(item.Labels)-1 {
|
||||
b.WriteString("\n")
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
|
@ -17,11 +17,6 @@ type pingResultMsg struct {
|
|||
IP string
|
||||
}
|
||||
|
||||
type domainListMsg struct {
|
||||
Status string
|
||||
Domains []string
|
||||
}
|
||||
|
||||
type dnsRecordListMsg struct {
|
||||
Status string
|
||||
Records []string
|
||||
|
|
@ -58,7 +53,6 @@ type Model struct {
|
|||
textInput textinput.Model
|
||||
loading bool
|
||||
state uint8
|
||||
domains []string
|
||||
records []string
|
||||
client *porkbun.Client
|
||||
err error
|
||||
|
|
@ -159,16 +153,6 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
return m, nil
|
||||
}
|
||||
|
||||
if len(m.domains) > 0 {
|
||||
var cmd tea.Cmd
|
||||
m.paginator, cmd = m.paginator.Update(msg)
|
||||
if msg.String() == "esc" {
|
||||
m.domains = nil
|
||||
return m, nil
|
||||
}
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
if len(m.records) > 0 {
|
||||
var cmd tea.Cmd
|
||||
m.paginator, cmd = m.paginator.Update(msg)
|
||||
|
|
@ -191,15 +175,6 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
m.paginator.PerPage = 1
|
||||
m.paginator.SetTotalPages(len(msg.Records))
|
||||
m.paginator.Page = 0
|
||||
m.domains = msg.Records
|
||||
return m, nil
|
||||
|
||||
case domainListMsg:
|
||||
m.loading = false
|
||||
m.paginator.PerPage = 1
|
||||
m.paginator.SetTotalPages(len(msg.Domains))
|
||||
m.paginator.Page = 0
|
||||
m.domains = msg.Domains
|
||||
return m, nil
|
||||
|
||||
case pingResultMsg:
|
||||
|
|
@ -238,10 +213,6 @@ func (m *Model) View() string {
|
|||
)
|
||||
}
|
||||
|
||||
if len(m.domains) > 0 {
|
||||
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.domains[m.paginator.Page], m.paginator.View())
|
||||
}
|
||||
|
||||
if len(m.records) > 0 {
|
||||
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.records[m.paginator.Page], m.paginator.View())
|
||||
}
|
||||
|
|
@ -256,23 +227,9 @@ func (m *Model) handleSelection(i menuItem) (tea.Model, tea.Cmd) {
|
|||
m.textInput.Focus()
|
||||
return m, textinput.Blink
|
||||
case domainListAll:
|
||||
m.loading = true
|
||||
cmd := func() tea.Msg {
|
||||
resp, err := m.client.DomainListAll(0, true)
|
||||
if err != nil {
|
||||
return messages.ErrorMsg(err)
|
||||
}
|
||||
var domains []string
|
||||
for _, domain := range resp.Domains {
|
||||
view := renderDomainItem(&domain)
|
||||
domains = append(domains, view)
|
||||
}
|
||||
return domainListMsg{
|
||||
Status: resp.Status,
|
||||
Domains: domains,
|
||||
}
|
||||
return m, func() tea.Msg {
|
||||
return messages.ListDomainsMsg{}
|
||||
}
|
||||
return m, tea.Batch(cmd, m.spinner.Tick)
|
||||
case utilPing:
|
||||
m.loading = true
|
||||
cmd := func() tea.Msg {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue